<!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