create symbology from json not working correctly

5192
4
Jump to solution
04-10-2015 02:08 PM
JoseLuis_Serrano
New Contributor III

I am trying to apply some symbology form a Json like string. I have a point, polyline and polygon datasets and only the polyline and polygon layers are getting symbolized, although not like defined in the Json. So, my guess is that I am doing something really wrong.

Here is the code, in case someone can point me in the right direction.

Thanks!

function getSimpleRenderer(tmpLayer) {  
            var jsonSymbologies = {};
            jsonSymbologies.subs_point = '{"color":[250,0,250,255],"size":12,"angle":-30,"xoffset":0,"yoffset":0,"type":"esriSMS","style":"esriSMSCircle","outline":{"color":[255,0,0,255],"width":1,"type":"esriSLS","style":"esriSLSSolid"}}';
            jsonSymbologies.trans_polyline = '{"color": [0,255,0,255], "width": 1, "type": "esriSLS", "style": "esriSLSLongDashDot"}';
            jsonSymbologies.region_polygon = '{"color": [255,0,0,255], "type": "esriSFS","style": "esriSFSSolid", "outline": {"color":  [230,230,230,255], "width": 0.5, "type": "esriSLS", "style": "esriSLSDashDot"}}';
            jsonSymbologies.buildable_polygon = '{"color": [255,255,0,255], "type": "esriSFS","style": "esriSFSSolid", "outline": {"color":  [230,230,230,255], "width": 0.5, "type": "esriSLS", "style": "esriSLSDashDot"}}';


            var layerSemanticTypes = ["subs", "trans", "region", "buildable"];


            var nameParts = tmpLayer.split("_");


            // reduce the synonyms in the semantic types
            var nameSemantic = nameParts[0].toLowerCase();
            arrayUtils.some(layerSemanticTypes, function (dictSemanticType) {
                if (nameSemantic.indexOf(dictSemanticType) > -1) {
                    nameSemantic = dictSemanticType;
                    return false;
                }
            });


            // reduce the synonyms in the geometry types
            var nameGeom = tmpLayer.split("_")[nameParts.length - 1].toLowerCase();
            if (nameGeom === "pnt") {
                nameGeom = "point";
            } else if (nameGeom === "line") {
                nameGeom = "polyline";
            }


            // get the appropiate renderer
            var symbol;
            var baseSymbol;
            var tmpJson;


            if (nameGeom === "point") {
                tmpJson = JSON.parse(jsonSymbologies[nameSemantic + "_point"]);
                baseSymbol = symbolJsonUtils.fromJson(tmpJson);
                symbol = new SimpleMarkerSymbol(baseSymbol)
            } else if (nameGeom === "polyline") {
                tmpJson = JSON.parse(jsonSymbologies[nameSemantic + "_polyline"]);
                baseSymbol = symbolJsonUtils.fromJson(tmpJson)
                symbol = new SimpleLineSymbol(baseSymbol)
            } else if (nameGeom === "polygon") {
                tmpJson = JSON.parse(jsonSymbologies[nameSemantic + "_polygon"]);
                baseSymbol = symbolJsonUtils.fromJson(tmpJson)
                symbol = new SimpleFillSymbol()
            }else{
                console.log(nameGeom + " is an undefined geometry type!");
                return false;
            }
            return new SimpleRenderer(symbol);
        }
0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Emeritus

Ragadmin,

  So basically your code for make the renderer is trying to do to much. This should work:

        if (nameGeom === "point") {
          tmpJson = JSON.parse(jsonSymbologies[nameSemantic + "_point"]);
          baseSymbol = symbolJsonUtils.fromJson(tmpJson);
        } else if (nameGeom === "polyline") {
          tmpJson = JSON.parse(jsonSymbologies[nameSemantic + "_polyline"]);
          baseSymbol = symbolJsonUtils.fromJson(tmpJson);
        } else if (nameGeom === "polygon") {
          tmpJson = JSON.parse(jsonSymbologies[nameSemantic + "_polygon"]);
          baseSymbol = symbolJsonUtils.fromJson(tmpJson);
        } else {
          console.log(nameGeom + " is an undefined geometry type!");
          return false;
        }
        return new SimpleRenderer(baseSymbol);

The symbolJsonUtil is already creating a specific symbol object based on the JSON so there is no need to try and create the particular symbol type again.

View solution in original post

0 Kudos
4 Replies
RobertScheitlin__GISP
MVP Emeritus

Ragadmin,

   Kind of hard to decipher your code without knowing what a tmpLayer object looks like.

0 Kudos
JoseLuis_Serrano
New Contributor III

Sorry, the context of the application is that I have a map with an ArcGISDynamicMapServiceLayer that has two dynamic workspaces defined. The application has two buttons, when I click the proj1 button, it reads three shp files and adds them to the service using the dynamicLayerInfos array. The shp files need a symbology, so I use the jsonSymbologies object to store a few symbologies in Json format.

Here is the whole script

(btw, I'm new to programming, so don't get too scared of the code)

var map, usaLayer;


require([
  "esri/map", "esri/layers/ArcGISDynamicMapServiceLayer",
  "esri/layers/DynamicLayerInfo", "esri/layers/LayerDataSource",
  "esri/layers/LayerDrawingOptions", "esri/layers/TableDataSource",
  "esri/Color", "esri/renderers/SimpleRenderer", "esri/symbols/jsonUtils",
  "esri/symbols/SimpleFillSymbol", "esri/symbols/SimpleMarkerSymbol", "esri/symbols/SimpleLineSymbol",
  "dojo/dom", "dojo/dom-construct", "dojo/dom-style",
  "dojo/_base/lang", "dojo/query", "dojo/on",
  "dojo/parser", "dojo/json", "dojo/_base/array", "dojo/dnd/Source", "dijit/registry", "dojo/ready",
  "dijit/form/Button", "dojo/domReady!"
], function (
  Map, ArcGISDynamicMapServiceLayer,
  DynamicLayerInfo, LayerDataSource,
  LayerDrawingOptions, TableDataSource,
  Color, SimpleRenderer, symbolJsonUtils,
  SimpleFillSymbol, SimpleMarkerSymbol, SimpleLineSymbol,
  dom, domConstruct, domStyle,
  lang, query, on,
  parser, JSON, arrayUtils, Source, registry, ready
) {
    //function init() {


        parser.parse();


        var dynamicLayerInfos;


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


        var initBasemap = new esri.layers.ArcGISTiledMapServiceLayer("http://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer");
        map.addLayer(initBasemap);


        usaLayer = new ArcGISDynamicMapServiceLayer("https://arcgis.edf-re.com/rag/rest/services/Other/dynamicworkspaceservice/MapServer", {
            "id": "abc",
            "opacity": 1
        });


        //here you create the DynamicLayerInfos that you need to add the new layers to the service
        usaLayer.on("load", function (e) {
            dynamicLayerInfos = e.target.createDynamicLayerInfosFromLayerInfos();
            dynamicLayerInfos = []; // this eliminates all the existing layers in the map service


        });


        registry.byId("proj1").on("click", addProject);
        registry.byId("proj2").on("click", addProject);


        // add the layer to the existing map service
        map.addLayer(usaLayer);


        function addProject() {
            console.log("start");


            // get the workspaceID based on the selected project
            var projID = this.onClick.target.id;
            var workspaceID = projID;


            // read the folder contents based on the selected workspaceID
            var layerList = [];
            if (workspaceID === "proj1") {
                layerList = ["substation_v12_point", "transmission_v12_polyline", "regions_v12_polygon"];
            } else{
                layerList = ["subs_v1_pnt", "trans_v1_polyline", "buildable_v1_polygon"];
            }
           
            var options = []; // for the renderers


            arrayUtils.forEach(layerList, function (tmpLayer, i) {
                var dynamicLayerInfo = new DynamicLayerInfo();
                dynamicLayerInfo.id = dynamicLayerInfos.length;
                dynamicLayerInfo.name = tmpLayer;


                var dataSource = new TableDataSource();
                dataSource.workspaceId = workspaceID; // not exposed via REST :(
                dataSource.dataSourceName = tmpLayer;


                var layerSource = new LayerDataSource();
                layerSource.dataSource = dataSource;
                dynamicLayerInfo.source = layerSource;


                dynamicLayerInfos.push(dynamicLayerInfo);


                // get the right renderer here
                var renderer = getSimpleRenderer(tmpLayer);
                if (renderer !== false) {
                    console.log("ok renderer");
                    var drawingOptions = new LayerDrawingOptions();
                    drawingOptions.renderer = renderer;
                    options[i+1] = drawingOptions;
                }
            });


            // set the dynimicaLayerInfo for all layers and update the map
            usaLayer.setDynamicLayerInfos(dynamicLayerInfos, true);
            usaLayer.setLayerDrawingOptions(options);


            console.log("end");
        }


        function getSimpleRenderer(tmpLayer) {  
            var jsonSymbologies = {};
            jsonSymbologies.subs_point = '{"color":[250,0,250,255],"size":12,"angle":-30,"xoffset":0,"yoffset":0,"type":"esriSMS","style":"esriSMSCircle","outline":{"color":[255,0,0,255],"width":1,"type":"esriSLS","style":"esriSLSSolid"}}';
            jsonSymbologies.trans_polyline = '{"color": [0,255,0,255], "width": 1, "type": "esriSLS", "style": "esriSLSLongDashDot"}';
            jsonSymbologies.region_polygon = '{"color": [255,0,0,255], "type": "esriSFS","style": "esriSFSSolid", "outline": {"color":  [230,230,230,255], "width": 0.5, "type": "esriSLS", "style": "esriSLSDashDot"}}';
            jsonSymbologies.buildable_polygon = '{"color": [255,255,0,255], "type": "esriSFS","style": "esriSFSSolid", "outline": {"color":  [230,230,230,255], "width": 0.5, "type": "esriSLS", "style": "esriSLSDashDot"}}';


            var layerSemanticTypes = ["subs", "trans", "region", "buildable"];


            var nameParts = tmpLayer.split("_");


            // reduce the synonyms in the semantic types
            var nameSemantic = nameParts[0].toLowerCase();
            arrayUtils.some(layerSemanticTypes, function (dictSemanticType) {
                if (nameSemantic.indexOf(dictSemanticType) > -1) {
                    nameSemantic = dictSemanticType;
                    return false;
                }
            });


            // reduce the synonyms in the geometry types
            var nameGeom = tmpLayer.split("_")[nameParts.length - 1].toLowerCase();
            if (nameGeom === "pnt") {
                nameGeom = "point";
            } else if (nameGeom === "line") {
                nameGeom = "polyline";
            }


            // get the appropiate renderer
            var symbol;
            var baseSymbol;
            var tmpJson;


            if (nameGeom === "point") {
                tmpJson = JSON.parse(jsonSymbologies[nameSemantic + "_point"]);
                baseSymbol = symbolJsonUtils.fromJson(tmpJson);
                symbol = new SimpleMarkerSymbol(baseSymbol)
            } else if (nameGeom === "polyline") {
                tmpJson = JSON.parse(jsonSymbologies[nameSemantic + "_polyline"]);
                baseSymbol = symbolJsonUtils.fromJson(tmpJson)
                symbol = new SimpleLineSymbol(baseSymbol)
            } else if (nameGeom === "polygon") {
                tmpJson = JSON.parse(jsonSymbologies[nameSemantic + "_polygon"]);
                baseSymbol = symbolJsonUtils.fromJson(tmpJson)
                symbol = new SimpleFillSymbol()
            }else{
                console.log(nameGeom + " is an undefined geometry type!");
                return false;
            }
            return new SimpleRenderer(symbol);
        }
   // }


   // ready(init);


  });
0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Ragadmin,

  So basically your code for make the renderer is trying to do to much. This should work:

        if (nameGeom === "point") {
          tmpJson = JSON.parse(jsonSymbologies[nameSemantic + "_point"]);
          baseSymbol = symbolJsonUtils.fromJson(tmpJson);
        } else if (nameGeom === "polyline") {
          tmpJson = JSON.parse(jsonSymbologies[nameSemantic + "_polyline"]);
          baseSymbol = symbolJsonUtils.fromJson(tmpJson);
        } else if (nameGeom === "polygon") {
          tmpJson = JSON.parse(jsonSymbologies[nameSemantic + "_polygon"]);
          baseSymbol = symbolJsonUtils.fromJson(tmpJson);
        } else {
          console.log(nameGeom + " is an undefined geometry type!");
          return false;
        }
        return new SimpleRenderer(baseSymbol);

The symbolJsonUtil is already creating a specific symbol object based on the JSON so there is no need to try and create the particular symbol type again.

0 Kudos
JoseLuis_Serrano
New Contributor III

Thank you Robert,

you were right, if I use symbolJsonUtils, I don't need to create the symbol again. I also had a small error assigning the symbology to the correct index in the options[] array.

0 Kudos