Hide Table of Contents
Using Location Providers and DataAdapterFeatureLayer (beta)

Location providers are used to infer the geographical location of features based on their attributes. This functionality is very powerful for data that is coming from non-traditional sources, as it provides a means to quickly lend geographic context to that data.

Using Location Providers

  1. The locate() on each location provider expects an array of Graphic instances, so you may need to process your data and convert it from its current structure.

    Let's assume you have some data that is represented as an array of hash objects, similar to :

    var data = [{
      municipality: "Amsterdam",
      windmills: 10
      //... more key-value pairs 
    },
      //... more objects
    ];

    In order for your data to be used by a locationProvider you first need to convert your data to Graphics. Note that we only populate the attributes, and not the geometries.

    var myFeatures = array.map(data, function(entry){
      return new Graphic({ 
        attributes: entry
      }); 
    });
  2. Determine the correct type of location provider for your data. There are various different types of location providers, and selecting one may require knowledge of both the GIS resources at your disposal as well as knowledge about the data that you are going to be using. For example, if you know that you will be using data with municipalities in the Netherlands, you will probably want to use the StandardGeographyLayerLocationProvider.
    var mylocationProvider = new StandardGeographyLayerLocationProvider({
      geographyQueryTemplate: '${municipality}',  // Attribute in the feature that contains the municipality
      queryParameters: {
        countryID: 'NL',                          // Search in the Netherlands
        geographyLayerIDs: ['NL.Gemeenten']       // ...in the municipality layer
      }
    });
    // see "Available Location Providers" below for more examples.
  3. Simply call the locationProvider.locate() method. This method returns a promise, so you can register callback functions using the then() method:
    mylocationProvider.locate(myFeatures).then(function(result){
      console.log("Locate succeeded: ", result.succeeded)
      array.forEach(myFeatures, function(feature){
        map.graphics.add(feature);
      });
    });

Using Location Providers with a DataAdapterFeatureLayer

DataAdapterFeatureLayer is a layer that uses a data adapter instead of a traditional Esri service to acquire its data. It works in conjunction with a location provider to acquire its geometry. That is to say, you can use a location provider without using a DataAdapterFeatureLayer (as described above), but you will need to use location providers if you're working with a DataAdapterFeatureLayer, and this means implementing a data adapter.

A data adapter is a simple object that wraps data coming from non-traditional sources and provides methods for interacting with that data. At minimum, it has the method signatures shown below. Each method is assumed to be asynchronous and should return a Promise.

var myDataAdapter = {
  getTableInfo: function(tableId){
    var deferred = new Deferred();
    deferred.resolve({
      idField: "id",  // fieldName that is a unique identifier
      fields: [...]   // array of esri Field definitions
    });
    return deferred.promise;
  },
  query: function(queryParameters){
    var deferred = new Deferred();
    deferred.resolve({
      features:[....] // a array of features corresponding to the queryParameters
    });
    return deferred.promise;
  }
}

To create a DataAdapterFeatureLayer will need the following objects.

  • A dataAdapter Object
  • The Query Parameters that the DataAdapterFeatureLayer will use when querying the dataAdapter
  • A locationProvider to be used to infer the location of the data return by your dataAdapter

Assuming you have those things in place, the steps are fairly straightforward:

  1. Use your data adapter to query a table and return the records you want in your layer.
  2. Create a DataAdapterFeatureLayer object to capture those query results.
  3. Specify a location provider to use. At runtime, the map will geo-enable the records in your DataAdapterFeatureLayer using the supplied location provider.
var myLayer = new DataAdapterFeatureLayer(myDataAdapter, {
  dataAdapterQuery: {
    tableId: "[unique table identifier]",
    outFields: [
      "X",
      "Y"
    ] // A list of Fields available in the adapter to be used as attributes on your features. 
  },
  locationProvider: new CoordinatesLocationProvider({
    xField: "X",  
    yField: "Y"  
  })
});
map.addLayer(myLayer);

Available Location Providers

CoordinateLocationProvider used when you need to extract coordinate pairs from your attributes. This means you will need to have two fields, one denoting X values, and one denoting Y values.

var mylocationProvider = new CoordinatesLocationProvider({
  xField: "X", // Attribute in the feature that contains the x coordinate
  yField: "Y" // Attribute in the feature that contains the y coordinate
});

GeometryLocationProvider used when your data contains serialized Esri geometry JSON.

var mylocationProvider: new GeometryLocationProvider({
  geometryField: "shape",           // Attribute in the feature that contains the geometry JSON string
  geometryType: "esriGeometryPoint" // the type of geometry to expect
});

LocatorLocationProvider used when you want to use a Locator, including the World Geocoder, to determine the location of your data.

var mylocationProvider = new LocatorLocationProvider({
  mylocator: new Locator ("http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer"),
  addressFields: {   
    "Address": "STREET",
    "City": "CITY",
    "State": "STATE",
    "Zip": "ZIP"
  } // the addressFields parameter to be used with the Locator. 
    // The upper-case values correspond to attributes in the expected features.
});

QueryTaskLocationProvider uses a query task on an existing ArcGIS Map Service or Feature Service to find a geometry based on attribute matching. The whereFields parameter will be used to generate a where clause based on the input features. The unicode parameter, adds support for services that require the 'N' prefix in there where clauses in order to support unicode characters.

var queryTask = new QueryTask("http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Specialty/ESRI_StatesCitiesRivers_USA/MapServer/0");
var mylocationProvider: new QueryTaskLocationProvider({
  queryTask: queryTask,
  queryParameters: {
      outFields: ["CITY_NAME ", "STATE_NAME"] 
  },  // fields from the service to append to the features.
  whereFields: {
      "CITY_NAME ": 'municipality'
  } // the match criteria to use, a hash map of [Service Field]: [Feature Field]. 
    // In this case the QueryTask will have generated a where clause that limits the
    // CITY_NAME field by using the values in the 'municipality' fields in the input features.
});

StandardGeographyQueryLocationProvider uses a StandardGeographyQueryTask to query the GeoEnrichment Service to find the location of the features. By using the 'useFuzzySearch' query paramenter you can take advantage of the very powerful fuzzy logic for finding of locations built into the GeoEnrichment Service. More information on fuzzy search logic can be found here.

var mylocationProvider= new StandardGeographyQueryLocationProvider({
  geographyQueryTemplate: "${COUNTRY}",
  queryParameters: {
    geographyLayerIDs: ["countries"],
    useFuzzySearch: true 
  },  
  standardGeographyQueryTask: new StandardGeographyQueryTask()
});