I have an ESRI map that I initialize with a given extent. When I draw the map with its initial extent, the extent of what is actually displayed is cut off by about 5-10%, so some features on my FeatureLayers lie outside the initial view. It seems like the map is trying to form a "best fit" zoom level to match the requested extent to the map size, but in this case, the best fit leaves the top and bottom of the view cropped off.
I created a demo to show this behavior:
const map = new EsriMap({
basemap: 'topo',
});
const extent = {
spatialReference: {
latestWkid: 3857,
wkid: 102100,
},
xmin: -8418477.75984,
ymin: 5691645.413467902,
xmax: -8413622.645963104,
ymax: 5694628.596517603,
};
const mapView = new EsriMapView({
container: document.querySelector('#viewDiv'),
extent,
map,
});
const geometry = new EsriPolygon({
rings: [
[extent.xmax, extent.ymax],
[extent.xmax, extent.ymin],
[extent.xmin, extent.ymin],
[extent.xmin, extent.ymax],
[extent.xmax, extent.ymax],
],
spatialReference: extent.spatialReference,
});
const symbol = {
type: 'simple-line',
color: [255, 0, 0],
width: 2,
};
const graphic = new EsriGraphic({
geometry,
symbol,
});
mapView.graphics.add(graphic);
See live at https://codepen.io/asgallant/pen/rrWmLW. The red box is the requested extent. If you change the height of the map's container, the map changes its initial zoom level at certain break points.
I would like to configure the map to always choose a default zoom level that fully encapsulates the requested extent, so no features are cut off. I know I can just set the zoom level to whatever I want, but I have hundreds of different maps, requiring different zoom levels to achieve the stated goal. Does anyone know how to accomplish this?
You can use when
callback to check if map's extent contains your required extent. If your expected extent is outside map's extent's boundary you just zoom-out.
You can check your posted example working here.
mapView.when(function(){
if(!mapView.extent)
return;
const ext = new EsriExtent(extent);
while(mapView.zoom > 0 && !mapView.extent.contains(ext)) {
mapView.zoom -= 0.5;
}
});