Dynamic rendering based on attributes of two layers

1487
4
Jump to solution
03-20-2018 06:01 PM
Quynh_NhuMai
New Contributor III

I am rendering some dynamic layers based on attributes. I'm largely basing the code on this example : Change attribute used for a renderer | ArcGIS API for JavaScript 3.23 

I would like to be able to render two different layers in the same way (two different attribute options). They have the same attributes, so I am using the same renderer, but simply changing the optionsArray number to correspond to the correct layer. However, the problem I am running into is that the second layer still changes even if the user chooses the first layer in the combo box (the details surrounding this issue are related to the updated information below).

**UPDATE** What I've realized is that the issue lies in the fact that the new layerDrawingOptions only sets the drawing options of the layer that was chosen in the combo box. The layer that is not chosen (and therefore not defined within the drawing optionsArray) re-renders it's symbology the way it was published by the service. What I'm looking for is: if the first layer from the combo box's renderer has been changed, and then the second has been changed in a different way, the first choice persists.

My specific question is this: How do I save the current drawing options and only update to include the demand of the user? 

The code I'm using to create the comboboxes and render by attributes is here:

require([
  "esri/layers/FeatureLayer",
  "esri/layers/LayerDrawingOptions",
  "esri/InfoTemplate",
  "esri/symbols/SimpleLineSymbol",
  "esri/symbols/SimpleFillSymbol",
  "esri/renderers/UniqueValueRenderer",
  "esri/Color",
  "dijit/form/Select",
  "dijit/form/Button",
  "dojo/domReady!",
  "dojo/on",
], function(
  FeatureLayer, LayerDrawingOptions, InfoTemplate,
  SimpleLineSymbol, SimpleFillSymbol,
  UniqueValueRenderer, Color, Select, Button, on
) {


  var layer_select = new Select({
    name: "render_layer_select",
    options: [
      {label: "E_TRONCO", value: "E_TRONCO"},
      {label: "E_TRONCO Privé", value: "E_TRONCO_PR"}
    ]
  }, "render_layer_select");
  layer_select.startup();

  var res_select = new Select({
    name: "render_res_select",
    options: [
      {label: "Réseau par matériau", value: "MAT_RES"},
      {label: "Réseau par type", value: "RES_RES"}
    ]
  }, "render_res_select");
  res_select.startup();

  dynLayerCommune.on("load", getRenderLayers);

  var renderLayers;

  function getRenderLayers() {
    var layers = dojo.map(window.myMap.layerIds, function (layerId) {
      return window.myMap.getLayer(layerId);
    });
    for (i = 0; i < layers.length; i++) {
      var layerInfos = layers[i].layerInfos;
      renderLayers = [[],[]];
      for (j = 0; j < layerInfos.length; j++) {
        var layer = layerInfos[j];
        if (layer.name == 'E_TRONCO') {
          renderLayers[0].push(layer.id);
        }
        if (layer.name == 'E_TRONCO_PRIVE') {
          renderLayers[1].push(layer.id);
        }
      }
    }
    return renderLayers;
  };

  var renderButton = new Button({
    label: "Go",
    onClick: function () {
      var res_select_value = dijit.byId("render_res_select").get("value");
      if (res_select_value == 'RES_RES') {
        renderTypeRes();
      }
      if (res_select_value == 'MAT_RES') {
        renderMateriauRes();
      }
    }
  }, "render_button").startup();


  function renderTypeRes() {
    var defaultSymbol = new SimpleLineSymbol().setStyle(SimpleFillSymbol.STYLE_SOLID);

    //create renderer
    var renderer = new UniqueValueRenderer(defaultSymbol, "RESEAU");

    //add symbol for each possible value
    renderer.addValue({
      value: "DISTRIBUTION PRIVE",
      symbol: new SimpleLineSymbol().setColor(new Color([255, 0, 0, 1])),
      label: "DISTRIBUTION PRIVE"
      }
    );
    renderer.addValue({
      value: "DISTRIBUTION PUBLIC",
      symbol: new SimpleLineSymbol().setColor(new Color([0, 255, 0, 1])),
      label: "DISTRIBUTION PUBLIC"
      }
    );
    renderer.addValue({
      value: "PRODUCTION EAU INDUSTRIELLE",
      symbol: new SimpleLineSymbol().setColor(new Color([0, 0, 255, 1])),
      label: "PRODUCTION EAU INDUSTRIELLE"
      }
    );
    renderer.addValue({
      value: "PRODUCTION PUBLIC",
      symbol: new SimpleLineSymbol().setColor(new Color([255, 0, 255, 1])),
      label: "PRODUCTION PUBLIC"
      }
    );
    renderer.addValue({
      value: "PURGE",
      symbol: new SimpleLineSymbol().setColor(new Color([255, 153, 51, 1])),
      label: "PURGE"
      }
    );
    renderer.addValue({
      value: "REFOULEMENT PUBLIC",
      symbol: new SimpleLineSymbol().setColor(new Color([0, 255, 255, 1])),
      label: "REFOULEMENT PUBLIC"
      }
    );

    renderer.addValue({
      value: "",
      symbol: new SimpleLineSymbol().setColor(new Color([0, 0, 0, 1])),
      label: ""
      }
    );

    //set up dynamic layer parameters
    var optionsArray = [];
    var drawingOptions = new LayerDrawingOptions();
    drawingOptions.renderer = renderer;
    var layer_select_value = dijit.byId("render_layer_select").get("value");

    if (layer_select_value == 'E_TRONCO') {
      for (i = 0; i < renderLayers[0].length; i++) {
        var layer_idx = renderLayers[0][i];
        optionsArray[layer_idx] = drawingOptions;
      }
    }
    if (layer_select_value == 'E_TRONCO_PR') {
      for (i = 0; i < renderLayers[1].length; i++) {
        var layer_idx = renderLayers[1][i];
        optionsArray[layer_idx] = drawingOptions;
      }
    }
    window.myMap.getLayer("commune_layer").setLayerDrawingOptions(optionsArray);
    window.myMap.getLayer("commune_layer").show();
  }

  function renderMateriauRes() {
    var defaultSymbol = new SimpleLineSymbol().setStyle(SimpleFillSymbol.STYLE_SOLID);

    //create renderer
    var renderer = new UniqueValueRenderer(defaultSymbol, "MATERIAU");

    //add symbol for each possible value
    renderer.addValue({
      value: "ACIER",
      symbol: new SimpleLineSymbol().setColor(new Color([244, 197, 66, 1])),
      label: "ACIER"
      }
    );
    renderer.addValue({
      value: "AMCI",
      symbol: new SimpleLineSymbol().setColor(new Color([244, 65, 65, 1])),
      label: "AMCI"
      }
    );
    renderer.addValue({
      value: "FTD",
      symbol: new SimpleLineSymbol().setColor(new Color([50, 155, 40, 1])),
      label: "FTD"
      }
    );
    renderer.addValue({
      value: "FTG",
      symbol: new SimpleLineSymbol().setColor(new Color([50, 155, 40, 1])),
      label: "FTG"
      }
    );
    renderer.addValue({
      value: "PEBF",
      symbol: new SimpleLineSymbol().setColor(new Color([47, 121, 206, 1])),
      label: "PEBF"
      }
    );
    renderer.addValue({
      value: "PEHD",
      symbol: new SimpleLineSymbol().setColor(new Color([47, 121, 206, 1])),
      label: "PEHD"
      }
    );

    renderer.addValue({
      value: "PEN",
      symbol: new SimpleLineSymbol().setColor(new Color([14, 74, 142, 1])),
      label: "PEN"
      }
    );

    renderer.addValue({
      value: "PERD",
      symbol: new SimpleLineSymbol().setColor(new Color([47, 121, 206, 1])),
      label: "PERD"
      }
    );

    renderer.addValue({
      value: "PVC",
      symbol: new SimpleLineSymbol().setColor(new Color([219, 15, 202, 1])),
      label: "PVC"
      }
    );

    renderer.addValue({
      value: "PVC BIOROC",
      symbol: new SimpleLineSymbol().setColor(new Color([219, 15, 202, 1])),
      label: "PVC BIOROC"
      }
    );

    renderer.addValue({
      value: "PVCU",
      symbol: new SimpleLineSymbol().setColor(new Color([219, 15, 202, 1])),
      label: "PVCU"
      }
    );

    //set up dynamic layer parameters
    var optionsArray = [];
    var drawingOptions = new LayerDrawingOptions();
    drawingOptions.renderer = renderer;
    var layer_select_value = dijit.byId("render_layer_select").get("value");

    if (layer_select_value == 'E_TRONCO') {
      for (i = 0; i < renderLayers[0].length; i++) {
        var layer_idx = renderLayers[0][i];
        optionsArray[layer_idx] = drawingOptions;
      }
    }
    if (layer_select_value == 'E_TRONCO_PR') {
      for (i = 0; i < renderLayers[1].length; i++) {
        var layer_idx = renderLayers[1][i];
        optionsArray[layer_idx] = drawingOptions;
      }
    }
    window.myMap.getLayer("commune_layer").setLayerDrawingOptions(optionsArray);
    window.myMap.getLayer("commune_layer").show();
  }
});

I declared commune_layer in another file like this:

dynLayerCommune = new DynamicMapServiceLayer("http://ourserver.com/arcgis/rest/services/US/our_service/MapServer", {
 "id" : "commune_layer"
 });‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos
1 Solution

Accepted Solutions
Quynh_NhuMai
New Contributor III

Turns out I got pretty confused by the way the drawing options work. I ended up saving current drawing options in this way, and simply updating it with each user choice.

var currentDrawingOptions = window.myMap.getLayer("commune_layer").layerDrawingOptions;
    if (currentDrawingOptions) {
      optionsArray = currentDrawingOptions;
    }

View solution in original post

0 Kudos
4 Replies
RobertScheitlin__GISP
MVP Emeritus

Quynh,

   I am probably missing something, but I don't see where you are attempting to apply this renderer to a second layer.

0 Kudos
Quynh_NhuMai
New Contributor III
//set up dynamic layer parameters
 var optionsArray = [];
 var drawingOptions = new LayerDrawingOptions();
 drawingOptions.renderer = renderer;
 var layer_select_value = dijit.byId("render_layer_select").get("value");
 if (layer_select_value == 'E_TRONCO') {
 optionsArray[33] = drawingOptions;
 }
 if (layer_select_value == 'E_TRONCO_PR') {
 optionsArray[139] = drawingOptions;
 }
 window.myMap.getLayer("commune_layer").setLayerDrawingOptions(optionsArray);
 window.myMap.getLayer("commune_layer").show();

In this section of code (which is duplicated in each function renderMateriauRes() and renderTypeRes()), I set the layerDrawingOptions of the dynamic layer "commune_layer".

If i'm understanding how this works correctly, the optionsArray index refers to the dynamic layer's feature class that is to be rendered dynamically. The two layers I am trying to render are number 33 and 139 and both contain the same attribute "RESEAU" and "MATERIAU" that the renderers are based on.

Currently, feature class 33 and 139 are both changing colors, but the logic is not working correctly for feature class 139 as it changes color even if the user selects the feature class 33 option from the select box.

0 Kudos
Quynh_NhuMai
New Contributor III

Turns out I got pretty confused by the way the drawing options work. I ended up saving current drawing options in this way, and simply updating it with each user choice.

var currentDrawingOptions = window.myMap.getLayer("commune_layer").layerDrawingOptions;
    if (currentDrawingOptions) {
      optionsArray = currentDrawingOptions;
    }
0 Kudos
KenBuja
MVP Esteemed Contributor

If you haven't already fixed it, your original code has a problem with the require modules and function arguments. "dojo/on" has to be placed before "dojo/domReady!"