Load Layers from Config file

2355
17
Jump to solution
09-11-2012 07:23 AM
LuciHawkins
Occasional Contributor III
Is anyone familiar with loading layers from a config file?  I am trying to do it and I get various results depending upon the method I try.  The method quoted gives me duplicate entries of each layer added.  I have created the array called layrnames, but cannot determine proper function to use to load all the layers names I have pushed into the array.  Any help would be greatly appreciated 🙂

Thanks,  Luci

function init(){
                esri.config.defaults.geometryService = new esri.tasks.GeometryService("http://fwb-gissrv/ArcGIS/rest/services/Geometry/GeometryServer");
               
                //create popup for multiple popups
                var popup = new esri.dijit.Popup({
                    fillSymbol: new esri.symbol.SimpleFillSymbol(esri.symbol.SimpleFillSymbol.STYLE_SOLID, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([255, 0, 0]), 2), new dojo.Color([240, 128, 128, 0.25]))
                }, dojo.create("div"));
               
                //map.spatialReference = new esri.SpatialReference({wkid:102100});
               
                //set initial extent
                var initExtent = new esri.geometry.Extent(-9651200, 3555500, -9636400, 3562470, new esri.SpatialReference({
                    "wkid": 102100
                }));
               
                locator = new esri.tasks.Locator("http://fwb-gissrv/ArcGIS/rest/services/GeoCodes/AddressessFWB/GeocodeServer");
                dojo.connect(locator, "onAddressToLocationsComplete", showResultsl);
               
                //load map
                map = new esri.Map("map", {
                    extent: initExtent,
                    slider: true,
                    lods: lods,
                    infoWindow: popup
                });
               
                //add basemap gallery tiles
                createBasemapGallery();
               
                dojo.connect(basemapGallery, "onError", function(msg){
                    console.log(msg)
                });
               
                dojo.xhrGet({
                    url: "Config.json",
                    handleAs: "json",
                    preventCache: true,
                    load: function(responseObject, ioArgs){
                        layrname = responseObject.Lyrname;
                       
                        //add layers from config file
                        if (layrname.length != 0) {
                            for (var i = 0; i < layrname.length; i++) {
                                layname = (layrname.lname);
                                laytitle = (layrname.ltitle);
                                layurl = (layrname.lUrl);
                                layrvis = (layrname.lVisb);
                                layid = (layrname.lyid);
                                layname = new esri.layers.ArcGISDynamicMapServiceLayer(layurl, {
                                    id: layid,
                                    visible: layrvis
                                });
                                legendLayers.push({
                                    layer: layname,
                                    title: laytitle
                                });
        layrnames.push({
         layern: layname
        });
        map.addLayer(layname);
                            }
                        };
     
                        dojo.connect(map, 'onLayeraddResult', function(results){
                            var legend = new esri.dijit.Legend({
                                map: map,
                                layerInfos: legendLayers
                            }, "legendDiv");
                            legend.startup();
                        });
                       
      //map.addLayers([layname]);
                                         
                        dojo.connect(map, 'onLayerAddResult', function(results){
                       
                            //add check boxes
                            dojo.forEach(legendLayers, function(layer){
                                var layerName = layer.title;
                                var checkBox = new dijit.form.CheckBox({
                                    name: "checkBox" + layer.layer.id,
                                    value: layer.layer.id,
                                    checked: layer.layer.visible,
                                    onChange: function(evt){
                                        var clayer = map.getLayer(this.value);
                                        clayer.setVisibility(!clayer.visible);
                                        this.checked = clayer.visible;
          legend.refresh();
                                    }
                                });
                               
                                //add the check box and label to the toc
                                dojo.place(checkBox.domNode, dojo.byId("toggle"), "after");
                                var checkLabel = dojo.create('label', {
                                    'for': checkBox.name,
                                    innerHTML: layerName
                                }, checkBox.domNode, "after");
                                dojo.place("<br />", checkLabel, "after");
                            });
                           
                        });
                       
                    }
                });
0 Kudos
1 Solution

Accepted Solutions
BenFousek
Occasional Contributor III
Luci -
I left too much proprietary junk in there. Start simple and build from there.
js object
var layersDynamic = [{     url: 'http://server/ArcGIS/rest/services/Flood/MapServer',     token: true,     name: 'Flood',     id: 'flood',     visible: false,     opacity: 1,     imageFormat: 'png24',     dpi: 96, }, {     url: 'http://server/ArcGIS/rest/services/MunicipalBoundaries/MapServer',     token: true,     name: 'Municipal Boundaries',     id: 'mboundaries',     visible: true,     opacity: 1,     imageFormat: 'png24',     dpi: 96, }];


iteration
dojo.forEach(layersDynamic, function(l) { addDynamic(l) });


function
function addDynamic(l) {     var url;     if (l.token == true) {         url = l.url + '?token=' + //TOKEN OR TOKEN VARIABLE HERE//     } else {         url = l.url     }     var layer = new esri.layers.ArcGISDynamicMapServiceLayer(url, {         id: l.id,         visible: l.visible,         opacity: l.opacity     });     layer.setImageFormat(l.imageFormat); //implicitly set - doesn't always work if added to layer object params     layer.setDPI(l.dpi); //implicitly set - doesn't always work if added to layer object params      var control = '<div id="' + l.id + '_layer_control"><input id="' + l.id + '_control_cb" />  ' + l.name + '<div>';     dojo.place(control, 'toc', 'first');     var checkbox = new dijit.form.CheckBox({         checked: l.visible,         onChange: function () {             if (layer.visible == true) {                 layer.hide()             } else {                 layer.show()             }         }     }, l.id + '_control_cb');     map.addLayer(layer); //last }


One thing to remember: if the service isn't secured "token" should be set to false; if it is you'll have to provide one.

View solution in original post

17 Replies
BenFousek
Occasional Contributor III
Is the json generated, e.g. asp, php, etc; or is it a file?
0 Kudos
LuciHawkins
Occasional Contributor III
It resides in a file:

{
'Lyrname' :
[
  {"lname": "parcelsLayer", "ltitle": "Parcels", "lUrl": "http://fwb-gissrv/ArcGIS/rest/services/Maps/Parcels/MapServer", "lVisb": "false", "lyid": "parcelsaa"},
  {"lname": "parcelsarLayer", "ltitle": "Parcels Aerial", "lUrl": "http://fwb-gissrv/ArcGIS/rest/services/Maps/ParcelsAerial/MapServer", "lVisb": "true", "lyid": "parcelsab"},
  {"lname": "hydroLayer", "ltitle": "Hydrography", "lUrl": "http://fwb-gissrv/ArcGIS/rest/services/Maps/Hydrography/MapServer", "lVisb": "true", "lyid": "hydro"},
  {"lname": "bfpLayer", "ltitle": "Building Footprints", "lUrl": "http://fwb-gissrv/ArcGIS/rest/services/Maps/BFP/MapServer", "lVisb": "true", "lyid": "bfpa"}
]
}
0 Kudos
LuciHawkins
Occasional Contributor III
The file, config.json, is where I am pulling the information from. I have tried to just create an array of the layernames and cannot get it to work either.

Text I tried in Config.json file:

{
'AaLyrname' : "parcelsLayer, parcelsarLayer, firmLayer, hurricaneLayer"
}

Text I tried in Default.html file:

dojo.xhrGet({
url: "Config.json",
handleAs: "json",
preventCache: true,
load: function(responseObject, ioArgs){
layrname = responseObject.Lyrname;
aalyrname = responseObject.AaLyrname;
var aaalyrname=aalyrname.join();
map.addLayers([aaalyrname]);
0 Kudos
ReneRubalcava
Frequent Contributor
Can you use Firebug or Chrome dev tools to see what the responseObject looks like?

Also, you should wrap 'LyrName' with double quotes, so it's "LyrName" to be valid JSON. JSON doesn't use single quotes.

You can usually check your JSON validity wth this site.
http://jsonformatter.curiousconcept.com/
0 Kudos
LuciHawkins
Occasional Contributor III
The Json formatter says the config.json file is "Valid".  I tried to install firefox and firebug but there is a bug in the new version of firefox that is not allowing our proxy and non-proxy websites to work together.
0 Kudos
BenFousek
Occasional Contributor III
In my opinion, you are making an unnecessary request and limiting easy enhancement of your application. I've stripped this down so it's simpler.

The first file I load in the head is config.js. Here's a config object:
var config = {
    token: 'some_token',
    tools: [
        {
            name: 'Measure',
            widget: 'bowc.widget.Measure',
            placeAt: 'new floating pane',
            placeControls: ['toolbar','mapContext']
        }
    ],
    layersDynamic: [
        {
            url: 'http://server/ArcGIS/rest/services/Flood/MapServer',
            token: true,
            name: 'Flood',
            id: 'flood',
            visible: false,
            opacity: 1,
            imageFormat: 'png24',
            dpi: 96,
            legend: true,
            parcelLabelControl: false,
            subLayerControl: true,
            identify: true,
            identifyLayers: ['*'],
            info: true,
            infoHtml: 'This layer displays the FEMA flood zones.'
        },
        {
            url: 'http://server/ArcGIS/rest/services/MunicipalBoundaries/MapServer',
            token: true,
            name: 'Municipal Boundaries',
            id: 'mboundaries',
            visible: true,
            opacity: 1,
            imageFormat: 'png24',
            dpi: 96,
            legend: true,
            parcelLabelControl: false,
            subLayerControl: true,
            identify: false,
            identifyLayers: undefined,
            info: true,
            infoHtml: 'This layer displays city limits and the urban growth boundary (UGB).'
        }
    ],
    layersFeature: [

    ]
}

You'll notice that beyond layers, there is also global objects (the token), and objects used to determine layout and functionality. In fact all my apps are built and controlled by a single base class, which uses the config object for all it's params.

Somewhere in my buildUI function it's time to add layers:
dojo.forEach(config.layersDynamic, function(l) { app.layers.addDynamic(l) });

Simple iteration of the object.

Here's app.layers.addDynamic()
var app = {
    layers: {
        addDynamic: function (l) {
            var url;
            if (l.token == true) {
                url = l.url + '?token=' + token
            } else {
                url = l.url
            }
            var layer = new esri.layers.ArcGISDynamicMapServiceLayer(url, {
                id: l.id,
                visible: l.visible,
                opacity: l.opacity
            });
            layer.setImageFormat(l.imageFormat); //implicitly set - doesn't always work if added to layer object params
            layer.setDPI(l.dpi); //implicitly set - doesn't always work if added to layer object params

            var control = '<div id="' + l.id + '_layer_control"><input id="' + l.id + '_control_cb" />  ' + l.name + ' &nbsp<img id="' + l.id + '_update" src="images/updating.gif" style="display:none; width:14px; height:14px;" /><div>'
            dojo.place(control, 'toc', 'first');
            var checkbox = new dijit.form.CheckBox({
                checked: l.visible,
                onChange: function () {
                    if (layer.visible == true) {
                        layer.hide()
                    } else {
                        layer.show()
                    }
                }
            }, l.id + '_control_cb');
            dojo.connect(layer, 'onUpdateStart', function (evt) {
                dojo.style(l.id + '_update', 'display', 'inline')
            });
            dojo.connect(layer, 'onUpdateEnd', function (evt) {
                dojo.style(l.id + '_update', 'display', 'none')
            });
            if (l.legend == true) {
             //add to legend
            }
            app.map.addLayer(layer); //last
        }
    }
}

Layer added with some extras. Just like yours.

So there's one approach which may help.
0 Kudos
LuciHawkins
Occasional Contributor III
I am still in the early learning stage of HTML5 and javascript.  So, what I tried was this:

I copied your config object code and made a config.js file and modified it with my map services.  I then added <script type="text/javascript" src="js/config.js"></script> so that it is the first item loaded in my default.html file.

Then, I removed all of the code from my default.html file that had anything to do with reading in my old config.json file.

I then copied your code for adding layers in my default.html where I would want the layers added after the lengendDijit was started.

Then, I copied the last code you have and made it into a utils.js file which I am loading at the top of my default.html file.

I tested it and the layers are not loading. 

Any advice?

Thanks,  Luci
0 Kudos
BenFousek
Occasional Contributor III
Luci -
I left too much proprietary junk in there. Start simple and build from there.
js object
var layersDynamic = [{     url: 'http://server/ArcGIS/rest/services/Flood/MapServer',     token: true,     name: 'Flood',     id: 'flood',     visible: false,     opacity: 1,     imageFormat: 'png24',     dpi: 96, }, {     url: 'http://server/ArcGIS/rest/services/MunicipalBoundaries/MapServer',     token: true,     name: 'Municipal Boundaries',     id: 'mboundaries',     visible: true,     opacity: 1,     imageFormat: 'png24',     dpi: 96, }];


iteration
dojo.forEach(layersDynamic, function(l) { addDynamic(l) });


function
function addDynamic(l) {     var url;     if (l.token == true) {         url = l.url + '?token=' + //TOKEN OR TOKEN VARIABLE HERE//     } else {         url = l.url     }     var layer = new esri.layers.ArcGISDynamicMapServiceLayer(url, {         id: l.id,         visible: l.visible,         opacity: l.opacity     });     layer.setImageFormat(l.imageFormat); //implicitly set - doesn't always work if added to layer object params     layer.setDPI(l.dpi); //implicitly set - doesn't always work if added to layer object params      var control = '<div id="' + l.id + '_layer_control"><input id="' + l.id + '_control_cb" />  ' + l.name + '<div>';     dojo.place(control, 'toc', 'first');     var checkbox = new dijit.form.CheckBox({         checked: l.visible,         onChange: function () {             if (layer.visible == true) {                 layer.hide()             } else {                 layer.show()             }         }     }, l.id + '_control_cb');     map.addLayer(layer); //last }


One thing to remember: if the service isn't secured "token" should be set to false; if it is you'll have to provide one.
LuciHawkins
Occasional Contributor III
Thank you so much.  I believe it is working for the most part.  When I tested it in IE 9 I get a debug message about 'layersDynamic" being undefined and my layers do not load.  Is the proper method of loading the config.js (js object) the use of   <script type="text/javascript" src="js/config.js"/> or do I need to load it in a different manner so that IE9 knows that is it a variable?

Thank you!

Luci
0 Kudos