Skip to content

Instantly share code, notes, and snippets.

@asizer
Last active June 20, 2016 18:04
Show Gist options
  • Save asizer/ac703cbb2c1dc4b2c22be2782a0bbb7f to your computer and use it in GitHub Desktop.
Save asizer/ac703cbb2c1dc4b2c22be2782a0bbb7f to your computer and use it in GitHub Desktop.
Locate Button calls break basemap tiles

The issue

Using the jsapi Locate Button with webmaps sometimes causes basemap tiles to not refresh correctly.

The particular situation

This appears to happen when the map zoom level at the time the Locate Button is pressed is much smaller than the max zoom level for the basemap. For instance, if a basemap has a max zoom of 16, the starting map zoom seems to need to be 5 or less to see this issue.

The function calls

This issue is reproducible without the Locate Button by just calling the two functions that the Button calls sequentially: setScale() and centerAt(<pt>).

The example

This example can be used to show any esri basemap (excluding OSM) will break on a sequential call of these two methods, if the starting zoom is sufficiently small. Open the link to the full-size example, then use the url param ?basemap= with one of these built-in tiled basemap names (streets, hybrid, terrain, topo, gray, dark-gray, oceans, national-geographic, osm) to switch to a webmap with the specified basemap.

<!DOCTYPE html>
<html>
<head>
<title>Locator Button problem</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no,width=device-width" />
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<link rel="stylesheet" href="//js.arcgis.com/3.17/esri/css/esri.css">
<style>
html, body {
font-family: "Open Sans", sans-serif;
height: 100%;
width: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
.head-foot {
background-color: gray;
color: #eee;
left: 0;
right: 0;
height: 60px;
font-size: 30px;
text-align: center;
line-height: 1.2em;
}
#header {
height: 110px;
}
#map {
position: absolute;
top: 110px;
right: 0;
left: 0;
bottom: 60px;
}
/* map buttons */
#setZoom, #breakMap, #zoom {
position: absolute;
z-index: 50;
left: 20px;
}
#zoom {
top: 40px;
left: 60px;
color: white;
background: gray;
padding: 5px 10px;
font-size: 11px;
}
#setZoom {
top: 95px;
}
#breakMap {
top: 135px;
}
#footer {
position: absolute;
bottom: 0;
line-height: 50px;
}
button {
background: white;
padding: 5px 10px;
border-color: dodgerblue;
cursor: pointer;
}
button[disabled] {
cursor: not-allowed;
border-color: gray;
}
.hide {
visibility: hidden;
}
.webmap-change-wrapper {
font-size: 12px;
}
.webmap-change {
border: 1px solid dodgerblue;
padding: 3px 6px;
background: white;
color: dodgerblue;
cursor: pointer;
}
</style>
<script src="//js.arcgis.com/3.17/"></script>
<script>
var map, locator, home, setZoomBtn, breakMapBtn, warningSpan, minStartingZoom;
require([
'esri/arcgis/utils',
'esri/urlUtils',
'esri/geometry/Point',
'dojo/dom',
'dojo/query',
'dojo/dom-attr',
'dojo/dom-class',
'dojo/on'
], function(arcgisUtils, urlUtils, Point, dom, dojoQuery, domAttr, domClass, dojoOn) {
var webmaps = {
gray: '8b3d38c0819547faa83f7b7aca80bd76',
'dark-gray': '1970c1995b8f44749f4b9b6e81b5ba45',
oceans: '5ae9e138a17842688b0b79283a4353f6',
hybrid: '86265e5a4bbb4187a59719cf134e0018',
'national-geographic': 'd94dcdbe78e141c2b2d3a91d5ca8b9c9',
topo: 'd5e02a0c1f2b4ec399823fdd3c2fdebd',
streets: '8bf7167d20924cbf8e25e7b11c7c502c',
terrain: 'fe44cf9a739848939988addfeba473e4',
osm: 'b834a68d7a484c5fb473d4ba90d35e71'
};
// satellite, terrain, osm
var redlands = new Point({
x: -13046371.012730137,
y: 4036465.211003201,
spatialReference: {
wkid: 102100
}
});
function reloadPage(evt) {
console.debug('reloadPage', evt);
if (evt && evt.target) {
var val = domAttr.get(evt.target, 'value');
window.location.search = 'basemap=' + val;
}
}
function onZoomEnd() {
var zoomedOutFarEnough = map.getZoom() <= minStartingZoom;
domAttr.set(setZoomBtn, {disabled: zoomedOutFarEnough});
domClass.toggle(warningSpan, 'hide', zoomedOutFarEnough);
dom.byId('currentZoom').innerHTML = map.getZoom();
}
function getUrlParams() {
var urlParams = urlUtils.urlToObject(document.location.search).query;
if (urlParams) {
return urlParams;
}
return urlUtils.urlToObject(document.location.hash).query || {};
}
console.debug('almost there...');
var webmapId = webmaps[getUrlParams().basemap] || webmaps.gray;
console.debug('webmapId', webmapId);
arcgisUtils.createMap(webmapId, 'map').then(function(response) {
console.debug('map created');
map = response.map;
minStartingZoom = map.getMaxZoom() - 11;
setZoomBtn = dom.byId('setZoom');
breakMapBtn = dom.byId('breakMap');
warningSpan = dom.byId('warning');
dom.byId('minStartingZoom').innerHTML = minStartingZoom;
onZoomEnd();
map.on('zoom-end', onZoomEnd);
dojoQuery('.webmap-change').on('click', reloadPage);
dojoOn(setZoomBtn, 'click', function() {
map.setZoom(minStartingZoom);
});
dojoOn(breakMapBtn, 'click', function() {
globalDef = map.setScale(map.getMaxScale());
globalDef.then(function() {
console.debug('map setScale done');
}, function() {
console.debug('map setScale FAIL');
});
map.centerAt(redlands).then(function() {
console.debug('centerAt done');
}, function() {
console.debug('centerAt FAIL');
});
});
});
});
</script>
</head>
<body>
<div id="header" class="head-foot">
Demonstrating the breaking of a webmap from a zoomed out state<br>
using the same function calls as the Locate Button.
<div class="webmap-change-wrapper">
<span class="instructions">Change basemap and reload: </span>
<span class="webmap-change" value="gray">gray</span>
<span class="webmap-change" value="dark-gray">dark-gray</span>
<span class="webmap-change" value="oceans">oceans</span>
<span class="webmap-change" value="hybrid">hybrid</span>
<span class="webmap-change" value="national-geographic">national-geographic</span>
<span class="webmap-change" value="topo">topo</span>
<span class="webmap-change" value="streets">Streets</span>
<span class="webmap-change" value="terrain">terrain</span>
<span class="webmap-change" value="osm">osm</span>
</div>
</div>
<div id="map">
<div id="zoom">Current zoom: <span id="currentZoom"></span></div>
<button id="setZoom">Zoom out to level <span id="minStartingZoom">5</span></button>
<button id="breakMap">
Break map by calling<br>
<code>setScale()</code> and <code>centerAt()</code><br>
<span id="warning">(might not break at this starting zoom level)</span>
</button>
</div>
<div id="footer" class="head-foot">testing <code>setScale()</code> and <code>centerAt()</code></div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment