Search code examples
javascriptdojoesri-javascript-api

How to zoom to feature selection when map and Layer wkid are different?


I have a mapservice using the Esri ArcGis Js Api v3.11.

On that map, the user can query every FeatureLayer and does get a simple grid returned. The row click event has the following handler attached:

_grid.on('dgrid-select', function(event) {
    var data = event.rows[0].data;
    //get the current selected featureLayer
    //build a query against it, using the objectId
    //zoom to position: https://developers.arcgis.com/javascript/3/jssamples/fl_zoomgrid.html
    var layerUrl = dijit.byId("LayerSelectBox").get("value");
    var url = lang.replace(_baseUrl, { layer: layerUrl });
    var fl = new FeatureLayer(url, {
        mode: FeatureLayer.MODE_SELECTION,
        outFields: ["ObjectID"]
    });
    //clear selection
    fl.clearSelection();
    query.objectIds = [data.OBJECTID];
    fl.selectFeatures(query, FeatureLayer.SELECTION_NEW, function(features) {
        //zoom to the selected feature
        var geometryExtent = features[0].geometry.getExtent().expand(5.0);
        _map.setExtent(geometryExtent);
    });
});

while the query and everything around it is working fine, zooming to the result is giving me a headache. The map has a Spatial Reference Wkid of 102100, the returned geometry of 102362.

Trying to set the extent of the map to that of the geometry or centering to a point results in the follwing error:

Map: Geometry (wkid: 102362) cannot be converted to spatial reference of the map (wkid: 102100)

The documentation to .selectFeatures (https://developers.arcgis.com/javascript/3/jsapi/featurelayer-amd.html#selectfeatures) only offers this bit of useful information:

The input query. The query object has the following restrictions to avoid conflicts between layer and map properties.

  • outFields specified by the query object are overridden by the outFields specified in the FeatureLayer constructor.
  • The returnGeometry value specified by the query object is ignored and true is used.
  • The outSpatialReference set by the query object is ignored and the map's spatial reference is used.

To be honest, that confueses me a bit. How can I convert / transform the result sr to the maps sr and center the map on it? Querying a FeatureLayer by clicking on it on the map, results in a small Dialog Window with a Zoom to button out of the box, so the functionality is there for the grabs. I just seem to be doing something fundamentally wrong.


Solution

  • In the end, the GeometryService was my rescue:

    fl.selectFeatures(query, FeatureLayer.SELECTION_NEW, function(features) {
    
        var gmsvc = new GeometryService("url//to/Geometryservice");
    
        var fooExtent = graphicUtils.graphicsExtent(features);
    
        var projectParams = new ProjectParameters();  
        projectParams.geometries = [fooExtent];  
        projectParams.outSR = map.spatialReference;  
        gmsvc.project(projectParams).then(function(x) {
            map.setExtent(x[0]);
        })
    });
    

    I am using the graphicUtils to calculate an extent from a set of geometries. This isn't strictly neccessary, but since my results can be anything, ranging from a point to a polygon, this is a nice touch and saves some switch statements.

    Next I am using my geometry service to project the extent into the spatial reference of the map and once that is done, I am setting that extent.