Get an IdentifyParameter for an IdentifyTask result

3048
5
Jump to solution
01-07-2014 09:37 AM
KenBuja
MVP Esteemed Contributor
I'm running IdentifyTasks on several different dynamic layers and I like to find out which results came from a specific service. The application is built as a template, where the layers are added using information (urls, etc) from a configuration file.

I'm using code that was developed from this thread to get my list of results. In the code, a list of IdentifyTasks is built with different IdentifyParameters for each visible layer in the map. Each of the features gets the result's layerName appended to its attributes

                formatResults = arrayUtils.map(results, function (result) {                     var feature = result.feature;                     var layerName = result.layerName;                     feature.attributes.layerName = result.layerName;                     return feature;                 });


Here is an example of the application. There are two different  services that are being identified, Benthic Data and Additional Data. The content in the  infowindow will depend on which service the feature is from.

[ATTACH=CONFIG]30326[/ATTACH]

However, since the layers are being added dynamically, I could have a case where  different services could contain layers with the same name. Therefore,  instead of the layerName, I'd like to get the url of the service appended to each feature.

Is there a way to do that? If that isn't possible, could I get the layer ID (not the numeric layerID, but the ArcGISDynamicMapServiceLayer id)?
0 Kudos
1 Solution

Accepted Solutions
KenBuja
MVP Esteemed Contributor
Here's the updated code.

Something to note is that one of the dynamic layers being identified includes layers within a group layer. If the group layer is one of the visible layers (which is not necessary to show the individual layers within it), the results will contain duplicate values. There will be results for each layer within the group layer and results for each individual layer within it that is visible.

Therefore, extra code was added to filter out group layers in the visibleLayers property in the createIdentifyParams function.

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


            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></body>

</html>

View solution in original post

0 Kudos
5 Replies
TracySchloss
Frequent Contributor
I see why you need to do this, but it looks to me that 'result' at this point doesn't know where it came from.  You'll have to somehow capture this information maybe at the point you define the identify tasks and parameters?  Maybe in an array, although I'm not sure how you're going to retrieve that information back out again. 

I have a whole other set of functions that do a  number of query tasks to generate grids of whatever the currently visible layers.  That made me study deferred/promise/all from a slightly different angle.  Let me see if anything in that might apply in this situation.
0 Kudos
KenBuja
MVP Esteemed Contributor
This is a way to attach the IdentifyTask parameters to the IdentifyResults. This came from Esri support (curiously in legacy mode and using the depreciated DeferredList)

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

        dojo.require("esri.map");
        dojo.require("esri.dijit.Popup");
        dojo.require("dojo.DeferredList");
        dojo.require("dojo.promise.all");

        var map;
        var identifyTask, identifyParams, idPoint;
        var identifyResults;

        function init() {
            var popup = new esri.dijit.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 esri.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);
        }

        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 dojo.promise.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) {
                    idParams.layerIds = layer.visibleLayers;
                } else {
                    idParams.layerIds = [];
                }
                idParams.tolerance = 3;
                idParams.returnGeometry = true;
                identifyParamsList.push(idParams);
            });
            return identifyParamsList;
        }

        dojo.ready(init);
    </script>
</head>

<body>
    <div id="map"></div>
</body>

</html>

0 Kudos
TracySchloss
Frequent Contributor
Both legacy and deprecated?  Interesting.  Is there a new object that could replace DeferredList?
0 Kudos
KenBuja
MVP Esteemed Contributor
According to the documentation, it is replaced by the dojo/promise API.
0 Kudos
KenBuja
MVP Esteemed Contributor
Here's the updated code.

Something to note is that one of the dynamic layers being identified includes layers within a group layer. If the group layer is one of the visible layers (which is not necessary to show the individual layers within it), the results will contain duplicate values. There will be results for each layer within the group layer and results for each individual layer within it that is visible.

Therefore, extra code was added to filter out group layers in the visibleLayers property in the createIdentifyParams function.

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


            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></body>

</html>
0 Kudos