constrain zoom levels for some basemaps OR cancel map zoom

1287
7
Jump to solution
12-07-2016 04:57 PM
SebastianRoberts
Occasional Contributor III

I've added some aerial basemaps with the basemap widget that don't have the same default LODs as the default basemap.  Some have fewer zoom levels, and some require additional zoom levels.  Is there an easy way to constrain/add zoom levels if a certain basemap is turned on with the basemap widget?  

If not, I've been able to add an LOD to the map before it gets created, then use a zoom event handler to zoom back to the previous level if the user has a certain basemap turned on and attempts to zooms out of the range for that basemap. However, this creates an odd zoom in/ zoom out user experience. What I'd rather do is cancel the zoom event in this case.  I could listen for zoom-start, but I can't find a way to cancel the map zoom.  Does anyone know how to do this in the javascript API?

0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Esteemed Contributor

Sebastian,

   Well there is not a real good way to do this then. Here is something you could try though:

What I am doing is if the basemap is National Geographic and the user zooms in beyond 16 then I display a busy indicator and snap back to level 16 then hide the indicator.

    require([
     "esri/dijit/util/busyIndicator",
...
     busyUtil,
...
      bi = busyUtil.create({
        target: "map",
        fadeDuration: 500
      });

      basemapGallery.on("selection-change", function(evt){
        if(evt.target._selectedBasemap.title === "National Geographic"){
          var zoomEndEvt = on.pausable(map, "zoom-end", function(event){
            if (event.level > 16){
              zoomEndEvt.pause();
              bi.show();
              map.setLevel(16).then(function(){
                bi.hide();
                zoomEndEvt.resume();
              });
            }
          });
        }

View solution in original post

0 Kudos
7 Replies
RobertScheitlin__GISP
MVP Esteemed Contributor

Have you considered updating the maps LODs by added and removing LODs based on the selected basemap?


There is no way to just cancel the zoom event (many people have wanted to and tried).

SebastianRoberts
Occasional Contributor III

I have, but I didn't think it was possible.  I know you can set LODs in the Map constructor, but I don't see a method call or a property that I can update on the Map class after it is created.  Is there a way to do that?

0 Kudos
RobertScheitlin__GISP
MVP Esteemed Contributor

Sebastian,

   I have not done much testing but you can access the maps lods at runtime using 

map.__tileInfo.lods
0 Kudos
SebastianRoberts
Occasional Contributor III

Robert,

  Thanks for the suggestion.  I tried adding the additional LOD to the array, but it does not seem to update the map.  The zoom tools, double click, and the mouse wheel do not allow me to zoom in the extra level.  Perhaps I'm just stuck with the quick zoom in/ zoom out user experience.

if(this.basemapGallery.getSelected().title === 'West County 2016'){
  this.map.__tileInfo.lods.push({"level":10,"resolution":0.14929107082380833,"scale":564.248587});
}
0 Kudos
RobertScheitlin__GISP
MVP Esteemed Contributor

Sebastain,

   If it is just adding LODs then you can do this in the WAB UI on the map tab you can add additional LODs. The way I have mine is after a certain scale the esri basemap turns off (based on minScale) and then my basemap (orthos) cuts on (maxScale)

0 Kudos
SebastianRoberts
Occasional Contributor III

Robert,

  Thanks.  I'd like to avoid adding an LOD to the overall web map.  All my other basemaps stop at 1:1,128 and wouldn't benefit from another LOD. The higher res image is only for part of the county, so I wanted to allow zooming to the 1:564 LOD only if a user deliberately chooses the higher res image so they are less likely to be confused by a blank map outside of the high res footprint.

0 Kudos
RobertScheitlin__GISP
MVP Esteemed Contributor

Sebastian,

   Well there is not a real good way to do this then. Here is something you could try though:

What I am doing is if the basemap is National Geographic and the user zooms in beyond 16 then I display a busy indicator and snap back to level 16 then hide the indicator.

    require([
     "esri/dijit/util/busyIndicator",
...
     busyUtil,
...
      bi = busyUtil.create({
        target: "map",
        fadeDuration: 500
      });

      basemapGallery.on("selection-change", function(evt){
        if(evt.target._selectedBasemap.title === "National Geographic"){
          var zoomEndEvt = on.pausable(map, "zoom-end", function(event){
            if (event.level > 16){
              zoomEndEvt.pause();
              bi.show();
              map.setLevel(16).then(function(){
                bi.hide();
                zoomEndEvt.resume();
              });
            }
          });
        }

View solution in original post

0 Kudos