'use strict';
const basemap = require('./basemap.js');
/**
* @ngdoc module
* @name mapManager
* @description
*
* The `MapManager` module exports an object with the following properties:
* - `Extent` {type} of esri/geometry
* - `Map` {type} of esri/map
* - `OverviewMap` {type} of esri/dijit/OverviewMap
* - `Scalebar` {type} of esri/dijit/Scalebar
* - `getExtentFromSetting {function} create an ESRI Extent object from extent setting JSON object.
* - `setupMap` {function} interates over config settings and apply logic for any items present.
* - `setProxy` {function} Set proxy service URL to avoid same origin issues
*/
// mapManager module, provides function to setup a map
module.exports = function (esriBundle) {
// note: a decision was made to include esri/dijit/Scalebar here because
// it has minimum interaction after creation, no need for the additional
// scalebar.js
const mapManager = {
Extent: esriBundle.Extent,
Map: esriBundle.Map,
OverviewMap: esriBundle.OverviewMap,
Scalebar: esriBundle.Scalebar,
getExtentFromJson,
setupMap,
setProxy,
mapDefault,
findClosestLOD
};
let basemapCtrl;
let scalebarCtrl;
let overviewMapCtrl;
/**
* @ngdoc method
* @name setupMap
* @memberof mapManager
* @description
* Setup map features with info provided by configuration
* <div>
* -- Demo: The follwoing is from description section of ngDoc --
*
* <h4>TODO</h4>
* <p>Rename BasemapControl and ScalebarControl</p>
* -- End of description section --
* </div>
*
* @param {esriMap} map ESRI map object
* @param {Object} settings JSON object of map configurations
* @return {Object} with following properties:
* <ul>
* <li>BasemapControl - an object with setBasemap function and a BasemapGallery object</li>
* <li>OverviewMapControl - a reference to the overviewMap control on the map</li>
* <li>ScalebarControl - a reference to the scalebar control on the map</li>
* </ul>
*/
function setupMap(map, settings) {
// check to see if property exists in settings
if (settings.basemaps) {
// need to pass esriBundle to basemap module in order to use it
// the alternative is to pass geoApi reference after creation, and then use the geoApi to
// access the properly initialized modules.
// or Is there an other way to do it?
const lbasemap = basemap(esriBundle);
// basemapCtrl is a basemap gallery object, should store this value for application use
basemapCtrl = lbasemap.makeBasemaps(settings.basemaps, map);
} else {
console.warn('warning: basemaps setting does not exist');
}
// TODO: add code to setup scalebar
if (settings.scalebar) {
scalebarCtrl = new mapManager.Scalebar({
map: map,
attachTo: settings.scalebar.attachTo,
scalebarUnit: settings.scalebar.scalebarUnit
});
scalebarCtrl.show();
} else {
console.warn('scalebar setting does not exists');
}
// TODO: add code to setup north arrow
// Setup overview map
if (settings.overviewMap && settings.overviewMap.enabled) {
if (overviewMapCtrl) {
overviewMapCtrl.destroy();
overviewMapCtrl = null;
}
overviewMapCtrl = mapManager.OverviewMap({
map: map,
expandFactor: 1,
visible: settings.overviewMap.enabled
});
overviewMapCtrl.startup();
basemapCtrl.basemapGallery.on('selection-change', () => {
overviewMapCtrl.destroy();
overviewMapCtrl = mapManager.OverviewMap({
map: map,
expandFactor: 1,
visible: settings.overviewMap.enabled
});
overviewMapCtrl.startup();
});
} else {
console.warn('overviewMap setting does not exist, or it\'s visible' +
' setting is set to false.');
}
// TODO: add code to setup mouse co-ordinates
// return as object so we can use this in our geo section of fgpv
return {
BasemapControl: basemapCtrl,
OverviewMapControl: overviewMapCtrl,
ScalebarControl: scalebarCtrl
};
}
/**
* @ngdoc method
* @name setProxy
* @memberof mapManager
* @description
* Set proxy service URL to avoid same origin issues
*
* @param {string} proxyUrl should point to a proxy with an interface compatible with ESRI's resource proxy
*/
function setProxy(proxyUrl) {
esriBundle.esriConfig.defaults.io.proxyUrl = proxyUrl;
}
/**
* @ngdoc method
* @name mapDefault
* @memberof mapManager
* @description
* Sets or gets map default config values.
*
* @param {String} key name of the default property
* @param {Any} value value to set for the specified default property
*/
function mapDefault(key, value) {
if (typeof value === 'undefined') {
return esriBundle.esriConfig.defaults.map[key];
} else {
esriBundle.esriConfig.defaults.map[key] = value;
}
}
/**
* @ngdoc method
* @name getExtentFromJson
* @memberof mapManager
* @description
* create an ESRI Extent object from extent setting JSON object.
*
* @param {object} extentJson that follows config spec
*/
function getExtentFromJson(extentJson) {
return esriBundle.Extent({ xmin: extentJson.xmin, ymin: extentJson.ymin,
xmax: extentJson.xmax, ymax: extentJson.ymax,
spatialReference: { wkid: extentJson.spatialReference.wkid } });
}
/**
* @ngdoc method
* @name findClosestLOD
* @memberof mapManager
* Finds the level of detail closest to the provided scale.
*
* @param {Array} lods list of levels of detail objects
* @param {Number} scale scale value to search for in the levels of detail
* @return {Object} the level of detail object closest to the scale
*/
function findClosestLOD(lods, scale) {
const diffs = lods.map(lod => Math.abs(lod.scale - scale));
const lodIdx = diffs.indexOf(Math.min(...diffs));
return lods[lodIdx];
}
return mapManager;
};