Select to view content in your preferred language

Problem to Set a ClassBreaksRenderer for Dynamic Layer

2765
14
Jump to solution
03-24-2014 12:24 PM
tomwang1
Regular Contributor
Hi,

I have a problem to set a ClassBreaksRenderer for Dynamic Layer. But the code works to use FeatureLayer instead. Also  works if to set a SimpleRenderer for Dynamic Layer. Please advise!

Thanks,

Tom

[HTML]
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
    <title></title>
    <link rel="stylesheet" href="http://js.arcgis.com/3.8/js/dojo/dijit/themes/tundra/tundra.css">
    <link rel="stylesheet" href="http://js.arcgis.com/3.8/js/esri/css/esri.css">
    <style>
      html, body { height: 100%; width: 100%; margin: 0; padding: 0; }     
      #map{ margin: 0; padding: 0; }
      #feedback {
        background: #fff;
        color: #444;
        position: absolute;
        font-family: arial;
        height: 32px;
        left: 30px;       
        top: 35px;
        width: 97px;
        z-index: 40;
      }
    </style>

    <script src="http://js.arcgis.com/3.8/"></script>
    <script>
        var map;

        require([
          "esri/map",
          "esri/layers/FeatureLayer",
          "esri/layers/ArcGISDynamicMapServiceLayer",
          "esri/layers/ArcGISTiledMapServiceLayer",
          "esri/layers/DynamicLayerInfo",
          "esri/layers/LayerDataSource",
          "esri/layers/LayerDrawingOptions",
          "esri/renderers/ClassBreaksRenderer",
          "esri/renderers/SimpleRenderer",
          "esri/symbols/SimpleFillSymbol",
          "esri/symbols/SimpleLineSymbol",
          "dojo/dom",
          "dojo/dom-construct",
          "dojo/dom-style",
          "dojo/parser",
          "dojo/query",
          "dojo/_base/array",
          "dojo/_base/Color",
          "dojo/dnd/Source",
          "dijit/registry",
          "dijit/form/Button",
          "dijit/layout/BorderContainer",
          "dijit/layout/ContentPane",
          "dojo/domReady!"
        ],
          function (
            Map, FeatureLayer, ArcGISDynamicMapServiceLayer, ArcGISTiledMapServiceLayer,
            DynamicLayerInfo, LayerDataSource, LayerDrawingOptions,
            ClassBreaksRenderer,SimpleRenderer, SimpleFillSymbol, SimpleLineSymbol, dom, domConstruct,
            domStyle, parser, query, arrayUtils, Color, Source, registry
        ) {

              parser.parse();

              var dndSource, layerLookup, dynamicLayerInfos;

              map = new Map("map", {
                  center: [-93.636, 46.882],
                  zoom: 4,
                  slider: false
              });

              var basemapLayer = new ArcGISTiledMapServiceLayer("http://services.arcgisonline.com/ArcGIS/rest/services/World_Terrain_Base/MapServer");
              map.addLayer(basemapLayer);

             
              registry.byId("layer").on("click", addLayer);

              function addLayer() {
                  var layerName, dataSource, layerSource, options, drawingOptions;

                  // disable the "Add" button
                  registry.byId("layer").set("disabled", true);

                  var symbol = new SimpleFillSymbol();
                  symbol.setColor(new Color([150, 150, 150, 0.5]));
                  var m_renderer = new ClassBreaksRenderer(symbol, "POP");
                  m_renderer.addBreak(0, 1000, new SimpleFillSymbol().setColor(new Color([56, 168, 0, 0.5])));
                  m_renderer.addBreak(1000, 10000, new SimpleFillSymbol().setColor(new Color([139, 209, 0, 0.5])));
                  m_renderer.addBreak(10000, 100000, new SimpleFillSymbol().setColor(new Color([255, 255, 0, 0.5])));
                  m_renderer.addBreak(100000, 1000000, new SimpleFillSymbol().setColor(new Color([255, 128, 0, 0.5])));
                  m_renderer.addBreak(1000000, Infinity, new SimpleFillSymbol().setColor(new Color([255, 0, 0, 0.5])));

                  var m_queryDataSource = new esri.layers.QueryDataSource();
                  m_queryDataSource.geometryType = "polygon";
                  m_queryDataSource.oidFields = ["OBJECTID"];
                  m_queryDataSource.query = "Select OBJECTID, Shape, Population POP from US_STATE";
                  m_queryDataSource.spatialReference = new esri.SpatialReference({ wkid: 102100 });
                  m_queryDataSource.workspaceId = "myworkspace";
                  layerSource = new LayerDataSource();
                  layerSource.dataSource = m_queryDataSource;

                  ////---------- feature layer
                  //var urlDyn = "http://myserver/arcgis/rest/services/BioD_DynamicMap/MapServer/dynamicLayer";
                  //var featureLayer = new FeatureLayer(urlDyn, {
                  //    mode: FeatureLayer.MODE_ONDEMAND,
                  //    outFields: ["*"],
                  //    source: layerSource
                  //});
                  //featureLayer.setRenderer(m_renderer);
                  //map.addLayer(featureLayer);
                  ////----------feature layer


                  //---------- Dynamic layer
                  layerName = "add a new layer from database";
                  var usaLayer = new ArcGISDynamicMapServiceLayer("http://myserver/arcgis/rest/services/BioD_DynamicMap/MapServer",
                  { "id": "NEW LAYER" });
                  usaLayer.setVisibleLayers([0]);
                  if (!dynamicLayerInfos) {
                      dynamicLayerInfos = usaLayer.createDynamicLayerInfosFromLayerInfos();
                  }
                  var dynamicLayerInfo = new DynamicLayerInfo();
                  dynamicLayerInfo.id = 0;
                  dynamicLayerInfo.name = layerName;
                  dynamicLayerInfo.source = layerSource;
                  dynamicLayerInfos.push(dynamicLayerInfo);
                  usaLayer.setDynamicLayerInfos(dynamicLayerInfos, true);
                  drawingOptions = new LayerDrawingOptions();
                  //---------- Dynamic layer

                  ////---------- Dynamic layer -- (1) SimpleRenderer
                  //drawingOptions.renderer = new SimpleRenderer(
                  //  new SimpleFillSymbol("solid", null,
                  //    new Color([255, 0, 255, 0.75]) // fuchsia lakes!
                  //  ));
                  ////---------- Dynamic layer -- (1) SimpleRenderer

                  //---------- Dynamic layer -- (2) ClassBreaksRenderer
                  drawingOptions.renderer = m_renderer;
                  //---------- Dynamic layer -- (2) ClassBreaksRenderer

                 
                  //---------- Dynamic layer
                  options = [];
                  options[0] = drawingOptions;
                  usaLayer.setLayerDrawingOptions(options);                 
                  map.addLayer(usaLayer);
                  //---------- Dynamic layer                 
              }
          });
    </script>
  </head>

  <body class="tundra">
    <div data-dojo-type="dijit/layout/BorderContainer"
         data-dojo-props="design:'headline',gutters:false"
         style="width: 100%; height: 100%; margin: 0;">
      <div id="map"
           data-dojo-type="dijit/layout/ContentPane"
           data-dojo-props="region:'center'">
        <div id="feedback">         
          <button id="layer"
                    data-dojo-type="dijit/form/Button">
              Add Layer
            </button>
        </div>
      </div>
    </div>
  </body>
[/HTML]
0 Kudos
14 Replies
Noah-Sager
Esri Regular Contributor
Hi Tom,

Yes, this is a bit confusing. The reason for this difference is that while FeatureLayers are graphics that can be modified (renderer) on the clientside, DynamicMapServiceLayers are graphics that come from ArcGIS Server (a PNG or other raster format), and can be modified on the serverside.

I think the SimpleRenderer is able to be set for DynamicMapServiceLayers because it is changing all symbology to one new symbology, whereas the ClassBreaksRenderer is actually requiring some processing and decision making, so it requires a LayerDrawingOptions method to do some work on the serverside.

Typically, we recommend customers work with FeatureLayers when there is a need for end users to interact with clientside geometry and attributes immediately, such as with the ClassBreaksRenderer.

I hope this clarifies the issue.

-Noah
0 Kudos
tomwang1
Regular Contributor
Hi Noah,

FeatureLayer dose not performed well in our case.  To set a classBreaksRenderer for dynamic layer works perfectly in Esri Silverlight API.

ArcGIS Server Rest API is the source of all esri API. I am really looking forward to see Esri JavaScript Team to have a solution. we are in process of creating a new version of JavaScript to replace our Silverlight version.

Also I would like to use GenerateRendererTask for Dynamic Layer, not only for Feature Layer. Please advise!!!



Thanks,


Tom
0 Kudos
JianHuang
Deactivated User
Tom,

You can call generateRendererTask with DynamicLayers.

var source = dynamicLayerInfo.source; var generateRendererTask = new GenerateRendererTask(mapServiceUrl + "/dynamicLayer", {    "source": source }); var params = new GenerateRendererParameters(); //set the params here //...  var generateRendererDefer = generateRendererTask.execute(params); generateRendererDefer.then(function(renderer){   //apply it to the layer   var layerDrawingOption = new LayerDrawingOptions();     layerDrawingOption.renderer = renderer;   layer.layerDrawingOptions[id] = layerDrawingOption;   layer.setLayerDrawingOptions(layer.layerDrawingOptions); });


Hope this helps.
0 Kudos
tomwang1
Regular Contributor
Hi Noah Sager and Huang Jian,

Supper thanks for your help on this. Really appreciated! I don't know how to mark Noah and Jian both as a correct answer. Your guys pointed me to a right direction.


Tom
0 Kudos
tomwang1
Regular Contributor
Hi,

Sorry I have to come back this question. Yes, the code works when to use "classificationDefinition". But how to do it if I would like to create my own classbreaks? Please advise!


[HTML]
var source = dynamicLayerInfo.source;
var generateRendererTask = new GenerateRendererTask(mapServiceUrl + "/dynamicLayer", {
   "source": source
});
var params = new GenerateRendererParameters();
//set the params here
params.classificationDefinition = ...

var generateRendererDefer = generateRendererTask.execute(params);
generateRendererDefer.then(function(renderer){
  //apply it to the layer
  var layerDrawingOption = new LayerDrawingOptions(); 
  layerDrawingOption.renderer = renderer;
  layer.layerDrawingOptions[id] = layerDrawingOption;
  layer.setLayerDrawingOptions(layer.layerDrawingOptions);
});
[/HTML]

For example, classbreaks like this:
[HTML]
var m_renderer = new ClassBreaksRenderer(symbol, "field name");
                  m_renderer.addBreak(0, 1, new SimpleFillSymbol().setColor(new Color([56, 168, 0, 0.5])));
                  m_renderer.addBreak(1, 5, new SimpleFillSymbol().setColor(new Color([139, 209, 0, 0.5])));
                  m_renderer.addBreak(6, 10, new SimpleFillSymbol().setColor(new Color([255, 255, 0, 0.5])));
                  m_renderer.addBreak(11, 20, new SimpleFillSymbol().setColor(new Color([255, 128, 0, 0.5])));
                  m_renderer.addBreak(21, Infinity, new SimpleFillSymbol().setColor(new Color([255, 0, 0, 0.5])));
[/HTML]
0 Kudos