Can't See The Layer List

2481
19
Jump to solution
09-29-2016 09:38 AM
LloydBronn
Occasional Contributor II

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>‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos
19 Replies
LloydBronn
Occasional Contributor II

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. 

0 Kudos
LloydBronn
Occasional Contributor II

Still trying to figure this out. 

0 Kudos
Drew
by
Occasional Contributor III

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.

LloydBronn
Occasional Contributor II

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>
0 Kudos
KenBuja
MVP Esteemed Contributor

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;

LloydBronn
Occasional Contributor II

Thanks so much!! 

0 Kudos
LloydBronn
Occasional Contributor II

Would it be possible to do this with two different identify tasks with two different tolerances?

0 Kudos
KenBuja
MVP Esteemed Contributor

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

0 Kudos
LloydBronn
Occasional Contributor II

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;
0 Kudos
LloydBronn
Occasional Contributor II

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. 

0 Kudos