Leaflet basemap issue

2816
3
Jump to solution
01-03-2018 07:01 AM
Labels (1)
AllenScully
Occasional Contributor III

I'm helping a colleague with a small leaflet application.  We are running into trouble when trying to add our own basemap service using the 'L.tiledMapLayer' method.  I suspect the issue is with our map service, but we use this service successfully in several custom javascript applications, as well as other ESRI and GeoCortex applications.  

When using an ESRI basemap URL, it seems to work fine:

 

L.esri.tiledMapLayer({
 url: "http://services.arcgisonline.com/arcgis/rest/services/World_Topo_Map/MapServer"
}).addTo(map);

 

However swapping out the ESRI URL for our own (non-secured and publicly accessible) tiled service, the basemap does not render, and the dev tools show a bunch of 404 Not found errors for the tiles.

 

L.esri.tiledMapLayer({
url: "https://maps2.tucsonaz.gov/arcgis/rest/services/BaseMaps/gisBaseMap_Topo/MapServer"
}).addTo(map);

 

Wondering if this is setting within our service, so that as currently configured it won't work with Leaflet?

 

Thanks - 

Allen

Tags (2)
1 Solution

Accepted Solutions
JohnGravois
Frequent Contributor

there were a few different things going on causing problems.

1. your own service doesn't support making CORS requests. thats okay, but its necessary for you to pass through `useCors: false` in your own constructor

2. even though your service advertises itself as wkid: 3857, its actually using a custom XY for its origin, which is problematic when the internal API attempts to translate the global LODs the service is missing.

3. there was a bug in esri-leaflet that led to us attempting to override custom LODs provided in code when we recognized the coordinate system as web mercator. (i fixed that here and published v2.1.2).

all that said, in our latest release, we display the service correctly, but its still up to you to describe the custom projection in your own code.

var crs = new L.Proj.CRS("EPSG:3857","+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs", {
 origin: [-20037700, 30241100], // your origin is custom
 resolutions: [
 611.4962262813797, // you are missing some smaller scale LODS as well
 305.74811314055756,
 152.87405657041106, // ...
 ]
});
var map = L.map('map', {
 crs: crs
}).setView([32.2217, -110.926], 2);

L.esri.tiledMapLayer({
 url: 'https://maps2.tucsonaz.gov/arcgis/rest/services/BaseMaps/gisBaseMap_Topo/MapServer',
 useCors: false
}).addTo(map);‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

live sample: http://jsbin.com/yovezox/edit?html,output 

(based on the sample in our documentation here)

View solution in original post

3 Replies
JohnGravois
Frequent Contributor

there were a few different things going on causing problems.

1. your own service doesn't support making CORS requests. thats okay, but its necessary for you to pass through `useCors: false` in your own constructor

2. even though your service advertises itself as wkid: 3857, its actually using a custom XY for its origin, which is problematic when the internal API attempts to translate the global LODs the service is missing.

3. there was a bug in esri-leaflet that led to us attempting to override custom LODs provided in code when we recognized the coordinate system as web mercator. (i fixed that here and published v2.1.2).

all that said, in our latest release, we display the service correctly, but its still up to you to describe the custom projection in your own code.

var crs = new L.Proj.CRS("EPSG:3857","+proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs", {
 origin: [-20037700, 30241100], // your origin is custom
 resolutions: [
 611.4962262813797, // you are missing some smaller scale LODS as well
 305.74811314055756,
 152.87405657041106, // ...
 ]
});
var map = L.map('map', {
 crs: crs
}).setView([32.2217, -110.926], 2);

L.esri.tiledMapLayer({
 url: 'https://maps2.tucsonaz.gov/arcgis/rest/services/BaseMaps/gisBaseMap_Topo/MapServer',
 useCors: false
}).addTo(map);‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

live sample: http://jsbin.com/yovezox/edit?html,output 

(based on the sample in our documentation here)

AllenScully
Occasional Contributor III

John - Many thanks for looking in to this and the detailed response.  This works well, and has helped us understand some implications of our basemap-building decisions.  

So just to clarify - the source data used to build our basemap is in our local State Plane system but we make the data frame Web Mercator (without re-projecting the individual feature classes) in order to make it more friendly in web applications.   This is what creates the need for the extra coding within leaflet, correct?

Allen

0 Kudos
JohnGravois
Frequent Contributor

my pleasure. to answer your follow up question, no. i'd expect the workflow you describe above to result in a published service CRS that is identical to Google/Bing/ArcGIS Online.

https://services.arcgisonline.com/arcgis/rest/services/World_Topo_Map/MapServer

0 Kudos