dynamic

1559
21
Jump to solution
12-02-2017 04:01 AM
anjelinaponkerat
Occasional Contributor II

Hi

I,m going to add dynamic layer over basemap by bellow sample code, but there is a bug in my code! what is wrong? plese help me...

<!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=yes">

<title>Map</title>
<link rel="stylesheet" href="https://js.arcgis.com/3.22/dijit/themes/claro/claro.css">
<link rel="stylesheet" href="https://js.arcgis.com/3.22/dijit/themes/tundra/tundra.css">
<link rel="stylesheet" href="https://js.arcgis.com/3.22/esri/css/esri.css">
<style>
html,
body {
height: 100%;
width: 100%;
margin: 0%;
font-family:Mitra;

}

#map {
border: solid 1px #B5BCC7;
padding: 0;
font-family:Mitra;
}

#paneHeader {

background-color: #ffffff;

color: white;
text-align: center;
height: 30px;
margin: 0;
overflow: hidden;
font-size: 16px;
padding: 8px 5px;
font-family:Mitra;
}

#rightPane {
width: 150px;
margin: 0;
padding: 0;
font-family:Mitra;
font-size: 13px;
}

#HomeButton {
position: absolute;
top: 95px;
left: 20px;
z-index: 50;
}
#bufferDialogBtn {
float: right;
}

.nonModal_underlay {
display: none;
}
h3 {
margin: 0 0 5px 0;
border-bottom: 1px solid #444;
}
.shadow {
box-shadow: 0 0 5px #888;
}
#feedback {
background: #fff;
color: #444;
position: absolute;
font-family: arial;
height: 300px;
left: 30px;
margin: 5px;
padding: 10px;
top: 30px;
width: 300px;
z-index: 40;
}
#note,
#hint {
font-size: 80%;
}
#note {
font-weight: 700;
padding: 0 0 10px 0;
}
#layerList {
width: 200px;
}
.dojoDndItemOver {
background: #ccc;
}
</style>

<script src="https://js.arcgis.com/3.22/"></script>

<script>
var map;
require([
"dojo/dom", "esri/Color", "dojo/keys", "dojo/parser", "esri/config",
"esri/sniff", "esri/map", "esri/SnappingManager", "esri/dijit/Measurement",
"esri/layers/FeatureLayer", "esri/renderers/SimpleRenderer", "esri/tasks/GeometryService",
"esri/symbols/SimpleLineSymbol", "esri/symbols/SimpleFillSymbol",
"esri/dijit/Scalebar",
"esri/dijit/BasemapGallery",
"esri/dijit/BasemapLayer",
"esri/dijit/Basemap",
"esri/dijit/OverviewMap",
"esri/tasks/locator",
"esri/dijit/Search",
"esri/symbols/PictureMarkerSymbol",
"esri/InfoTemplate",
"esri/dijit/HomeButton",
"esri/geometry/Extent",
"esri/SpatialReference",
"esri/dijit/VisibleScaleRangeSlider",
"esri/geometry/scaleUtils",
"esri/virtualearth/VETiledLayer",
"dijit/form/Button",
"esri/tasks/query",
"esri/geometry/Circle",
"esri/graphic",
"esri/symbols/SimpleMarkerSymbol",
"dojo/on",
"esri/toolbars/draw",
"esri/units",
"esri/layers/ArcGISDynamicMapServiceLayer",
"esri/layers/DynamicLayerInfo",
"esri/layers/LayerDataSource",
"esri/layers/LayerDrawingOptions",
"esri/layers/TableDataSource",
"dojo/dom",
"dojo/dom-construct",
"dojo/dom-style",
"dojo/query",
"dojo/_base/array",
"dojo/dnd/Source",
"dijit/registry",
"dijit/form/Button",
"dijit/layout/BorderContainer",
"dijit/layout/ContentPane",
"dijit/TitlePane",
"dijit/Dialog",
"dojo/domReady!"
], function(
dom, Color, keys, parser, esriConfig,
has, Map, SnappingManager, Measurement,
FeatureLayer, SimpleRenderer, GeometryService,
SimpleLineSymbol, SimpleFillSymbol,
Scalebar, BasemapGallery, BasemapLayer, Basemap, OverviewMap, Locator, Search, PictureMarkerSymbol, InfoTemplate, HomeButton, Extent, SpatialReference, VisibleScaleRangeSlider, scaleUtils, VETiledLayer, Button, Query, Circle, Graphic,
SimpleMarkerSymbol, on, Draw, units,
ArcGISDynamicMapServiceLayer,
DynamicLayerInfo, LayerDataSource,
LayerDrawingOptions, TableDataSource, domConstruct, domStyle, query, arrayUtils, Source, registry
) {

parser.parse();

esriConfig.defaults.io.proxyUrl = "/proxy/";
esriConfig.defaults.io.alwaysUseProxy = false;


esriConfig.defaults.geometryService = new GeometryService("https://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer");

map = new Map("map");

var basemaps = [];
var waterTemplateLayer = new BasemapLayer({
url: "https://sampleserver1.arcgisonline.com/ArcGIS/rest/services/WaterTemplate/LocalGovernmentInfrastruct..."
});
var waterBasemap = new Basemap({
layers: [waterTemplateLayer],
title: "Water Template",
thumbnailUrl: "images/waterThumb.png"
});
basemaps.push(waterBasemap);
var publicSafetyLayer = new BasemapLayer({
url: "https://sampleserver1.arcgisonline.com/ArcGIS/rest/services/PublicSafety/PublicSafetyBasemap/MapServ..."
});
var publicSafetyBasemap = new Basemap({
layers: [publicSafetyLayer],
title: "Public Safety",
thumbnailUrl: "images/safetyThumb.png"
});
basemaps.push(publicSafetyBasemap);

var basemapGallery = new BasemapGallery({
showArcGISBasemaps: false,
basemaps: basemaps,
map: map
}, "basemapGallery");
basemapGallery.startup();

basemapGallery.on("error", function(error) {
console.log(error);
});

var scalebar = new Scalebar({
map: map,
// "dual" displays both miles and kilometers
// "english" is the default, which displays miles
// use "metric" for kilometers
scalebarUnit: "dual"
});

var dynamicLayerInfos;

var dndSource = new Source("layerList");
dndSource.on("DndDrop", reorderLayers);

usaLayer = new ArcGISDynamicMapServiceLayer("https://sampleserver6.arcgisonline.com/arcgis/rest/services/USA/MapServer", {
"id": "usa"
});
usaLayer.on("load", function (e) {
dynamicLayerInfos = e.target.createDynamicLayerInfosFromLayerInfos();
arrayUtils.forEach(dynamicLayerInfos, function (info) {
var i = {
id: info.id,
name: info.name,
position: info.id
};
if (arrayUtils.indexOf(usaLayer.visibleLayers, info.id) > -1) {
i.visible = true;
} else {
i.visible = false;
}
infos[info.id] = i;
});
infos.total = dynamicLayerInfos.length;
e.target.setDynamicLayerInfos(dynamicLayerInfos, true);
});
// only create the layer list the first time update-end fires
on.once(usaLayer, "update-end", buildLayerList);
map.addLayer(usaLayer);

// add the lakes layer to the existing map service
registry.byId("lakes").on("click", addLakes);

function buildLayerList() {
dndSource.clearItems();
domConstruct.empty(dom.byId("layerList"));

var layerNames = [];
for (var info in infos) {
if (!infos[info].hasOwnProperty("id")) {
continue;
}
// only want the layer's name, don't need the db name and owner name
var nameParts = infos[info].name.split(".");
var layerName = nameParts[nameParts.length - 1];
var layerDiv = createToggle(layerName, infos[info].visible);
layerNames[infos[info].position] = layerDiv;
}

dndSource.insertNodes(false, layerNames);
}

function toggleLayer(e) {
for (var info in infos) {
var i = infos[info];
if (i.name === e.target.name) {
i.visible = !i.visible;
}
}
var visible = getVisibleLayers();
if (visible.length === 0) {
usaLayer.setVisibleLayers([-1]);
} else {
usaLayer.setDynamicLayerInfos(visible);
}
}

function reorderLayers() {
var newOrder = getVisibleLayers();
usaLayer.setDynamicLayerInfos(newOrder);
}

function addLakes() {
var lakes = "Lakes";
registry.byId(lakes.toLowerCase()).set("disabled", true);

// update global object with layer info
infos[infos.total] = {
id: infos.total,
name: lakes,
position: infos.total,
visible: true
};
infos.total += 1;
buildLayerList();

// layer name in the workspace
var layerName = "ss6.gdb." + lakes;
// create a new dynamic layer info object for the lakes layer
var dynamicLayerInfo = new DynamicLayerInfo();
dynamicLayerInfo.id = dynamicLayerInfos.length;
dynamicLayerInfo.name = layerName;
// can also set things like min/max scale

// create a table data source to access the lakes layer
var dataSource = new TableDataSource();
dataSource.workspaceId = "MyDatabaseWorkspaceIDSSR2"; // not exposed via REST 😞
dataSource.dataSourceName = layerName;
// and now a layer source
var layerSource = new LayerDataSource();
layerSource.dataSource = dataSource;
dynamicLayerInfo.source = layerSource;
dynamicLayerInfos.push(dynamicLayerInfo);
// set new infos, but don't refresh
// map will be updated when the drawing options are set
var layers = getVisibleLayers();
usaLayer.setDynamicLayerInfos(layers, true);

var drawingOptions = new LayerDrawingOptions();
drawingOptions.renderer = new SimpleRenderer(
new SimpleFillSymbol("solid", null,
new Color([0, 150, 255, 1])
));
var options = [];
options[4] = drawingOptions;

usaLayer.setLayerDrawingOptions(options);
}

function getVisibleLayers() {
// get layer name nodes, build an array corresponding to new layer order
var layerOrder = [];
query("#layerList .dojoDndItem label").forEach(function (n, idx) {
for (var info in infos) {
var i = infos[info];
if (i.name === n.innerHTML) {
layerOrder[idx] = i.id;
// keep track of a layer's position in the layer list
i.position = idx;
break;
}
}
});
// find the layer IDs for visible layer
var ids = arrayUtils.filter(layerOrder, function (l) {
return infos.visible;
});
// get the dynamicLayerInfos for visible layers
var visible = arrayUtils.map(ids, function (id) {
return dynamicLayerInfos[id];
});
return visible;
}

function createToggle(name, visible) {
var div = domConstruct.create("div");
var layerVis = domConstruct.create("input", {
checked: visible,
id: name,
name: name,
type: "checkbox"
}, div);
on(layerVis, "click", toggleLayer);
var layerSpan = domConstruct.create("label", {
for: name,
innerHTML: name
}, div);
return div;
}


});


</script>

</head>

<body class="claro">
<div data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="design:'headline', gutters:true" style="width:100%;height:100%;">

<div id="map" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'center'">



<div id="feedback" class="shadow">
<h3>Add and Re-order Layers</h3>
<div id="info">
<div id="note">
Note: This sample requires an ArcGIS Server version 10.1 or later map service.
</div>

<div id="hint">
Click and drag a map layer name below to re-order layers. The first layer in the list will be drawn on top.
</div>

<div><strong>Map Layers</strong></div>

<div id="layerList"></div>

<button id="lakes" data-dojo-type="dijit/form/Button">
Add Lakes
</button>

</div>
</div>


</div>






<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'right'" id="rightPane">

<div data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="design:'headline', gutters:false" style="width:100%;height:100%;">
<div id="paneHeader" data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'top'">
<span>Select Basemap</span>
</div>
<div data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'center'">
<div id="basemapGallery"></div>
</div>
</div>
</div>
</div>
</body>

</html>

0 Kudos
21 Replies
anjelinaponkerat
Occasional Contributor II

Yes

I see layers in web page when are "on"  in arcmap.

0 Kudos
RobertScheitlin__GISP
MVP Emeritus
That does not answer my question. You already told me that you can see them in ArcMap.


0 Kudos
anjelinaponkerat
Occasional Contributor II

Yes I see toggle but the corresponding layer does not open when I select and turn it on !!

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Anjelina,

  OK I thought of a possible issue when you switch to your own Map Service. Your map service has to support:

Supports Dynamic Layers: true

You can check for this by opening the MapService Rest endpoint in your browser and look for the above text.

0 Kudos
anjelinaponkerat
Occasional Contributor II

Yes supports dynamic layers is enabled, but...

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Sorry, I am at a loss here them...

0 Kudos
anjelinaponkerat
Occasional Contributor II

condition1:

I did these steps:

1- turn on all layers in arc map and publish web service

2- load web service in my arcgis js api sample

result: every thing is ok and i can see my layers and trurn them on and off.

condition2:

I did these steps:

1- turn off layers in Arc Map and publish service.

2- load web service in my arcgis js api sample

result: layers dont load in web page and I just see toggle option and layers name, but layers can not load and show !!

why? please test my 2 conditions.

 

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Anjelina,

  Yes I see that issue with the sample. It was also reported in this thread with no response:

Dynamic layers fail when map layers not visible by default 

I don't have a fix for that.

That is a very old sample. You should look at using the LayerList widget instead:

LayerList widget | ArcGIS API for JavaScript 3.22 

0 Kudos
anjelinaponkerat
Occasional Contributor II

Hi

I checked  LayerList widget | ArcGIS API for JavaScript 3.22   but I dont know how can change "map id" with my own web map servces? I,m not on arcgis Online and going to use my own web map service :

   //Create a map based on an ArcGIS Online web map id
    arcgisUtils.createMap("f63fed3f87fc488489e27c026fa5d434", "map").then(function(response){
        var myWidget = new LayerList({
           map: response.map,
           layers: arcgisUtils.getLayerList(response)
        },"layerList");
        myWidget.startup();
    });
0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Just because the sample show using a webmap does not mean that is the only way the widget will work. You definitely can use just layers from your server.

0 Kudos