Our application uses Leaflet to display various kinds of maps (TMS, WMS, WMTS, XYZ etc.) as well as GeoJSON objects on the map. The problem is in how we define and use the WMS maps and layers.
We're using a library to convert the XML response of the GetCapabilities
request to a JSON and then we parse with our own implementation the WMS version, BoundingBox, CRS, maxZoom
and minZoom
(from MaxScaleDenominator and MinScaleDenominator) and layer names for the layers that we want to use. that we use when adding the WMS layers for Leaflet. We use Leaflet with the default CRS (EPSG:3857
). However, the BoundingBox for a couple WMS layers don't seem to work as I expect them to work. I have created some simple implementations for describing the issue:
The first test implementation can be found from this github gist. There are two files: leaflet_with_no_bounds.html
and leaflet_with_epsg3857_bounds.html
. With the _no_bounds.html
version the overlays are displayed on the Map as they should, but obviously Leaflet is loading new tiles every time the Map is panned or zoomed on, regardless of where we are panning (because the bounds are not defined for the layers if I'm not wrong?). With the _epsg3857_bounds.html
version I have a couple problems:
- Leaflet doesn't seem to request and render the
Map_With_Not_Working_Bounds
at all, regardless of where I'm panning or zooming at.
Does anyone have any idea why not?
I manually copied and pasted the boundaries from the GetCapabilities
response to the bounds
object when creating and adding the layer to Leaflet
2. Leaflet STILL seems to request and render the Map_With_Working_Bounds
, regardless of where I'm panning or zooming at.
Am I wrong thinking that the bounds are there to let Leaflet know when it actually should request the tiles, and when not?
The second test implementation can be found from this github gist. Here we have three files: leaflet_2_with_no_bounds.html
, leaflet_2_with_epsg4326_bounds.html
and leaflet_2_with_epsg3857_bounds.html
. Problems with these:
- With the
_no_bounds
version Leaflet is requesting the tiles constantly when zooming and panning, but it works very inconsistently. Sometimes the tiles are returned from the service and rendered on the map, and sometimes not (try multiple different zoom levels and toggling the layers on and off). - The
_epsg4326_bounds.html
version works exactly the same (why is that? The Leaflet map is usingEPSG:3857
, notEPSG:4326
, how and why do theEPSG:4326
boundaries work at all?) - The
_epsg_3857_bounds.html
version doesn't seem to request any tiles EVER.
Why could that be?
I've been trying to Google and read through the WMS documentation to resolve these issues and I feel like I can't research this any more on my own, hence I'm asking for help. I've also tried using all these layers in QGIS, and they seem to work better in QGIS, though QGIS seems to always request tiles with EPSG:4326 even though I've set the project and layers to use EPSG:3857, so I can't really tell if that helps much.
EDIT: I edited the Gist test implementations a bit, they were missing the version
definition and crs
as well in some cases (Leaflet uses 1.1.1 by default if not defined)
1 Answer 1
I realized that my knowledge and way of thinking was wrong here, with the help of Ian and my co-worker.
So if I'm not wrong: Leaflet requires the LatLngBounds
to always be in degrees (which EPSG:4326 provides them in) and not meters (which EPSG:3857 provides them in), even if the layer that you're creating uses crs
EPSG:3857. Hence I should always read either the Layer.BoundingBox
with crs
EPSG:4326 from the GetCapabilities
request (because EPSG:4326 provides the layers bounding box in meters), or it's LatLonBoundingBox
(in WMS <1.3.0) or EX_GeographicBoundingBox
(in WMS 1.3.0).
So because of that, my leaflet_2_with_epsg4326_bounds.html
should work, since it's using the EPSG:4326 boundaries. But the reason it's sometimes not rendering all tiles is that the service is actually rate limited. I just got confused because the browser doesn't show the response at all (it just shows "This request has no response data available") because the throttled request's response was in the application/vnd.ogc.se_xml
format, but by using Fiddler I was able to read the XML and it said that I had made requests too frequently. I'll be able to work around it by providing tileSize
which is larger than 256
(which is the default).
-
<EX_GeographicBoundingBox>
in a WMS 1.3.0 GetCapabilities response and<LatLonBoundingBox...
in a WMS 1.1.1 GetCapabilities response have nothing to do with the projection used by the WMS. They just provide a hint to the location of the data. They are always specified in decimal degrees.nmtoken– nmtoken2021年11月25日 16:23:15 +00:00Commented Nov 25, 2021 at 16:23
bounds: new L.LatLngBounds( new L.LatLng(6225638.766865120, 6676690.825125160), new L.LatLng(-7054596.823974940, -2448678.407635810), )
which are clearly not latitude and longitudeLatLonBoundingBox
in the capabilities (at least before you parsed them into JSON)