Seems like all the other basemaps can be used in the esri.Map() constructor, but this one doesn't have a corresponding entry in the list of acceptable values. I've tried just "terrain", and it didn't work.
3 Answers
You can combine the two layers as a single Basemap
and pass them to the map constructor. Below is a full working example using the two layers you are interested in.
This came from a discussion we had over on github related to using non-mercator maps as basemaps for the Configurable Map Viewer (cmv) that is based on the ESRI JS API.
This does not fully address your additional requirement to save the basemap with the user settings but perhaps gives you an idea on how to proceed. There might be additional details in that discussion related to the BaseMap widget that would be helpful for you. One of the tricks there was to include no basemap at all (or a blank one) and allow the BaseMap widget to determine the starting basemap. Something like that might work for your requirement to save the basemap.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/>
<title>Simple Map</title>
<link rel="stylesheet" href="http://js.arcgis.com/3.10/js/esri/css/esri.css">
<style>
html, body, #map {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
body {
background-color: #FFF;
overflow: hidden;
font-family: "Trebuchet MS";
}
</style>
<script src="http://js.arcgis.com/3.10/"></script>
<script>
var map;
require(["esri/map", "esri/dijit/Basemap", "esri/dijit/BasemapLayer", "dojo/domReady!"], function(Map, Basemap, BasemapLayer) {
map = new Map("map", {
basemap: new Basemap({
id: 'terrain',
layers: [
new BasemapLayer({
url: 'http://services.arcgisonline.com/arcgis/rest/services/World_Terrain_Base/MapServer'
}),
new BasemapLayer({
url: 'http://services.arcgisonline.com/ArcGIS/rest/services/Reference/World_Reference_Overlay/MapServer'
})
]
}),
center: [-122.45, 37.75], // longitude, latitude
zoom: 12
});
});
</script>
</head>
<body>
<div id="map"></div>
</body>
</html>
UPDATE:
While answering a question over at the cmv github repository, it occurred to me that there is another solution that may get you closer to what you desire. The available basemaps are just an object within the esri.config.defaults.map
. You can add your own custom basemaps to that object and they are treated like the standard ESRI basemaps. The advantage of this approach is you can refer to the basemap id in the map constructor and thus that id can be saved in the user settings as you desired. Here's a full example:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/>
<title>Simple Map</title>
<link rel="stylesheet" href="http://js.arcgis.com/3.10/js/esri/css/esri.css">
<style>
html, body, #map {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
body {
background-color: #FFF;
overflow: hidden;
font-family: "Trebuchet MS";
}
</style>
<script src="http://js.arcgis.com/3.10/"></script>
<script>
var map;
esriConfig.defaults.map.basemaps.terrain = {
baseMapLayers: [
{
url: "http://services.arcgisonline.com/arcgis/rest/services/World_Terrain_Base/MapServer"
},
{
url: "http://services.arcgisonline.com/ArcGIS/rest/services/Reference/World_Reference_Overlay/MapServer"
}
],
title: "Terrain Basemap"
};
require(["esri/map", "esri/config", "dojo/domReady!"], function(Map, esriConfig) {
map = new Map("map", {
basemap: "terrain",
center: [-122.45, 37.75], // longitude, latitude
zoom: 12
});
});
</script>
</head>
<body>
<div id="map"></div>
</body>
</html>
-
that's a nice approach, which has the advantage that the new Terrain layer behaves just like the other basemaps Commented Aug 20, 2014 at 23:28
-
I have updated my answer with an additional alternative that may be closer to what is desired.– tmcgeeCommented Aug 21, 2014 at 7:32
The map reference lists the available basemaps which can be specified using the keyword:
Valid values are: "streets" , "satellite" , "hybrid", "topo", "gray", "oceans",
"national-geographic", "osm".
You can add other layers as a basemap by finding their REST endpoint and adding them as a tiled layer. There's a example script here.
The Esri Terrain layer seems to be coming from http://services.arcgisonline.com/arcgis/rest/services/World_Terrain_Base/MapServer
The labels seem to be coming from http://services.arcgisonline.com/ArcGIS/rest/services/Reference/World_Reference_Overlay/MapServer
You can add these two layers manually to reproduce the Terrain With Labels basemap combination.
-
Thanks for the quick response. The way my application works, I need to save the basemap with the user settings. For all other basemaps that's possible with one of the valid values, but not for this specific map. Any reason for that? Commented Aug 20, 2014 at 17:10
-
You can only use the Esri pre-canned basemaps ("streets", "satellite", "topo", etc.) in the constructor. If you search the Esri JavaScript code, you can find "Streets" and "Satellite" basemaps defined in the code, but not "Terrain".
You don't actually have to specify a basemap in the constructor. In the code example below, I am adding the streets basemap manually. Then I'm adding the terrain basemap over top with an opacity set to 0.8 so you can still see the streets.
<script>
var map;
require(["esri/map", "esri/layers/ArcGISTiledMapServiceLayer"],
function (Map, ArcGISTiledMapServiceLayer ) {
map = new Map("map", {
center: [-77.123, 40.123],
zoom: 9
});
var streetsBasemap = new ArcGISTiledMapServiceLayer(
"http://services.arcgisonline.com/arcgis/rest/services/World_Street_Map/MapServer/");
map.addLayer(streetsBasemap);
var terrianBasemap = new ArcGISTiledMapServiceLayer(
"http://services.arcgisonline.com/arcgis/rest/services/World_Terrain_Base/MapServer");
terrianBasemap.setOpacity(0.8);
map.addLayer(terrianBasemap);
});
</script>