My goal is to use both wms layers and arcgis tiled layers as basemaps. I have accomplished this before in a separate application by simply adding it to the map as a layer and reordering the selected 'basemap' layer to 0.
EDIT: I recently revisited this and found a more simplistic solution. This works in both 'custom' and 'agol' mode. No changes to Controller.js are required.
basemaps.js
define([
'esri/layers/WMSLayer',
'esri/layers/WMSLayerInfo',
'esri/geometry/Extent'
], function (WMSLayer, WMSLayerInfo, Extent) {
return {
map: true, // needs a refrence to the map
mode: 'agol', //must be either 'agol' or 'custom'
title: 'Basemaps', // tilte for widget
mapStartBasemap: 'hybrid', // must match one of the basemap keys below
//basemaps to show in menu. define in basemaps object below and reference by name here
// TODO Is this array necessary when the same keys are explicitly included/excluded below?
basemapsToShow: ['hybrid','streets','topo', 'Natural2015','Infrared2015', 'Natural2013', 'Natural2012', 'Infrared2012', 'Natural2010', 'Natural2007', 'Infrared2007'],
// a WMS configuration (WMSLayer): This setup currently only supports one wms server.
wmsConfig: new WMSLayer('http://geodata.state.nj.us/imagerywms/Natural2015?', {
id: 'wmslayer',
resourceInfo: {
extent: new Extent({
'xmin': -166753.95750000002,
'ymin': 1423.4125000000931,
'xmax': 1100824.1675,
'ymax': 997517.1625000001,
'spatialReference': {
'wkid': 3424
}
}),
layerInfos: [new WMSLayerInfo({
title: 'Imagery'
})],
version: ['1.1.1']
},
visibleLayers: []
}),
// define all valid custom basemaps here. Object of Basemap objects. For custom basemaps, the key name and basemap id must match.
basemaps: { // agol basemaps
streets: {
title: 'Streets'
},
hybrid: {
title: 'Hybrid'
},
topo: {
title: 'Topo'
},
// examples of WMS layers
Natural2015: {
title: '2015 - Leaf Off (WMS)',
wms: true,
basemap :{
id: 'Natural2015'
}
},
Infrared2015: {
title: '2015 - Infrared (WMS)',
wms: true,
basemap :{
id: 'Infrared2015'
}
},
Natural2013: {
title: '2013 - Leaf On (WMS)',
wms: true,
basemap :{
id: 'Natural2013'
}
},
Natural2012: {
title: '2012 - Leaf Off (WMS)',
wms: true,
basemap :{
id: 'Natural2012'
}
},
Infrared2012: {
title: '2012 - Infrared (WMS)',
wms: true,
basemap :{
id: 'Infrared2012'
}
},
Natural2010: {
title: '2010 - Leaf On (WMS)',
wms: true,
basemap :{
id: 'Natural2010'
}
},
Natural2007: {
title: '2007 - Leaf Off (WMS)',
wms: true,
basemap :{
id: 'Natural2007'
}
},
Infrared2007: {
title: '2007 - Infrared (WMS)',
wms: true,
basemap :{
id: 'Infrared2007'
}
}
}
};
});
Basemaps.js
define([
'dojo/_base/declare',
'dijit/_WidgetBase',
'dijit/_TemplatedMixin',
'dijit/_WidgetsInTemplateMixin',
'dojo/_base/lang',
'dijit/DropDownMenu',
'dijit/MenuItem',
'dojo/_base/array',
'dojox/lang/functional',
'dojo/text!./Basemaps/templates/Basemaps.html',
'esri/dijit/BasemapGallery',
'dojo/i18n!./Basemaps/nls/resource',
'dijit/form/DropDownButton',
'xstyle/css!./Basemaps/css/Basemaps.css'
], function (declare, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, lang, DropDownMenu, MenuItem, array, functional, template, BasemapGallery, i18n) {
// main basemap widget
return declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], {
templateString: template,
widgetsInTemplate: true,
i18n: i18n,
mode: 'agol',
title: i18n.title,
//baseClass: 'gis_Basemaps_Dijit',
//buttonClass: 'gis_Basemaps_Button',
//menuClass: 'gis_Basemaps_Menu',
mapStartBasemap: 'streets',
basemapsToShow: ['streets', 'satellite', 'hybrid', 'topo', 'gray', 'oceans', 'national-geographic', 'osm'],
validBasemaps: [],
postCreate: function () {
this.inherited(arguments);
this.currentBasemap = this.mapStartBasemap || null;
var WMSLayer = this.wmsConfig;
//WMS loading indicator for basemaps dropdown
WMSLayer.on('update-start', lang.hitch(this, function () {
this.dropDownButton.set('iconClass', 'fa fa-refresh fa-spin');
}));
WMSLayer.on('update-end', lang.hitch(this, function () {
this.dropDownButton.set('iconClass', 'basemapsIcon');
}));
if (this.mode === 'custom') {
this.gallery = new BasemapGallery({
map: this.map,
showArcGISBasemaps: false,
basemaps: functional.map(this.basemaps, function (map) {
return map.basemap;
})
});
// if (this.map.getBasemap() !== this.mapStartBasemap) { //based off the title of custom basemaps in viewer.js config
// this.gallery.select(this.mapStartBasemap);
// }
this.gallery.startup();
}
this.menu = new DropDownMenu({
style: 'display: none;' //,
//baseClass: this.menuClass
});
array.forEach(this.basemapsToShow, function (basemap) {
if (this.basemaps.hasOwnProperty(basemap)) {
var menuItem = new MenuItem({
id: basemap,
label: this.basemaps[basemap].title,
iconClass: (basemap == this.mapStartBasemap) ? 'selectedIcon' : 'emptyIcon',
onClick: lang.hitch(this, function () {
var wms = this.basemaps[basemap].wms;
if (basemap !== this.currentBasemap) {
this.currentBasemap = basemap;
if (this.mode === 'custom' && !wms) {
this.map.removeLayer(WMSLayer);
this.gallery.select(basemap);
}
else if (this.mode === 'agol' && !wms) {
this.map.removeLayer(WMSLayer);
this.map.setBasemap(basemap);
}
else if (this.mode === 'custom' && wms){
this.map.addLayer(WMSLayer, 1);
this.wmsConfig.setVisibleLayers(this.basemaps[basemap].basemap.id);
this.map.setBasemap(null);
}
else if (this.mode === 'agol' && wms){
this.map.addLayer(WMSLayer, 1);
this.wmsConfig.setVisibleLayers(this.basemaps[basemap].basemap.id);
}
var ch = this.menu.getChildren();
array.forEach(ch, function (c) {
if (c.id == basemap) {
c.set('iconClass', 'selectedIcon');
} else {
c.set('iconClass', 'emptyIcon');
}
});
}
})
});
this.menu.addChild(menuItem);
}
}, this);
this.dropDownButton.set('dropDown', this.menu);
},
startup: function () {
this.inherited(arguments);
if (this.mode === 'custom') {
if (this.map.getBasemap() !== this.mapStartBasemap) { //based off the title of custom basemaps in viewer.js config
this.gallery.select(this.mapStartBasemap);
}
} else {
if (this.mapStartBasemap) {
if (this.map.getBasemap() !== this.mapStartBasemap) { //based off the agol basemap name
this.map.setBasemap(this.mapStartBasemap);
}
}
}
}
});
});