Last active
August 29, 2015 14:08
-
-
Save kflaw/ba632838f52c900f321d to your computer and use it in GitHub Desktop.
cmv identify dijit
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
define([ | |
'dojo/_base/declare', | |
'dijit/_WidgetBase', | |
'dijit/_TemplatedMixin', | |
'dijit/_WidgetsInTemplateMixin', | |
'dijit/MenuItem', | |
'dojo/_base/lang', | |
'dojo/_base/array', | |
'dojo/promise/all', | |
'dojo/topic', | |
'dojo/on', | |
'dojo/dom-construct', | |
'dojo/query', | |
'esri/layers/ImageServiceParameters', | |
'esri/layers/MosaicRule', | |
'esri/layers/ArcGISImageServiceLayer', | |
'dojo/store/Memory', | |
'esri/tasks/IdentifyTask', | |
'esri/tasks/IdentifyParameters', | |
'esri/dijit/PopupTemplate', | |
'dojo/text!./Identify/templates/Identify.html', | |
'dijit/form/Form', | |
'dijit/form/FilteringSelect', | |
'xstyle/css!./Identify/css/Identify.css', | |
'dojo/dom-attr', | |
'dijit/form/HorizontalSlider', | |
'dijit/TooltipDialog', | |
'dijit/popup', | |
'dojo/dom', | |
'dojo/dom-style', | |
'dijit/form/HorizontalRuleLabels', | |
'dojo/domReady!' | |
], function (declare, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, MenuItem, lang, array, all, topic, on, domConstruct, query, | |
ImageServiceParameters, MosaicRule, ArcGISImageServiceLayer, Memory, IdentifyTask, IdentifyParameters, PopupTemplate, IdentifyTemplate, | |
domAttr, HorizontalSlider, TooltipDialog, popup, dom, domStyle, HorizontalRuleLabels) { | |
var imageServiceLayer = null; | |
var imageInt = 0; | |
var feature; | |
var popupContent; | |
var imageID; | |
var popContent2; | |
var removeLayer; | |
var myDialog; | |
var imageSlider; | |
return declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], { | |
widgetsInTemplate: true, | |
templateString: IdentifyTemplate, | |
baseClass: 'gis_IdentifyDijit', | |
mapClickMode: null, | |
identifies: {}, | |
infoTemplates: {}, | |
ignoreOtherGraphics: true, | |
createDefaultInfoTemplates: true, | |
layerSeparator: '||', | |
allLayersId: '***', | |
postCreate: function () { | |
this.inherited(arguments); | |
if (!this.identifies) { | |
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); | |
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.own(topic.subscribe('mapClickMode/currentSet', lang.hitch(this, 'setMapClickMode'))); | |
this.map.on('click', lang.hitch(this, function (evt) { | |
if (this.mapClickMode === 'identify') { | |
this.executeIdentifyTask(evt); | |
} | |
})); | |
if (this.mapRightClickMenu) { | |
this.addRightClickMenu(); | |
} | |
// rebuild the layer selection list when the map is updated | |
// but only if we have a UI | |
if (this.parentWidget) { | |
this.createIdentifyLayerList(); | |
this.map.on('update-end', lang.hitch(this, function () { | |
this.createIdentifyLayerList(); | |
})); | |
} | |
addLink = domConstruct.create("a",{ | |
"class": "action", | |
"id": "rasterLock", | |
"innerHTML": "Add image", | |
"href": "javascript:void(0);" | |
}, query(".actionList", this.map.infoWindow.domNode)[0]); | |
on(addLink, 'click', lang.hitch(this, function(event) { | |
//dojo.setAttr(dojo.byId("rasterLock"), "innerHTML", "Adding image..."); | |
feature = this.map.infoWindow.getSelectedFeature(); | |
popupContent = parseInt(feature.attributes.is_oid); | |
if (isNaN(popupContent)) { | |
alert('Cannot add image for selected feature.'); | |
} | |
else { | |
imageInt = imageInt + 1; | |
imageID = "Image" + popupContent; | |
var arr = [popupContent]; | |
var imgParams = new ImageServiceParameters(); | |
imgParams.noData = 0; | |
var mr = new MosaicRule(); | |
mr.method = MosaicRule.METHOD_LOCKRASTER; | |
mr.lockRasterIds = arr; | |
imgParams.mosaicRule = mr; | |
var MC_ImageService = "http://sv04esri:6080/arcgis/rest/services/Testing/IS_test/ImageServer"; | |
imageServiceLayer = new ArcGISImageServiceLayer(MC_ImageService, { | |
id: imageID, | |
imageServiceParameters: imgParams, | |
opacity: 0.75 | |
}); | |
dojo.setAttr(dojo.byId("rasterLock"), "innerHTML", "Add image"); | |
this.map.addLayer(imageServiceLayer); | |
} | |
}) | |
); | |
removeLink = domConstruct.create("a",{ | |
"class": "action", | |
"id": "rasterRemove", | |
"innerHTML": "Remove image", | |
"href": "javascript:void(0);" | |
}, query(".actionList", this.map.infoWindow.domNode)[0]); | |
on(rasterRemove, 'click', lang.hitch(this, function() { | |
feature2 = this.map.infoWindow.getSelectedFeature(); | |
popContent2 = parseInt(feature2.attributes.is_oid); | |
removeLayer = "Image" + popContent2; | |
if (isNaN(popContent2)) { | |
alert('There is no image associated with this feature to remove.'); | |
} | |
// if (imageInt == 0){ | |
// alert("There are currently no images loaded in the map."); | |
// } | |
else if (removeLayer !== "ImageNaN") { | |
var imageLayer = this.map.getLayer(removeLayer); | |
if (typeof imageLayer !== 'undefined') { | |
this.map.removeLayer(imageLayer); | |
imageInt = imageInt - 1 | |
} | |
else { | |
alert("This image is not loaded in the map."); | |
} | |
} | |
}) | |
); | |
transparencyLink = domConstruct.create("a",{ | |
"class": "action", | |
"id": "adjustTransparency", | |
"innerHTML": " Image opacity", | |
"href": "javascript:void(0);" | |
}, query(".actionList", this.map.infoWindow.domNode)[0]); | |
imageSlider = new HorizontalSlider({ | |
value: 7.5, | |
minimum: 0, | |
maximum: 10, | |
intermediateChanges: true, | |
discreteValues: 11, | |
showButtons: false, | |
style: "width:200px;", | |
onChange: lang.hitch(this, function(value) { | |
transparencyLayer.setOpacity(value / 10); | |
domStyle.set(transparencyLayer, 'opacity', value); | |
}) | |
}, "imageSlider"); | |
// var rule = new HorizontalRuleLabels({ | |
// labels: ['100%', '50%', '0%'], | |
// style: 'height:1em;font-size:75%;' | |
// }, imageSlider.bottomDecoration); | |
// rule.startup(); | |
imageSlider.startup(); | |
var myTooltipDialog = new dijit.TooltipDialog({ | |
id: 'myTooltipDialog', | |
style: "width: 225px;", | |
content: imageSlider, | |
onMouseLeave: function(){ | |
dijit.popup.close(myTooltipDialog); | |
} | |
}); | |
on(transparencyLink, 'click', lang.hitch(this, function() { | |
dijit.popup.open({ | |
popup: myTooltipDialog, | |
around: transparencyLink | |
}); | |
}) | |
); | |
}, | |
addRightClickMenu: function () { | |
this.map.on('MouseDown', lang.hitch(this, function (evt) { | |
this.mapRightClick = evt; | |
})); | |
this.mapRightClickMenu.addChild(new MenuItem({ | |
label: 'Identify here', | |
onClick: lang.hitch(this, 'handleRightClick') | |
})); | |
}, | |
executeIdentifyTask: function (evt) { | |
if (!this.checkForGraphicInfoTemplate(evt)) { | |
return; | |
} | |
this.map.infoWindow.hide(); | |
this.map.infoWindow.clearFeatures(); | |
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); | |
if (layerIds.length > 0) { | |
var params = lang.clone(identifyParams); | |
params.layerIds = layerIds; | |
identifies.push(layer.identifyTask.execute(params)); | |
identifiedlayers.push(layer); | |
} | |
})); | |
if (identifies.length > 0) { | |
this.map.infoWindow.setTitle('Identifying...'); | |
this.map.infoWindow.setContent('<div class="loading"></div>'); | |
this.map.infoWindow.show(mapPoint); | |
all(identifies).then(lang.hitch(this, 'identifyCallback', identifiedlayers), lang.hitch(this, 'identifyError')); | |
} | |
}, | |
checkForGraphicInfoTemplate: function (evt) { | |
if (evt.graphic) { | |
// 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)) { | |
return false; | |
} | |
if (!this.ignoreOtherGraphics) { | |
// handles graphic from another type of graphics layer | |
// added to the map and so the identify is not found | |
if (!this.identifies.hasOwnProperty(layer.id)) { | |
return false; | |
} | |
// no layerId (graphics) or sublayer not defined | |
if (isNaN(layer.layerId) || !this.identifies[layer.id].hasOwnProperty(layer.layerId)) { | |
return false; | |
} | |
} | |
} | |
return true; | |
}, | |
createIdentifyParams: function (point) { | |
var identifyParams = new IdentifyParameters(); | |
identifyParams.tolerance = this.identifyTolerance; | |
identifyParams.returnGeometry = true; | |
identifyParams.layerOption = IdentifyParameters.LAYER_OPTION_VISIBLE; | |
identifyParams.geometry = point; | |
identifyParams.mapExtent = this.map.extent; | |
identifyParams.width = this.map.width; | |
identifyParams.height = this.map.height; | |
identifyParams.spatialReference = this.map.spatialReference; | |
return identifyParams; | |
}, | |
getSelectedLayer: function () { | |
var selectedLayer = this.allLayersId; // default is all layers | |
// if we have a UI, then get the selected layer | |
if (this.parentWidget) { | |
var form = this.identifyFormDijit.get('value'); | |
if (!form.identifyLayer || form.identifyLayer === '') { | |
this.identifyLayerDijit.set('value', selectedLayer); | |
} else { | |
selectedLayer = form.identifyLayer; | |
} | |
} | |
return selectedLayer; | |
}, | |
getLayerIds: function (layer, selectedLayer) { | |
var arrIds = selectedLayer.split(this.layerSeparator); | |
var allLayersId = this.allLayersId; | |
var ref = layer.ref, | |
selectedIds = layer.layerInfo.layerIds; | |
var layerIds = []; | |
if (ref.visible) { | |
if (arrIds[0] === allLayersId || ref.id === arrIds[0]) { | |
if (arrIds.length > 1 && arrIds[1]) { // layer explicity requested | |
layerIds = [arrIds[1]]; | |
} 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) { | |
layerIds = [ref.layerId]; | |
} | |
} else if (ref.layerInfos) { | |
layerIds = this.getLayerInfos(ref, selectedIds); | |
} | |
} | |
} | |
return layerIds; | |
}, | |
getLayerInfos: function (ref, selectedIds) { | |
var layerIds = []; | |
array.forEach(ref.layerInfos, lang.hitch(this, function (layerInfo) { | |
if (!this.includeSubLayer(layerInfo, ref, selectedIds)) { | |
return; | |
} | |
layerIds.push(layerInfo.id); | |
})); | |
return layerIds; | |
}, | |
identifyCallback: function (identifiedlayers, responseArray) { | |
var fSet = []; | |
array.forEach(responseArray, function (response, i) { | |
var ref = identifiedlayers[i].ref; | |
array.forEach(response, function (result) { | |
result.feature.geometry.spatialReference = this.map.spatialReference; //temp workaround for ags identify bug. remove when fixed. | |
if (result.feature.infoTemplate === undefined) { | |
var infoTemplate = this.getInfoTemplate(ref, null, result); | |
if (infoTemplate) { | |
result.feature.setInfoTemplate(infoTemplate); | |
} else { | |
return; | |
} | |
} | |
fSet.push(result.feature); | |
}, this); | |
}, this); | |
this.map.infoWindow.setFeatures(fSet); | |
}, | |
identifyError: function (err) { | |
this.map.infoWindow.hide(); | |
topic.publish('viewer/handleError', { | |
source: 'Identify', | |
error: err | |
}); | |
}, | |
handleRightClick: function () { | |
this.executeIdentifyTask(this.mapRightClick); | |
}, | |
getInfoTemplate: function (layer, layerId, result) { | |
var popup = null; | |
if (result) { | |
layerId = result.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? | |
popup = new PopupTemplate(popup); | |
this.identifies[layer.id][layerId] = popup; | |
} | |
} | |
} | |
} | |
// if no Popup config found, create one with all attributes or layer fields | |
if (!popup) { | |
popup = this.createInfoTemplate(layer, layerId, result); | |
} | |
return popup; | |
}, | |
createInfoTemplate: function (layer, layerId, result) { | |
var popup = null, fieldInfos = []; | |
var layerName = this.getLayerName(layer); | |
if (result) { | |
layerName = result.layerName; | |
} | |
// from the results | |
if (result && result.feature) { | |
var attributes = result.feature.attributes; | |
if (attributes) { | |
for (var prop in attributes) { | |
if (attributes.hasOwnProperty(prop)) { | |
fieldInfos.push({ | |
fieldName: prop, | |
visible: true | |
}); | |
} | |
} | |
} | |
// 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) { | |
var foundField = array.filter(fields, function (field) { | |
return (field.name === fieldName); | |
}); | |
if (foundField.length > 0) { | |
fieldInfos.push({ | |
fieldName: foundField[0].name, | |
label: foundField[0].alias, | |
visible: true | |
}); | |
} | |
}); | |
// from the fields layer | |
} else if (layer.fields) { | |
array.forEach(layer.fields, function (field) { | |
fieldInfos.push({ | |
fieldName: field.name, | |
label: field.alias, | |
visible: true | |
}); | |
}); | |
} | |
if (fieldInfos.length > 0) { | |
popup = new PopupTemplate({ | |
title: layerName, | |
fieldInfos: fieldInfos, | |
showAttachments: (layer.hasAttachments) | |
}); | |
if (!this.identifies[layer.id]) { | |
this.identifies[layer.id] = {}; | |
} | |
this.identifies[layer.id][layerId] = popup; | |
} | |
return popup; | |
}, | |
createIdentifyLayerList: function () { | |
var id = null; | |
var identifyItems = []; | |
var selectedId = this.identifyLayerDijit.get('value'); | |
var sep = this.layerSeparator; | |
array.forEach(this.layers, lang.hitch(this, function (layer) { | |
var ref = layer.ref, | |
selectedIds = layer.layerInfo.layerIds; | |
// only include layers that are currently visible | |
if (ref.visible) { | |
var name = this.getLayerName(layer); | |
if ((ref.declaredClass === 'esri.layers.FeatureLayer') && !isNaN(ref.layerId)) { // feature layer | |
identifyItems.push({ | |
name: name, | |
id: ref.id + sep + ref.layerId | |
}); | |
// previously selected layer is still visible so keep it selected | |
if (ref.id + sep + ref.layerId === selectedId) { | |
id = selectedId; | |
} | |
} else { // dynamic layer | |
array.forEach(ref.layerInfos, lang.hitch(this, function (layerInfo) { | |
if (!this.includeSubLayer(layerInfo, ref, selectedIds)) { | |
return; | |
} | |
identifyItems.push({ | |
name: name + ' \\ ' + layerInfo.name, | |
id: ref.id + sep + layerInfo.id | |
}); | |
// previously selected sublayer is still visible so keep it selected | |
if (ref.id + sep + layerInfo.id === selectedId) { | |
id = selectedId; | |
} | |
})); | |
} | |
} | |
})); | |
identifyItems.sort(function (a, b) { | |
return (a.name > b.name) ? 1 : ((b.name > a.name) ? -1 : 0); | |
}); | |
this.identifyLayerDijit.set('disabled', (identifyItems.length < 1)); | |
if (identifyItems.length > 0) { | |
identifyItems.unshift({ | |
name: '*** All Visible Layers ***', | |
id: '***' | |
}); | |
if (!id) { | |
id = identifyItems[0].id; | |
} | |
} | |
var identify = new Memory({ | |
data: identifyItems | |
}); | |
this.identifyLayerDijit.set('store', identify); | |
this.identifyLayerDijit.set('value', id); | |
}, | |
includeSubLayer: function (layerInfo, ref, selectedIds) { | |
// exclude group layers | |
if (layerInfo.subLayerIds !== null) { | |
return false; | |
} | |
// only include sublayers that are currently visible | |
if (array.indexOf(ref.visibleLayers, layerInfo.id) < 0) { | |
return false; | |
} | |
// only include sublayers that are within the current map scale | |
if (!this.layerVisibleAtCurrentScale(layerInfo)) { | |
return false; | |
} | |
// restrict which layers are included | |
if (selectedIds) { | |
if (array.indexOf(selectedIds, layerInfo.id) < 0) { | |
return false; | |
} | |
} | |
// don't allow the layer if we don't have an infoTemplate | |
// already and creating a default one is not desired | |
if (!this.createDefaultInfoTemplates) { | |
var infoTemplate = this.getInfoTemplate(ref, layerInfo.id); | |
if (!infoTemplate) { | |
return false; | |
} | |
} | |
// all tests pass so include this sublayer | |
return true; | |
}, | |
getLayerName: function (layer) { | |
var name = null; | |
if (layer.layerInfo) { | |
name = layer.layerInfo.title; | |
} | |
if (!name) { | |
array.forEach(this.layers, function (lyr) { | |
if (lyr.ref.id === layer.id) { | |
name = lyr.layerInfo.title; | |
return; | |
} | |
}); | |
} | |
if (!name) { | |
name = layer.name; | |
if (!name && layer.ref) { | |
name = layer.ref._titleForLegend; // fall back to old method using title from legend | |
} | |
} | |
return name; | |
}, | |
layerVisibleAtCurrentScale: function (layer) { | |
var mapScale = this.map.getScale(); | |
return !(((layer.maxScale !== 0 && mapScale < layer.maxScale) || (layer.minScale !== 0 && mapScale > layer.minScale))); | |
}, | |
setMapClickMode: function (mode) { | |
this.mapClickMode = mode; | |
var map = this.map; | |
array.forEach(map.graphicsLayerIds, function (layerID) { | |
var layer = map.getLayer(layerID); | |
if (layer) { | |
// add back any infoTemplates that | |
// had been previously removed | |
if (mode === 'identify') { | |
if (this.infoTemplates[layer.id]) { | |
layer.infoTemplate = lang.clone(this.infoTemplates[layer.id]); | |
} | |
// 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; | |
} | |
} | |
} | |
}, this); | |
} | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment