Problem with Identify on a DynamicMapServiceLayer with a class break renderer applied

3688
6
Jump to solution
03-29-2016 03:40 PM
TomRippetoe
Occasional Contributor

I am seeing some unexpected behavior when my code performs an Identify operation against a DynamicMapServiceLayer that has a class breaks renderer applied to it. My code is using the default Identify operation, i.e. map.setInfoWindowOnClick(true).

The 'unexpected behavior' is that no feature(s) from the dynamic map service is returned in the Identify features result set when i have set a class breaks renderer on the dynamic map service. But, when i use just the default renderer, the Identify behaves as expected - a feature is returned from the Identify operation.

One potentially interesting bit of info is that the dynamic map service URL is a map service created as part of a geoprocessing service (that may just be a red herring but thought i would include it just in case......)

Here's a code snippet:

var vizLayer = new ArcGISDynamicMapServiceLayer(url, { "id": vLayer.id });

var renderer = new ClassBreaksRenderer(genericSymbol, "vizRender");

renderer.addBreak({minValue: -10, maxValue: 20, symbol: LowSymbol, label: "0 - 20%"});

renderer.addBreak({minValue: 20, maxValue: 40, symbol: MediumLowSymbol, label: "20 - 40%"});

renderer.addBreak({minValue: 40, maxValue: 60, symbol: MediumSymbol, label: "40 - 60%"});

renderer.addBreak({minValue: 60, maxValue: 80, symbol: MediumHighSymbol, label: "60 - 80%"});

renderer.addBreak({minValue: 80, maxValue: 110, symbol: HighSymbol, label: "80 - 100%"});

var optionsArray = [];

var drawingOptions = new LayerDrawingOptions();

drawingOptions.renderer = renderer;

optionsArray[0] = drawingOptions;

vizLayer.setLayerDrawingOptions(optionsArray);

When I comment out the last line of code, (vizLayer.setLayerDrawingOptions(optionsArray)) and leave everything else the same, the Identify returns a feature(s) from the dynamic map service.  However, if i leave the line of code in, the Identify returns no features from the dynamic map service.

Is that the expected behavior? is there a way i can do an Identify against a dynamic service with a renderer applied?

Thank you.

0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Emeritus

Thomas,

  Sorry for the delay. Here is a sample that show how using a esri service that supports layer drawing options. And yes you do have to set the infoTemplate.

<!DOCTYPE html>
<html>

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">

  <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
  <title>Class Breaks Renderer</title>

  <link rel="stylesheet" href="https://js.arcgis.com/3.13/esri/css/esri.css">
  <link rel="stylesheet" href="https://js.arcgis.com/3.13/dijit/themes/claro/claro.css">
  <style>
    html,
    body,
    #map {
      height: 100%;
      margin: 0;
      padding: 0;
    }
  </style>
  <script src="https://js.arcgis.com/3.13/"></script>
  <script>
    var map;
    require([
      "esri/map", "esri/layers/FeatureLayer",
      "esri/InfoTemplate", "esri/symbols/SimpleFillSymbol",
      "esri/renderers/ClassBreaksRenderer", "esri/layers/ImageParameters",
      "esri/layers/ArcGISDynamicMapServiceLayer",
      "esri/layers/LayerDrawingOptions",
      "esri/config", "esri/Color", "dojo/dom-style", "dojo/domReady!"
    ], function(
      Map, FeatureLayer,
      InfoTemplate, SimpleFillSymbol,
      ClassBreaksRenderer, ImageParameters,
      ArcGISDynamicMapServiceLayer,
      LayerDrawingOptions, esriConfig,
      Color, domStyle
    ) {
      //esriConfig.defaults.io.corsEnabledServers.push("sampleserver1.arcgisonline.com");
      map = new Map("map", {
        basemap: "streets",
        center: [-98.215, 38.382],
        zoom: 7,
        slider: false
      });

      map.setInfoWindowOnClick(true);
      var url = "http://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer";
      var imageParameters = new ImageParameters();
      imageParameters.layerIds = [2];
      imageParameters.format = "png32";
      imageParameters.layerOption = ImageParameters.LAYER_OPTION_SHOW;

      var vizLayer = new ArcGISDynamicMapServiceLayer(url, {
        "id": "vizLayer",
        "imageParameters": imageParameters
      });
      var infoTemplate = new InfoTemplate("${NAME}", "${*}");
      vizLayer.setInfoTemplates({
        2: { infoTemplate: infoTemplate }
      });
      var layerDefinitions = [];
      layerDefinitions[2] = "STATE_NAME = 'Kansas'";
      vizLayer.setLayerDefinitions(layerDefinitions);

      var symbol = new SimpleFillSymbol();
      symbol.setColor(new Color([150, 150, 150, 0.5]));

      var renderer = new ClassBreaksRenderer(symbol, "POP07_SQMI");
      renderer.addBreak(0, 25, new SimpleFillSymbol().setColor(new Color([56, 168, 0, 0.5])));
      renderer.addBreak(25, 75, new SimpleFillSymbol().setColor(new Color([139, 209, 0, 0.5])));
      renderer.addBreak(75, 175, new SimpleFillSymbol().setColor(new Color([255, 255, 0, 0.5])));
      renderer.addBreak(175, 400, new SimpleFillSymbol().setColor(new Color([255, 128, 0, 0.5])));
      renderer.addBreak(400, 999999, new SimpleFillSymbol().setColor(new Color([255, 0, 0, 0.5])));

      var optionsArray = [];
      var drawingOptions = new LayerDrawingOptions();
      drawingOptions.renderer = renderer;
      optionsArray[2] = drawingOptions;
      vizLayer.setLayerDrawingOptions(optionsArray);
      map.addLayer(vizLayer);
      map.setInfoWindowOnClick(true);
    });
  </script>
</head>

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

</html>

View solution in original post

0 Kudos
6 Replies
RobertScheitlin__GISP
MVP Emeritus

Thomas,

  Can you share a code sample that exhibits this issue? FYI terminology for what you are talking about is a layer popup when you say identify people are going to assume the Identify task. I think it is going to have something to do with the symbol you have defined for the renderer.

0 Kudos
TomRippetoe
Occasional Contributor

Hi Robert.

(Last night I tried to reply to your comment via email, but it seems not to have worked. So, i am copy/pasting my reply directly on the GeoNet site. Sorry if this ends up being eventually duplicated.....).

Thanks for your reply.  You are correct, I am not using an Identify Task. I apologize for the confusion.  I am using the map’s default ‘onClick’ behavior to display a popup/info window. The code to set that is:

map.setInfoWindowOnClick(true);

Not sure I have much code to show other than the snippet I presented in the original post. In lieu of code,  here is a more detailed description that is hopefully helpful.  I am using the 3.13 API.  My map has 10+ layers on it – mostly typical stuff: states, congressional districts, multiple levels of HUCs and so on.  One of the tools I have built takes a collection of user input, then calls a server side geoprocessing service that we created.  The GP service does some modeling work and generates a map service for all the HUC 12s within a selected HUC 8.  That resulting map service is then added to the map as a dynamic map layer.  A user can then click anywhere in the HUC 8 (or anywhere on the map actually), and a popup displays features from the visible layers that are “underneath” the click, e.g. the state, congressional district, HUC 8  Code, HUC 12 Code, and so.

If I don’t apply a renderer to the GP generated map layer, intersecting features from that layer are displayed in the popup. However, if I set the class break renderer for the GP generated layer, no features from that layer are displayed in popup.

Using Fiddler to compare the REST query requests that are generated as a result of the map click, I can see that there is a REST request against the GP generated layer when the renderer is not set, but there is not a REST request against the GP generated layer when I set the class break renderer.

This is the code I use to create the ‘generic symbol’ that is passed into the class break renderer as the default symbol (class break renderer code in original post):

var genericSymbol = new SimpleFillSymbol();

genericSymbol.setColor(new Color([200,200,200,1]));

genericSymbol.setOutline(new SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new Color([100,100,100]),0.5));

Thanks again for your help.

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Thomas,

  No, unfortunately a better description does not help much because there is no normal reason that using a classbreak renderer should affect the popup. So it is more to due with your code implementation. Can you maybe adjust this code sample to demonstrate your issue?

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">

    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
    <title>Class Breaks Renderer</title>

    <link rel="stylesheet" href="https://js.arcgis.com/3.16/esri/css/esri.css">
    <style>
      html, body, #map{
        height: 100%;
        margin: 0;
        padding: 0;
      }
    </style>
    <script src="https://js.arcgis.com/3.16/"></script>
    <script>
      var map;
      require([
        "esri/map", "esri/layers/FeatureLayer",
        "esri/InfoTemplate", "esri/symbols/SimpleFillSymbol",
        "esri/renderers/ClassBreaksRenderer",
        "esri/Color", "dojo/dom-style", "dojo/domReady!"
      ], function(
        Map, FeatureLayer,
        InfoTemplate, SimpleFillSymbol,
        ClassBreaksRenderer,
        Color, domStyle
      ) {
        map = new Map("map", {
          basemap: "streets",
          center: [-98.215, 38.382],
          zoom: 7,
          slider: false
        });

        var symbol = new SimpleFillSymbol();
        symbol.setColor(new Color([150, 150, 150, 0.5]));

        // Add five breaks to the renderer.
        // If you have ESRI's ArcMap available, this can be a good way to determine break values.
        // You can also copy the RGB values from the color schemes ArcMap applies, or use colors
        // from a site like www.colorbrewer.org
        //
        // alternatively, ArcGIS Server's generate renderer task could be used
        var renderer = new ClassBreaksRenderer(symbol, "POP07_SQMI");
        renderer.addBreak(0, 25, new SimpleFillSymbol().setColor(new Color([56, 168, 0, 0.5])));
        renderer.addBreak(25, 75, new SimpleFillSymbol().setColor(new Color([139, 209, 0, 0.5])));
        renderer.addBreak(75, 175, new SimpleFillSymbol().setColor(new Color([255, 255, 0, 0.5])));
        renderer.addBreak(175, 400, new SimpleFillSymbol().setColor(new Color([255, 128, 0, 0.5])));
        renderer.addBreak(400, Infinity, new SimpleFillSymbol().setColor(new Color([255, 0, 0, 0.5])));

        var infoTemplate = new InfoTemplate("${NAME}", "${*}");
        var featureLayer = new FeatureLayer("https://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer/3", {
          mode: FeatureLayer.MODE_SNAPSHOT,
          outFields: ["*"],
          infoTemplate: infoTemplate
        });

        featureLayer.setDefinitionExpression("STATE_NAME = 'Kansas'");
        featureLayer.setRenderer(renderer);
        map.addLayer(featureLayer);
      });
    </script>
  </head>

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

</html>
0 Kudos
TomRippetoe
Occasional Contributor

Hi Robert.

I am working on a JSBIN which merges together your sample code and my code.  I am using the Esri sample service URL from your sample, but i am running into problems when calling:

vizLayer.setLayerDrawingOptions(optionsArray);

I am guessing that "https://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer" does not allow server side dynamic rendering?  Do you know of any Esri sample services that do allow that? or perhaps I am doing something else wrong altogether?

Anyway, if you comment out the line for 'setLayerDrawingOptions()', the map does display without error.  And if you click on a county, no info window is displayed.  Is the problem as simple as me not defining an InfoWindowTemplate?  Not sure why, but i have assumed that a default info window/popup would be displayed even if i didn't define one.

Tom

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Thomas,

  Sorry for the delay. Here is a sample that show how using a esri service that supports layer drawing options. And yes you do have to set the infoTemplate.

<!DOCTYPE html>
<html>

<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">

  <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
  <title>Class Breaks Renderer</title>

  <link rel="stylesheet" href="https://js.arcgis.com/3.13/esri/css/esri.css">
  <link rel="stylesheet" href="https://js.arcgis.com/3.13/dijit/themes/claro/claro.css">
  <style>
    html,
    body,
    #map {
      height: 100%;
      margin: 0;
      padding: 0;
    }
  </style>
  <script src="https://js.arcgis.com/3.13/"></script>
  <script>
    var map;
    require([
      "esri/map", "esri/layers/FeatureLayer",
      "esri/InfoTemplate", "esri/symbols/SimpleFillSymbol",
      "esri/renderers/ClassBreaksRenderer", "esri/layers/ImageParameters",
      "esri/layers/ArcGISDynamicMapServiceLayer",
      "esri/layers/LayerDrawingOptions",
      "esri/config", "esri/Color", "dojo/dom-style", "dojo/domReady!"
    ], function(
      Map, FeatureLayer,
      InfoTemplate, SimpleFillSymbol,
      ClassBreaksRenderer, ImageParameters,
      ArcGISDynamicMapServiceLayer,
      LayerDrawingOptions, esriConfig,
      Color, domStyle
    ) {
      //esriConfig.defaults.io.corsEnabledServers.push("sampleserver1.arcgisonline.com");
      map = new Map("map", {
        basemap: "streets",
        center: [-98.215, 38.382],
        zoom: 7,
        slider: false
      });

      map.setInfoWindowOnClick(true);
      var url = "http://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer";
      var imageParameters = new ImageParameters();
      imageParameters.layerIds = [2];
      imageParameters.format = "png32";
      imageParameters.layerOption = ImageParameters.LAYER_OPTION_SHOW;

      var vizLayer = new ArcGISDynamicMapServiceLayer(url, {
        "id": "vizLayer",
        "imageParameters": imageParameters
      });
      var infoTemplate = new InfoTemplate("${NAME}", "${*}");
      vizLayer.setInfoTemplates({
        2: { infoTemplate: infoTemplate }
      });
      var layerDefinitions = [];
      layerDefinitions[2] = "STATE_NAME = 'Kansas'";
      vizLayer.setLayerDefinitions(layerDefinitions);

      var symbol = new SimpleFillSymbol();
      symbol.setColor(new Color([150, 150, 150, 0.5]));

      var renderer = new ClassBreaksRenderer(symbol, "POP07_SQMI");
      renderer.addBreak(0, 25, new SimpleFillSymbol().setColor(new Color([56, 168, 0, 0.5])));
      renderer.addBreak(25, 75, new SimpleFillSymbol().setColor(new Color([139, 209, 0, 0.5])));
      renderer.addBreak(75, 175, new SimpleFillSymbol().setColor(new Color([255, 255, 0, 0.5])));
      renderer.addBreak(175, 400, new SimpleFillSymbol().setColor(new Color([255, 128, 0, 0.5])));
      renderer.addBreak(400, 999999, new SimpleFillSymbol().setColor(new Color([255, 0, 0, 0.5])));

      var optionsArray = [];
      var drawingOptions = new LayerDrawingOptions();
      drawingOptions.renderer = renderer;
      optionsArray[2] = drawingOptions;
      vizLayer.setLayerDrawingOptions(optionsArray);
      map.addLayer(vizLayer);
      map.setInfoWindowOnClick(true);
    });
  </script>
</head>

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

</html>
0 Kudos
TomRippetoe
Occasional Contributor

Setting the infoTemplate was the key. Thank you.

0 Kudos