Pubblicando un servizio di mappa con il dynamic layer abilitato ci consente di modificare il renderer di un layer, riposizionare un layer rispetto agli altri od anche aggiungere un nuovo layer da uno dei workspace registrati con il servizio. E' evidente che così aumentiamo l'interazione che l'utente può avere con le mappe via web; ma evita anche allo sviluppatore, ad esempio per il renderer, di scriversi centinaia, se non migliaia, di linee di codice per calcolarsi breaks, applicare una color ramp e fare altre operazioni dovendosi scaricare sul client tutti i dati con in più il problema che il server potrebbe limitare l'operazione con la proprietà maxRecordCount.
Ma vediamo come abilitare questa funzionalità nel nostro servizio di mappa e come ad esempio aggiungere un nuovo layer alla mappa.
Nel Service Editor selezioniamo sotto Capabilities la voce Mapping e sul pannello di destra clicchiamo Allow per request modification of layer order symbology così abilitiamo i dynamic layer per il servizio di mappa.
Poiché desideriamo aggiungere un layer dinamicamente clicchiamo su Manage... e registriamo uno o più geodatabase che contengono i dati che vogliamo utilizzare on the fly. Potremo caricare layer, table ad esempio per fare join.
Quando indichiamo un geodatabase dobbiamo indicare un identificato univoco per quel workspace che sarà utilizzato dall'applicazione per aggiungere i dati. Possiamo indicare una cartella contenente raster o shapefile, un file geodatabase o un enterprise geodatabase. In questo ultimo caso abbiamo anche la possibilità di bloccare la versione utilizzata dall'utente.
Selezioniamo un file geodatabase.
In questo caso è lo stesso utilizzato dal servizio.
Occorre ricordarsi che anche i workspace aggiunti per i dynamic layer devo essere registrati e l'utente ArcGIS Server deve avere almeno i privilegi di lettura per il workspace contenente i dati da caricare nel servizio.
Con i web client Esri possiamo aggiungere dinamicamente il nostro layer. Ad esempio con le API javascript (analogamente possiamo utilizzare le classi relative anche agli altri web client Esri) creiamo un datasource con TableDataSource e lo associamo ad un LayerDataSource per poi utilizzarlo come source in un feature layer:
//define the layer's data source from a table var dataSource = new esri.layers.TableDataSource(); dataSource.workspaceId = "My Workspace ID"; dataSource.dataSourceName = "Cities"; var layerSource = new esri.layers.LayerDataSource(); layerSource.dataSource = dataSource; //create a new feature layer based on the table data source var featureLayer = new esri.layers.FeatureLayer('http://myserver:6080/arcgis/rest/services/Demo/USA/MapServer/dynamicLayer', { mode: esri.layers.FeatureLayer.MODE_ONDEMAND, outFields: ["*"], infoTemplate: infoTemplate, source: layerSource });
E qui possiamo vedere l'esempio completo:
<!DOCTYPE html> <html> <head> <title>Dynamic Layer</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=7, IE=9, IE=10" /> <link rel="stylesheet" href="http://serverapi.arcgisonline.com/jsapi/arcgis/3.5/js/dojo/dijit/themes/claro/claro.css" /> <link rel="stylesheet" href="http://serverapi.arcgisonline.com/jsapi/arcgis/3.5/js/esri/css/esri.css" /> <style type="text/css"> html, body, #mapDiv, .map.container { padding: 0; margin: 0; height: 100%; } </style> <script type="text/javascript"> dojoConfig = { parseOnLoad: true };</script> <script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/3.5/"></script> <script type="text/javascript"> dojo.require("esri.map"); dojo.require("esri.layers.FeatureLayer"); var map; function init() { esri.config.defaults.geometryService = new esri.tasks.GeometryService("http://tasks.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer"); map = new esri.Map("mapDiv", { basemap: "satellite", center: [0, 0], zoom: 2 }); map.on("load", initOperationalLayer); } function initOperationalLayer() { var content = "<b>Name</b>: ${AREANAME}" + "<br /><b>Pop</b>: ${POP2000}"; var infoTemplate = new esri.InfoTemplate("Dynamic Layer", content); //define the layer's data source from a table var dataSource = new esri.layers.TableDataSource(); dataSource.workspaceId = "My Workspace ID"; dataSource.dataSourceName = "Cities"; var layerSource = new esri.layers.LayerDataSource(); layerSource.dataSource = dataSource; //create a new feature layer based on the table data source var featureLayer = new esri.layers.FeatureLayer('http://myserver:6080/arcgis/rest/services/Demo/USA/MapServer/dynamicLayer', { mode: esri.layers.FeatureLayer.MODE_ONDEMAND, outFields: ["*"], infoTemplate: infoTemplate, source: layerSource }); featureLayer.on("load", function (evt) { //project the extent if the map's spatial reference is different that the layer's extent. var gs = esri.config.defaults.geometryService; var extent = evt.layer.fullExtent; if (extent.spatialReference.wkid === map.spatialReference.wkid) { map.setExtent(extent); } else { gs.project([extent], map.spatialReference).then(function (results) { map.setExtent(results[0]); }); } }); var renderer = new esri.renderer.SimpleRenderer( new esri.symbol.SimpleMarkerSymbol(esri.symbol.SimpleMarkerSymbol.STYLE_SQUARE, 10, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([255, 0, 0]), 1), new dojo.Color([0, 255, 0, 0.25]))); featureLayer.setRenderer(renderer); map.addLayer(featureLayer); map.infoWindow.resize(150, 105); } dojo.ready(init); </script> </head> <body class="claro"> <div id="mapDiv"> </div> </body> </html>
Qui abbiamo visto un semplice esempio ma potete far caricare dall'utente i propri layer utilizzando ad esempio un servizio di geoprocessing che carica il dato in uno dei workspace registrati nel pool dei workspace del servizio con un nome univoco del layer (ad esempio facendo generare al geoprocessing un GUID) e restituendo al client il nome univoco del layer così che lo possa caricare con il codice visto precedentemente.
Possiamo anche caricare tabelle e fare join on the fly. Per maggiori dettagli vedere la classe JoinDataSource