Problem: IdentifyTask returns scale dependent layers outside of scale range. It’s different between jsapi 2.x and 3.x. It’s taken me about six attempts to get this right, each time declaring that I’ve nailed it!!.. in mock irony, because one of my C++ professor’s favorite lines was “…Son, programming is like nailing jello to a wall.” Guess the post modern irony didn’t help.
A Solution: Note the checking of subLayerIds for null, scale checking, after getting the visibleLayers from service.
function doIdentify(evt) {
var referenceLayer = new esri.layers.ArcGISDynamicMapServiceLayer(referenceMapServiceName, {id: 'referenceLayer'});
var aVisibleSubLayers = referenceLayer.visibleLayers,
aLayersInScale = [],
identifyParams = new esri.tasks.IdentifyParameters(),
identifyTask = new esri.tasks.IdentifyTask(referenceLayer.url);
//loop thru visible sublayers that are not group layers, then check within scale
if (referenceLayer.visible === true && aVisibleSubLayers.length !== 0 && aVisibleSubLayers[0] !== -1) {
dojo.forEach(referenceLayer.createDynamicLayerInfosFromLayerInfos(), function (dLayInfo) {
if (dLayInfo.subLayerIds === null && dojo.indexOf(aVisibleSubLayers, dLayInfo.id) !== -1 &&
(dLayInfo.minScale === undefined || dLayInfo.minScale === 0 || map.getScale() <= dLayInfo.minScale) &&
(dLayInfo.maxScale === undefined || dLayInfo.maxScale === 0 || map.getScale() >= dLayInfo.maxScale)) {
aLayersInScale.push(dLayInfo.id);
}
});
}
if (aLayersInScale.length > 0) {
identifyParams.geometry = evt.mapPoint;
identifyParams.mapExtent = map.extent;
identifyParams.tolerance = 3;
identifyParams.returnGeometry = true;
identifyParams.layerIds = aLayersInScale;
identifyParams.layerOption = esri.tasks.IdentifyParameters.LAYER_OPTION_ALL;
identifyParams.width = map.width;
identifyParams.height = map.height;
identifyTask.execute(identifyParams, function(idResults) {
doSomethingWithIdentifyResults(idResults);
});
}
}
Bonus: Identifies on multiple services at once and returns results as one array using dojo.DeferredList
dojo.require("dojo.DeferredList");
referenceLayer = new esri.layers.ArcGISDynamicMapServiceLayer(referenceMapServiceName, {id: 'referenceLayer'});
//Operational layers
operationalLayer = new esri.layers.ArcGISDynamicMapServiceLayer(operationalMapServiceName, {id: 'operationalLayer'});
function executeIdentify(geom, serviceName, aLayerIds) {
var identifyParams = new esri.tasks.IdentifyParameters(),
identifyTask = new esri.tasks.IdentifyTask(serviceName);
identifyParams.geometry = geom;
identifyParams.mapExtent = map.extent;
identifyParams.tolerance = 3;
identifyParams.returnGeometry = true;
identifyParams.layerIds = aLayerIds;
identifyParams.layerOption = esri.tasks.IdentifyParameters.LAYER_OPTION_ALL;
identifyParams.width = map.width;
identifyParams.height = map.height;
return identifyTask.execute(identifyParams);
}
function doIdentify(evt) {
var geom = evt.mapPoint,
aLayersInScale,
aDeferreds = [],
deferredList,
currentScale = map.getScale(),
aVisibleSubLayers,
aAGSDynMapServicesToIdentify = [referenceLayer, operationalLayer];
map.graphics.clear();
identifyLayerKeyPrevious = undefined;
//loop thru dynamic services, then thru visible sublayers that are not group layers, then check within scale
dojo.forEach(aAGSDynMapServicesToIdentify, function (agsDynMapService) {
aVisibleSubLayers = agsDynMapService.visibleLayers;
if (agsDynMapService.visible === true && aVisibleSubLayers.length !== 0 && aVisibleSubLayers[0] !== -1) {
aLayersInScale = [];
dojo.forEach(agsDynMapService.createDynamicLayerInfosFromLayerInfos(), function (dLayInfo) {
if (dLayInfo.subLayerIds === null && dojo.indexOf(aVisibleSubLayers, dLayInfo.id) !== -1 &&
(dLayInfo.minScale === undefined || dLayInfo.minScale === 0 || currentScale <= dLayInfo.minScale) &&
(dLayInfo.maxScale === undefined || dLayInfo.maxScale === 0 || currentScale >= dLayInfo.maxScale)) {
aLayersInScale.push(dLayInfo.id);
}
});
if (aLayersInScale.length > 0) {
aDeferreds.push(executeIdentify(evt.mapPoint, agsDynMapService.url, aLayersInScale));
}
}
});
// create a deferred list to aggregate the state for multiple asynchronous identify queries
deferredList = new dojo.DeferredList(aDeferreds);
deferredList.then(function (aIdentifyResults) {
// "aIdentifyResults" is 2D array of results
// array[n][0] boolean true or false, success or failure of individual call
// array[n][1] is the array of identity results returned
doSomethingWithIdentifyResults(aIdentifyResults);
});
}
.
This looks very helpful. Can you also share the “doSomethingWithIdentifyResults” function?
Thanks
Simon