I'm working with the layer list widget LayerList widget | ArcGIS API for JavaScript 3.18. I've combined it into a map with the basemap gallery and the raster identify popup. The problem is that I can't see the layer list from the map service. It works just fine using the example script above. I'm also wondering if it's possible to make the layer list pane only go down a quarter of the page instead of all the way down so it looks like a widget within the map and not a separate box next to the map? Here is my code:
<!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="https://js.arcgis.com/3.18/dijit/themes/claro/claro.css">
<link rel="stylesheet" type="text/css" href="https://js.arcgis.com/3.18/esri/css/esri.css">
<style>
html, body, .container, #map {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
margin: 0;
font-family: "arial";
}
.esriScalebar {
padding: 20px 20px;
}
#layerListPane {
width: 18%;
}
.esriLayer {
background-color: #fff;
}
.esriLayerList .esriList {
border-top: none;
}
.esriLayerList .esriTitle {
background-color: #fff;
border-bottom: none;
}
.esriLayerList .esriList ul {
background-color: transparent;
}
</style>
<script>var dojoConfig = { parseOnLoad: true };</script>
<script src="http://js.arcgis.com/3.18/"></script>
<script>
require([
"esri/map",
"esri/InfoTemplate",
"esri/layers/ArcGISDynamicMapServiceLayer",
"esri/dijit/LayerList",
"esri/arcgis/utils",
"esri/dijit/BasemapGallery",
"esri/symbols/SimpleFillSymbol",
"esri/symbols/SimpleLineSymbol",
"esri/tasks/IdentifyTask",
"esri/tasks/IdentifyParameters",
"esri/dijit/Popup",
"dojo/_base/array",
"esri/Color",
"dojo/dom-construct",
"dojo/parser",
"dijit/layout/BorderContainer",
"dijit/layout/ContentPane",
"dijit/TitlePane",
"dojo/domReady!"
], function (
Map, InfoTemplate, ArcGISDynamicMapServiceLayer,
LayerList, arcgisUtils,
BasemapGallery, SimpleFillSymbol,
SimpleLineSymbol, IdentifyTask, IdentifyParameters, Popup,
arrayUtils, Color, domConstruct, parser
) {
parser.parse();
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: "gray",
center: [-96.8, 38.5],
zoom: 4,
infoWindow: popup
});
var basemapGallery = new BasemapGallery({
showArcGISBasemaps: true,
map: map
}, "basemapGallery");
basemapGallery.startup();
basemapGallery.on("error", function(msg) {
console.log("basemap gallery error: ", msg);
});
map.on("load", mapReady);
var floodURL = "http://gis.mymetcon.com/arcgis/rest/services/Flood_Potential/MapServer";
map.addLayer(new ArcGISDynamicMapServiceLayer(floodURL,
{ opacity: .75 }));
var myWidget = new LayerList({
map: map,
layers: [{
layer: floodURL,
id: "Forecast Days",
subLayers: true
}],
//layer: floodLayer
}, "layerList");
function mapReady () {
map.on("click", executeIdentifyTask);
//create identify tasks and setup parameters
identifyTask = new IdentifyTask(floodURL);
identifyParams = new IdentifyParameters();
identifyParams.tolerance = 1;
identifyParams.returnGeometry = true;
identifyParams.layerIds = [0, 1, 2, 3, 4, 5];
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);
deferred.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;
//alert(result);
feature.attributes.layerName = layerName;
var risklevel = feature.attributes[ 'Pixel Value']
if(risklevel === '0'){risklevel = 'No Flooding';}
else if(risklevel === '1'){risklevel = 'Possible Flooding';}
else if(risklevel === '2'){risklevel = 'Probable Flooding';}
else if(risklevel === '3'){risklevel = 'Flooding';}
else if(risklevel === '4'){risklevel = 'More Significant Flooding';}
else if(risklevel === '5'){risklevel = 'Significant Flooding';}
else {risklevel = 'No Flooding';}
var floodRiskTemplate = new InfoTemplate(layerName,
"Risk Level: " + risklevel);
feature.setInfoTemplate(floodRiskTemplate);
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 class="claro">
<div class="container" data-dojo-type="dijit/layout/BorderContainer"
data-dojo-props="design:'headline',gutters:false">
<div id="layerListPane" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'right'">
<div id="layerList"></div>
</div>
<div id="map" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'center'">
<div style="position:absolute; left:75px; top:20px; z-Index:999;">
<div data-dojo-type="dijit/TitlePane" style="font-family:arial;background-color:lightgray"
data-dojo-props="title:'Switch Basemap', closable:false, open:false">
<div id="basemapGallery"></div>
</div>
</div>
</div>
</div>
</body>
</html>
Solved! Go to Solution.
I have that variable set already, but that made me realize that the identify task is referencing the map service URL and its layer IDs directly. When changed it to floodLayer and set identifyParams.layerIds = floodLayer.visibleLayers; the popup window was gone, my layers disappeared and the basemap was not visible.
Still trying to figure this out.
I would suggest creating a simple sample of the issue you are having and letting us play with it.
Its always nice to see what you are working with.
Here is the code. I'm pretty sure the problem is that the identify task is referencing the map service URL and its layer IDs, not the dynamic map service layer variable. When I change floodURL to floodLayer in line 170, the map gets all messed up and the layers are gone.
<!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="https://js.arcgis.com/3.18/dijit/themes/claro/claro.css">
<link rel="stylesheet" type="text/css" href="https://js.arcgis.com/3.18/esri/css/esri.css">
<style>
html, body, .container, #map {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
margin: 0;
font-family: "arial";
}
.esriScalebar {
padding: 20px 20px;
}
#layerListPane {
position: absolute;
top: 0px;
right: 10px;
width: 300px;
z-index: 101;
padding: 10px;
bottom: 720px;
box-shaddow: 0 0 5px 0 #DDD;
background-color:;
}
.esriLayer {
background-color:;
}
.esriLayerList .esriList {
background-color:;
}
.esriLayerList .esriTitle
background-color: ;
border-bottom: none;
}
.esriLayerList .esriList ul {
background-color: ;
}
</style>
<script>var dojoConfig = { parseOnLoad: true };</script>
<script src="http://js.arcgis.com/3.18/"></script>
<script>
require([
"esri/map",
"esri/geometry/webMercatorUtils",
"esri/InfoTemplate",
"esri/layers/ArcGISDynamicMapServiceLayer",
"esri/dijit/LayerList",
"esri/arcgis/utils",
"esri/dijit/BasemapGallery",
"esri/symbols/SimpleFillSymbol",
"esri/symbols/SimpleLineSymbol",
"esri/tasks/IdentifyTask",
"esri/tasks/IdentifyParameters",
"esri/dijit/Popup",
"dojo/_base/array",
"esri/Color",
"dojo/query",
"dojo/dom",
"dojo/dom-class",
"dojo/dom-construct",
"dojo/parser",
"dijit/layout/BorderContainer",
"dijit/layout/ContentPane",
"dijit/TitlePane",
"dojo/domReady!"
], function (
Map,webMercatorUtils, InfoTemplate, ArcGISDynamicMapServiceLayer,
LayerList, arcgisUtils,
BasemapGallery, SimpleFillSymbol,
SimpleLineSymbol, IdentifyTask, IdentifyParameters, Popup,
arrayUtils, Color, query, dom, domClass, domConstruct, parser
) {
parser.parse();
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: "gray",
center: [-96.8, 38.5],
zoom: 4,
infoWindow: popup
});
var basemapGallery = new BasemapGallery({
showArcGISBasemaps: true,
map: map
}, "basemapGallery");
basemapGallery.startup();
basemapGallery.on("error", function(msg) {
console.log("basemap gallery error: ", msg);
});
map.on("load", function() {
//after map loads, connect to listen to mouse move & drag events
map.on("mouse-move", showCoordinates);
map.on("mouse-drag", showCoordinates);
});
function showCoordinates(evt) {
//the map is in web mercator but display coordinates in geographic (lat, long)
var mp = webMercatorUtils.webMercatorToGeographic(evt.mapPoint);
//display mouse coordinates
dom.byId("info").innerHTML = "Longitude: " + mp.x.toFixed(3) + " " + "Latitude: " + mp.y.toFixed(3);
}
map.on("load", mapReady);
var floodURL = "http://gis.mymetcon.com/arcgis/rest/services/Flood_Potential/MapServer";
var floodLayer = (new ArcGISDynamicMapServiceLayer(floodURL,
{ opacity: .75 }));
map.addLayer(floodLayer);
var myWidget = new LayerList({
map: map,
layers: [{
layer: floodLayer,
id: "Forecast Days",
showsubLayers: true
}],
}, "layerList");
myWidget.startup();
myWidget.on('load', function(){
expandLayerList();
});
function expandLayerList() {
query('.esriLayer').forEach(function(node){
domClass.add(node, "esriListExpand");
});
query('.esriToggleButton').forEach(function(node){
domClass.replace(node, "esri-icon-down", "esri-icon-right");
});
}
function mapReady () {
map.on("click", executeIdentifyTask);
//create identify tasks and setup parameters
identifyTask = new IdentifyTask(floodURL);
identifyParams = new IdentifyParameters();
identifyParams.tolerance = 1;
identifyParams.returnGeometry = true;
identifyParams.layerIds = [0,1,2,3,4];
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);
deferred.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;
//alert(result);
feature.attributes.layerName = layerName;
var risklevel = feature.attributes[ 'Pixel Value']
if(risklevel === '0'){risklevel = 'No Flooding';}
else if(risklevel === '1'){risklevel = 'Possible Flooding';}
else if(risklevel === '2'){risklevel = 'Probable Flooding';}
else if(risklevel === '3'){risklevel = 'Flooding';}
else if(risklevel === '4'){risklevel = 'More Significant Flooding';}
else if(risklevel === '5'){risklevel = 'Significant Flooding';}
else {risklevel = 'No Flooding';}
var floodRiskTemplate = new InfoTemplate(layerName,
"Risk Level: " + risklevel);
feature.setInfoTemplate(floodRiskTemplate);
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 class="claro">
<div class="container" data-dojo-type="dijit/layout/BorderContainer"
data-dojo-props="design:'headline',gutters:false">
<div id="layerListPane">
<div id="layerList"></div>
</div>
<div id="map" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'center'">
<span id="info" style="font-family:arial;position:absolute;left:15px; bottom:5px; background-color:lightgray; opacity: 0.70; z-index:50;"></span>
<div style="position:absolute; left:75px; top:20px; z-Index:999;">
<div data-dojo-type="dijit/TitlePane" style="font-family:arial;background-color:lightgray"
data-dojo-props="title:'Switch Basemap', closable:false, open:false">
<div id="basemapGallery"></div>
</div>
</div>
</div>
</div>
</body>
</html>
This seems to be working correctly: JS Bin - Collaborative JavaScript Debugging
I moved the variable declarations for floodURL and floodLayer to the top, commented out the line
identifyParams.layerIds = [0,1,2,3,4];
and added the line
identifyParams.layerIds = floodLayer.visibleLayers;
Thanks so much!!
Would it be possible to do this with two different identify tasks with two different tolerances?
Yes there is.
Take a look at this reply and look for the createIdentifyParams function: https://community.esri.com/message/382158?commentID=382158#comment-382158
Both of my identify tasks are for different sublayers of a single dynamic map service layer. The tolerances are different for features (7) and rasters (1). I have all the different iTemplate popups configured. As with the other example, I have an analysisURL and analysisLayer.
function mapReady() {
map.on("click", executeIdentifyTask);
//create identify tasks and setup parameters
identifyTask = new IdentifyTask(analysisURL);
identifyParams = new IdentifyParameters();
identifyParams.returnGeometry = true;
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;
promises = [];
identifyParams.tolerance = 7;
identifyParams.layerIds = [1,2,4,5,6,8,9];
promises.push(identifyTask.execute(identifyParams));
identifyParams.tolerance = 1;
identifyParams.layerIds = [12,13,14,17,18,19];
promises.push(identifyTask.execute(identifyParams));
var iPromises = new all(promises);
iPromises.then(lang.hitch(this, function (r) {
var idResults = [];
arrayUtils.map(r, function(response) {
arrayUtils.map(response, function(result) {
var feature = result.feature;
var layerName = result.layerName;
feature.attributes.layerName = layerName;
var iTemplate;
I change the code as follows, and it works fine for the feature layers (layerIds = [1,2,4,5,6,8,9]), but not for the rasters. Changing the tolerance doesn't seem to help
function mapReady() {
map.on("click", executeIdentifyTask);
//create identify tasks and setup parameters
identifyTask = new IdentifyTask(analysisURL);
identifyParams = new IdentifyParameters();
identifyParams.returnGeometry = true;
//identifyParams.layerOption = IdentifyParameters.LAYER_OPTION_ALL;
identifyParams.tolerance = 7;
identifyParams.layerIds = analysisLayer.visibleLayers;
identifyParams.width = map.width;
identifyParams.height = map.height;
}
function executeIdentifyTask(event) {
identifyParams.geometry = event.mapPoint;
identifyParams.mapExtent = map.extent;
promises = [];
//identifyParams.tolerance = 7;
//identifyParams.layerIds = [1,2,4,5,6,8,9];
promises.push(identifyTask.execute(identifyParams))
//identifyParams.tolerance = 1;
//identifyParams.layerIds = [12,13,14,17,18,19];
//promises.push(identifyTask.execute(identifyParams));
var iPromises = new all(promises);
iPromises.then(lang.hitch(this, function (r) {
var idResults = [];
arrayUtils.map(r, function(response) {
arrayUtils.map(response, function(result) {
var feature = result.feature;
var layerName = result.layerName;
feature.attributes.layerName = layerName;
var iTemplate;
Looking at your example in that link, the popup window is showing visible layers, but it looks like those layers are always visible. I have a layer list to toggle on and off sublayers. I only want the popup to show the visible layers that are toggled on. The snippet I have above works, but the tolerances are different for features and rasters in the map service. The popup only shows the results for the toggled features, not the rasters.