enhanced-basemap-gallery-widget
Version:
This widget is enhanced to include the ability to fade between basemaps.
614 lines (556 loc) • 24.3 kB
JavaScript
///////////////////////////////////////////////////////////////////////////
// Copyright © 2014 Esri. All Rights Reserved.
//
// Licensed under the Apache License Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
///////////////////////////////////////////////////////////////////////////
define([
'dojo/_base/declare',
'dijit/_WidgetsInTemplateMixin',
'dojo/Deferred',
'jimu/BaseWidget',
'jimu/portalUtils',
'jimu/dijit/Message',
'jimu/PanelManager',
'jimu/SpatialReference/wkidUtils',
'jimu/portalUrlUtils',
'jimu/utils',
'esri/dijit/Basemap',
'esri/dijit/BasemapLayer',
'esri/dijit/BasemapGallery',
'dojo/_base/lang',
'dojo/_base/array',
'dojo/_base/html',
'dojo/query',
'esri/request',
'dojo/on',
'dojo/promise/all',
'./utils',
'dijit/form/HorizontalSlider',
'dijit/form/HorizontalRuleLabels',
'dojo/dom-construct',
'dojo/dom-geometry',
'dojo/aspect'
],
function(
declare,
_WidgetsInTemplateMixin,
Deferred,
BaseWidget,
portalUtils,
Message,
PanelManager,
SRUtils,
portalUrlUtils,
jimuUtils,
Basemap,
BasemapLayer,
BasemapGallery,
lang,
array,
html,
query,
esriRequest,
on,
all,
utils,
HorizontalSlider,
HorizontalRuleLabels,
domConstruct,
domGeom,
aspect) {
var clazz = declare([BaseWidget, _WidgetsInTemplateMixin], {
name: 'eBasemapGallery',
baseClass: 'jimu-widget-ebasemapgallery',
basemapGallery: null,
spatialRef: null,
hybridBasemapArray: null,
hyBasemap: null,
defaultBasemapId: null,
secondBasemapId: null,
hybridBasemapId: null,
selectedBMNode: null,
selectedBMNode2: null,
selectedBMNode3: null,
hybridChangeEvent: false,
hybridAdded: false,
imgthumbposleft: 0,
webmapBasemap: null,
postCreate: function() {
this.own(on(this.domNode, 'mousedown', lang.hitch(this, function (event) {
event.stopPropagation();
if (event.altKey) {
var msgStr = this.nls.widgetverstr + ': ' + this.manifest.version;
msgStr += '\n' + this.nls.wabversionmsg + ': ' + this.manifest.wabVersion;
msgStr += '\n' + this.manifest.description;
new Message({
titleLabel: this.nls.widgetversion,
message: msgStr
});
}
})));
},
startup: function() {
/*jshint unused: false*/
this.inherited(arguments);
this.initBasemaps();
this.defaultBasemapId = this.map.getBasemap();
this.own(
aspect.before(this, 'destroy', this.beforeDestroy)
);
},
resize: function() {
this._responsive();
},
_responsive: function() {
// the default width of esriBasemapGalleryNode is 85px,
// margin-left is 10px, margin-right is 10px;
var paneNode = query('#' + this.id)[0];
var width = html.getStyle(paneNode, 'width');
var column = parseInt(width / 105, 10);
if (column > 0) {
var margin = width % 105;
var addWidth = parseInt(margin / column, 10);
query('.esriBasemapGalleryNode', this.id).forEach(function(node) {
html.setStyle(node, 'width', 85 + addWidth + 'px');
});
}
var imgthumbnode = query('.esriBasemapGalleryNode > a > .esriBasemapGalleryThumbnail', this.id)[0];
this.imgthumbposleft = parseInt(domGeom.getMarginBox(imgthumbnode).l, 10) + 10;
query('.bm-addbtn', this.id).forEach(lang.hitch(this,function(node) {
html.setStyle(node, 'left', this.imgthumbposleft + 'px');
}));
var sWidth = (width - 261) / 2;
html.setStyle(this.spacer1, 'width', sWidth + 'px');
html.setStyle(this.spacer2, 'width', sWidth + 'px');
},
initBasemaps: function() {
var basemapsDef;
var portalSelfDef;
var config = lang.clone(this.config.basemapGallery);
//load form portal or config file.
if (!config.basemaps || config.basemaps.length === 0) {
basemapsDef = utils._loadPortalBaseMaps(this.appConfig.portalUrl,
this.map.spatialReference);
} else {
basemapsDef = new Deferred();
basemapsDef.resolve(config.basemaps);
}
var portal = portalUtils.getPortal(this.appConfig.portalUrl);
portalSelfDef = portal.loadSelfInfo();
all({
'portalSelf': portalSelfDef,
'basemaps': basemapsDef
}).then(lang.hitch(this, function(result) {
var basemaps = result.basemaps;
var basemapObjs = [];
var i = 0;
var webmapBasemap = this._getWebmapBasemap();
basemaps = array.filter(basemaps, function(basemap) {
var bingKeyResult;
var spatialReferenceResult;
// first, filter bingMaps
if(result.portalSelf.bingKey) {
// has bingKey, can add any bing map or not;
bingKeyResult = true;
} else if(!utils.isBingMap(basemap)) {
// do not have bingKey and basemap is not bingMap.
bingKeyResult = true;
} else {
// do not show basemap if do not has bingKey as well as basemap is bingMap.
bingKeyResult = false;
}
// second, filter spatialReference.
// only show basemaps who has same spatialReference with current map.
if (SRUtils.isSameSR(this.map.spatialReference.wkid,
basemap.spatialReference.wkid)) {
spatialReferenceResult = true;
} else {
spatialReferenceResult = false;
}
// basemap does not have title means basemap load failed.
return basemap.title && bingKeyResult && spatialReferenceResult;
}, this);
// if basemap of current webmap is not include, so add it.
for(i = 0; i < basemaps.length; i++) {
if (utils.compareSameBasemapByOrder(basemaps[i], webmapBasemap)) {
break;
}
}
if(i === basemaps.length) {
basemaps.push(webmapBasemap);
}
for (i = 0; i < basemaps.length; i++) {
var n = basemaps[i].layers.length;
var layersArray = [];
for (var j = 0; j < n; j++) {
layersArray.push(new BasemapLayer(basemaps[i].layers[j]));
}
basemaps[i].layers = layersArray;
if (!basemaps[i].thumbnailUrl) {
basemaps[i].thumbnailUrl = this.folderUrl + "images/default.jpg";
} else {
if (basemaps[i].thumbnailUrl.indexOf('//') === 0) {
basemaps[i].thumbnailUrl = basemaps[i].thumbnailUrl +
utils.getToken(this.appConfig.portalUrl);
} else {
basemaps[i].thumbnailUrl =
jimuUtils.processUrlInWidgetConfig(basemaps[i].thumbnailUrl, this.folderUrl);
}
}
basemapObjs.push(new Basemap(basemaps[i]));
}
config.map = this.map;
if (this.appConfig.portalUrl) {
config.portalUrl = this.appConfig.portalUrl;
}
config.basemaps = basemapObjs;
config.showArcGISBasemaps = false;
config.bingMapsKey = result.portalSelf.bingKey;
this.basemapGallery = new BasemapGallery(config, this.basemapGalleryDiv);
this.basemapGallery.startup();
this.own(on(this.basemapGallery, "selection-change", lang.hitch(this, this.selectionChange)));
this.own(on(this.basemapGallery, "add, remove", lang.hitch(this, this._onAddorRemoveBasemap)));
this._responsive();
this._selectWebBasemap();
}));
},
_onAddorRemoveBasemap: function() {
this._responsive();
query('.esriBasemapGalleryNode', this.id).forEach(lang.hitch(this,function(node) {
this.addNode = domConstruct.create('div', {
'class': 'bm-addbtn',
'id': node.id +'_addBtn',
'title': this.nls.add,
'style': 'left:' + this.imgthumbposleft + 'px'
}, node);
this.own(
on(node, 'mouseover', lang.hitch(this, this._showAddBtn))
);
this.own(
on(node, 'mouseout', lang.hitch(this, this._hideAddBtn))
);
this.own(
on(this.addNode, 'click', lang.hitch(this, this._addBtnClick))
);
}));
},
_selectWebBasemap: function(){
this.webmapBasemap = this._getWebmapBasemap();
var sNode = query(".esriBasemapGalleryLabelContainer span", this.selectedBasemapGalleryNode)[0];
var sNode2 = query(".esriBasemapGalleryThumbnail", this.selectedBasemapGalleryNode)[0];
array.some(this.basemapGallery.basemaps, lang.hitch(this,function(lyr){
if(this.webmapBasemap.title === lyr.title || this.webmapBasemap.layers[0].url === lyr.layers[0].url){
var tNode = query('.esriBasemapGalleryNode > .esriBasemapGalleryLabelContainer span[ title = "' + lyr.title + '" ]', this.id).parent().parent()[0];
this.selectedBMNode = tNode;
html.setStyle(tNode,'display','none');
var tNode2 = query('.esriBasemapGalleryThumbnail', tNode)[0];
html.addClass(tNode,'.esriBasemapGallerySelectedNode');
this.defaultBasemapId = lyr.id;
sNode.innerHTML = sNode.title = sNode.alt = lyr.title;
sNode2.title = sNode2.alt = tNode2.alt;
sNode2.src = tNode2.src;
}
}));
query('.esriBasemapGalleryNode', this.id).forEach(lang.hitch(this,function(node) {
this.addNode = domConstruct.create('div', {
'class': 'bm-addbtn',
'id': node.id +'_addBtn',
'title': this.nls.add,
'style': 'left:' + this.imgthumbposleft +'px'
}, node);
this.own(
on(node, 'mouseover', lang.hitch(this, this._showAddBtn))
);
this.own(
on(node, 'mouseout', lang.hitch(this, this._hideAddBtn))
);
this.own(
on(this.addNode, 'click', lang.hitch(this, this._addBtnClick))
);
}));
},
_removeBtnClick: function(evt) {
html.setStyle(this.selectedBasemapGalleryNode, 'visibility', 'visible');
html.setStyle(this.selectedBasemap1, 'visibility', 'hidden');
html.setStyle(this.selectedBasemap2, 'visibility', 'hidden');
html.setStyle(this.faderDiv,'display','none');
this._resetBasemaps1and2();
this._removeHybridBasemap((evt.target.id === "removeBM1") ? "second" : "primary");
this.hybridBasemapArray=[];
},
_resetBasemaps1and2: function(){
var sNode = query(".esriBasemapGalleryLabelContainer span", this.selectedBasemap1)[0];
var sNode2 = query(".esriBasemapGalleryThumbnail", this.selectedBasemap1)[0];
var sNode3 = query(".esriBasemapGalleryLabelContainer span", this.selectedBasemap2)[0];
var sNode4 = query(".esriBasemapGalleryThumbnail", this.selectedBasemap2)[0];
sNode3.innerHTML = sNode3.title = sNode3.alt = sNode.innerHTML = sNode.title = sNode.alt = "";
sNode4.title = sNode4.alt = sNode2.title = sNode2.alt = "";
sNode4.src = sNode2.src = this.folderUrl + "/images/default.jpg";
},
_addBtnClick: function(evt) {
//begin by removing the hybrid basemap if one exists
if(this.hybridBasemapId){
array.map(this.hyBasemap.getLayers(), lang.hitch(this,function(lyr){
lyr.opacity = 1;
}));
this.basemapGallery.remove(this.hybridBasemapId);
this.hybridAdded = false;
this.hybridBasemapId = null;
}
var gItem = this.defaultBasemapId.split("_")[1];
this.hybridBasemapArray=[];
this.hybridBasemapArray.push(gItem);
evt.stopImmediatePropagation();
evt.preventDefault();
if(this.selectedBMNode2){
html.setStyle(this.selectedBMNode2, 'display', 'block');
}
html.setStyle(this.selectedBasemapGalleryNode, 'visibility', 'hidden');
var sNode = query(".esriBasemapGalleryLabelContainer span", this.selectedBasemap1)[0];
var sNode2 = query(".esriBasemapGalleryThumbnail", this.selectedBasemap1)[0];
var sNode3 = query(".esriBasemapGalleryLabelContainer span", this.selectedBasemapGalleryNode)[0];
var sNode4 = query(".esriBasemapGalleryLabelContainer span", this.selectedBasemap2)[0];
var sNode5 = query(".esriBasemapGalleryThumbnail", this.selectedBasemap2)[0];
var bm2Node = html.byId(evt.target.id.replace("_addBtn", ""));
this.selectedBMNode2 = bm2Node;
this.secondBasemapId = bm2Node.id.replace("galleryNode_", "");
gItem = bm2Node.id.split("_")[2];
this.hybridBasemapArray.push(gItem);
html.setStyle(bm2Node, 'display', 'none');
var aNode2 = query('.esriBasemapGalleryThumbnail', bm2Node)[0];
sNode4.innerHTML = sNode.title = sNode.alt = aNode2.alt;
sNode5.title = sNode5.alt = aNode2.alt;
sNode5.src = aNode2.src;
array.some(this.basemapGallery.basemaps, lang.hitch(this,function(lyr){
if(sNode3.title === lyr.title){
var tNode = query('.esriBasemapGalleryNode > .esriBasemapGalleryLabelContainer span[ title = "' + lyr.title + '" ]', this.id).parent().parent()[0];
var tNode2 = query('.esriBasemapGalleryThumbnail', tNode)[0];
sNode.innerHTML = sNode.title = sNode.alt = lyr.title;
sNode2.title = sNode2.alt = tNode2.alt;
sNode2.src = tNode2.src;
}
}));
html.setStyle(this.selectedBasemap1, 'visibility', 'visible');
html.setStyle(this.selectedBasemap2, 'visibility', 'visible');
html.setStyle(this.faderDiv,'display','inline-block');
this._addHybridBasemap();
},
_getBasemapNodeFromTarget: function(target) {
var retval;
if(target.tagName === "A"){
retval = target.parentNode;
}else if(target.tagName === "IMG"){
retval = target.parentNode.parentNode;
}else if(target.tagName === "SPAN"){
retval = target.parentNode.parentNode;
}else if(target.tagName === "DIV"){
if(html.hasClass(target, 'esriBasemapGalleryNode')){
retval = target;
}else if(html.hasClass(target, 'esriBasemapGalleryLabelContainer')){
retval = target.parentNode;
}else if(html.hasClass(target, 'bm-addbtn')){
retval = target.parentNode;
}else if(html.hasClass(target, 'bm-removebtn')){
retval = target.parentNode;
}
}
return retval;
},
_showAddBtn: function(evt){
var node = this._getBasemapNodeFromTarget(evt.target);
if(html.hasClass(node, 'currentSelected') || html.hasClass(node, 'basemap1') || html.hasClass(node, 'basemap2')){
return;
}
var addBtnNode = query('.bm-addbtn', node)[0];
html.setStyle(addBtnNode, 'display', 'inline-block');
},
_hideAddBtn: function(evt){
var node = this._getBasemapNodeFromTarget(evt.target);
if(html.hasClass(node, 'currentSelected') || html.hasClass(node, 'basemap1') || html.hasClass(node, 'basemap2')){
return;
}
var addBtnNode = query('.bm-addbtn', node)[0];
html.setStyle(addBtnNode, 'display', 'none');
},
_showRemoveBtn: function(evt){
var node = this._getBasemapNodeFromTarget(evt.target);
var addRemoveNode = query('.bm-removebtn', node)[0];
html.setStyle(addRemoveNode, 'display', 'inline-block');
},
_hideRemoveBtn: function(evt){
var node = this._getBasemapNodeFromTarget(evt.target);
var addRemoveNode = query('.bm-removebtn', node)[0];
html.setStyle(addRemoveNode, 'display', 'none');
},
_onFaderChanged: function(evt){
var floorValue = Math.floor(evt);
//loop through the hybrid basemap layers and adjust transparency
array.map(this.hyBasemap.getLayers(), lang.hitch(this,function(lyr){
if(lyr.hybrid === 0){
lyr.opacity = (100 - floorValue) / 100;
}else if(lyr.hybrid === 1){
lyr.opacity = floorValue / 100;
}
}));
this.hybridChangeEvent = true;
this.basemapGallery.select(this.hybridBasemapId);
},
_getWebmapBasemap: function() {
var thumbnailUrl;
if (this.map.itemInfo.item.thumbnail) {
thumbnailUrl = portalUrlUtils.getItemUrl(this.appConfig.portalUrl,
this.map.itemInfo.item.id) + "/info/" + this.map.itemInfo.item.thumbnail;
} else {
thumbnailUrl = null;
}
return {
title: this.map.itemInfo.itemData.baseMap.title,
thumbnailUrl: thumbnailUrl,
layers: this.map.itemInfo.itemData.baseMap.baseMapLayers,
spatialReference: this.map.spatialReference
};
},
_addHybridBasemap: function (){
var bmObj = {
id: "basemap_" + this.basemapGallery.basemaps.length.toString(),
title: "Hybrid Mashup",
thumbnailUrl: this.folderUrl + "/images/default.jpg",
layers: []
};
this.hybridBasemapId = bmObj.id;
var bmLyrOrder = 0;
array.map(this.hybridBasemapArray, lang.hitch(this,function(bLyrId){
array.map(this.basemapGallery.basemaps[bLyrId].getLayers(), lang.hitch(this,function(lyr){
lyr.visibility = true;
lyr.opacity = 0.5;
lyr.hybrid = bmLyrOrder;
bmObj.layers.push(lyr);
}));
bmLyrOrder++;
}));
this.hyBasemap = new Basemap(bmObj);
this.basemapGallery.add(this.hyBasemap);
this.hybridAdded = true;
this.hybridChangeEvent = true;
this.basemapGallery.select(this.hybridBasemapId);
this.fader.set('value', 50);
this.selectedBMNode = html.byId("galleryNode_" + this.defaultBasemapId);
this.selectedBMNode2 = html.byId("galleryNode_" + this.secondBasemapId);
this.selectedBMNode3 = html.byId("galleryNode_" + this.hybridBasemapId);
html.setStyle(this.selectedBMNode, 'display', 'none');
html.setStyle(this.selectedBMNode2, 'display', 'none');
html.setStyle(this.selectedBMNode3, 'display', 'none');
},
_removeHybridBasemap: function (which){
array.map(this.hyBasemap.getLayers(), lang.hitch(this,function(lyr){
lyr.opacity = 1;
}));
this.basemapGallery.remove(this.hybridBasemapId);
this.hybridAdded = false;
this.hybridBasemapId = null;
this.hybridChangeEvent = false;
if(which === "primary"){
this.basemapGallery.select(this.defaultBasemapId);
this.secondBasemapId = null;
this.hybridBasemapId = null;
this.selectedBMNode2 = null;
this.selectedBMNode3 = null;
}else{
this.basemapGallery.select(this.secondBasemapId);
this.secondBasemapId = null;
this.hybridBasemapId = null;
this.selectedBMNode2 = null;
this.selectedBMNode3 = null;
}
},
beforeDestroy: function() {
if(this.hybridAdded){
array.map(this.hyBasemap.getLayers(), lang.hitch(this,function(lyr){
lyr.opacity = 1;
}));
this.basemapGallery.remove(this.hybridBasemapId);
}
this.hybridAdded = false;
this.hybridBasemapId = null;
this.hybridChangeEvent = false;
if(this.webmapBasemap){
this.basemapGallery.select(this.webmapBasemap);
}
this.basemapGallery.destroy();
this.selectedBMNode = null;
this.selectedBMNode2 = null;
this.selectedBMNode3 = null;
this.webmapBasemap = null;
},
selectionChange: function() {
if(this.hybridChangeEvent){
this.hybridChangeEvent = false;
return;
}
if(this.selectedBMNode){
html.setStyle(this.selectedBMNode, 'display', 'inline-block');
}
if(this.selectedBMNode2){
html.setStyle(this.selectedBMNode2, 'display', 'inline-block');
}
var basemap = this.basemapGallery.getSelected();
if(basemap.title === "Hybrid Mashup"){
basemap = query(".esriBasemapGalleryLabelContainer span", this.selectedBMNode)[0];
}
var sNode = query(".esriBasemapGalleryLabelContainer span", this.selectedBasemapGalleryNode)[0];
var sNode2 = query(".esriBasemapGalleryThumbnail", this.selectedBasemapGalleryNode)[0];
var sNode3 = query(".esriBasemapGalleryLabelContainer span", this.selectedBasemap1)[0];
var sNode4 = query(".esriBasemapGalleryThumbnail", this.selectedBasemap1)[0];
array.some(this.basemapGallery.basemaps, lang.hitch(this,function(lyr){
if(basemap.title === lyr.title || basemap.layers[0].url === lyr.layers[0].url){
var tNode = query('.esriBasemapGalleryNode > .esriBasemapGalleryLabelContainer span[ title = "' +
lyr.title + '" ]', this.id).parent().parent()[0];
html.setStyle(tNode, 'display', 'none');
this.selectedBMNode = tNode;
var tNode2 = query('.esriBasemapGalleryThumbnail', tNode)[0];
html.addClass(tNode,'.esriBasemapGallerySelectedNode');
this.defaultBasemapId = lyr.id;
if(this.hybridAdded){
sNode3.innerHTML = sNode3.title = sNode3.alt = lyr.title;
sNode4.title = sNode4.alt = tNode2.alt;
sNode4.src = tNode2.src;
}
sNode.innerHTML = sNode.title = sNode.alt = lyr.title;
sNode2.title = sNode2.alt = tNode2.alt;
sNode2.src = tNode2.src;
}
}));
if (this.isPreload) {
PanelManager.getInstance().closePanel(this.id + '_panel');
}
if(this.hybridAdded){
//begin by removing the hybrid basemap if one exists
if(this.hybridBasemapId){
array.map(this.hyBasemap.getLayers(), lang.hitch(this,function(lyr){
lyr.opacity = 1;
}));
this.basemapGallery.remove(this.hybridBasemapId);
this.hybridAdded = false;
this.hybridBasemapId = null;
}
var gItem = this.defaultBasemapId.split("_")[1];
this.hybridBasemapArray=[];
this.hybridBasemapArray.push(gItem);
gItem = this.selectedBMNode2.id.split("_")[2];
this.hybridBasemapArray.push(gItem);
this._addHybridBasemap();
}
}
});
return clazz;
});