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.
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
Solved! Go to Solution.
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
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
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
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
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