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.
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 }); });
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.
mylocationProvider.locate(myFeatures).then(function(result){ console.log("Locate succeeded: ", result.succeeded) array.forEach(myFeatures, function(feature){ map.graphics.add(feature); }); });
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.
Assuming you have those things in place, the steps are fairly straightforward:
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);
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("https://www.example.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() });