<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <!--The viewport meta tag is used to improve the presentation and behavior of the samples on iOS devices--> <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"> <title>Identify with Popup</title> <link rel="stylesheet" href="http://js.arcgis.com/3.9/js/esri/css/esri.css"> <style> html, body, #map { height:100%; width:100%; margin:0; padding:0; } </style> <script src="http://js.arcgis.com/3.9/"></script> <script> var map; require([ "esri/map", "esri/InfoTemplate", "esri/layers/ArcGISDynamicMapServiceLayer", "esri/symbols/SimpleFillSymbol", "esri/symbols/SimpleLineSymbol", "esri/tasks/IdentifyTask", "esri/tasks/IdentifyParameters", "esri/dijit/Popup", "dojo/_base/array", "esri/Color", "dojo/dom-construct", "dojo/domReady!" ], function ( Map, InfoTemplate, ArcGISDynamicMapServiceLayer, SimpleFillSymbol, SimpleLineSymbol, IdentifyTask, IdentifyParameters, Popup, arrayUtils, Color, domConstruct ) { var identifyTask, identifyParams; var popup = new Popup({ fillSymbol: new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID, new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID, new Color([255, 0, 0]), 2), new Color([255, 255, 0, 0.25])) }, domConstruct.create("div")); map = new Map("map", { basemap: "satellite", center: [-83.275, 42.573], zoom: 18, infoWindow: popup }); map.on("load", mapReady); var parcelsURL = "http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/BloomfieldHillsMichigan/Parcels/MapServer"; map.addLayer(new ArcGISDynamicMapServiceLayer(parcelsURL, { opacity: .55 })); function mapReady () { map.on("click", executeIdentifyTask); //create identify tasks and setup parameters identifyTask = new IdentifyTask(parcelsURL); identifyParams = new IdentifyParameters(); identifyParams.tolerance = 3; identifyParams.returnGeometry = true; identifyParams.layerIds = [0, 2]; identifyParams.layerOption = IdentifyParameters.LAYER_OPTION_ALL; identifyParams.width = map.width; identifyParams.height = map.height; } function executeIdentifyTask (event) { identifyParams.geometry = event.mapPoint; identifyParams.mapExtent = map.extent; var deferred = identifyTask .execute(identifyParams) .addCallback(function (response) { // response is an array of identify result objects // Let's return an array of features. return arrayUtils.map(response, function (result) { var feature = result.feature; var layerName = result.layerName; feature.attributes.layerName = layerName; if (layerName === 'Tax Parcels') { var taxParcelTemplate = new InfoTemplate("", "${Postal Address} <br/> Owner of record: ${First Owner Name}"); feature.setInfoTemplate(taxParcelTemplate); } else if (layerName === 'Building Footprints') { console.log(feature.attributes.PARCELID); var buildingFootprintTemplate = new InfoTemplate("", "Parcel ID: ${PARCELID}"); feature.setInfoTemplate(buildingFootprintTemplate); } return feature; }); }); // InfoWindow expects an array of features from each deferred // object that you pass. If the response from the task execution // above is not an array of features, then you need to add a callback // like the one above to post-process the response and return an // array of features. map.infoWindow.setFeatures([deferred]); map.infoWindow.show(event.mapPoint); } }); </script> </head> <body> <div id="map"></div> </body> </html>
Solved! Go to Solution.
Here is an example of having multiple dynamic services. This also adds in attributes showing which service each result comes from.
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <!--The viewport meta tag is used to improve the presentation and behavior of the samples on iOS devices--> <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"> <title>Identify with Popup</title> <link rel="stylesheet" href="http://js.arcgis.com/3.8/js/esri/css/esri.css"> <style> html, body, #map { height: 100%; width: 100%; margin: 0; padding: 0; } </style> <script>var dojoConfig = { parseOnLoad: true };</script> <script src="http://js.arcgis.com/3.8/"></script> <script> var map; var identifyTask, identifyParams, idPoint; var identifyResults; require([ "esri/map", "esri/dijit/Popup", "dojo/promise/all", "dojo/domReady!" ], function ( Map, Popup, All ) { var popup = new Popup({ fillSymbol: new esri.symbol.SimpleFillSymbol(esri.symbol.SimpleFillSymbol.STYLE_SOLID, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([255, 0, 0]), 2), new dojo.Color([255, 255, 0, 0.25])) }, dojo.create("div")); map = new Map("map", { basemap: "satellite", center: [-83.275, 42.573], zoom: 18, infoWindow: popup }); dojo.connect(map, "onLoad", mapReady); var landBaseLayer = new esri.layers.ArcGISDynamicMapServiceLayer("http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/BloomfieldHillsMichigan/Parcels/MapServer", { opacity: .55 }); map.addLayer(landBaseLayer); var militaryLayer = new esri.layers.ArcGISDynamicMapServiceLayer("http://sampleserver6.arcgisonline.com/arcgis/rest/services/Military/MapServer", { opacity: .55 }); map.addLayer(militaryLayer); console.log(militaryLayer.declaredClass); function mapReady(map) { dojo.connect(map, "onClick", runIdentifies); } function runIdentifies(evt) { identifyResults = []; idPoint = evt.mapPoint; var layers = dojo.map(map.layerIds, function (layerId) { return map.getLayer(layerId); }); layers = dojo.filter(layers, function (layer) { if (layer.visibleLayers[0] !== -1) { return layer.getImageUrl && layer.visible } }); //Only dynamic layers have the getImageUrl function. Filter so you only query visible dynamic layers var tasks = dojo.map(layers, function (layer) { return new esri.tasks.IdentifyTask(layer.url); }); //map each visible dynamic layer to a new identify task, using the layer url var defTasks = dojo.map(tasks, function (task) { return new dojo.Deferred(); }); //map each identify task to a new dojo.Deferred var params = createIdentifyParams(layers, evt); var promises = []; for (i = 0; i < tasks.length; i++) { promises.push(tasks.execute(params)); //Execute each task } var allPromises = new All(promises); allPromises.then(function (r) { showIdentifyResults(r, tasks); }); } function showIdentifyResults(r, tasks) { var results = []; var taskUrls = []; r = dojo.filter(r, function (result) { return r[0]; }); for (i = 0; i < r.length; i++) { results = results.concat(r); for (j = 0; j < r.length; j++) { taskUrls = taskUrls.concat(tasks.url); } } results = dojo.map(results, function (result, index) { var feature = result.feature; var layerName = result.layerName; var serviceUrl = taskUrls[index]; feature.attributes.layerName = result.layerName; var template = new esri.InfoTemplate("", "Service Url: " + serviceUrl + "<br/><br/>Layer name: " + result.layerName + "<br/><br/> Object Id: ${OBJECTID}"); feature.setInfoTemplate(template); var resultGeometry = feature.geometry; var resultType = resultGeometry.type; return feature; }); if (results.length === 0) { map.infoWindow.clearFeatures(); } else { map.infoWindow.setFeatures(results); } map.infoWindow.show(idPoint); return results; } function createIdentifyParams(layers, evt) { var identifyParamsList = []; identifyParamsList.length = 0; dojo.forEach(layers, function (layer) { var idParams = new esri.tasks.IdentifyParameters(); idParams.width = map.width; idParams.height = map.height; idParams.geometry = evt.mapPoint; idParams.mapExtent = map.extent; idParams.layerOption = esri.tasks.IdentifyParameters.LAYER_OPTION_VISIBLE; var visLayers = layer.visibleLayers; if (visLayers !== -1) { var subLayers = []; for (var i = 0; i < layer.layerInfos.length; i++) { if (layer.layerInfos.subLayerIds == null) subLayers.push(layer.layerInfos.id); } idParams.layerIds = subLayers; } else { idParams.layerIds = []; } idParams.tolerance = 3; idParams.returnGeometry = true; identifyParamsList.push(idParams); }); return identifyParamsList; } }); </script> </head> <body> <div id="map"></div> </body> </html>
dojo.connect(map,"onClick",executeIdentifyTask);
//create identify tasks and setup parameters
identifyTaskCombined = new esri.tasks.IdentifyTask("<//URL Services>");
identifyTaskReps = new esri.tasks.IdentifyTask("<//URL Services>");
identifyTaskZoning = new esri.tasks.IdentifyTask("<//URL Services>");
identifyParamsCombined = new esri.tasks.IdentifyParameters();
identifyParamsCombined.tolerance = 7;
identifyParamsCombined.returnGeometry = true;
identifyParamsCombined.layerIds = [2];
identifyParamsCombined.layerOption = esri.tasks.IdentifyParameters.LAYER_OPTION_VISIBLE;
identifyParamsCombined.width = map.width;
identifyParamsCombined.height = map.height;
identifyParamsReps = new esri.tasks.IdentifyParameters();
identifyParamsReps.tolerance = 7;
identifyParamsReps.returnGeometry = true;
identifyParamsReps.layerIds = [2];
identifyParamsReps.layerOption = esri.tasks.IdentifyParameters.LAYER_OPTION_VISIBLE;
identifyParamsReps.width = map.width;
identifyParamsReps.height = map.height;
identifyParamsZoning = new esri.tasks.IdentifyParameters();
identifyParamsZoning.tolerance = 7;
identifyParamsZoning.returnGeometry = true;
identifyParamsZoning.layerIds = [2];
identifyParamsZoning.layerOption = esri.tasks.IdentifyParameters.LAYER_OPTION_VISIBLE;
identifyParamsZoning.width = map.width;
identifyParamsZoning.height = map.height;
//resize the map when the browser resizes
dojo.connect(dijit.byId('map'), 'resize', map,map.resize);
};
function executeIdentifyTask(evt){
identifyParamsReps.geometry = evt.mapPoint;
identifyParamsReps.mapExtent = map.extent;
var deferred = identifyTaskReps.execute(identifyParamsReps);
deferred.addCallback(function(response){
if (response.length > 0) {
// console.log(response.length)
// response is an array of identify result objects
// Let's return an array of features.
return dojo.map(response, function(result){
var feature = result.feature;
feature.attributes.layerName = result.layerName;
var template = new esri.InfoTemplate("", "");
feature.setInfoTemplate(template);
return feature;
});
}
else {
identifyParamsCombined.geometry = evt.mapPoint;
identifyParamsCombined.mapExtent = map.extent;
var deferred = identifyTaskCombined.execute(identifyParamsCombined);
deferred.addCallback(function(response){
// response is an array of identify result objects
// Let's return an array of features.
return dojo.map(response, function(result){
var feature = result.feature;
feature.attributes.layerName = result.layerName;
var template = new esri.InfoTemplate("", ""); //booger
feature.setInfoTemplate(template);
return feature;
});
});
};
map.infoWindow.setFeatures([deferred]);
map.infoWindow.show(evt.mapPoint);
});
map.infoWindow.setFeatures([deferred]);
map.infoWindow.show(evt.mapPoint);
};
identifyTask = new IdentifyTask("http://server/ArcGIS/rest/services/YourNewCombinedLayers/MapServer");
identifyParams = new IdentifyParameters();
...
identifyParams.layerIds = [0, 1, 2]; //Layer ids in the new map service
...
Here is an example of having multiple dynamic services. This also adds in attributes showing which service each result comes from.
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <!--The viewport meta tag is used to improve the presentation and behavior of the samples on iOS devices--> <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"> <title>Identify with Popup</title> <link rel="stylesheet" href="http://js.arcgis.com/3.8/js/esri/css/esri.css"> <style> html, body, #map { height: 100%; width: 100%; margin: 0; padding: 0; } </style> <script>var dojoConfig = { parseOnLoad: true };</script> <script src="http://js.arcgis.com/3.8/"></script> <script> var map; var identifyTask, identifyParams, idPoint; var identifyResults; require([ "esri/map", "esri/dijit/Popup", "dojo/promise/all", "dojo/domReady!" ], function ( Map, Popup, All ) { var popup = new Popup({ fillSymbol: new esri.symbol.SimpleFillSymbol(esri.symbol.SimpleFillSymbol.STYLE_SOLID, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([255, 0, 0]), 2), new dojo.Color([255, 255, 0, 0.25])) }, dojo.create("div")); map = new Map("map", { basemap: "satellite", center: [-83.275, 42.573], zoom: 18, infoWindow: popup }); dojo.connect(map, "onLoad", mapReady); var landBaseLayer = new esri.layers.ArcGISDynamicMapServiceLayer("http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/BloomfieldHillsMichigan/Parcels/MapServer", { opacity: .55 }); map.addLayer(landBaseLayer); var militaryLayer = new esri.layers.ArcGISDynamicMapServiceLayer("http://sampleserver6.arcgisonline.com/arcgis/rest/services/Military/MapServer", { opacity: .55 }); map.addLayer(militaryLayer); console.log(militaryLayer.declaredClass); function mapReady(map) { dojo.connect(map, "onClick", runIdentifies); } function runIdentifies(evt) { identifyResults = []; idPoint = evt.mapPoint; var layers = dojo.map(map.layerIds, function (layerId) { return map.getLayer(layerId); }); layers = dojo.filter(layers, function (layer) { if (layer.visibleLayers[0] !== -1) { return layer.getImageUrl && layer.visible } }); //Only dynamic layers have the getImageUrl function. Filter so you only query visible dynamic layers var tasks = dojo.map(layers, function (layer) { return new esri.tasks.IdentifyTask(layer.url); }); //map each visible dynamic layer to a new identify task, using the layer url var defTasks = dojo.map(tasks, function (task) { return new dojo.Deferred(); }); //map each identify task to a new dojo.Deferred var params = createIdentifyParams(layers, evt); var promises = []; for (i = 0; i < tasks.length; i++) { promises.push(tasks.execute(params)); //Execute each task } var allPromises = new All(promises); allPromises.then(function (r) { showIdentifyResults(r, tasks); }); } function showIdentifyResults(r, tasks) { var results = []; var taskUrls = []; r = dojo.filter(r, function (result) { return r[0]; }); for (i = 0; i < r.length; i++) { results = results.concat(r); for (j = 0; j < r.length; j++) { taskUrls = taskUrls.concat(tasks.url); } } results = dojo.map(results, function (result, index) { var feature = result.feature; var layerName = result.layerName; var serviceUrl = taskUrls[index]; feature.attributes.layerName = result.layerName; var template = new esri.InfoTemplate("", "Service Url: " + serviceUrl + "<br/><br/>Layer name: " + result.layerName + "<br/><br/> Object Id: ${OBJECTID}"); feature.setInfoTemplate(template); var resultGeometry = feature.geometry; var resultType = resultGeometry.type; return feature; }); if (results.length === 0) { map.infoWindow.clearFeatures(); } else { map.infoWindow.setFeatures(results); } map.infoWindow.show(idPoint); return results; } function createIdentifyParams(layers, evt) { var identifyParamsList = []; identifyParamsList.length = 0; dojo.forEach(layers, function (layer) { var idParams = new esri.tasks.IdentifyParameters(); idParams.width = map.width; idParams.height = map.height; idParams.geometry = evt.mapPoint; idParams.mapExtent = map.extent; idParams.layerOption = esri.tasks.IdentifyParameters.LAYER_OPTION_VISIBLE; var visLayers = layer.visibleLayers; if (visLayers !== -1) { var subLayers = []; for (var i = 0; i < layer.layerInfos.length; i++) { if (layer.layerInfos.subLayerIds == null) subLayers.push(layer.layerInfos.id); } idParams.layerIds = subLayers; } else { idParams.layerIds = []; } idParams.tolerance = 3; idParams.returnGeometry = true; identifyParamsList.push(idParams); }); return identifyParamsList; } }); </script> </head> <body> <div id="map"></div> </body> </html>
I have no problem with identifying multiple map services, but within two of the services there are grouped layers. I cannot get results returned for sublayers.
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 default)
- 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 the group layer and all sublayers checked, and within the visible scale range, nothing is returned in results.
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)
I use
idParams.layerIds = layer.visibleLayers;
which gives me the list of visible layers to use in the IdentifyTask.
This works with the subgroups I have in one of my services (and I also use the TOC widget to turn them on.

Ken, thanks for confirming this scenario. I happen to have a virtual server with 10.2.0 services running, and after substituting with a similar map service (also containing subgroups) it does indeed return the sublayers.
May I ask what API and Server combination you are using? Just for additional reference.
Much appreciated!
Hi!, I would like to know how to add context menu in each layer of the list to an attribute table is open and display it as flaps please!
thanks