Leaflet / Leaflet

πŸƒ JavaScript library for mobile-friendly interactive maps πŸ‡ΊπŸ‡¦
https://leafletjs.com
BSD 2-Clause "Simplified" License
40.28k stars 5.76k forks source link

EPSG 4326 Support Broken for TileLayers #1207

Closed jasonbeverage closed 10 years ago

jasonbeverage commented 11 years ago

Map's created with crs: L.CRS.EPSG4326 appear to be broken. http://jsfiddle.net/hueBa/3/ shows the issue. The map only displays the western hemisphere of the earth and the marker is incorrectly positioned.

EPSG4326 L.TileLayer.WMS layers seem to work fine though.

jasonbeverage commented 11 years ago

The issue appears to be with the _getWrapTileNum function not taking into account that EPSG 4326 tile layers have 2x1 tiles at their root level instead of being a standard quadtree. I see there is a //TODO comment in that function so perhaps this is a known issue.

The marker positioning has a similar issue, the L.CRS.scale function needs to take into account the 2x1 tiling scheme as well.

Would it make sense for L.CRS to have a numWide and a numHigh setting that describes the root tiling scheme of the map?

DrYSG commented 11 years ago

Is also a problem with the display of polylines in EPSG 4326? I came across this JSfiddle and to my way of seeing this, there seems to be an issue: http://jsfiddle.net/EkP8j/9/

DrYSG commented 11 years ago

I have been looking at this with Jason, and I think I have some useful information for the developers:

Leaflet says it supports EPSG 4326 (Plate Carree, aka ll84) projections. I think it does, but take a look at these two jsfiddles:

http://jsfiddle.net/drysg/cBzVc/ - This is the original 3857 web Mercator. As you can see the overlay of both the tiles and the red outline are properly placed near Kraknow. (click the mouse on the map and you get the lat/long as a popup).

Ok, now look at:

http://jsfiddle.net/drysg/XPP54/ - This is in EPSG 4326 (ll84).

The background is a MapCarta ll84 slippy tiles. It seems that leaflet does not know about the 2x1 aspect ratio that OSG wants. That is why the background wraps (http://wiki.osgeo.org/wiki/Tile_Map_Service_Specification#global-geodetic) Well, if they want to support that fine. I am actually happier with with a 1x1 map (I can generate that with SAFE FME). So ignore that for a while.

Switch the background to the CloudMade OSM map (ingore that the origin is at 85N, so that the map is 5 degrees shifted to the south).

Now everything looks correct, to me.

The only thing I need now is to figure out the formula for the SLIPPY tile numbering. The web page at http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames

Describes how to do this for Web Mercator.

What would the formula be for LL84, where the map bounds are not (-85, -180; 85, 180) but rather (-90, -180; 90, 180)

rburhum commented 11 years ago

I think @jasonbeverage 's problem is related to the fact that in the MetaCarta TMS, at zoom level 0, there are two 256x256 px images instead of one. In OpenLayers, you have to set the maxResolution property to 0.703125 to make the zoom levels work properly.

This comes from:

  360.0 (the entire world) / 512px (*two* images - not one - of 256px represent the entire world) = 0.703125

You can see this in the OpenLayers TMS example http://openlayers.org/dev/examples/tms.html.

Perhaps there is a way to do the equivalent in Leaflet that would solve this issue?

jasonbeverage commented 11 years ago

Yup, that's exactly my issue. Leaflet is assuming a 1x1 tile at the root instead of two. On Feb 24, 2013 3:07 PM, "Ragi Yaser Burhum" notifications@github.com wrote:

I think @jasonbeverage https://github.com/jasonbeverage 's problem is related to the fact that in the MetaCarta TMS, at zoom level 0, there are two 256x256 px images instead of one. In OpenLayers, you have to set the maxResolution property to 0.703125 to make the zoom levels work properly.

This comes from:

360.0 (the entire world) / 512px (two images - not one - of 256px represent the entire world) = 0.703125

You can see this in the OpenLayers TMS example http://openlayers.org/dev/examples/tms.html.

Perhaps there is a way to do the equivalent in Leaflet that would solve this issue?

β€” Reply to this email directly or view it on GitHubhttps://github.com/Leaflet/Leaflet/issues/1207#issuecomment-14014901.

rburhum commented 11 years ago

@jasonbeverage I googled and found this http://www.makina-corpus.org/blog/leaflet-tiles-lambert-93-projection-2154 and http://blog.thematicmapping.org/2012/07/using-custom-projections-with-tilecache.html which give a technique to create custom resolutions with custom tile sizes. Perhaps you could try this technique out and report back?

DrYSG commented 11 years ago

Well, I happen to find that what Leaflet does now - works fine for me. So if you do change leaflet, I would like you to keep the current EPSG4326 tiling scheme as an option.

I am using SAFE FME to create the tiles. SAFE supports all 4 of the OGC GlobalCRS84 tiling schemes (see: Web Map Tiling Service Implementation Standard http://www.opengeospatial.org/standards/wmts ) appendix E.

I find that if I use GlobalCRS84Quad I get something that I can directly use in the current implementation of Leaflet. All I have to do is bias the Y coordinate of the TMS tile with real_row = tile_row + Pow(2, zoomLevel -2);

So could you keep this format of tiling since it seems to be very close to OGC GlobalCRS84Quad. (or directly support GlobalCRS84Quad)?

rburhum commented 11 years ago

In my case, retiling is not an option (too many systems/clients already relying on the current tiling scheme). I wanted to try out Leaflet as a replacement for OL which does the job fine, but doesn't have the nice looking plugins/transitions that Leaflet has. I'll probably try out the custom tiling scheme when I get some spare cycles.

mourner commented 10 years ago

Thanks for the useful comments guys and sorry for such a delay with the response. I'm moving the issue to 0.7 where I plan to rewrite projections architecture a bit, trying a bit different approach that should make customizing things like that much easier. I could hack around the current projection implementation but projections are confusing for me and there are so many possible options and issues so for the risk of not breaking anything that works alrady, I feel I need to have a fresh start on that.

pfctdayelise commented 10 years ago

leaflet-tilelayer4326bug Hm, I think this bug is the cause of this problem? (the lat-lon in the popup is approximately Hobart) It's a shame CloudMade doesn't support WMS... no way to use overlays of ESPG:4326 data with CloudMade. :(

DrYSG commented 10 years ago

Any estimate when this gets into the main branch? 0.8-dev build? I have a bug report in with the MiniMap Plug-in

https://github.com/Norkart/Leaflet-MiniMap/issues/48

and a demo on CodePen which shows the problem:

http://codepen.io/DrYSG/pen/ICzro

@DrYSG

mourner commented 10 years ago

@DrYSG today-tomorrow, see #2247

jasonbeverage commented 10 years ago

Thanks Vladimir, looking forward to checking this out. On Dec 2, 2013 1:07 PM, "Vladimir Agafonkin" notifications@github.com wrote:

Closed #1207 https://github.com/Leaflet/Leaflet/issues/1207 via 00166b9https://github.com/Leaflet/Leaflet/commit/00166b9c4f053e3fbbdd7f7531fba078a14e4fcf .

β€” Reply to this email directly or view it on GitHubhttps://github.com/Leaflet/Leaflet/issues/1207 .

DrYSG commented 10 years ago

I just grabbed the latest version of Leaflet (0.8-dev) with the fixes for EPSG4326, but I am still having some issue at zoom level 1 (and not at the others). I am assuming it is my problem, but I can't figure this out.

In the demo at: http://codepen.io/DrYSG/pen/ICzro you can see the issue.

The actual tiles are stored at: https://drive.google.com/folderview?id=0B2Ay-nw1QSW2VXV3VVJ1U2pMWnM&usp=sharing

You will see that that I am properly doubling resolution at each zoom level, but I think it is a tile naming issue:

LEVEL 0: Works fine

One tile named 0-0-0.jpg

LEVEL 1: This seems to be off by 90 degrees latitude, but correct for longitude

Two tiles: 1-0-0.jpg, 1-1-0.jpg

Level 2: works file

Eight tiles: 2-0-1.jpg, 2-1-1.jpg, 2-2-1.jpg, 2-3-1.jpg 2-0-2.jpg, 2-1-2.jpg, 2-2-2.jpg, 2-3-2.jpg

@DrYSG

mourner commented 10 years ago

@DrYSG it seems that your EPSG4326 tile source has 1x1 in the root, while Leaflet assues 2x1 for this projection. You'll have to redefine some CRS properties to make that work.

DrYSG commented 10 years ago

Since levels 2, 3, etc. are working fine. I am assuming that it is 0 and 1 that I have to fix (not hard with SAFE FME). But can you tell me what the tiling at zoom (1) is? (and what the indexes should be for the two tiles at level 0, and N tiles at level 1?

Zoom level 0: 2x1 Zoom level 1: ?x? Zoom level 2: 4x2 ranges from 0,1 - 3,2 Zoom level 3: 8x4 (it is interesting that this goes from 0,2 - 7,5 Zoom level 4: 16x8 ranges from 0,4 - 15,11

mourner commented 10 years ago

No, they're not working fine β€” I see broken tiles around the working ones...

mourner commented 10 years ago

@DrYSG try this crs option:

L.extend({}, L.CRS.EPSG4326, {transformation: new L.Transformation(1 / 180, 1, -1 / 180, 0.5)})
DrYSG commented 10 years ago

I do have the latest version of leaflet so it already defines things as:

L.CRS.EPSG4326 = L.extend({}, L.CRS, { code: 'EPSG:4326',

projection: L.Projection.LonLat,
transformation: new L.Transformation(1 / 180, 1, -1 / 180, 0.5),

wrapLng: [-180, 180]

});

But it is interesting to me that levels 3,4,5,6,7 all play correctly with vectors, lat/long references, etc. I was under the impression that the broken tiles outside were not really important, since everything else lines up perfectly..

SAFE is saying that they are using the scaling according to OGC Annex E:

he four tiling schemes available in the WebMapTiler conform to the Open Ge= ospatial Consortium's Web Map Tiling Service Implementation Standard, which= can be found at this url:

"http://portal.opengeospatial.org/files/?artifact_id=3D35326"

Please see the scale sets in Annex E.

Is there no way in Leaflet to set up your TileLayer to conform to one of th= ese scale sets?

Kind regards, Dave Campanas www.safe.com/support

They created this help file user of SAFE FME, about tiling schemes:

http://fmepedia.safe.com/articles/FAQ/Which-Web-Map-Tiling-Scheme-Should-I-Use

mourner commented 10 years ago

@DrYSG oh, yeah mistake, I meant new L.Transformation(1 / 360, 0.5, -1 / 360, 0.5) (the one that was before)

mourner commented 10 years ago

I don't have access to that OGC portal.

DrYSG commented 10 years ago

I found a another link to the OGC document,

http://portal.opengeospatial.org/files/?artifact_id=35326

But the SAFE page is easier to read:

http://fmepedia.safe.com/articles/FAQ/Which-Web-Map-Tiling-Scheme-Should-I-Use

DrYSG commented 10 years ago

My bug. But this has been a very useful thread for me. Thank you so much for your expert help. I plan to have a new demo of this with the root at 2x1 on Monday (should show the map insert working also).

BTW, while I like the 2x1 root (it makes things much cleaner at top). I did see in the that OGC document ( ) that they do say that GoogleCRS84QUAD is supposed to be 1x1 at level 0. (Now don't get me started about OGC, they been at their workshops and and my meetings with them have not left me with good impressions, so I am not a fan of theirs, and I could say much more).

Here is what they say in their document:

GoogleCRS84Quad (urn:ogc:def:wkss:OGC:1.0:GoogleCRS84Quad) This well-known scale set has been defined to allow quadtree pyramids in CRS84. Level 0 allows representing the whole world in a single 256x256 pixels (where the first 64 and last 64 lines of the tile are left blank). The next level represents the whole world in 2x2 tiles of 256x256 pixels and so on in powers of 2. Scale denominator is only accurate near the equator.

DrYSG commented 10 years ago

Updated Demo of EPSG 4326 CRS, with 2x1 root tiling is now up at:

http://codepen.io/DrYSG/pen/ICzro

MiniMap works fine also

davidchouse commented 10 years ago

I am still seeing issues as well. Am I doing something wrong? Simple example: var map = L.map('map', { crs : L.CRS.EPSG4326, center: [0, 0], zoom: 1 });

L.tileLayer('http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer/tile/{z}/{y}/{x}.png', {
    tileSize:512
}).addTo(map);

Map does not show at zoom 0, and is only trying to pull one tile at zoom 1. Here is zoom level 1 request:

screen shot 2014-02-03 at 10 30 26 am

davidchouse commented 10 years ago

Previous post solved. It was due to the 512 tile size issue here: https://github.com/Leaflet/Leaflet/issues/2417 Used "scale" solution and it works.

rburhum commented 9 years ago

I tested this for another project and it worked fine. Thank you!

However, is this going to be released soon?

scottlepp commented 8 years ago

@davidchouse can you provide a snippet of how you used scale?

DrYSG commented 8 years ago

@scottlepp - I no longer have any issues with 4326.

scottlepp commented 8 years ago

I'm on 0.7.x. It appears the scale function should work on 0.7.x? Trying @davidchouse example here: http://plnkr.co/edit/rGH91y?p=preview

DrYSG commented 8 years ago

@scottlepp and @davidchouse I am using 0.8 with no problems.

NaderCHASER commented 8 years ago

@scottlepp You're missing a { in your URL for {x}.

http://plnkr.co/edit/ZRJZv5zRM7OkXmfkLBh2?p=preview

scottlepp commented 8 years ago

It's working on 0.7.x with a custom crs (based on what leaflet 1.0 is doing): http://plnkr.co/edit/rGH91y?p=preview

orangeagain commented 2 years ago

I got this offset, X axis is correct, Y axis is wrong, anyone know how to fix it? (x line is expected) ζ— ζ ‡ι’˜ My code:

 var myCrs = L.extend({}, L.CRS.EPSG4326, {
          transformation: new L.Transformation(1 / 360, 0.5, -1 / 360, 0.5),
          }
        );
        var map = L.map('mapid', {
          crs: myCrs,
          zoomControl: false,
          attributionControl: false,
          zoomSnap: 0.25,
          maxBoundsViscosity: 1.0,
        })
       googlemap = 'http://172.23.163.76:8082/maps/vt?lyrs=s&gl=cn&x={x}&y={y}&z={z}&time=1602824597685&scale=2'
       var googleTerrain = L.tileLayer(googlemap, {})
Falke-Design commented 2 years ago

@orangeagain I don't know if this is changing something but have you tried to change the values of transformation: new L.Transformation(1 / 360, 0.5, -1 / 360, 0.5),?