Info window- Selection by zoom?

3226
4
Jump to solution
08-12-2014 02:18 PM
RickeyFight
MVP Regular Contributor

My webapp uses info-windows. I have a lot of objects right near each other. I do not need these to be select-able until a certain zoom level.

 

I have other objects I want to be select-able at all times (green camera Icon) and some only when I zoom in. I cannot turn off the layer at certain zoom level because I need to see all the objects at all times.

netgeoInfowindow.PNG

What happens now is that when I select an object when I am zoomed out 10 objects or more are end up selected.

I am aware of this function identifyParams.tolerance = 10; but there is the difference between points and polygons, the points are very hard to select and the polygons are too easy.

 

Does anyone know how to get around this?

I can but don't want to make another service just for the objects that are select-able at all times.

 

Thank you,

Rickey

0 Kudos
1 Solution

Accepted Solutions
OwenEarley
Occasional Contributor III

Hi Rickey,

I have commented the sections you may need to change:

            function mapReady(map) { 

                dojo.connect(map, "onClick", executeIdentifyTask); 

 

                //create identify tasks and setup parameters  

                identifyTask = new esri.tasks.IdentifyTask("http://gis.ashland.or.us/arcgis/rest/services/cemetery/MapServer"); 

 

                identifyParams = new esri.tasks.IdentifyParameters(); 

                identifyParams.tolerance = 10; 

                identifyParams.returnGeometry = true; 

                // identifyParams.layerIds = [3,1,0];  <-- Remove this line from here

                identifyParams.layerOption = esri.tasks.IdentifyParameters.LAYER_OPTION_ALL; 

                identifyParams.width = map.width; 

                identifyParams.height = map.height; 

                dojo.addClass(map.infoWindow.domNode, "myTheme"); 

            } 

 

            function executeIdentifyTask(evt) { 

                identifyParams.geometry = evt.mapPoint; 

                identifyParams.mapExtent = map.extent; 

 

                // Add your required layer ids and zoom level here

                if (map.getZoom() > 16) { 

                    identifyParams.layerIds = [3,1,0];  // Identify all

                } else { 

                    identifyParams.layerIds = [3];  // Identify photos only

                }

                var deferred = identifyTask.execute(identifyParams); 

 

                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;

                       // ... etc ...

Basically, don't set the layer ids when you define the initial identify parameters (line 11 above). Set the layer ids when the identify task is about to execute so you can check the current map extent (lines 23-28 above). This way you are defining the layers to include dynamically based on the current map zoom level.

Hope this helps.

Owen

View solution in original post

0 Kudos
4 Replies
OwenEarley
Occasional Contributor III

If you are using the Identify Task to query the features you could define your layer ids in the identify parameters dynamically based on the map zoom:

function init() {

    map.on("click", doIdentify);

    identifyTask = new IdentifyTask("http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/BloomfieldHillsMichigan/Parcels/MapServer");

    // define static identify parameters

    identifyParams = new IdentifyParameters();

    identifyParams.tolerance = 3;

    identifyParams.returnGeometry = true;

    identifyParams.layerOption = IdentifyParameters.LAYER_OPTION_ALL;

    identifyParams.width = map.width;

    identifyParams.height = map.height;

    //... etc ...

     

}

function doIdentify (event) {

    map.graphics.clear();           

    // set layers to use based on zoom level

    if (map.getZoom() > 16) {

        identifyParams.layerIds = [0, 2];

    } else {

        identifyParams.layerIds = [2];

    }

    identifyParams.geometry = event.mapPoint;

    identifyParams.mapExtent = map.extent;

    identifyTask.execute(identifyParams, function (idResults) {

      addToMap(idResults, event);

    });

}

I created a Zoom Based Identify Sample‌ on JS Bin. This is a quick re-work of an ESRI sample that limits the identification of buildings until you zoom in above level 16.

When the map loads it will be at zoom level 16 and buildings are not included in the identify params when there is a map click event. As soon as you zoom in beyond level 16 then buildings are included via the identifyParams.layerIds property.

Note that if you are not using a tiled base map you will need to check against map scale instead of zoom level.

Hope this helps.

Owen

Spatial XP

RickeyFight
MVP Regular Contributor

Owen,

Thank you for the quick reply. I believe that this solution could work for me. I have tried this morning and I am having a hard time incorporating your sample code into mine.

            function mapReady(map) {

                dojo.connect(map, "onClick", executeIdentifyTask);

                //create identify tasks and setup parameters

                identifyTask = new esri.tasks.IdentifyTask("http://gis.ashland.or.us/arcgis/rest/services/cemetery/MapServer");

                identifyParams = new esri.tasks.IdentifyParameters();

                identifyParams.tolerance = 10;

                identifyParams.returnGeometry = true;

                identifyParams.layerIds = [3,1,0];

                identifyParams.layerOption = esri.tasks.IdentifyParameters.LAYER_OPTION_ALL;

                identifyParams.width = map.width;

                identifyParams.height = map.height;

                dojo.addClass(map.infoWindow.domNode, "myTheme");

            }

            function executeIdentifyTask(evt) {

                identifyParams.geometry = evt.mapPoint;

                identifyParams.mapExtent = map.extent;

                var deferred = identifyTask.execute(identifyParams);

                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;

                        if (result.layerName === 'Cemetery_Plots') {

                            console.log(feature.attributes.Last_Name);

                            var template = new esri.InfoTemplate("${First_Name} ${Last_Name} ", "<a href=http://gis.ashland.or.us/Scratch_web/cemetery/${Photo_loc} target='_blank'> <img src=${Photo_loc} WIDTH=150 HEIGHT=150></a> <br/> <b>Last Name:</b> ${Last_Name} <br/><b> First Name:</b> ${First_Name}<br/><b> Cemetery:</b> ${Cemetery}<br/> <b>Section:</b> ${Section}<br/> <b>Block: </b>${Block}<br/> <b>Lot:</b> ${Lot}<br/> <b>Space:</b> ${Space}<br/> <b>Age:</b> ${Age}<br/> <b>Date of Birth: </b>${Date_of_Birth}<br/> <b>Birth City:</b> ${Birth_Citys}<br/><b> Birth State:</b> ${Birth_State}<br/> <b>Birth Country:</b> ${Birth_Country}<br/><b> Date of Death: </b>${Date_of_Death}<br/> <b>Death State:</b> ${Death_State}<br/><b> Death City: </b>${Death_City}<br/> <b>Spouses Name: </b>${Spouses_Name}<br/> <b>Undertaker:</b> ${Undertaker}<br/> <b>Year of Birth:</b> ${Year_of_Birth}<br/> <b>Personal Notes:</b> ${Personal_Notes}");

                            feature.setInfoTemplate(template);

                        } else if (result.layerName === 'Mausoleum_Plots') {

                            var template = new esri.InfoTemplate("${First_Name} ${Last_Name} ", "<br/> <a href=http://gis.ashland.or.us/Scratch_web/cemetery/${Photo_loc} target=_blank ;'>Grave Stone Photo</a><br/> Last Name: ${Last_Name} <br/> First Name: ${First_Name}<br/> Cemetery: ${Cemetery}<br/> Section: ${Section}<br/> Block: ${Block}<br/> Lot: ${Lot}<br/> Space: ${Space}<br/> Age: ${Age}<br/> Date of Birth: ${Date_of_Birth}<br/> Birth City: ${Birth_Citys}<br/> Birth State: ${Birth_State}<br/> Birth Country: ${Birth_Country}<br/> Date of Death: ${Date_of_Death}<br/> Death State: ${Death_State}<br/> Death City: ${Death_City}<br/> Spouses Name: ${Spouses_Name}<br/> Undertaker: ${Undertaker}<br/> Year of Birth: ${Year_of_Birth}<br/> Personal Notes: ${Personal_Notes}");

                            feature.setInfoTemplate(template);

                        } else if (result.layerName === 'panorama_photos_loc') {

                            var template = new esri.InfoTemplate("${Location}  "," <a href=${URL} target=_blank ;'><img style=border:0; src=${Image_loc} alt=Panoramic Photo  width=220 height=70></a><br/>");

                            feature.setInfoTemplate(template);

  }

         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(evt.mapPoint);

                map.infoWindow.resize(map.infoWindow._contentPane.scrollWidth + 10, map.infoWindow._contentPane.scrollHeight + 200);

                map.infoWindow.setContent(template);

                map.infoWindow.show(evt.screenPoint, map.getInfoWindowAnchor(evt.screenPoint));

                map.infoWindow.setContent(graphic.getContent());

            }

Thank you

0 Kudos
OwenEarley
Occasional Contributor III

Hi Rickey,

I have commented the sections you may need to change:

            function mapReady(map) { 

                dojo.connect(map, "onClick", executeIdentifyTask); 

 

                //create identify tasks and setup parameters  

                identifyTask = new esri.tasks.IdentifyTask("http://gis.ashland.or.us/arcgis/rest/services/cemetery/MapServer"); 

 

                identifyParams = new esri.tasks.IdentifyParameters(); 

                identifyParams.tolerance = 10; 

                identifyParams.returnGeometry = true; 

                // identifyParams.layerIds = [3,1,0];  <-- Remove this line from here

                identifyParams.layerOption = esri.tasks.IdentifyParameters.LAYER_OPTION_ALL; 

                identifyParams.width = map.width; 

                identifyParams.height = map.height; 

                dojo.addClass(map.infoWindow.domNode, "myTheme"); 

            } 

 

            function executeIdentifyTask(evt) { 

                identifyParams.geometry = evt.mapPoint; 

                identifyParams.mapExtent = map.extent; 

 

                // Add your required layer ids and zoom level here

                if (map.getZoom() > 16) { 

                    identifyParams.layerIds = [3,1,0];  // Identify all

                } else { 

                    identifyParams.layerIds = [3];  // Identify photos only

                }

                var deferred = identifyTask.execute(identifyParams); 

 

                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;

                       // ... etc ...

Basically, don't set the layer ids when you define the initial identify parameters (line 11 above). Set the layer ids when the identify task is about to execute so you can check the current map extent (lines 23-28 above). This way you are defining the layers to include dynamically based on the current map zoom level.

Hope this helps.

Owen

0 Kudos
RickeyFight
MVP Regular Contributor

Thank you so much! My map uses zoom level so I had to change line 1.

  if (map.getScale() < 1000) {   

                    identifyParams.layerIds = [3,1,0];  // Identify all 

                } else {   

                    identifyParams.layerIds = [3];  // Identify photos only 

                }  

 

Thanks again,

Rickey

0 Kudos