Using Custom Basemaps with Default Zoom Widget

639
11
03-26-2019 07:31 AM
BenRomlein
Occasional Contributor

I'm using a TileLayer to create a Basemap for my JavaScript 4.10 app:

var streetsTile = new TileLayer({ url: "https://myserver/arcgis/rest/.../MapServer", });

var streetsBase = new Basemap({ baseLayers: [streetsTile] });

var map = new Map({
   basemap: streetsBase
});

var view = new MapView({
   container: 'mapView',
   map: map,
});

With this code, the default zoom widget doesn't work to zoom in at the outermost scale. After I zoom in once (with mouse wheel or double click) I can zoom in or out using the widget. If I zoom back to the outermost scale, I have to zoom in once with another method before the widget will work again. Using Esri basemaps, the widget functions normally, so the problem is related to my basemap.

What is causing this behavior? How can I correct it so the widget will work at all zoom levels?

I've tried creating a TileInfo and using its lods as a constraints for my view:

var myInfo = TileInfo.create({
   origin: new Point({
      spatialReference: streetsTile.spatialReference,
      x: -5120900.0,
      y: 9998100.0

      }),
   spatialReference: streetsTile.spatialReference,
   scales: [2500000, 1000000, 500000, 250000, 125000, 64000, 32000, 16000, 8000, 4000, 2000, 1000]
});

var view = new MapView({
   container: 'mapView',
   map: map,
   constraints: {
      lods: myInfo.lods
   }
});

But this does not resolve the problem. If I remove the scales property from my TileInfo and use the default scales, the widget will work but I don't want that many scales in my app.

How can I make the zoom widget work with my basemap while still limiting the scales to only the levels I have cached?

0 Kudos
11 Replies
BenRomlein
Occasional Contributor

Anyone else have this problem or can reproduce?

0 Kudos
RobertScheitlin__GISP
MVP Esteemed Contributor

Ben,

   This is how I specify my custom base maps lods:

  var lods = [{
    "level": 0,
    "resolution": 0.43402777777777773,
    "scale": 500
  }, {
    "level": 1,
    "resolution": 0.8680555555555555,
    "scale": 1000
  }, {
    "level": 2,
    "resolution": 1.736111111111111,
    "scale": 2000
  }, {
    "level": 3,
    "resolution": 3.472222222222222,
    "scale": 4000
  }, {
    "level": 4,
    "resolution": 5.208333333333333,
    "scale": 6000
  }, {
    "level": 5,
    "resolution": 6.944444444444444,
    "scale": 8000
  }, {
    "level": 6,
    "resolution": 8.680555555555555,
    "scale": 10000
  }, {
    "level": 7,
    "resolution": 13.020833333333332,
    "scale": 15000
  }, {
    "level": 8,
    "resolution": 26.041666666666664,
    "scale": 30000
  }, {
    "level": 9,
    "resolution": 30.381944444444443,
    "scale": 35000
  }, {
    "level": 10,
    "resolution": 34.72222222222222,
    "scale": 40000
  }, {
    "level": 11,
    "resolution": 52.08333333333333,
    "scale": 60000
  }, {
    "level": 12,
    "resolution": 69.44444444444444,
    "scale": 80000
  }, {
    "level": 13,
    "resolution": 104.16666666666666,
    "scale": 120000
  }, {
    "level": 14,
    "resolution": 138.88888888888889,
    "scale": 160000
  }, {
    "level": 15,
    "resolution": 173.61111111111111,
    "scale": 200000
  }, {
    "level": 16,
    "resolution": 217.01388888888889,
    "scale": 250000
  }, {
    "level": 17,
    "resolution": 260.41666666666663,
    "scale": 300000
  }];

  map = new Map({});
  view = new MapView({
    map: map,
    container: "mapContainer",
    zoom: 1,
    center: new Point({
      x: 654661.637354886,
      y: 1187279.83575856,
      spatialReference: {
        wkid: 102629
      }
    }),
    constraints: {
      lods: lods
    }
  });
0 Kudos
BenRomlein
Occasional Contributor

Thanks, Robert. Implementing this code gives me the same issue--the Zoom widget doesn't work when the view is zoomed to the outermost scale. Is there something else I'm missing?

var lods = [{
"level": 11,
"resolution": 0.26458386250105836,
"scale": 1000
}, {
"level": 10,
"resolution": 0.5291677250021167,
"scale": 2000
}, {
"level": 9,
"resolution": 1.0583354500042335,
"scale": 4000
}, {
"level": 8,
"resolution": 2.116670900008467,
"scale": 8000
}, {
"level": 7,
"resolution": 4.233341800016934,
"scale": 16000
}, {
"level": 6,
"resolution": 8.466683600033868,
"scale": 32000
}, {
"level": 5,
"resolution": 16.933367200067735,
"scale": 64000
}, {
"level": 4,
"resolution": 33.0729828126323,
"scale": 125000
}, {
"level": 3,
"resolution": 66.1459656252646,
"scale": 250000
}, {
"level": 2,
"resolution": 132.2919312505292,
"scale": 500000
}, {
"level": 1,
"resolution": 264.5838625010584,
"scale": 1000000
}, {
"level": 0,
"resolution": 661.4596562526459,
"scale": 2500000
}];

var view = new MapView({
container: 'mapView',
map: map,
zoom: 0,
center: new Point({
x: centerX,
y: centerY,
spatialReference: {
wkid: mySpatialReferenceID
}
}),

constraints: {
lods: lods
}
});

0 Kudos
RobertScheitlin__GISP
MVP Esteemed Contributor

Ben,

  Must be something else you are doing. I have no problem with the default zoom widget in 4.x using a custom base map and specifying my LODs.

0 Kudos
BenRomlein
Occasional Contributor

Hey Robert,

Thanks for the advice. I'm at a total loss as to why this isn't working. Here's the entire code from my example:

require([ "esri/Map", "esri/views/MapView", "esri/layers/TileLayer", "esri/Basemap", "esri/geometry/Point", "esri/config" ], function(Map, MapView, TileLayer, Basemap, Point, esriConfig){ esriConfig.request.proxyUrl = "../proxy/proxy.ashx"; var lods = [{ "level": 11, "resolution": 0.26458386250105836, "scale": 1000 }, { "level": 10, "resolution": 0.5291677250021167, "scale": 2000 }, { "level": 9, "resolution": 1.0583354500042335, "scale": 4000 }, { "level": 8, "resolution": 2.116670900008467, "scale": 8000 }, { "level": 7, "resolution": 4.233341800016934, "scale": 16000 }, { "level": 6, "resolution": 8.466683600033868, "scale": 32000 }, { "level": 5, "resolution": 16.933367200067735, "scale": 64000 }, { "level": 4, "resolution": 33.0729828126323, "scale": 125000 }, { "level": 3, "resolution": 66.1459656252646, "scale": 250000 }, { "level": 2, "resolution": 132.2919312505292, "scale": 500000 }, { "level": 1, "resolution": 264.5838625010584, "scale": 1000000 }, { "level": 0, "resolution": 661.4596562526459, "scale": 2500000 }]; var streetsTile = new TileLayer({ url: "https://myserver/arcgis/rest/services/Basemaps/Streets/Mapserver" }); var streetsBase = new Basemap({ baseLayers: [streetsTile] }); var map = new Map({ basemap: streetsBase }); var view = new MapView({ container: 'mapView', map: map, zoom: 0, center: new Point({ x: 560624.2184404366, y: 4418006.635128269, spatialReference: { wkid: 26916 } }), constraints: { lods: lods } }); });

I'm really not doing anything else besides creating a Basemap from a tile layer and passing that to Map as the basemap for my map. Is there anything you can see that would explain why the Zoom Widget would behave so strangely with my map?

The rest of the app is boilerplate--

html:

<!DOCTYPE html>
<html>
<head>
<title>Map View Test</title>
<link rel="stylesheet" href="https://js.arcgis.com/4.11/esri/themes/light/main.css">
<link rel="stylesheet" href="viewer.css">
<script src="https://js.arcgis.com/4.11/"></script>
</head>
<body>
<div id="mapView"></div>
<script src="viewer.js"></script>
</body>
</html>

css:

html, body, #mapView {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}

Thanks again for your help.

0 Kudos
RobertScheitlin__GISP
MVP Esteemed Contributor

Ben,

   Those LODs are some of the Exact scale and resolution value that your data is cached at (i.e when you go to the mapservices Rest endpoint in the browser it lists the maps Levels of Detail)?

Tile Info:

  • Height: 256
  • Width: 256
  • DPI: 96
  • Levels of Detail: 7
    • Level ID: 0 [ Start Tile, End Tile ]
      • Resolution: 8.680555555555555
      • Scale: 10000
    • Level ID: 1 [ Start Tile, End Tile ]
      • Resolution: 6.944444444444444
      • Scale: 8000
    • Level ID: 2 [ Start Tile, End Tile ]
      • Resolution: 5.208333333333333
      • Scale: 6000
0 Kudos
BenRomlein
Occasional Contributor

Yes, I've copied these values from the server:

Tile Info:

  • Height: 512
  • Width: 512
  • DPI: 96
  • Levels of Detail: 12
    • Level ID: 
      • Resolution: 661.4596562526459
      • Scale: 2500000
    • Level ID: 1
      • Resolution: 264.5838625010584
      • Scale: 1000000
    • Level ID: 
      • Resolution: 132.2919312505292
      • Scale: 500000
    • Level ID: 
      • Resolution: 66.1459656252646
      • Scale: 250000
    • Level ID: 4
      • Resolution: 33.0729828126323
      • Scale: 125000
    • Level ID: 5
      • Resolution: 16.933367200067735
      • Scale: 64000
    • Level ID: 6
      • Resolution: 8.466683600033868
      • Scale: 32000
    • Level ID: 
      • Resolution: 4.233341800016934
      • Scale: 16000
    • Level ID: 8
      • Resolution: 2.116670900008467
      • Scale: 8000
    • Level ID: 
      • Resolution: 1.0583354500042335
      • Scale: 4000
    • Level ID: 10 
      • Resolution: 0.5291677250021167
      • Scale: 2000
    • Level ID: 11
      • Resolution: 0.26458386250105836
      • Scale: 1000

Is this proper, or should I be using different values?

0 Kudos
RobertScheitlin__GISP
MVP Esteemed Contributor

Ben,

 Something I am noticing about your code is level 0 you have your largest scale and in my code it is right the opposite.

0 Kudos
RobertScheitlin__GISP
MVP Esteemed Contributor

Ben,

   If you look at my working code level 0 has the smallest scale. So you need to reverse the values you get for the rest endpoint.

0 Kudos