My application loads multiple map services, and within two of the services there are grouped layers (created in ArcMap). Is it possible to return identify results for sublayers under a grouped layer, when not visible by default?
For example see below, or image attached:
Water Layers (= map service level)
- Water Valve
- Water Fire Hydrant
- Water Abandoned/Removed (= layer group, not visible by defaul)
- Fire Hydrant (A/R)
- Water Valve (A/R)
- Water Line (A/R)
- Water Line
Using the "LAYER_OPTION_VISIBLE" layerOption doesn't work. The "Water Abandoned/Removed" group layer is not visible by default from the mxd settings, so users must make it visible by checking it on the TOC/Legend (widget by NLiu). With this group layer and all sublayers checked, and when zoomed to a visible scale range, no results are found.
I tried applying your code above with no success either.
My identify code is rather long, as I built a custom info window, but here's where I set the currently visible layers upon map "click" event. It passes the correct ID's into the array [8,9,10] which equate to Fire Hydrant (A/R), Water Valve (A/R), and Water Line (A/R). But Identify Task does not produce any results for these three layers. It only works if I use LAYER_OPTION_ALL, but then I have the obvious problem of returning results from layers not currently visible.
function buildCurrentMapServiceLayerList(serviceLayer) { var lyrInfos = {}; var hasVisibleLayers = false; dynamicLayerInfos = serviceLayer.createDynamicLayerInfosFromLayerInfos(); array.forEach(dynamicLayerInfos, function (info) { var i = { id: info.id, name: info.name }; if (array.indexOf(serviceLayer.visibleLayers, info.id) > -1) { i.visible = true; hasVisibleLayers = true; } else { i.visible = false; } if (!info.subLayerIds) { lyrInfos[info.id] = i; } }); if (hasVisibleLayers === true) { mapServiceInfos[serviceLayer.id] = lyrInfos; } }
Then, to create parameters and execute identify task...
var serviceName = mapServiceInfos[idxName]; for (var idxLayer in serviceName) { //loop through layers within the current map service var layer = serviceName[idxLayer]; if (layer.name.toUpperCase().indexOf("LABEL") == -1 && layer.visible == true) { layersToIdentify.push(layer.id); } } identifyParams.layerIds = layersToIdentify; identifyParams.tolerance = 8; identifyParams.returnGeometry = true; identifyParams.layerOption = IdentifyParameters.LAYER_OPTION_VISIBLE; identifyParams.width = map.width; identifyParams.height = map.height; identifyParams.geometry = event.mapPoint; identifyParams.mapExtent = map.extent; if (layersToIdentify.length > 0) { var idDeferred = identifyTask.execute(identifyParams, function (idResults) { processIdentifyResults(idResults, event); }); }
(Using js api 3.10 against ArcGIS Server 10.0 services, soon to upgrade to 10.2.2)
Solved! Go to Solution.
Update: I found a solution.
It was hard to reproduce this issue with any other 10.02 map service / JS API 3.10 combination. However, I used LAYER_OPTION_ALL combined with this function below to guarantee I will only identify against currently visible layers at the current map scale.
The scale range was the key here.
function visibleAtCurExtent(layerInfo) { isVisible = false; //First criteria: must be a layer that is checked as visible; this doesn't guarantee it's visible at the current map extent if (array.indexOf(serviceLayer.visibleLayers, layerInfo.id) > -1) { var mapScale = map.getScale(); // initial: 288,000 var layerMinScale = layerInfo.minScale; //fittings: min=1000, max=0 var layerMaxScale = layerInfo.maxScale; //If layer has no min/max scale range, or currently above min scale range and no max scale or below max scale range, it is visible if ((layerMinScale === 0 && layerMaxScale === 0) || (layerMinScale >= mapScale && (layerMaxScale === 0 || layerMaxScale <= mapScale))) { isVisible = true; } } return isVisible; }
Then, apply when looping through DynamicLayerInfos:
array.forEach(dynamicLayerInfos, function (info) { var blnVisAtCurExt = visibleAtCurExtent(info); ......
Update: I found a solution.
It was hard to reproduce this issue with any other 10.02 map service / JS API 3.10 combination. However, I used LAYER_OPTION_ALL combined with this function below to guarantee I will only identify against currently visible layers at the current map scale.
The scale range was the key here.
function visibleAtCurExtent(layerInfo) { isVisible = false; //First criteria: must be a layer that is checked as visible; this doesn't guarantee it's visible at the current map extent if (array.indexOf(serviceLayer.visibleLayers, layerInfo.id) > -1) { var mapScale = map.getScale(); // initial: 288,000 var layerMinScale = layerInfo.minScale; //fittings: min=1000, max=0 var layerMaxScale = layerInfo.maxScale; //If layer has no min/max scale range, or currently above min scale range and no max scale or below max scale range, it is visible if ((layerMinScale === 0 && layerMaxScale === 0) || (layerMinScale >= mapScale && (layerMaxScale === 0 || layerMaxScale <= mapScale))) { isVisible = true; } } return isVisible; }
Then, apply when looping through DynamicLayerInfos:
array.forEach(dynamicLayerInfos, function (info) { var blnVisAtCurExt = visibleAtCurExtent(info); ......