/**
* Widget that renders the map and the Esri widgets on the map
* @module app/widget/MapWidget
* @author David Kristiansen <david.kristiansen@nscc.ca>
* @copyright Nova Scotia Community College 2017
*/
define([
"dojo/dom",
"dojo/_base/declare",
"dojo/_base/lang",
"dojo/on",
"dojo/topic",
"dojo/json",
"dijit/registry",
"esri/domUtils",
"esri/layers/ArcGISDynamicMapServiceLayer",
"esri/layers/FeatureLayer",
"esri/map",
"esri/SpatialReference",
"esri/geometry/Extent",
"esri/geometry/Point",
"esri/dijit/Scalebar",
"esri/dijit/HomeButton",
"esri/tasks/QueryTask",
"esri/tasks/query",
"esri/graphic",
"esri/lang",
"dojo/dom-style",
"dijit/TooltipDialog",
"dijit/popup",
"app/widget/FloodLvlWidget",
"dojo/text!../Layers.json"
], function (
dom,
declare,
lang,
on,
topic,
JSON,
registry,
domUtils,
ArcGISDynamicMapServiceLayer,
FeatureLayer,
Map,
SpatialReference,
Extent,
Point,
Scalebar,
HomeButton,
QueryTask,
Query,
Graphic, esriLang,
domStyle,
TooltipDialog, dijitPopup,
FloodLvlWidget,
jsonLayers
) {
return declare([], {
map: null,
homeButton: null,
scalebar: null,
ovLayer: "//agrgims.cogs.nscc.ca/arcgis/rest/services/mcfm_pro/sa_flood/MapServer/0",
options: {
extent: null,
center: null,
zoom: null,
basemap: null
},
/** @constructor
* @param {object} args Object of properties to mixin
* @param {object} srcRefNode Dom node for the widget to attach to
**/
constructor: function (param, srcRefNode) {
/** mix in settings and defaults
* @mixin args
*/
declare.safeMixin(this.options, param);
/** Dom widget node */
this.domNode = srcRefNode;
// properties
this.extent = this.options.extent || null;
this.center = this.options.center || null;
this.zoom = this.options.zoom || 13;
this.basemap = this.options.basemap || "topo";
},
/**
* Starts the widget after the dom has been constructed.
* Calls createMap and sets up the map widgets and calls addlayers: scalebar, homebutton and flood level slider
**/
startup: function () {
// console.log("MapWidget::startup");
this.createMap();
var floodlvl = new FloodLvlWidget();
floodlvl.startup();
this.scalebar = new Scalebar({
map: this.map,
// "dual" displays both miles and kilmometers
// "english" is the default, which displays miles
// use "metric" for kilometers
scalebarUnit: "dual",
// scalebarStyle: "ruler",
// attachTo: "bottom-right"
});
this.homeButton = new HomeButton({
map: this.map
}, "homebutton");
this.homeButton.startup();
this.addLayers();
},
/**
* Creates the map per Esri JSAPI
* Checks extent and sets it accordingly
**/
createMap: function () {
// console.log("MapWidget::createMap");
if (this.extent === null) {
if (this.center === null) {
console.error("No center or extent for map. Defaulting to Halifax, NS.");
this.map = new Map("mapDiv", {
center: [-63.60, 44.65],
zoom: this.zoom,
basemap: this.basemap
});
} else {
this.map = new Map("mapDiv", {
center: this.center,
zoom: this.zoom,
basemap: this.basemap
});
}
} else {
this.map = new Map("mapDiv", {
extent: new Extent(this.extent),
basemap: this.basemap
});
}
},
/**
* Parses the JSON files of Layers.json and adds them to the map.
* Adds the feature layer used as the overview.
* Sets up map events and popups.
**/
addLayers: function () {
// console.log("MapWidget::addLayers");
var dialog;
var map = this.map;
var homeButton = this.homeButton;
var overViewMap = new FeatureLayer(this.ovLayer, {
mode: FeatureLayer.MODE_AUTO,
outFields: ["said","name","default_stn_id","survey_year"]
});
dialog = new TooltipDialog({
id: "tooltipDialog",
style: "position: absolute; width: 250px; font: normal normal normal 10pt Helvetica;z-index:100"
});
dialog.startup();
this.map.addLayer(overViewMap);
//listen for when the onMouseOver event fires on the countiesGraphicsLayer
//when fired, create a new graphic with the geometry from the event.graphic and add it to the maps graphics layer
overViewMap.on("mouse-over", openDialog);
overViewMap.on("mouse-out", closeDialog);
overViewMap.on("click", function (evt) {
registry.byId("fsbLCA").set('value', evt.graphic.attributes.said);
topic.publish("fsb/Zoom", evt.graphic.attributes.said);
});
on(map, "update-end", hideLoading);
on(map, "update-start", showLoading);
var loading = dom.byId("loadingImg");
function showLoading() {
domUtils.show(loading);
}
function hideLoading(error) {
domUtils.hide(loading);
}
var oLayers = JSON.parse(jsonLayers);
console.log(oLayers);
var aLayers = [];
for (var i = 0; i < oLayers.layers.length; i++) {
var temp = new ArcGISDynamicMapServiceLayer(oLayers.layers[i].url, {
id: oLayers.layers[i].id,
visible: oLayers.layers[i].visible,
opacity: oLayers.layers[i].opacity
});
var tmpLegend = oLayers.layers[i].legend;
lang.mixin(temp, {
title: oLayers.layers[i].title,
legend: tmpLegend
});
aLayers.push(temp);
}
this.map.addLayers(aLayers);
// console.log("MapWidget::addLayers done!");
topic.subscribe("fsb/LCA", lang.hitch(this, function (top, location) {
var lvl = registry.byId('twlSlider').value;
var floodLyrDefinition = [];
floodLyrDefinition[location.said] = "level_cm = " + lvl;
var floodlayer = map.getLayer("floodlayer");
floodlayer.setVisibleLayers([location.said], true);
floodlayer.setLayerDefinitions(floodLyrDefinition);
}));
topic.subscribe("floodUpdate/slider", function (val, source) {
var floodlayer = map.getLayer("floodlayer");
var locationList = floodlayer.visibleLayers;
var location = locationList.pop();
var floodLyrDefinition = [];
floodLyrDefinition[location] = "level_cm = " + val;
floodlayer.setVisibleLayers([location], true);
floodlayer.setLayerDefinitions(floodLyrDefinition);
});
topic.subscribe("fsb/Zoom", lang.hitch(this, function (said) {
showLoading();
if (overViewMap.loaded) {
for (i = 0; i < overViewMap.graphics.length; i++) {
var OMSaid = overViewMap.graphics[i].attributes.said;
if (overViewMap.graphics[i].attributes.said === said) {
gotoStudyArea(overViewMap.graphics[i]);
return;
}
}
var queryTask = new QueryTask(this.ovLayer);
var query = new Query();
query.where = "said=" + said;
query.returnGeometry = true;
queryTask.execute(query, function (fs) {
var geo = fs.features[0];
gotoStudyArea(geo);
});
} else {
console.error("Not all features are loaded yet.");
}
}));
function openDialog(evt) {
var t = "Study Area: ${name}</br>Survey Year: ${survey_year}";
var content = esriLang.substitute(evt.graphic.attributes, t);
dialog.setContent(content);
domStyle.set(dialog.domNode, "opacity", 0.85);
dijitPopup.open({
popup: dialog,
x: evt.pageX,
y: evt.pageY
});
map.setMapCursor("pointer");
}
function closeDialog(evt) {
dijitPopup.close(dialog);
map.setMapCursor("default");
}
function gotoStudyArea(evt) {
var feat;
if (evt.geometry) {
feat = evt.geometry;
} else if (evt.graphic.geometry) {
feat = evt.graphic.geometry;
} else {
console.error("Cannot zoom to exent beacuse geometry is missing",evt);
return;
}
if (feat.type === 'polygon') {
var featExt = feat.getExtent();
map.setExtent(featExt);
} else if (feat.type === 'point') {
var saPt = new Point(evt.graphic.attributes.X, evt.graphic.attributes.Y, new SpatialReference({
wkid: 3857
}));
map.centerAndZoom(saPt, 13);
}
hideLoading();
}
}
});
});