Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

parse cached maps that use Google scheme, but only include a subset of levels #530

Closed
jgravois opened this issue May 11, 2015 · 11 comments · Fixed by #548
Closed

parse cached maps that use Google scheme, but only include a subset of levels #530

jgravois opened this issue May 11, 2015 · 11 comments · Fixed by #548
Assignees

Comments

@jgravois
Copy link
Contributor

currently people are having trouble connecting to cached map services that are missing zoom levels at the smallest scales.

folks like @jonahadkins have created proxies to workaround this issue, but it feels to me like something we can/should be handling internally.

more info: https://geonet.esri.com/message/517527?et=watches.email.thread
and here

@patrickarlt
Copy link
Contributor

I was originally going to just post the disclaimer from the custom projections sample and be done with this. The key here is "default scales and resolutions".

This demo should be implemented at your own risk. Esri Leaflet only supports tiles that have been published in Web Mercator Auxiliary Sphere tiling scheme (WKID 102100/3857) at the default scales and resolutions. Strong knowledge of projections, spatial references and tiling schemes is required for this.

But it really started to bug me because I thought I might be able to make this work. It looks like https://gist.github.com/croxton/6248586 might be able to help us with this.

L.CRS.CustomZoom = L.extend({}, L.CRS.EPSG3857, {
    scale: function (zoom) {
        // return the corresponding scale value for a given zoom level
    }
});

var map = new L.Map('map', {
    crs: L.CRS.CustomZoom // use it in our map
});

We would have to think carefully about the API and make sure it doesn't break anything but I think it makes sense for L.esri.TiledMapLayer to handle this if it can. I am a little worried about dynamically changing the CRS of the map based on which tiles are being displayed.

@jonahadkins
Copy link

and @cbupp colaborated on another library with with @JasonSanford to create a reuseable library for this sort of thing... maybe you can utilize that project

@cbupp
Copy link

cbupp commented May 11, 2015

Yup, here's a link to that repo: https://github.com/JasonSanford/tileify-ags (it specifically handles the case of tileifying a non-tiled image service...which would still be cool, but outside the scope of this specifc issue)

@patrickarlt
Copy link
Contributor

My main worry about doing this is we would have to modify the maps CRS on the fly. Consider this.

  var map = L.map('map').setView([37.75, -122.23], 10);

  // since this needs to asynchronously setup the maps `options.crs` property to support
  // the zoom level of the map service
  L.esri.tiledMapLayer(someServiceWithOddZoomLevels).addTo(map);

  // this is still using regular web mercator at default scales and it will get really weird
  // when our tiled map layer kicks in and changes the scales on the map on the fly. 
  L.polygon(...).addTo(map);

This could cause all sorts of unforeseen problems. Also consider the case where you have lots of these kinds of tile layers and people are toggling them on and off. This could quickly get messy. I need to experiment with changing the CRS on the fly and see what kind of problems it introduces.


On the flip side I would consider writing a helper like this...

L.esri.Util.createCrs(someServiceWithOddZoomLevels, function(error, crs) {
  var map = L.map('map', {crs: crs}).setView([37.75, -122.23], 10);

  L.esri.tiledMapLayer(someServiceWithOddZoomLevels).addTo(map);
});

This approach maximizes reducing conflicts with other code but forces you to wrap your map initialization in a callback which also sucks and wont work out of the box.

@jgravois
Copy link
Contributor Author

i was hopeful we'd be able to leave the map CRS alone and just intercept requests for tiles and introspect/modify the Z level in the URL based on an initial metadata query (to confirm a scale level match), but that was probably just wishful thinking...

@patrickarlt
Copy link
Contributor

@jgravois thats not actually a terrible idea. It looks like it works great. http://jsbin.com/daxexotaja/3/edit

So now here is my question. Will users expect it to work this way? Will they expect to be able to mix tile services at different scales? Will they expect to be able to mix different projections too? Why are my zoom level numbers different between my service and Leaflet?

Anyway here is how I imagine this working.

  1. L.esri.TiledMapLayer extends L.TileLayer delaying its onAdd behavior until the metadata request goes through.
  2. We also override getTileUrl() (https://github.com/Leaflet/Leaflet/blob/v0.7.3/src/layer/tile/TileLayer.js#L464-L471) to return the proper zoom level for the service from the zoom level of the map.using code from https://github.com/gisinc/arcgis-level-fixer/blob/master/src/ZoomLevelFixer.js
  3. If the service is not published in web mercator we just and push a console warning and pass through normally

@cbupp @JasonSanford @jonahadkins do think this is the right approach? I would really like to not modify the map CRS on the fly but remapping zoom levels client side would make it work.

@jgravois
Copy link
Contributor Author

i logged this issue specifically for the use case where a customer has utilized web mercator and google's standard scales, but skipped publishing tiles at world scale. on older versions of ArcGIS Server this has the effect of assigning an incorrect tile index of 0 to the first scale level published.

everything will most likely go to hell if they did anything else so we'll need console warnings and explicit doc in the website to define realistic expectations.

edit:
rereading your last message i can see that your questions were hypothetical, so my apologies if i ended up beating a dead horse.

@patrickarlt
Copy link
Contributor

@jgravois could you find a whole bunch of tile services that are mercator but published at non-standard scales? I can try to tackle this.

@cbupp
Copy link

cbupp commented May 12, 2015

@patrickarlt heres one I used when testing ALF:

http://gismaps.vita.virginia.gov/arcgis/rest/services/MostRecentImagery/MostRecentImagery_WGS/MapServer

Also, to your question earlier: That's how I imagined it could get baked in. And I agree, if it's not web mercator, you just post a console warning.

@patrickarlt patrickarlt self-assigned this May 13, 2015
@patrickarlt
Copy link
Contributor

Ok I'm assigning myself to this. It does suck that we will have make an additional metadata request to figure this out I think its better then a cryptic and unrecoverable failure.

@jonahadkins
Copy link

fwiw: background on what started this for us - openstreetmap/iD#2313

Thanks 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants