',
@@ -82,5 +65,23 @@ define([
}, 250, null, lang.partial(domConstruct.destroy, this.domNode));
}
});
+
+ // main growler dijit container
+ var Growler = declare([_WidgetBase, _TemplatedMixin], {
+ templateString: '',
+ postCreate: function () {
+ this.inherited(arguments);
+ this.own(topic.subscribe('growler/growl', lang.hitch(this, 'growl')));
+ },
+ growl: function (props) {
+ props = props || {};
+ lang.mixin(props, {
+ _container: this.containerNode
+ });
+ var g = new Growl(props);
+ g.startup();
+ }
+ });
+
return Growler;
});
\ No newline at end of file
diff --git a/viewer/js/gis/dijit/Help.js b/viewer/js/gis/dijit/Help.js
index 2e605fecc..461a374d1 100644
--- a/viewer/js/gis/dijit/Help.js
+++ b/viewer/js/gis/dijit/Help.js
@@ -1,5 +1,5 @@
define([
- 'dojo/_base/declare',
+ 'dojo/_base/declare',
'dijit/_WidgetBase',
'dijit/_TemplatedMixin',
'dijit/_WidgetsInTemplateMixin',
@@ -8,45 +8,46 @@ define([
'dojo/on',
'dojo/_base/lang',
'dojo/aspect',
- 'dojo/text!./Help/templates/HelpDialog.html',
+ 'dojo/text!./Help/templates/HelpDialog.html',
+ 'dojo/i18n!./Help/nls/resource',
'dijit/form/Button',
- 'dijit/layout/TabContainer',
- 'dijit/layout/ContentPane',
- 'xstyle/css!./Help/css/Help.css'
-], function (declare, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, _FloatingWidgetMixin, domConstruct, on, lang, aspect, template) {
+ 'dijit/layout/TabContainer',
+ 'dijit/layout/ContentPane',
+ 'xstyle/css!./Help/css/Help.css'
+], function (declare, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, _FloatingWidgetMixin, domConstruct, on, lang, aspect, template, i18n) {
- return declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, _FloatingWidgetMixin], {
- widgetsInTemplate: true,
- templateString: template,
- title: 'Help',
- html: 'Help',
- domTarget: 'helpDijit',
- draggable: false,
- baseClass: 'helpDijit',
- postCreate: function () {
- this.inherited(arguments);
- this.parentWidget.draggable = this.draggable;
- if (this.parentWidget.toggleable) {
- this.own(aspect.after(this.parentWidget, 'toggle', lang.hitch(this, function () {
- this.containerNode.resize();
- })));
- } else {
- var help = domConstruct.place(this.html, this.domTarget);
- on(help, 'click', lang.hitch(this.parentWidget, 'show'));
- }
- },
- onOpen: function () {
- // Make sure the content is visible when the dialog
- // is shown/opened. Something like this may be needed
- // for all floating windows that don't open on startup?
- if (!this.openOnStartup) {
- this.containerNode.resize();
- }
- },
- close: function () {
- if (this.parentWidget.hide) {
- this.parentWidget.hide();
- }
- }
- });
+ return declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, _FloatingWidgetMixin], {
+ widgetsInTemplate: true,
+ templateString: template,
+ i18n: i18n,
+ html: 'link'.replace('link', i18n.link),
+ domTarget: 'helpDijit',
+ draggable: false,
+ baseClass: 'helpDijit',
+ postCreate: function () {
+ this.inherited(arguments);
+ this.parentWidget.draggable = this.draggable;
+ if (this.parentWidget.toggleable) {
+ this.own(aspect.after(this.parentWidget, 'toggle', lang.hitch(this, function () {
+ this.containerNode.resize();
+ })));
+ } else {
+ var help = domConstruct.place(this.html, this.domTarget);
+ on(help, 'click', lang.hitch(this.parentWidget, 'show'));
+ }
+ },
+ onOpen: function () {
+ // Make sure the content is visible when the dialog
+ // is shown/opened. Something like this may be needed
+ // for all floating windows that don't open on startup?
+ if (!this.openOnStartup) {
+ this.containerNode.resize();
+ }
+ },
+ close: function () {
+ if (this.parentWidget.hide) {
+ this.parentWidget.hide();
+ }
+ }
+ });
});
\ No newline at end of file
diff --git a/viewer/js/gis/dijit/Help/nls/es/resource.js b/viewer/js/gis/dijit/Help/nls/es/resource.js
new file mode 100644
index 000000000..6c4cea412
--- /dev/null
+++ b/viewer/js/gis/dijit/Help/nls/es/resource.js
@@ -0,0 +1,36 @@
+define ({
+ link: 'Ayuda',
+ navigation: {
+ title: 'Navegación',
+ description: 'Mapa de navegación a través del ratón y el teclado:',
+ pan1: 'Arrastre a la sartén',
+ recenter: 'SHIFT + Clic para volver a centrar',
+ zoomIn1: 'SHIFT + Arrastre para ampliar la imagen',
+ zoomOut1: 'SHIFT + CTRL + arrastrar para alejarla',
+ zoomIn2: 'De desplazamiento del ratón hacia adelante para hacer un zoom',
+ zoomOut2: 'De desplazamiento del ratón hacia atrás para reducir',
+ pan2: 'Utilice las teclas de flecha para desplazarse',
+ zoomInLevel: '+ clave para hacer un zoom un nivel',
+ zoomOutLevel: '- clave para alejar un nivel',
+ zoomCenter: 'Doble click para Centro y hacer zoom in'
+ },
+ search: {
+ title: 'Buscar',
+ description: 'Una variedad de búsquedas se pueden realizar en el buscador:',
+ address: 'Buscar por Dirección',
+ place: 'Búsqueda Territorial',
+ etc: 'Buscar por código postal, condado, etc.'
+ },
+ tools: {
+ title: 'Herramientas',
+ description: 'Además de las capacidades de búsqueda, se proporcionan las siguientes herramientas:',
+ measure: {
+ title: 'Medición',
+ description: 'La herramienta de medida proporciona la capacidad para dibujar un punto, una línea o un polígono en el mapa y especificar la unidad de medida.'
+ },
+ print: {
+ title: 'Impresión',
+ description: 'Este mapa se puede exportar a diversos formatos y diseños.'
+ }
+ }
+});
\ No newline at end of file
diff --git a/viewer/js/gis/dijit/Help/nls/fr/resource.js b/viewer/js/gis/dijit/Help/nls/fr/resource.js
new file mode 100644
index 000000000..6bda3e07f
--- /dev/null
+++ b/viewer/js/gis/dijit/Help/nls/fr/resource.js
@@ -0,0 +1,36 @@
+define ({
+ link: 'Aide',
+ navigation: {
+ title: 'Navigation',
+ description: 'Navigation dans la carte en utilisant la souris et le clavier:',
+ pan1: 'Clic + Glisser pour déplacer la carte',
+ recenter: 'SHIFT + Clic pour recentrer',
+ zoomIn1: 'SHIFT + Sélection pour agrandir',
+ zoomOut1: 'SHIFT + CTRL + glisser pour effectuer un zoom arrière',
+ zoomIn2: 'Roulette de la souris vers l\'avant pour agrandir',
+ zoomOut2: 'Roulette de la souris vers l\'avant pour rétrécir',
+ pan2: 'Utilisez les flèches pour vous déplacer',
+ zoomInLevel: '+ pour zoomer un niveau',
+ zoomOutLevel: '- pour rétrécir un niveau',
+ zoomCenter: 'Double cliquez pour centrer et agrandir'
+ },
+ search: {
+ title: 'Recherche',
+ description: 'Une variété de recherches peuvent être effectuées dans la zone de recherche:',
+ address: 'Recherche par adresse',
+ place: 'Recherche par nom de lieu',
+ etc: 'Recherche par code postal, région, etc.'
+ },
+ tools: {
+ title: 'Outils',
+ description: 'En plus des capacités de recherche, les outils suivants sont fournis:',
+ measure: {
+ title: 'Mesurer',
+ description: 'L\'outil de mesure fournit les capacités pour dessiner un point, une ligne ou un polygone sur la carte et indiquer l\'unité de mesure.'
+ },
+ print: {
+ title: 'Impression',
+ description: 'Cette carte peut être exportée vers différents formats et mises en page.'
+ }
+ }
+});
\ No newline at end of file
diff --git a/viewer/js/gis/dijit/Help/nls/pt-br/resource.js b/viewer/js/gis/dijit/Help/nls/pt-br/resource.js
new file mode 100644
index 000000000..2793d85a8
--- /dev/null
+++ b/viewer/js/gis/dijit/Help/nls/pt-br/resource.js
@@ -0,0 +1,36 @@
+define({
+ link: 'Ajuda',
+ navigation: {
+ title: 'Navegação',
+ description: 'Navegação no mapa usando o rato e o teclado',
+ pan1: 'Arrastar para mover',
+ recenter: 'SHIFT + Clique para centrar',
+ zoomIn1: 'SHIFT + Arrastar para aproximar à área',
+ zoomOut1: 'SHIFT + CTRL + Arrastar para afastar',
+ zoomIn2: 'Mover roda de deslocação do rato para a frente para aproximar',
+ zoomOut2: 'Mover roda de deslocação do rato para trás para afastar',
+ pan2: 'Teclas de seta para mover',
+ zoomInLevel: 'Tecla + para aproximar um nível',
+ zoomOutLevel: 'Tecla - para afastar um nível',
+ zoomCenter: 'Duplo clique para centrar e aproximar'
+ },
+ search: {
+ title: 'Pesquisa',
+ description: 'A caixa de pesquisa suporta vários tipos de pesquisa:',
+ address: 'Pesquisar por endereço',
+ place: 'Pesquisar por nome do local',
+ etc: 'Pesquisar por código postal, região, etc.'
+ },
+ tools: {
+ title: 'Ferramentas',
+ description: 'Além das funcionalidades de pesquisa, são incluídas as seguintes ferramentas:',
+ measure: {
+ title: 'Medir',
+ description: 'A ferramenta de medição permite desenhar um ponto, linha, ou polígono, no mapa e especificar a unidade de medida.'
+ },
+ print: {
+ title: 'Imprimir',
+ description: 'Este mapa pode ser exportado para diferentes formatos e modelos.'
+ }
+ }
+});
diff --git a/viewer/js/gis/dijit/Help/nls/pt-pt/resource.js b/viewer/js/gis/dijit/Help/nls/pt-pt/resource.js
new file mode 100644
index 000000000..2793d85a8
--- /dev/null
+++ b/viewer/js/gis/dijit/Help/nls/pt-pt/resource.js
@@ -0,0 +1,36 @@
+define({
+ link: 'Ajuda',
+ navigation: {
+ title: 'Navegação',
+ description: 'Navegação no mapa usando o rato e o teclado',
+ pan1: 'Arrastar para mover',
+ recenter: 'SHIFT + Clique para centrar',
+ zoomIn1: 'SHIFT + Arrastar para aproximar à área',
+ zoomOut1: 'SHIFT + CTRL + Arrastar para afastar',
+ zoomIn2: 'Mover roda de deslocação do rato para a frente para aproximar',
+ zoomOut2: 'Mover roda de deslocação do rato para trás para afastar',
+ pan2: 'Teclas de seta para mover',
+ zoomInLevel: 'Tecla + para aproximar um nível',
+ zoomOutLevel: 'Tecla - para afastar um nível',
+ zoomCenter: 'Duplo clique para centrar e aproximar'
+ },
+ search: {
+ title: 'Pesquisa',
+ description: 'A caixa de pesquisa suporta vários tipos de pesquisa:',
+ address: 'Pesquisar por endereço',
+ place: 'Pesquisar por nome do local',
+ etc: 'Pesquisar por código postal, região, etc.'
+ },
+ tools: {
+ title: 'Ferramentas',
+ description: 'Além das funcionalidades de pesquisa, são incluídas as seguintes ferramentas:',
+ measure: {
+ title: 'Medir',
+ description: 'A ferramenta de medição permite desenhar um ponto, linha, ou polígono, no mapa e especificar a unidade de medida.'
+ },
+ print: {
+ title: 'Imprimir',
+ description: 'Este mapa pode ser exportado para diferentes formatos e modelos.'
+ }
+ }
+});
diff --git a/viewer/js/gis/dijit/Help/nls/resource.js b/viewer/js/gis/dijit/Help/nls/resource.js
new file mode 100644
index 000000000..137c491ff
--- /dev/null
+++ b/viewer/js/gis/dijit/Help/nls/resource.js
@@ -0,0 +1,42 @@
+define({
+ root: {
+ link: 'Help',
+ navigation: {
+ title: 'Navigation',
+ description: 'Map navigation using mouse and keyboard:',
+ pan1: 'Drag to pan',
+ recenter: 'SHIFT + Click to recenter',
+ zoomIn1: 'SHIFT + Drag to zoom in',
+ zoomOut1: 'SHIFT + CTRL + Drag to zoom out',
+ zoomIn2: 'Mouse Scroll Forward to zoom in',
+ zoomOut2: 'Mouse Scroll Backward to zoom out',
+ pan2: 'Use Arrow keys to pan',
+ zoomInLevel: '+ key to zoom in a level',
+ zoomOutLevel: '- key to zoom out a level',
+ zoomCenter: 'Double Click to Center and Zoom in'
+ },
+ search: {
+ title: 'Search',
+ description: 'A variety of searches can be performed in the search box:',
+ address: 'Search by Address',
+ place: 'Search by Place Name',
+ etc: 'Search By Zip Code, County, etc.'
+ },
+ tools: {
+ title: 'Tools',
+ description: 'In addition to Search capabilities, the following tools are provided:',
+ measure: {
+ title: 'Measure',
+ description: 'The measure tool provides the capabilities to draw a point, line, or polygon on the map and specify the unit of measurement.'
+ },
+ print: {
+ title: 'Print',
+ description: 'This map can be exported to various formats and layouts.'
+ }
+ }
+ },
+ 'es': true,
+ 'fr': true,
+ 'pt-br': true,
+ 'pt-pt': true
+});
diff --git a/viewer/js/gis/dijit/Help/templates/HelpDialog.html b/viewer/js/gis/dijit/Help/templates/HelpDialog.html
index 82a31e5b9..da701f42f 100644
--- a/viewer/js/gis/dijit/Help/templates/HelpDialog.html
+++ b/viewer/js/gis/dijit/Help/templates/HelpDialog.html
@@ -2,42 +2,42 @@
-
+
- Map navigation using mouse and keyboard:
+ ${i18n.navigation.description}
- Drag to pan
+ ${i18n.navigation.pan1}
- SHIFT + Click to recenter
+ ${i18n.navigation.recenter}
- SHIFT + Drag to zoom in
+ ${i18n.navigation.zoomIn1}
- SHIFT + CTRL + Drag to zoom out
+ ${i18n.navigation.zoomOut1}
- Mouse Scroll Forward to zoom in
+ ${i18n.navigation.zoomIn2}
- Mouse Scroll Backward to zoom out
+ ${i18n.navigation.zoomOut2}
- Use Arrow keys to pan
+ ${i18n.navigation.pan2}
- + key to zoom in a level
+ ${i18n.navigation.zoomInLevel}
- - key to zoom out a level
+ ${i18n.navigation.zoomOutLevel}
- Double Click to Center and Zoom in
+ ${i18n.navigation.zoomCenter}
@@ -45,35 +45,34 @@
-
- A variety of searches can be performed in the search box:
+
+ ${i18n.search.description}
- Search by Address
+ ${i18n.search.address}
- Search by Place Name
+ ${i18n.search.place}
- Search By Zip Code, County, etc.
+ ${i18n.search.etc}
-
- In addition to Search capabilities, the following tools are provided:
+
+ ${i18n.tools.description}
- Measure
+ ${i18n.tools.measure.title}
- The measure tool provides the capabilities to draw a point, line, or polygon
- on the map and specify the unit of measurement.
+ ${i18n.tools.measure.description}
- Print
+ ${i18n.tools.print.title}
- This map can be exported to varouis formats and layouts
+ ${i18n.tools.print.description}
diff --git a/viewer/js/gis/dijit/Identify.js b/viewer/js/gis/dijit/Identify.js
index 1a7775fd5..ccae23bc5 100644
--- a/viewer/js/gis/dijit/Identify.js
+++ b/viewer/js/gis/dijit/Identify.js
@@ -16,13 +16,18 @@ define([
'esri/tasks/IdentifyTask',
'esri/tasks/IdentifyParameters',
'esri/dijit/PopupTemplate',
+ 'esri/layers/FeatureLayer',
+ 'esri/TimeExtent',
+ 'dojo/Deferred',
'dojo/text!./Identify/templates/Identify.html',
'dojo/i18n!./Identify/nls/resource',
+ './Identify/Formatters',
'dijit/form/Form',
'dijit/form/FilteringSelect',
'xstyle/css!./Identify/css/Identify.css'
-], function (declare, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, MenuItem, lang, array, all, topic, query, domStyle, domClass, Moveable, Memory, IdentifyTask, IdentifyParameters, PopupTemplate, IdentifyTemplate, i18n) {
+], function (declare, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, MenuItem, lang, array, all, topic, query, domStyle, domClass, Moveable, Memory, IdentifyTask, IdentifyParameters, PopupTemplate, FeatureLayer, TimeExtent, Deferred, IdentifyTemplate, i18n, Formatters) {
+
return declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], {
widgetsInTemplate: true,
templateString: IdentifyTemplate,
@@ -32,11 +37,31 @@ define([
mapClickMode: null,
identifies: {},
infoTemplates: {},
+ featureLayers: {},
ignoreOtherGraphics: true,
createDefaultInfoTemplates: true,
draggable: false,
layerSeparator: '||',
allLayersId: '***',
+ excludedFields: [
+ 'objectid', 'esri_oid', 'shape',
+ 'shape.len', 'shape_length',
+ 'shape_len', 'shape.stlength()',
+ 'shape.area', 'shape_area', 'shape.starea()'
+ ],
+ /**
+ * field type mappings to their default formatter functions
+ * overriding this object will globally replace the default
+ * formatter function for the field type
+ * @type {Object}
+ */
+ defaultFormatters: {
+ 'esriFieldTypeSmallInteger': Formatters.formatInt,
+ 'esriFieldTypeInteger': Formatters.formatInt,
+ 'esriFieldTypeSingle': Formatters.formatFloat,
+ 'esriFieldTypeDouble': Formatters.formatFloat,
+ 'esriFieldTypeDate': Formatters.formatDate
+ },
postCreate: function () {
this.inherited(arguments);
@@ -44,56 +69,10 @@ define([
this.identifies = {};
}
this.layers = [];
- array.forEach(this.layerInfos, function (layerInfo) {
- var lyrId = layerInfo.layer.id;
- var layer = this.map.getLayer(lyrId);
- if (layer) {
- var url = layer.url;
-
- // handle feature layers
- if (layer.declaredClass === 'esri.layers.FeatureLayer') {
-
- // If is a feature layer that does not support
- // Identify (Feature Service), create an
- // infoTemplate for the graphic features. Create
- // it only if one does not already exist.
- if (layer.capabilities && layer.capabilities.toLowerCase().indexOf('data') < 0) {
- if (!layer.infoTemplate) {
- var infoTemplate = this.getInfoTemplate(layer, layer.layerId);
- if (infoTemplate) {
- layer.setInfoTemplate(infoTemplate);
- return;
- }
- }
- }
-
- // If it is a feature Layer, we get the base url
- // for the map service by removing the layerId.
- var lastSL = url.lastIndexOf('/' + layer.layerId);
- if (lastSL > 0) {
- url = url.substring(0, lastSL);
- }
- }
-
- this.layers.push({
- ref: layer,
- layerInfo: layerInfo,
- identifyTask: new IdentifyTask(url)
- });
-
- // rebuild the layer selection list when any layer is hidden
- // but only if we have a UI
- if (this.parentWidget) {
- layer.on('visibility-change', lang.hitch(this, function (evt) {
- if (evt.visible === false) {
- this.createIdentifyLayerList();
- }
- }));
- }
- }
- }, this);
+ this.addLayerInfos(this.layerInfos);
this.own(topic.subscribe('mapClickMode/currentSet', lang.hitch(this, 'setMapClickMode')));
+ this.own(topic.subscribe('identify/addLayerInfos', lang.hitch(this, 'addLayerInfos')));
this.map.on('click', lang.hitch(this, function (evt) {
if (this.mapClickMode === 'identify') {
@@ -117,6 +96,80 @@ define([
this.setupDraggable();
}
},
+ /**
+ * handles an array of layerInfos to call addLayerInfo for each layerInfo
+ * @param {Array} layerInfos The array of layer infos
+ * @returns {undefined}
+ */
+ addLayerInfos: function (layerInfos) {
+ array.forEach(layerInfos, lang.hitch(this, 'addLayerInfo'));
+ },
+ /**
+ * Initializes an infoTemplate on a layerInfo.layer object if it doesn't
+ * exist already.
+ * @param {object} layerInfo A cmv layerInfo object that contains a layer property
+ * @return {undefined}
+ */
+ addLayerInfo: function (layerInfo) {
+ var lyrId = layerInfo.layer.id, layer = this.map.getLayer(lyrId), infoTemplate;
+ if (layer) {
+ var url = layer.url;
+
+ // handle feature layers
+ if (layer.declaredClass === 'esri.layers.FeatureLayer') {
+
+ // If is a feature layer that does not support
+ // Identify (Feature Service), create an
+ // infoTemplate for the graphic features. Create
+ // it only if one does not already exist.
+ if (layer.capabilities && array.indexOf(layer.capabilities.toLowerCase(), 'data') < 0) {
+ if (!layer.infoTemplate) {
+ infoTemplate = this.getInfoTemplate(layer, layer.layerId);
+ if (infoTemplate) {
+ layer.setInfoTemplate(infoTemplate);
+ var fieldInfos = infoTemplate.info.fieldInfos;
+ var formatters = array.filter(fieldInfos, function (info) {
+ return (info.formatter);
+ });
+ if (formatters.length > 0) {
+ layer.on('graphic-draw', lang.hitch(this, 'getFormattedFeature', layer.infoTemplate));
+ }
+ }
+ }
+ }
+
+ // If it is a feature Layer, we get the base url
+ // for the map service by removing the layerId.
+ var lastSL = url.lastIndexOf('/' + layer.layerId);
+ if (lastSL > 0) {
+ url = url.substring(0, lastSL);
+ }
+ } else if (layer.layerInfos) {
+ array.forEach(layer.layerInfos, lang.hitch(this, function (subLayerInfo) {
+ var subLayerId = subLayerInfo.id;
+ if ((layerInfo.layerIds === null) || (array.indexOf(layerInfo.layerIds, subLayerId) >= 0)) {
+ this.getFeatureLayerForDynamicSublayer(layer, subLayerId);
+ }
+ }));
+ }
+
+ this.layers.push({
+ ref: layer,
+ layerInfo: layerInfo,
+ identifyTask: new IdentifyTask(url)
+ });
+
+ // rebuild the layer selection list when any layer is hidden
+ // but only if we have a UI
+ if (this.parentWidget) {
+ layer.on('visibility-change', lang.hitch(this, function (evt) {
+ if (evt.visible === false) {
+ this.createIdentifyLayerList();
+ }
+ }));
+ }
+ }
+ },
addRightClickMenu: function () {
this.map.on('MouseDown', lang.hitch(this, function (evt) {
this.mapRightClick = evt;
@@ -129,7 +182,7 @@ define([
setupDraggable: function () {
var popups, handles, pointers, movable;
// the popup, handle (title) and pointers (arrows)
- popups = query('div.esriPopup');
+ popups = query('div.esriPopup');
handles = query('div.esriPopup div.titlePane div.title');
pointers = query('div.esriPopup div.outerPointer, div.esriPopup div.pointer');
@@ -150,8 +203,27 @@ define([
}
},
executeIdentifyTask: function (evt) {
+
+
+ var mapPoint = evt.mapPoint;
+ var identifyParams = this.createIdentifyParams(mapPoint);
+ var identifies = [];
+ var identifiedlayers = [];
+ var selectedLayer = this.getSelectedLayer();
+
+
if (!this.checkForGraphicInfoTemplate(evt)) {
- return;
+ // return;
+ var layer = array.filter(this.layers, function (l) {
+ return l.ref.id === evt.graphic._layer.id;
+ })[0];
+ if (!layer) {
+ return;
+ }
+ identifiedlayers.push(layer);
+ var d = new Deferred();
+ identifies.push(d.promise);
+ d.resolve([{feature: evt.graphic}]);
}
this.map.infoWindow.hide();
@@ -162,25 +234,23 @@ define([
return;
}
- var mapPoint = evt.mapPoint;
- var identifyParams = this.createIdentifyParams(mapPoint);
- var identifies = [];
- var identifiedlayers = [];
- var selectedLayer = this.getSelectedLayer();
- array.forEach(this.layers, lang.hitch(this, function (layer) {
- var layerIds = this.getLayerIds(layer, selectedLayer);
+ array.forEach(this.layers, lang.hitch(this, function (lyr) {
+ var layerIds = this.getLayerIds(lyr, selectedLayer);
if (layerIds.length > 0) {
var params = lang.clone(identifyParams);
- params.layerDefinitions = layer.ref.layerDefinitions;
+ params.layerDefinitions = lyr.ref.layerDefinitions;
params.layerIds = layerIds;
- identifies.push(layer.identifyTask.execute(params));
- identifiedlayers.push(layer);
+ if (lyr.ref.timeInfo && lyr.ref.timeInfo.timeExtent && this.map.timeExtent) {
+ params.timeExtent = new TimeExtent(this.map.timeExtent.startTime, this.map.timeExtent.endTime);
+ }
+ identifies.push(lyr.identifyTask.execute(params));
+ identifiedlayers.push(lyr);
}
}));
if (identifies.length > 0) {
- this.map.infoWindow.setTitle( this.i18n.mapInfoWindow.identifyingTitle );
+ this.map.infoWindow.setTitle(this.i18n.mapInfoWindow.identifyingTitle);
this.map.infoWindow.setContent('');
this.map.infoWindow.show(mapPoint);
all(identifies).then(lang.hitch(this, 'identifyCallback', identifiedlayers), lang.hitch(this, 'identifyError'));
@@ -192,7 +262,7 @@ define([
// handle feature layers that come from a feature service
// and may already have an info template
var layer = evt.graphic._layer;
- if (layer.infoTemplate || (layer.capabilities && layer.capabilities.toLowerCase().indexOf('data') < 0)) {
+ if (layer.infoTemplate || (layer.capabilities && array.indexOf(layer.capabilities.toLowerCase(), 'data') < 0)) {
return false;
}
@@ -254,7 +324,7 @@ define([
} else if ((ref.declaredClass === 'esri.layers.FeatureLayer') && !isNaN(ref.layerId)) { // feature layer
// do not allow feature layer that does not support
// Identify (Feature Service)
- if (ref.capabilities && ref.capabilities.toLowerCase().indexOf('data') > 0) {
+ if (ref.capabilities && array.indexOf(ref.capabilities.toLowerCase(), 'data') >= 0) {
layerIds = [ref.layerId];
}
} else if (ref.layerInfos) {
@@ -286,16 +356,33 @@ define([
if (result.feature.infoTemplate === undefined) {
var infoTemplate = this.getInfoTemplate(ref, null, result);
if (infoTemplate) {
+ if (result.layerId && ref.layerInfos && infoTemplate.info.showAttachments) {
+ result.feature._layer = this.getFeatureLayerForDynamicSublayer(ref, result.layerId);
+ }
result.feature.setInfoTemplate(infoTemplate);
} else {
return;
}
}
- fSet.push(result.feature);
+ var feature = this.getFormattedFeature(result.feature.infoTemplate, result.feature);
+ fSet.push(feature);
}, this);
}, this);
this.map.infoWindow.setFeatures(fSet);
},
+ getFormattedFeature: function (infoTemplate, feature) {
+ if (feature.graphic) {
+ feature = feature.graphic;
+ }
+ if (feature && infoTemplate && infoTemplate.info) {
+ array.forEach(infoTemplate.info.fieldInfos, function (info) {
+ if (typeof info.formatter === 'function') {
+ feature.attributes[info.fieldName] = info.formatter(feature.attributes[info.fieldName], feature.attributes, lang.clone(feature.geometry));
+ }
+ });
+ }
+ return feature;
+ },
identifyError: function (err) {
this.map.infoWindow.hide();
topic.publish('viewer/handleError', {
@@ -308,43 +395,41 @@ define([
},
getInfoTemplate: function (layer, layerId, result) {
- var popup = null,
- content = null;
+ var popup, config;
if (result) {
- layerId = result.layerId;
+ layerId = result.layerId || layer.layerId;
} else if (layerId === null) {
layerId = layer.layerId;
}
- // see if we have a Popup config defined for this layer
- if (this.identifies.hasOwnProperty(layer.id)) {
- if (this.identifies[layer.id].hasOwnProperty(layerId)) {
- popup = this.identifies[layer.id][layerId];
- if (popup) {
- if (typeof (popup.declaredClass) !== 'string') { // has it been created already?
- if (popup.content) {
- content = popup.content;
- }
- popup = new PopupTemplate(popup);
- if (content) {
- popup.setContent(content);
- }
- this.identifies[layer.id][layerId] = popup;
- }
+ var ids = this.identifies;
+ if (ids.hasOwnProperty(layer.id)) {
+ if (ids[layer.id].hasOwnProperty(layerId)) {
+ popup = ids[layer.id][layerId];
+ if (popup instanceof PopupTemplate) {
+ return popup;
}
}
+ } else {
+ ids[layer.id] = {};
}
- // if no Popup config found, create one with all attributes or layer fields
- if (!popup) {
- popup = this.createInfoTemplate(layer, layerId, result);
+ // by mixin in the users config with the default props we can
+ // generate a config object that provides the basics automatically
+ // while letting the user override only the parts they want...like mediaInfos
+ config = lang.mixin(this.createDefaultInfoTemplate(layer, layerId, result), ids[layer.id][layerId] || {});
+
+ popup = ids[layer.id][layerId] = new PopupTemplate(config);
+ if (config.content) {
+ popup.setContent(config.content);
}
- return popup;
+ return ids[layer.id][layerId];
},
- createInfoTemplate: function (layer, layerId, result) {
- var popup = null, fieldInfos = [];
+ createDefaultInfoTemplate: function (layer, layerId, result) {
+ var popup = null,
+ fieldInfos = [];
var layerName = this.getLayerName(layer);
if (result) {
@@ -357,57 +442,77 @@ define([
if (attributes) {
for (var prop in attributes) {
if (attributes.hasOwnProperty(prop)) {
- fieldInfos.push({
+ this.addDefaultFieldInfo(fieldInfos, {
fieldName: prop,
+ label: this.makeSentenceCase(prop),
visible: true
});
}
}
}
- // from the outFields of the layer
+ // from the outFields of the layer
} else if (layer._outFields && (layer._outFields.length) && (layer._outFields[0] !== '*')) {
var fields = layer.fields;
- array.forEach(layer._outFields, function (fieldName) {
+ array.forEach(layer._outFields, lang.hitch(this, function (fieldName) {
var foundField = array.filter(fields, function (field) {
return (field.name === fieldName);
});
if (foundField.length > 0) {
- fieldInfos.push({
+ this.addDefaultFieldInfo(fieldInfos, {
fieldName: foundField[0].name,
label: foundField[0].alias,
visible: true
});
}
- });
+ }));
- // from the fields layer
+ // from the fields layer
} else if (layer.fields) {
- array.forEach(layer.fields, function (field) {
- fieldInfos.push({
+ array.forEach(layer.fields, lang.hitch(this, function (field) {
+ this.addDefaultFieldInfo(fieldInfos, {
fieldName: field.name,
- label: field.alias,
+ label: field.alias === field.name ? this.makeSentenceCase(field.name) : field.alias,
visible: true
});
- });
+ }));
}
if (fieldInfos.length > 0) {
- popup = new PopupTemplate({
+ popup = {
title: layerName,
fieldInfos: fieldInfos,
showAttachments: (layer.hasAttachments)
- });
- if (!this.identifies[layer.id]) {
- this.identifies[layer.id] = {};
- }
- this.identifies[layer.id][layerId] = popup;
+ };
}
return popup;
},
+ /**
+ * converts a string to a nice sentence case format
+ * @url http://stackoverflow.com/questions/196972/convert-string-to-title-case-with-javascript
+ * @param {string} str The string to convert
+ * @return {string} The converted string
+ */
+ makeSentenceCase: function (str) {
+ if (!str.length) {
+ return '';
+ }
+ str = str.toLowerCase().replace(/_/g, ' ').split(' ');
+ for (var i = 0; i < str.length; i++) {
+ str[i] = str[i].charAt(0).toUpperCase() + (str[i].substr(1).length ? str[i].substr(1) : '');
+ }
+ return (str.length ? str.join(' ') : str);
+ },
+
+ addDefaultFieldInfo: function (fieldInfos, field) {
+ var nameLC = field.fieldName.toLowerCase();
+ if (array.indexOf(this.excludedFields, nameLC) < 0) {
+ fieldInfos.push(field);
+ }
+ },
createIdentifyLayerList: function () {
var id = null;
@@ -474,8 +579,10 @@ define([
if (layerInfo.subLayerIds !== null) {
return false;
}
- // only include sublayers that are currently visible
- if (array.indexOf(ref.visibleLayers, layerInfo.id) < 0) {
+
+ if (this.isDefaultLayerVisibility(ref) && !this.checkVisibilityRecursive(ref, layerInfo.id)) {
+ return false;
+ } else if (array.indexOf(ref.visibleLayers, layerInfo.id) < 0) {
return false;
}
// only include sublayers that are within the current map scale
@@ -503,6 +610,44 @@ define([
return true;
},
+ /**
+ * recursively check all a layer's parent(s) layers for visibility
+ * this only needs to be done if the layers visibleLayers array is
+ * set to the default visibleLayers. After setVisibleLayers
+ * is called the first time group layers are NOT included.
+ * @param {esri/layers/DynamicMapServiceLayer} layer The layer reference
+ * @param {Integer} id The sublayer id to check for visibility
+ * @return {Boolean} Whether or not the sublayer is visible based on its parent(s) visibility
+ */
+ checkVisibilityRecursive: function (layer, id) {
+ var layerInfos = array.filter(layer.layerInfos, function (layerInfo) {
+ return (layerInfo.id === id);
+ });
+ if (layerInfos.length > 0) {
+ var info = layerInfos[0];
+ if (layer.visibleLayers.indexOf(id) !== -1 &&
+ (info.parentLayerId === -1 || this.checkVisibilityRecursive(layer, info.parentLayerId))) {
+ return true;
+ }
+ }
+ return false;
+ },
+ /**
+ * check each defaultVisibility and if its not in the visibleLayers
+ * array, then the layer has non-default layer visibility
+ * @param {esri/layers/DynamicMapServiceLayer} layer The layer reference
+ * @return {Boolean} Whether or not we're operating with the default visibleLayers array or not
+ */
+ isDefaultLayerVisibility: function (layer) {
+ for (var i = 0; i < layer.layerInfos.length; i++) {
+ var item = layer.layerInfos[i];
+ if (item.defaultVisibility && layer.visibleLayers.indexOf(item.id) === -1) {
+ return false;
+ }
+ }
+ return true;
+ },
+
getLayerName: function (layer) {
var name = null;
if (layer.layerInfo) {
@@ -525,6 +670,17 @@ define([
return name;
},
+ getFeatureLayerForDynamicSublayer: function (layer, layerId) {
+ if (!layer.layerInfos) {
+ return false;
+ }
+ var key = layer.url + '/' + layerId;
+ if (!this.featureLayers.hasOwnProperty(key)) {
+ this.featureLayers[key] = new FeatureLayer(key);
+ }
+ return this.featureLayers[key];
+ },
+
layerVisibleAtCurrentScale: function (layer) {
var mapScale = this.map.getScale();
return !(((layer.maxScale !== 0 && mapScale < layer.maxScale) || (layer.minScale !== 0 && mapScale > layer.minScale)));
@@ -544,14 +700,12 @@ define([
}
// remove any infoTemplates that might
// interfere with clicking on a feature
- } else {
- if (layer.infoTemplate) {
- this.infoTemplates[layer.id] = lang.clone(layer.infoTemplate);
- layer.infoTemplate = null;
- }
+ } else if (layer.infoTemplate) {
+ this.infoTemplates[layer.id] = lang.clone(layer.infoTemplate);
+ layer.infoTemplate = null;
}
}
}, this);
}
});
-});
\ No newline at end of file
+});
diff --git a/viewer/js/gis/dijit/Identify/Formatters.js b/viewer/js/gis/dijit/Identify/Formatters.js
new file mode 100644
index 000000000..b7c259e9d
--- /dev/null
+++ b/viewer/js/gis/dijit/Identify/Formatters.js
@@ -0,0 +1,21 @@
+define([
+ 'dojo/number',
+ 'dojo/date/locale'
+], function (number, locale) {
+ return {
+ formatInt: function (value) {
+ return number.format(value);
+ },
+ formatFloat: function (value) {
+ return number.format(value, {
+ places: 3
+ });
+ },
+ formatDate: function (value) {
+ var date = new Date(value);
+ return locale.format(date, {
+ formatLength: 'short'
+ });
+ }
+ };
+});
diff --git a/viewer/js/gis/dijit/Identify/nls/es/resource.js b/viewer/js/gis/dijit/Identify/nls/es/resource.js
new file mode 100644
index 000000000..fda941704
--- /dev/null
+++ b/viewer/js/gis/dijit/Identify/nls/es/resource.js
@@ -0,0 +1,12 @@
+define ({
+ labels: {
+ selectLayer: 'Seleccione la opción "Todas las capas visibles" o una sola capa para identificar:',
+ allVisibleLayers: '*** Todas las capas visibles ***'
+ },
+ rightClickMenuItem: {
+ label: 'Identificar aquí'
+ },
+ mapInfoWindow: {
+ identifyingTitle: 'Identificando...'
+ }
+});
\ No newline at end of file
diff --git a/viewer/js/gis/dijit/Identify/nls/fr/resource.js b/viewer/js/gis/dijit/Identify/nls/fr/resource.js
new file mode 100644
index 000000000..013c39962
--- /dev/null
+++ b/viewer/js/gis/dijit/Identify/nls/fr/resource.js
@@ -0,0 +1,12 @@
+define ({
+ labels: {
+ selectLayer: 'Choisissez "Tous les calques visibles" ou une seule couche pour identifier:',
+ allVisibleLayers: '*** Tous les calques visibles ***'
+ },
+ rightClickMenuItem: {
+ label: 'Identifier ici'
+ },
+ mapInfoWindow: {
+ identifyingTitle: 'Identification...'
+ }
+});
\ No newline at end of file
diff --git a/viewer/js/gis/dijit/Identify/nls/pt-br/resource.js b/viewer/js/gis/dijit/Identify/nls/pt-br/resource.js
new file mode 100644
index 000000000..1a4d3327b
--- /dev/null
+++ b/viewer/js/gis/dijit/Identify/nls/pt-br/resource.js
@@ -0,0 +1,12 @@
+define({
+ labels: {
+ selectLayer: 'Escolha "Todas Camadas Visíveis" ou uma camada única para Identificar:',
+ allVisibleLayers: '*** Todas Camadas Visíveis ***'
+ },
+ rightClickMenuItem: {
+ label: 'Identifique aqui'
+ },
+ mapInfoWindow: {
+ identifyingTitle: 'Identificando...'
+ }
+});
\ No newline at end of file
diff --git a/viewer/js/gis/dijit/Identify/nls/pt-pt/resource.js b/viewer/js/gis/dijit/Identify/nls/pt-pt/resource.js
new file mode 100644
index 000000000..ab2998ff7
--- /dev/null
+++ b/viewer/js/gis/dijit/Identify/nls/pt-pt/resource.js
@@ -0,0 +1,12 @@
+define({
+ labels: {
+ selectLayer: 'Escolher "Todas as camadas visíveis" ou uma única camada para identificar:',
+ allVisibleLayers: '*** Todas as camadas visíveis ***'
+ },
+ rightClickMenuItem: {
+ label: 'Identificar aqui'
+ },
+ mapInfoWindow: {
+ identifyingTitle: 'A identificar...'
+ }
+});
\ No newline at end of file
diff --git a/viewer/js/gis/dijit/Identify/nls/resource.js b/viewer/js/gis/dijit/Identify/nls/resource.js
index 54093328c..f46111906 100644
--- a/viewer/js/gis/dijit/Identify/nls/resource.js
+++ b/viewer/js/gis/dijit/Identify/nls/resource.js
@@ -10,5 +10,9 @@ define ({
mapInfoWindow: {
identifyingTitle: 'Identifying...'
}
- }
+ },
+ 'es': true,
+ 'fr': true,
+ 'pt-br': true,
+ 'pt-pt': true
});
\ No newline at end of file
diff --git a/viewer/js/gis/dijit/LayerControl.js b/viewer/js/gis/dijit/LayerControl.js
index 7d76297f0..4a8f14098 100644
--- a/viewer/js/gis/dijit/LayerControl.js
+++ b/viewer/js/gis/dijit/LayerControl.js
@@ -28,12 +28,13 @@ define([
esriConfig,
require
) {
+
var LayerControl = declare([WidgetBase, Container], {
map: null,
layerInfos: [],
icons: {
- expand: 'fa-plus-square-o',
- collapse: 'fa-minus-square-o',
+ expand: 'fa-caret-right',
+ collapse: 'fa-caret-down',
checked: 'fa-check-square-o',
unchecked: 'fa-square-o',
update: 'fa-refresh',
@@ -50,6 +51,7 @@ define([
noLegend: null,
noZoom: null,
noTransparency: null,
+ menu: {},
subLayerMenu: {},
swipe: null,
swiperButtonStyle: 'position:absolute;top:20px;left:120px;z-index:50;',
@@ -67,7 +69,9 @@ define([
csv: './LayerControl/controls/CSV',
georss: './LayerControl/controls/GeoRSS',
wms: './LayerControl/controls/WMS',
+ wfs: './LayerControl/controls/WFS',
kml: './LayerControl/controls/KML',
+ vectortile: './LayerControl/controls/VectorTile',
webtiled: './LayerControl/controls/WebTiled',
imagevector: './LayerControl/controls/ImageVector',
raster: './LayerControl/controls/Raster',
@@ -82,6 +86,8 @@ define([
});
return;
}
+ // add any user-defined controls - possibly for user-defined layers
+ this._controls = lang.mixin(this._controls, options.controls || {});
},
postCreate: function () {
this.inherited(arguments);
@@ -115,10 +121,22 @@ define([
this.overlayReorder = false;
this.vectorReorder = false;
}
+ this._addLayerControls(this.layerInfos);
+ this._subscribeToTopics();
+ },
+ _subscribeToTopics: function () {
+ this._removeLayerControlsHandler = topic.subscribe('layerControl/removeLayerControls', lang.hitch(this, function (layers) {
+ this._removeLayerControls(layers);
+ }));
+ this._addLayerControlsHandler = topic.subscribe('layerControl/addLayerControls', lang.hitch(this, function (layerInfos) {
+ this._addLayerControls(layerInfos);
+ }));
+ },
+ _addLayerControls: function (layerInfos) {
// load only the modules we need
var modules = [];
// push layer control mods
- array.forEach(this.layerInfos, function (layerInfo) {
+ array.forEach(layerInfos, function (layerInfo) {
// check if control is excluded
var controlOptions = layerInfo.controlOptions;
if (controlOptions && controlOptions.exclude === true) {
@@ -136,7 +154,7 @@ define([
}, this);
// load and go
require(modules, lang.hitch(this, function () {
- array.forEach(this.layerInfos, function (layerInfo) {
+ array.forEach(layerInfos, function (layerInfo) {
// exclude from widget
var controlOptions = layerInfo.controlOptions;
if (controlOptions && controlOptions.exclude === true) {
@@ -150,11 +168,51 @@ define([
this._checkReorder();
}));
},
+ // remove the control given an array of layers
+ _removeLayerControls: function (layers) {
+ // helper function to determine which children's layer have a match in the layers parameter
+ function _filterList (entry) {
+ return layers.reduce(function (prior, curr) {
+ return (curr === entry.layer) || prior;
+ }, false);
+ }
+ // get a list of ALL the layers that meet the criteria
+ var layerControlList = this._overlayContainer.getChildren().filter(function (c) {
+ return _filterList(c);
+ }).concat(
+ this._vectorContainer.getChildren().filter(function (c) {
+ return _filterList(c);
+ })).concat(
+ this.getChildren().filter(function (c) {
+ return _filterList(c);
+ }));
+ // follow the same logic as when the layers were added
+ array.forEach(layerControlList, lang.hitch(this, function (layerControl) {
+ if (this.separated) {
+ if (layerControl._layerType === 'overlay') {
+ this._overlayContainer.removeChild(layerControl);
+ } else {
+ this._vectorContainer.removeChild(layerControl);
+ }
+ } else {
+ this.removeChild(layerControl);
+ }
+ layerControl.destroy();
+ }));
+ },
// create layer control and add to appropriate _container
- _addControl: function (layerInfo, LayerControl) {
- var layerControl = new LayerControl({
+ _addControl: function (layerInfo, Control) {
+ var layer = (typeof layerInfo.layer === 'string') ? this.map.getLayer(layerInfo.layer) : layerInfo.layer;
+ if (layerInfo.controlOptions && (layerInfo.type === 'dynamic' || layerInfo.type === 'feature')) {
+ if (layer.loaded) {
+ this._applyLayerControlOptions(layerInfo.controlOptions, layer);
+ } else {
+ layer.on('load', lang.hitch(this, '_applyLayerControlOptions', layerInfo.controlOptions));
+ }
+ }
+ var layerControl = new Control({
controller: this,
- layer: (typeof layerInfo.layer === 'string') ? this.map.getLayer(layerInfo.layer) : layerInfo.layer, // check if we have a layer or just a layer id
+ layer: layer,
layerTitle: layerInfo.title,
controlOptions: lang.mixin({
noLegend: null,
@@ -163,18 +221,84 @@ define([
swipe: null,
expanded: false,
sublayers: true,
- menu: this.subLayerMenu[layerInfo.type]
+ menu: this.menu[layerInfo.type],
+ subLayerMenu: this.subLayerMenu[layerInfo.type]
}, layerInfo.controlOptions)
});
layerControl.startup();
+ var position = layerInfo.position || 0;
if (this.separated) {
if (layerControl._layerType === 'overlay') {
- this._overlayContainer.addChild(layerControl, 'first');
+ this._overlayContainer.addChild(layerControl, position);
} else {
- this._vectorContainer.addChild(layerControl, 'first');
+ this._vectorContainer.addChild(layerControl, position);
}
} else {
- this.addChild(layerControl, 'first');
+ this.addChild(layerControl, position);
+ }
+ },
+ _applyLayerControlOptions: function (controlOptions, layer) {
+ if (typeof controlOptions.includeUnspecifiedLayers === 'undefined' && typeof controlOptions.subLayerInfos === 'undefined' && typeof controlOptions.excludedLayers === 'undefined') {
+ return;
+ }
+ var esriLayerInfos = [];
+ // Case 1: only show the layers that are explicitly listed
+ if (!controlOptions.includeUnspecifiedLayers && controlOptions.subLayerInfos && controlOptions.subLayerInfos.length !== 0) {
+ var subLayerInfos = array.map(controlOptions.subLayerInfos, function (sli) {
+ return sli.id;
+ });
+ array.forEach(layer.layerInfos, function (li) {
+ if (array.indexOf(subLayerInfos, li.id) !== -1) {
+ esriLayerInfos.push(li);
+ }
+ });
+ // Case 2: show ALL layers except those in the excluded list
+ } else if (controlOptions.excludedLayers) {
+ array.forEach(layer.layerInfos, function (li) {
+ if (array.indexOf(controlOptions.excludedLayers, li.id) === -1) {
+ esriLayerInfos.push(li);
+ }
+ });
+ // Case 3: just override the values found in the subLayerInfos
+ } else if (controlOptions.subLayerInfos) {
+ // show ALL layers that are in the map service's layerInfos, but take care to override the properties of each subLayerInfo as configured
+ this._mixinLayerInfos(layer.layerInfos, controlOptions.subLayerInfos);
+ this._setSublayerVisibilities(layer);
+ return;
+ }
+ // Finally, if we made use of the esriLayerInfos, make sure to apply all the subLayerInfos that were defined to our new array of esri layer infos
+ if (controlOptions.subLayerInfos) {
+ this._mixinLayerInfos(esriLayerInfos, controlOptions.subLayerInfos);
+ }
+ layer.layerInfos = esriLayerInfos;
+ this._setSublayerVisibilities(layer);
+ },
+ _setSublayerVisibilities: function (layer) {
+ var visibleIds = array.map(array.filter(layer.layerInfos, function (li) {
+ return li.defaultVisibility;
+ }), function (l) {
+ return l.id;
+ });
+ layer.setVisibleLayers(visibleIds);
+ },
+ _mixinLayerInfos: function (esriLayerInfos, subLayerInfos) {
+ // for each of the sublayers, go through the subLayerInfos from the controlOptions and see if defaultVisiblity is set to true or false
+ // then set each of the layer.layerInfos defaultVisibility appropriately
+ // assume defaultVisibility is true if it's not defined
+ if (subLayerInfos && subLayerInfos.length !== 0) {
+ array.forEach(subLayerInfos, function (sli) {
+ if (typeof sli.defaultVisibility === 'undefined') {
+ sli.defaultVisibility = true;
+ }
+ });
+ array.forEach(esriLayerInfos, function (li) {
+ var sli = array.filter(subLayerInfos, function (s) {
+ return s.id === li.id;
+ }).shift();
+ if (sli) {
+ lang.mixin(li, sli);
+ }
+ });
}
},
// move control up in controller and layer up in map
@@ -224,29 +348,37 @@ define([
if (this.separated) {
if (this.vectorReorder) {
array.forEach(this._vectorContainer.getChildren(), function (child) {
- if (!child.getPreviousSibling()) {
- child._reorderUp.set('disabled', true);
- } else {
- child._reorderUp.set('disabled', false);
+ if (child._reorderUp) {
+ if (!child.getPreviousSibling()) {
+ child._reorderUp.set('disabled', true);
+ } else {
+ child._reorderUp.set('disabled', false);
+ }
}
- if (!child.getNextSibling()) {
- child._reorderDown.set('disabled', true);
- } else {
- child._reorderDown.set('disabled', false);
+ if (child._reorderDown) {
+ if (!child.getNextSibling()) {
+ child._reorderDown.set('disabled', true);
+ } else {
+ child._reorderDown.set('disabled', false);
+ }
}
}, this);
}
if (this.overlayReorder) {
array.forEach(this._overlayContainer.getChildren(), function (child) {
- if (!child.getPreviousSibling()) {
- child._reorderUp.set('disabled', true);
- } else {
- child._reorderUp.set('disabled', false);
+ if (child._reorderUp) {
+ if (!child.getPreviousSibling()) {
+ child._reorderUp.set('disabled', true);
+ } else {
+ child._reorderUp.set('disabled', false);
+ }
}
- if (!child.getNextSibling()) {
- child._reorderDown.set('disabled', true);
- } else {
- child._reorderDown.set('disabled', false);
+ if (child._reorderDown) {
+ if (!child.getNextSibling()) {
+ child._reorderDown.set('disabled', true);
+ } else {
+ child._reorderDown.set('disabled', false);
+ }
}
}, this);
}
@@ -263,25 +395,23 @@ define([
var map = this.map;
if (layer.spatialReference === map.spatialReference) {
map.setExtent(layer.fullExtent, true);
- } else {
- if (esriConfig.defaults.geometryService) {
- esriConfig.defaults.geometryService.project(lang.mixin(new ProjectParameters(), {
- geometries: [layer.fullExtent],
- outSR: map.spatialReference
- }), function (r) {
- map.setExtent(r[0], true);
- }, function (e) {
- topic.publish('viewer/handleError', {
- source: 'LayerControl._zoomToLayer',
- error: e
- });
- });
- } else {
+ } else if (esriConfig.defaults.geometryService) {
+ esriConfig.defaults.geometryService.project(lang.mixin(new ProjectParameters(), {
+ geometries: [layer.fullExtent],
+ outSR: map.spatialReference
+ }), function (r) {
+ map.setExtent(r[0], true);
+ }, function (e) {
topic.publish('viewer/handleError', {
source: 'LayerControl._zoomToLayer',
- error: 'esriConfig.defaults.geometryService is not set'
+ error: e
});
- }
+ });
+ } else {
+ topic.publish('viewer/handleError', {
+ source: 'LayerControl._zoomToLayer',
+ error: 'esriConfig.defaults.geometryService is not set'
+ });
}
},
// layer swiper
@@ -359,4 +489,4 @@ define([
}
});
return LayerControl;
-});
\ No newline at end of file
+});
diff --git a/viewer/js/gis/dijit/LayerControl/controls/CSV.js b/viewer/js/gis/dijit/LayerControl/controls/CSV.js
index d5efc3784..e34b5db92 100644
--- a/viewer/js/gis/dijit/LayerControl/controls/CSV.js
+++ b/viewer/js/gis/dijit/LayerControl/controls/CSV.js
@@ -13,6 +13,7 @@ define([
_Control,
legendUtil
) {
+
var CSVControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], {
_layerType: 'vector', // constant
_esriLayerType: 'csv', // constant
diff --git a/viewer/js/gis/dijit/LayerControl/controls/Dynamic.js b/viewer/js/gis/dijit/LayerControl/controls/Dynamic.js
index caa52aa16..c4ce2a847 100644
--- a/viewer/js/gis/dijit/LayerControl/controls/Dynamic.js
+++ b/viewer/js/gis/dijit/LayerControl/controls/Dynamic.js
@@ -39,6 +39,7 @@ define([
legendUtil,
i18n
) {
+
var DynamicControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], {
_layerType: 'overlay', // constant
_esriLayerType: 'dynamic', // constant
@@ -87,6 +88,13 @@ define([
menu.addChild(new MenuSeparator());
}
},
+ _initCustomMenu: function () {
+ // add custom sublayer menu items if we only have one sublayer
+ if (!this._hasSublayers) {
+ array.forEach(this.controlOptions.subLayerMenu, lang.hitch(this, '_addCustomMenuItem', this.layerMenu));
+ this.layerMenu.addChild(new MenuSeparator());
+ }
+ },
// toggle all sublayers on/off
_toggleAllSublayers: function (state) {
array.forEach(this._sublayerControls, function (control) {
@@ -98,29 +106,40 @@ define([
_createSublayers: function (layer) {
// check for single sublayer - if so no sublayer/folder controls
if (layer.layerInfos.length > 1) {
+ var allLayers = array.map(layer.layerInfos, function (l) {
+ return l.id;
+ });
array.forEach(layer.layerInfos, lang.hitch(this, function (info) {
+ // see if there was any override needed from the subLayerInfos array in the controlOptions
+ var sublayerInfo = array.filter(this.controlOptions.subLayerInfos, function (sli) {
+ return sli.id === info.id;
+ }).shift();
+ lang.mixin(info, sublayerInfo);
var pid = info.parentLayerId,
slids = info.subLayerIds,
controlId = layer.id + '-' + info.id + '-sublayer-control',
control;
- if (pid === -1 && slids === null) {
- // it's a top level sublayer
- control = new DynamicSublayer({
- id: controlId,
- control: this,
- sublayerInfo: info,
- icons: this.icons
- });
- domConst.place(control.domNode, this.expandNode, 'last');
- } else if (pid === -1 && slids !== null) {
- // it's a top level folder
- control = new DynamicFolder({
- id: controlId,
- control: this,
- sublayerInfo: info,
- icons: this.icons
- });
- domConst.place(control.domNode, this.expandNode, 'last');
+ // it's a top level
+ if (pid === -1 || allLayers.indexOf(pid) === -1) {
+ if (slids === null) {
+ // it's a top level sublayer
+ control = new DynamicSublayer({
+ id: controlId,
+ control: this,
+ sublayerInfo: info,
+ icons: this.icons
+ });
+ domConst.place(control.domNode, this.expandNode, 'last');
+ } else if (slids !== null) {
+ // it's a top level folder
+ control = new DynamicFolder({
+ id: controlId,
+ control: this,
+ sublayerInfo: info,
+ icons: this.icons
+ });
+ domConst.place(control.domNode, this.expandNode, 'last');
+ }
} else if (pid !== -1 && slids !== null) {
// it's a nested folder
control = new DynamicFolder({
@@ -210,4 +229,4 @@ define([
}
});
return DynamicControl;
-});
\ No newline at end of file
+});
diff --git a/viewer/js/gis/dijit/LayerControl/controls/Feature.js b/viewer/js/gis/dijit/LayerControl/controls/Feature.js
index 2da71fec8..8706f5e29 100644
--- a/viewer/js/gis/dijit/LayerControl/controls/Feature.js
+++ b/viewer/js/gis/dijit/LayerControl/controls/Feature.js
@@ -13,6 +13,7 @@ define([
_Control,
legendUtil
) {
+
var FeatureControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], {
_layerType: 'vector', // constant
_esriLayerType: 'feature', // constant
@@ -27,4 +28,4 @@ define([
}
});
return FeatureControl;
-});
\ No newline at end of file
+});
diff --git a/viewer/js/gis/dijit/LayerControl/controls/GeoRSS.js b/viewer/js/gis/dijit/LayerControl/controls/GeoRSS.js
index c149b7411..86e99a560 100644
--- a/viewer/js/gis/dijit/LayerControl/controls/GeoRSS.js
+++ b/viewer/js/gis/dijit/LayerControl/controls/GeoRSS.js
@@ -11,6 +11,7 @@ define([
_Contained,
_Control
) {
+
var GeoRSSControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], {
_layerType: 'vector', // constant
_esriLayerType: 'georss', // constant
diff --git a/viewer/js/gis/dijit/LayerControl/controls/Image.js b/viewer/js/gis/dijit/LayerControl/controls/Image.js
index 6d0f1c597..6b845d01c 100644
--- a/viewer/js/gis/dijit/LayerControl/controls/Image.js
+++ b/viewer/js/gis/dijit/LayerControl/controls/Image.js
@@ -13,6 +13,7 @@ define([
_Control,
legendUtil
) {
+
var ImageControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], {
_layerType: 'overlay', // constant
_esriLayerType: 'image', // constant
diff --git a/viewer/js/gis/dijit/LayerControl/controls/ImageVector.js b/viewer/js/gis/dijit/LayerControl/controls/ImageVector.js
index add67e581..512b19ac4 100644
--- a/viewer/js/gis/dijit/LayerControl/controls/ImageVector.js
+++ b/viewer/js/gis/dijit/LayerControl/controls/ImageVector.js
@@ -13,6 +13,7 @@ define([
_Control,
legendUtil
) {
+
var ImageVectorControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], {
_layerType: 'overlay', // constant
_esriLayerType: 'imagevector', // constant
diff --git a/viewer/js/gis/dijit/LayerControl/controls/KML.js b/viewer/js/gis/dijit/LayerControl/controls/KML.js
index 21a32944d..5042c8df2 100644
--- a/viewer/js/gis/dijit/LayerControl/controls/KML.js
+++ b/viewer/js/gis/dijit/LayerControl/controls/KML.js
@@ -13,6 +13,7 @@ define([
_Control,
legendUtil
) {
+
var KMLControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], {
_layerType: 'vector', // constant
_esriLayerType: 'kml', // constant
diff --git a/viewer/js/gis/dijit/LayerControl/controls/Raster.js b/viewer/js/gis/dijit/LayerControl/controls/Raster.js
index c31195189..1ab1bf896 100644
--- a/viewer/js/gis/dijit/LayerControl/controls/Raster.js
+++ b/viewer/js/gis/dijit/LayerControl/controls/Raster.js
@@ -11,6 +11,7 @@ define([
_Contained,
_Control
) {
+
var RasterControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], {
_layerType: 'overlay', // constant
_esriLayerType: 'raster', // constant
diff --git a/viewer/js/gis/dijit/LayerControl/controls/Stream.js b/viewer/js/gis/dijit/LayerControl/controls/Stream.js
index 3f711d3d2..385cae7a8 100644
--- a/viewer/js/gis/dijit/LayerControl/controls/Stream.js
+++ b/viewer/js/gis/dijit/LayerControl/controls/Stream.js
@@ -13,6 +13,7 @@ define([
_Control,
legendUtil
) {
+
var StreamControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], {
_layerType: 'overlay', // constant
_esriLayerType: 'raster', // constant
diff --git a/viewer/js/gis/dijit/LayerControl/controls/Tiled.js b/viewer/js/gis/dijit/LayerControl/controls/Tiled.js
index 4e57b229b..242fe3acb 100644
--- a/viewer/js/gis/dijit/LayerControl/controls/Tiled.js
+++ b/viewer/js/gis/dijit/LayerControl/controls/Tiled.js
@@ -13,6 +13,7 @@ define([
_Control,
legendUtil
) {
+
var TiledControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], {
_layerType: 'overlay', // constant
_esriLayerType: 'tiled', // constant
diff --git a/viewer/js/gis/dijit/LayerControl/controls/VectorTile.js b/viewer/js/gis/dijit/LayerControl/controls/VectorTile.js
new file mode 100644
index 000000000..f6901ad4a
--- /dev/null
+++ b/viewer/js/gis/dijit/LayerControl/controls/VectorTile.js
@@ -0,0 +1,23 @@
+define([
+ 'dojo/_base/declare',
+ 'dijit/_WidgetBase',
+ 'dijit/_TemplatedMixin',
+ 'dijit/_Contained',
+ './_Control' // layer control base class
+], function (
+ declare,
+ _WidgetBase,
+ _TemplatedMixin,
+ _Contained,
+ _Control
+) {
+
+ var VectorTileControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], {
+ _layerType: 'overlay', // constant
+ _esriLayerType: 'vectortile', // constant
+ _layerTypeInit: function () {
+ this._expandRemove();
+ }
+ });
+ return VectorTileControl;
+});
\ No newline at end of file
diff --git a/viewer/js/gis/dijit/LayerControl/controls/WFS.js b/viewer/js/gis/dijit/LayerControl/controls/WFS.js
new file mode 100644
index 000000000..848e41d99
--- /dev/null
+++ b/viewer/js/gis/dijit/LayerControl/controls/WFS.js
@@ -0,0 +1,24 @@
+define([
+ 'dojo/_base/declare',
+ 'dijit/_WidgetBase',
+ 'dijit/_TemplatedMixin',
+ 'dijit/_Contained',
+ './_Control', // layer control base class
+ './../plugins/legendUtil'
+], function (
+ declare,
+ _WidgetBase,
+ _TemplatedMixin,
+ _Contained,
+ _Control
+) {
+
+ var WFSControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], {
+ _layerType: 'vector', // constant
+ _esriLayerType: 'wfs', // constant
+ _layerTypeInit: function () {
+ this._expandRemove();
+ }
+ });
+ return WFSControl;
+});
\ No newline at end of file
diff --git a/viewer/js/gis/dijit/LayerControl/controls/WMS.js b/viewer/js/gis/dijit/LayerControl/controls/WMS.js
index 443e13232..21817901b 100644
--- a/viewer/js/gis/dijit/LayerControl/controls/WMS.js
+++ b/viewer/js/gis/dijit/LayerControl/controls/WMS.js
@@ -11,6 +11,7 @@ define([
_Contained,
_Control
) {
+
var WMSControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], {
_layerType: 'overlay', // constant
_esriLayerType: 'wms', // constant
diff --git a/viewer/js/gis/dijit/LayerControl/controls/WebTiled.js b/viewer/js/gis/dijit/LayerControl/controls/WebTiled.js
index 7393cd952..3287bcbb8 100644
--- a/viewer/js/gis/dijit/LayerControl/controls/WebTiled.js
+++ b/viewer/js/gis/dijit/LayerControl/controls/WebTiled.js
@@ -11,6 +11,7 @@ define([
_Contained,
_Control
) {
+
var WebTiledControl = declare([_WidgetBase, _TemplatedMixin, _Contained, _Control], {
_layerType: 'overlay', // constant
_esriLayerType: 'webtiled', // constant
diff --git a/viewer/js/gis/dijit/LayerControl/controls/_Control.js b/viewer/js/gis/dijit/LayerControl/controls/_Control.js
index 4e39f478a..58e7f6179 100644
--- a/viewer/js/gis/dijit/LayerControl/controls/_Control.js
+++ b/viewer/js/gis/dijit/LayerControl/controls/_Control.js
@@ -1,7 +1,7 @@
define([
'dojo/_base/declare',
'dojo/_base/lang',
- //'dojo/_base/array',
+ 'dojo/_base/array',
'dojo/on',
'dojo/topic',
'dojo/dom-construct',
@@ -10,12 +10,13 @@ define([
'dojo/dom-attr',
'dojo/fx',
'dojo/html',
+ 'dijit/MenuItem',
'./../plugins/LayerMenu',
'dojo/text!./templates/Control.html'
], function (
declare,
lang,
- //array,
+ array,
on,
topic,
domConst,
@@ -24,6 +25,7 @@ define([
domAttr,
fx,
html,
+ MenuItem,
LayerMenu,
template
) {
@@ -43,6 +45,7 @@ define([
if (params.controller) {
this.icons = params.controller.icons;
} // if not you've got bigger problems
+ this._handlers = [];
},
postCreate: function () {
this.inherited(arguments);
@@ -66,7 +69,7 @@ define([
if (this.layer.loaded) {
this._initialize();
} else {
- this.layer.on('load', lang.hitch(this, '_initialize'));
+ this._handlers.push(this.layer.on('load', lang.hitch(this, '_initialize')));
}
},
// initialize the control
@@ -79,17 +82,8 @@ define([
controlOptions = this.controlOptions;
// set checkbox
this._setLayerCheckbox(layer, this.checkNode);
- // wire up layer visibility
- on(this.checkNode, 'click', lang.hitch(this, '_setLayerVisibility', layer, this.checkNode));
// set title
html.set(this.labelNode, this.layerTitle);
- // wire up updating indicator
- layer.on('update-start', lang.hitch(this, function () {
- domStyle.set(this.layerUpdateNode, 'display', 'inline-block'); //font awesome display
- }));
- layer.on('update-end', lang.hitch(this, function () {
- domStyle.set(this.layerUpdateNode, 'display', 'none');
- }));
// create layer menu
if ((controlOptions.noMenu !== true && this.controller.noMenu !== true) || (this.controller.noMenu === true && controlOptions.noMenu === false)) {
this.layerMenu = new LayerMenu({
@@ -99,6 +93,7 @@ define([
leftClickToOpen: true
});
this.layerMenu.startup();
+ this._initCustomMenu();
} else {
domClass.remove(this.menuNode, 'fa, layerControlMenuIcon, ' + this.icons.menu);
domStyle.set(this.menuClickNode, 'cursor', 'default');
@@ -108,19 +103,6 @@ define([
this._checkboxScaleRange();
this._scaleRangeHandler = layer.getMap().on('zoom-end', lang.hitch(this, '_checkboxScaleRange'));
}
- // if layer scales change
- this.layer.on('scale-range-change', lang.hitch(this, function () {
- if (layer.minScale !== 0 || layer.maxScale !== 0) {
- this._checkboxScaleRange();
- this._scaleRangeHandler = layer.getMap().on('zoom-end', lang.hitch(this, '_checkboxScaleRange'));
- } else {
- this._checkboxScaleRange();
- if (this._scaleRangeHandler) {
- this._scaleRangeHandler.remove();
- this._scaleRangeHandler = null;
- }
- }
- }));
// a function in each control widget for layer type specifics like legends and such
this._layerTypeInit();
// show expandNode
@@ -130,30 +112,51 @@ define([
}
// esri layer's don't inherit from Stateful
// connect to update events to handle "watching" layers
- layer.on('update-start', lang.hitch(this, '_updateStart'));
- layer.on('update-end', lang.hitch(this, '_updateEnd'));
- layer.on('visibility-change', lang.hitch(this, '_visibilityChange'));
+ this._handlers.push(
+ on(this.checkNode, 'click', lang.hitch(this, '_setLayerVisibility', layer, this.checkNode)),
+ layer.on('scale-range-change', lang.hitch(this, '_scaleRangeChange')),
+ layer.on('update-start', lang.hitch(this, '_updateStart')),
+ layer.on('update-end', lang.hitch(this, '_updateEnd')),
+ layer.on('visibility-change', lang.hitch(this, '_visibilityChange'))
+ );
+ },
+ _initCustomMenu: function () {
+ array.forEach(this.controlOptions.menu, lang.hitch(this, '_addCustomMenuItem', this.layerMenu));
+ },
+ _addCustomMenuItem: function (menu, menuItem) {
+ //create the menu item
+ var item = new MenuItem(menuItem);
+ item.set('onClick', lang.hitch(this, function () {
+ topic.publish('layerControl/' + menuItem.topic, {
+ layer: this.layer,
+ iconNode: this.iconNode,
+ menuItem: item
+ });
+ }));
+ menu.addChild(item);
},
// add on event to expandClickNode
_expandClick: function () {
- var i = this.icons;
- this._expandClickHandler = on(this.expandClickNode, 'click', lang.hitch(this, function () {
- var expandNode = this.expandNode,
- iconNode = this.expandIconNode;
- if (domStyle.get(expandNode, 'display') === 'none') {
- fx.wipeIn({
- node: expandNode,
- duration: 300
- }).play();
- domClass.replace(iconNode, i.collapse, i.expand);
- } else {
- fx.wipeOut({
- node: expandNode,
- duration: 300
- }).play();
- domClass.replace(iconNode, i.expand, i.collapse);
- }
- }));
+ this._expandClickHandler = on(this.expandClickNode, 'click', lang.hitch(this, '_expandClicked'));
+ this._handlers.push(this._expandClickHandler);
+ },
+ _expandClicked: function () {
+ var i = this.icons,
+ expandNode = this.expandNode,
+ iconNode = this.expandIconNode;
+ if (domStyle.get(expandNode, 'display') === 'none') {
+ fx.wipeIn({
+ node: expandNode,
+ duration: 300
+ }).play();
+ domClass.replace(iconNode, i.collapse, i.expand);
+ } else {
+ fx.wipeOut({
+ node: expandNode,
+ duration: 300
+ }).play();
+ domClass.replace(iconNode, i.expand, i.collapse);
+ }
},
// removes the icons and cursor:pointer from expandClickNode and destroys expandNode
_expandRemove: function () {
@@ -162,7 +165,13 @@ define([
domConst.destroy(this.expandNode);
},
// set layer visibility and update icon
- _setLayerVisibility: function (layer, checkNode) {
+ _setLayerVisibility: function (layer, checkNode, event) {
+
+ // prevent click event from bubbling
+ if (event.stopPropagation) {
+ event.stopPropagation();
+ }
+
if (layer.visible) {
this._setLayerCheckbox(layer, checkNode);
layer.hide();
@@ -205,8 +214,33 @@ define([
domClass.add(node, 'layerControlCheckIconOutScale');
}
},
+ _scaleRangeChange: function () {
+ if (this.layer.minScale !== 0 || this.layer.maxScale !== 0) {
+ this._checkboxScaleRange();
+ if (this._scaleRangeHandler) {
+ var handlerIndex = array.indexOf(this._handlers, this._scaleRangeHandler);
+ if (handlerIndex !== -1) {
+ this._handlers[handlerIndex].remove();
+ this._handlers.splice(handlerIndex, 1);
+ }
+ }
+ this._scaleRangeHandler = this.layer.getMap().on('zoom-end', lang.hitch(this, '_checkboxScaleRange'));
+ this._handlers.push(this._scaleRangeHandler);
+ } else {
+ this._checkboxScaleRange();
+ if (this._scaleRangeHandler) {
+ var handlerIndex2 = array.indexOf(this._handlers, this._scaleRangeHandler);
+ if (handlerIndex2 !== -1) {
+ this._handlers[handlerIndex2].remove();
+ this._handlers.splice(handlerIndex2, 1);
+ }
+ this._scaleRangeHandler = null;
+ }
+ }
+ },
// anything the widget may need to do before update
_updateStart: function () {
+ domStyle.set(this.layerUpdateNode, 'display', 'inline-block'); //font awesome display
// clone a layer state before layer updates for use after update
this._layerState = lang.clone({
visible: this.layer.visible,
@@ -215,6 +249,7 @@ define([
},
// anything the widget may need to do after update
_updateEnd: function () {
+ domStyle.set(this.layerUpdateNode, 'display', 'none');
// how to handle external layer.setVisibleLayers() ???
//
// without topics to get/set sublayer state this will be challenging
@@ -233,7 +268,13 @@ define([
if ((r.visible && domAttr.get(this.checkNode, 'data-checked') === 'unchecked') || (!r.visible && domAttr.get(this.checkNode, 'data-checked') === 'checked')) {
this._setLayerCheckbox(this.layer, this.checkNode);
}
+ },
+ destroy: function () {
+ this.inherited(arguments);
+ this._handlers.forEach(function (h) {
+ h.remove();
+ });
}
});
return _Control;
-});
\ No newline at end of file
+});
diff --git a/viewer/js/gis/dijit/LayerControl/controls/_DynamicFolder.js b/viewer/js/gis/dijit/LayerControl/controls/_DynamicFolder.js
index ffca235af..15a601720 100644
--- a/viewer/js/gis/dijit/LayerControl/controls/_DynamicFolder.js
+++ b/viewer/js/gis/dijit/LayerControl/controls/_DynamicFolder.js
@@ -25,15 +25,29 @@ define([
TemplatedMixin,
folderTemplate
) {
- var _DynamicFolder = declare([WidgetBase, TemplatedMixin], {
+ var _DynamicFolder = declare([WidgetBase, TemplatedMixin], {
control: null,
sublayerInfo: null,
icons: null,
// ^args
templateString: folderTemplate,
_expandClickHandler: null,
+ _handlers: [],
postCreate: function () {
this.inherited(arguments);
+ // Should the control be visible or hidden (depends on subLayerInfos)?
+ if (this.control.controlOptions.subLayerInfos && !this.control.controlOptions.includeUnspecifiedLayers) {
+ var subLayerInfos = array.map(this.control.controlOptions.subLayerInfos, function (sli) {
+ return sli.id;
+ });
+ if (array.indexOf(subLayerInfos, this.sublayerInfo.id) < 0) {
+ domClass.add(this.domNode, 'layerControlHidden');
+ }
+ }
+ // Should the control be visible or hidden?
+ if (this.control.controlOptions.layerIds && array.indexOf(this.control.controlOptions.layerIds, this.sublayerInfo.id) < 0) {
+ domClass.add(this.domNode, 'layerControlHidden');
+ }
var checkNode = this.checkNode;
domAttr.set(checkNode, 'data-sublayer-id', this.sublayerInfo.id);
domClass.add(checkNode, this.control.layer.id + '-layerControlSublayerCheck');
@@ -42,7 +56,13 @@ define([
} else {
this._setSublayerCheckbox(false, checkNode);
}
- on(checkNode, 'click', lang.hitch(this, function () {
+ this._handlers.push(on(checkNode, 'click', lang.hitch(this, function (event) {
+
+ // prevent click event from bubbling
+ if (event.stopPropagation) {
+ event.stopPropagation();
+ }
+
if (domAttr.get(checkNode, 'data-checked') === 'checked') {
this._setSublayerCheckbox(false, checkNode);
} else {
@@ -50,18 +70,18 @@ define([
}
this.control._setVisibleLayers();
this._checkboxScaleRange();
- }));
+ })));
html.set(this.labelNode, this.sublayerInfo.name);
this._expandClick();
if (this.sublayerInfo.minScale !== 0 || this.sublayerInfo.maxScale !== 0) {
this._checkboxScaleRange();
- this.control.layer.getMap().on('zoom-end', lang.hitch(this, '_checkboxScaleRange'));
+ this._handlers.push(this.control.layer.getMap().on('zoom-end', lang.hitch(this, '_checkboxScaleRange')));
}
},
// add on event to expandClickNode
_expandClick: function () {
var i = this.icons;
- this._expandClickHandler = on(this.expandClickNode, 'click', lang.hitch(this, function () {
+ this._handlers.push(this._expandClickHandler = on(this.expandClickNode, 'click', lang.hitch(this, function () {
var expandNode = this.expandNode,
iconNode = this.expandIconNode;
if (domStyle.get(expandNode, 'display') === 'none') {
@@ -77,7 +97,7 @@ define([
}).play();
domClass.replace(iconNode, i.folder, i.folderOpen);
}
- }));
+ })));
},
// set checkbox based on layer so it's always in sync
_setSublayerCheckbox: function (checked, checkNode) {
@@ -101,7 +121,13 @@ define([
if ((min !== 0 && scale > min) || (max !== 0 && scale < max)) {
domClass.add(node, 'layerControlCheckIconOutScale');
}
+ },
+ destroy: function () {
+ this.inherited(arguments);
+ this._handlers.forEach(function (h) {
+ h.remove();
+ });
}
});
return _DynamicFolder;
-});
\ No newline at end of file
+});
diff --git a/viewer/js/gis/dijit/LayerControl/controls/_DynamicSublayer.js b/viewer/js/gis/dijit/LayerControl/controls/_DynamicSublayer.js
index 159427057..51c9dd271 100644
--- a/viewer/js/gis/dijit/LayerControl/controls/_DynamicSublayer.js
+++ b/viewer/js/gis/dijit/LayerControl/controls/_DynamicSublayer.js
@@ -42,18 +42,37 @@ define([
templateString: sublayerTemplate,
i18n: i18n,
_expandClickHandler: null,
+ _handlers: [],
postCreate: function () {
this.inherited(arguments);
+ // Should the control be visible or hidden (depends on subLayerInfos)?
+ if (this.control.controlOptions.subLayerInfos && !this.control.controlOptions.includeUnspecifiedLayers) {
+ var subLayerInfos = array.map(this.control.controlOptions.subLayerInfos, function (sli) {
+ return sli.id;
+ });
+ if (array.indexOf(subLayerInfos, this.sublayerInfo.id) < 0) {
+ domClass.add(this.domNode, 'layerControlHidden');
+ }
+ }
+ // Should the control be visible or hidden?
+ if (this.control.controlOptions.layerIds && array.indexOf(this.control.controlOptions.layerIds, this.sublayerInfo.id) < 0) {
+ domClass.add(this.domNode, 'layerControlHidden');
+ }
var checkNode = this.checkNode;
domAttr.set(checkNode, 'data-sublayer-id', this.sublayerInfo.id);
domClass.add(checkNode, this.control.layer.id + '-layerControlSublayerCheck');
if (array.indexOf(this.control.layer.visibleLayers, this.sublayerInfo.id) !== -1) {
this._setSublayerCheckbox(true, checkNode);
} else {
-
this._setSublayerCheckbox(false, checkNode);
}
- on(checkNode, 'click', lang.hitch(this, function () {
+ this._handlers.push(on(checkNode, 'click', lang.hitch(this, function (event) {
+
+ // prevent click event from bubbling
+ if (event.stopPropagation) {
+ event.stopPropagation();
+ }
+
if (domAttr.get(checkNode, 'data-checked') === 'checked') {
this._setSublayerCheckbox(false, checkNode);
} else {
@@ -61,38 +80,38 @@ define([
}
this.control._setVisibleLayers();
this._checkboxScaleRange();
- }));
+ })));
html.set(this.labelNode, this.sublayerInfo.name);
this._expandClick();
if (this.sublayerInfo.minScale !== 0 || this.sublayerInfo.maxScale !== 0) {
this._checkboxScaleRange();
- this.control.layer.getMap().on('zoom-end', lang.hitch(this, '_checkboxScaleRange'));
+ this._handlers.push(this.control.layer.getMap().on('zoom-end', lang.hitch(this, '_checkboxScaleRange')));
}
//set up menu
- if (this.control.controlOptions.menu &&
- this.control.controlOptions.menu.length) {
- domClass.add(this.labelNode, 'menuLink');
- domClass.add(this.iconNode, 'menuLink');
+ if (this.control.controlOptions.subLayerMenu &&
+ this.control.controlOptions.subLayerMenu.length) {
this.menu = new Menu({
contextMenuForWindow: false,
- targetNodeIds: [this.labelNode],
+ targetNodeIds: [this.menuClickNode],
leftClickToOpen: true
});
- array.forEach(this.control.controlOptions.menu, lang.hitch(this, '_addMenuItem'));
+ array.forEach(this.control.controlOptions.subLayerMenu, lang.hitch(this, '_addMenuItem'));
this.menu.startup();
+ } else {
+ domClass.add(this.menuClickNode, 'hidden');
}
},
_addMenuItem: function (menuItem) {
//create the menu item
- var item = new MenuItem(menuItem);
+ var item = new MenuItem(menuItem);
item.set('onClick', lang.hitch(this, function () {
- topic.publish('LayerControl/' + menuItem.topic, {
- layer: this.control.layer,
- subLayer: this.sublayerInfo,
- iconNode: this.iconNode,
- menuItem: item
- });
- }));
+ topic.publish('layerControl/' + menuItem.topic, {
+ layer: this.control.layer,
+ subLayer: this.sublayerInfo,
+ iconNode: this.iconNode,
+ menuItem: item
+ });
+ }));
this.menu.addChild(item);
},
// add on event to expandClickNode
@@ -100,7 +119,7 @@ define([
var i = this.icons;
this._expandClickHandler = on(this.expandClickNode, 'click', lang.hitch(this, function () {
var expandNode = this.expandNode,
- iconNode = this.expandIconNode;
+ iconNode = this.expandIconNode;
if (domStyle.get(expandNode, 'display') === 'none') {
fx.wipeIn({
node: expandNode,
@@ -115,6 +134,7 @@ define([
domClass.replace(iconNode, i.expand, i.collapse);
}
}));
+ this._handlers.push(this._expandClickHandler);
},
// set checkbox based on layer so it's always in sync
_setSublayerCheckbox: function (checked, checkNode) {
@@ -131,14 +151,20 @@ define([
// check scales and add/remove disabled classes from checkbox
_checkboxScaleRange: function () {
var node = this.checkNode,
- scale = this.control.layer.getMap().getScale(),
- min = this.sublayerInfo.minScale,
- max = this.sublayerInfo.maxScale;
+ scale = this.control.layer.getMap().getScale(),
+ min = this.sublayerInfo.minScale,
+ max = this.sublayerInfo.maxScale;
domClass.remove(node, 'layerControlCheckIconOutScale');
if ((min !== 0 && scale > min) || (max !== 0 && scale < max)) {
domClass.add(node, 'layerControlCheckIconOutScale');
}
+ },
+ destroy: function () {
+ this.inherited(arguments);
+ this._handlers.forEach(function (h) {
+ h.remove();
+ });
}
});
return _DynamicSublayer;
-});
\ No newline at end of file
+});
diff --git a/viewer/js/gis/dijit/LayerControl/controls/templates/Control.html b/viewer/js/gis/dijit/LayerControl/controls/templates/Control.html
index 5836fe4b0..e7e224030 100644
--- a/viewer/js/gis/dijit/LayerControl/controls/templates/Control.html
+++ b/viewer/js/gis/dijit/LayerControl/controls/templates/Control.html
@@ -1,7 +1,7 @@