Multiple ArcGISDynamicMapServiceLayer IdentifyTask

1369
5
06-01-2017 04:04 PM
LoriEmerson_McCormack
Occasional Contributor

I used the sample cleverly written in post Identify Sample and modified it by setting visible layers for only a few layers in each map service.  However, when I click on the map, the identify brings up results for all the layers I clicked on even though they are not visible in the map.  

In this code snippet, the layer.visibleLayers[0] =  0,33,38,13.  Can someone explain those results?

function mapReady(map) {
dojo.connect(map, "onClick", runIdentifies);
pointsLayer.setVisibleLayers([33]);
linesLayer.setVisibleLayers([38, 44]);
polygonsLayer.setVisibleLayers([13, 27, 53, 62, 83]);
}

...

layers = dojo.filter(layers, function (layer) {
if (layer.visibleLayers[0] !== -1) {
return layer.getImageUrl && layer.visible
}

Can someone help me understand how multiple map services are handled in the identify task?  For a single map service, the identifyParams.layerIds is set to the index values of the layers to identify.  For multiple map services, is the identifyParams.layerIds set to the map url AND the index of the layer?  How does the IdentifyTask know which index belongs with which map service?

Thank you.

0 Kudos
5 Replies
KenBuja
MVP Esteemed Contributor

Were those the only changes you made to the code? If not, can you post your full script?

0 Kudos
LoriEmerson_McCormack
Occasional Contributor

<!DOCTYPE html>
<!--Source: ESRI User Forums: https://community.esri.com/message/382158?commentID=382158#comment-382158 -->
<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: [-117.42330, 47.751103],
zoom: 16,
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);

var pointsURL = "http://igis.spokanecounty.org/arcgis/rest/services/PublicWorks/PublicWorksQueriesPoints/MapServer";
var linesURL = "http://igis.spokanecounty.org/arcgis/rest/services/PublicWorks/PublicWorksQueriesLines/MapServer";
var polygonsURL = "http://igis.spokanecounty.org/arcgis/rest/services/PublicWorks/PublicWorksQueriesPolygons/MapServer";

var pointsLayer = new esri.layers.ArcGISDynamicMapServiceLayer(pointsURL, {
id: "pointsLayer",
visible: true
});
map.addLayer(pointsLayer);
var linesLayer = new esri.layers.ArcGISDynamicMapServiceLayer(linesURL, {
id: "linesLayer",
visible: true
});
map.addLayer(linesLayer);
var polygonsLayer = new esri.layers.ArcGISDynamicMapServiceLayer(polygonsURL, {
id: "polygonsLayer",
visible: true
});
map.addLayer(polygonsLayer);


function mapReady(map) {
dojo.connect(map, "onClick", runIdentifies);
pointsLayer.setVisibleLayers([33]);
linesLayer.setVisibleLayers([38, 44]);
polygonsLayer.setVisibleLayers([13, 27, 53, 62, 83]);
}

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) {
alert(layer.visibleLayers[0]);
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 idTemplate = new esri.InfoTemplate;
//var idTemplate = new esri.InfoTemplate("", "Service Url: " + serviceUrl + "<br/><br/>Layer name: " + result.layerName + "<br/><br/> Object Id: ${OBJECTID}");
//feature.setInfoTemplate(idTemplate);

switch (layerName) {
case "Parcels":
idTemplate.setContent("<b>PID_NUM</b>: ${PID_NUM}" +
"</br><b>owner_name:</b> ${owner_name}");
idTemplate.setTitle(layerName);
break;
default:
idTemplate.setTitle(layerName);
break;

} // end switch stmt
feature.setInfoTemplate(idTemplate);

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;
//alert(visLayers);
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>

0 Kudos
KenBuja
MVP Esteemed Contributor

Your alert message was just showing the first item in the array of visibleLayers

alert(layer.visibleLayers[0]);

If you change it to this, it will show all the visible layers in that layer

alert(layer.visibleLayers);

LoriEmerson_McCormack
Occasional Contributor

Ah, that makes sense.  Thank you.

Why does the code then go on and take forever for the identify popup to appear?  Why does the identify popup display all layers that were clicked at a point on the map, and not just the visible layers?

0 Kudos
LoriEmerson_McCormack
Occasional Contributor

The reason the ShowIdentifyResults was taking so long to display on the map was because it was creating results for all layers in each of the dynamic map service layers.

To only ShowIdentifyResults for the visible layers, I modified the createIdentifyParams function with this:

var visLayers = layer.visibleLayers;
if (visLayers !== -1) {
   var subLayers = [];
   for (var i = 0; i < visLayers.length; i++) {
      subLayers.push(visLayers);
   } // end for stmt

   alert("idParams.layerIds=" + subLayers);
   idParams.layerIds = subLayers;
} else {
   idParams.layerIds = [];
}

0 Kudos