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

Fix tutorials #7014

Merged
merged 3 commits into from
Mar 11, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Update WMS tutorial using Mundialis WMS (#4239)
  • Loading branch information
vncntcltt committed Mar 7, 2020
commit 8e8d648c5126c814d447964ebba0b7badc2965f7
Binary file modified docs/examples/wms/qgis-wms-layers.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions docs/examples/wms/wms-example-crs.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ title: WMS example
crs: L.CRS.EPSG4326
});

var wmsLayer = L.tileLayer.wms('https://demo.boundlessgeo.com/geoserver/ows?', {
layers: 'nasa:bluemarble'
var wmsLayer = L.tileLayer.wms('http://ows.mundialis.de/services/service?', {
layers: 'TOPO-OSM-WMS'
}).addTo(map);


Expand Down
4 changes: 2 additions & 2 deletions docs/examples/wms/wms-example1.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ title: WMS example
zoom: 3
});

var wmsLayer = L.tileLayer.wms('https://demo.boundlessgeo.com/geoserver/ows?', {
layers: 'ne:ne'
var wmsLayer = L.tileLayer.wms('http://ows.mundialis.de/services/service?', {
layers: 'TOPO-OSM-WMS'
}).addTo(map);

</script>
4 changes: 2 additions & 2 deletions docs/examples/wms/wms-example2.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ title: WMS example
zoom: 3
});

var wmsLayer = L.tileLayer.wms('https://demo.boundlessgeo.com/geoserver/ows?', {
layers: 'nasa:bluemarble'
var wmsLayer = L.tileLayer.wms('http://ows.mundialis.de/services/service?', {
layers: 'SRTM30-Colored-Hillshade'
}).addTo(map);

</script>
18 changes: 9 additions & 9 deletions docs/examples/wms/wms-example3.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,25 @@ title: WMS example
});

var basemaps = {
Countries: L.tileLayer.wms('https://demo.boundlessgeo.com/geoserver/ows?', {
layers: 'ne:ne_10m_admin_0_countries'
Topography: L.tileLayer.wms('http://ows.mundialis.de/services/service?', {
layers: 'TOPO-WMS'
}),

Boundaries: L.tileLayer.wms('https://demo.boundlessgeo.com/geoserver/ows?', {
layers: 'ne:ne_10m_admin_0_boundary_lines_land'
Places: L.tileLayer.wms('http://ows.mundialis.de/services/service?', {
layers: 'OSM-Overlay-WMS'
}),

'Countries, then boundaries': L.tileLayer.wms('https://demo.boundlessgeo.com/geoserver/ows?', {
layers: 'ne:ne_10m_admin_0_countries,ne:ne_10m_admin_0_boundary_lines_land'
'Topography, then places': L.tileLayer.wms('http://ows.mundialis.de/services/service?', {
layers: 'TOPO-WMS,OSM-Overlay-WMS'
}),

'Boundaries, then countries': L.tileLayer.wms('https://demo.boundlessgeo.com/geoserver/ows?', {
layers: 'ne:ne_10m_admin_0_boundary_lines_land,ne:ne_10m_admin_0_countries'
'Places, then topography': L.tileLayer.wms('http://ows.mundialis.de/services/service?', {
layers: 'OSM-Overlay-WMS,TOPO-WMS'
})
};

L.control.layers(basemaps, {}, {collapsed: false}).addTo(map);

basemaps.Countries.addTo(map);
basemaps.Topography.addTo(map);

</script>
29 changes: 0 additions & 29 deletions docs/examples/wms/wms-example4.md

This file was deleted.

75 changes: 35 additions & 40 deletions docs/examples/wms/wms.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,85 +14,88 @@ iframe {

WMS, short for [*web map service*](https://en.wikipedia.org/wiki/Web_Map_Service), is a popular way of publishing maps by professional GIS software (and seldomly used by non-GISers). This format is similar to map tiles, but more generic and not so well optimized for use in web maps. A WMS image is defined by the coordinates of its corners - a calculation that Leaflet does under the hood.

TMS stands for *tiled map service*, and is a map tiling standard more focused on web maps, very similar to the map tiles that Leaflet expects in a `L.TileLayer`.
TMS stands for [*tiled map service*](https://en.wikipedia.org/wiki/Tile_Map_Service), and is a map tiling standard more focused on web maps, very similar to the map tiles that Leaflet expects in a `L.TileLayer`.

WTMS, for [*web map tile service*](https://en.wikipedia.org/wiki/Web_Map_Tile_Service), is the standard protocol for map tiles and serves map tiles directly usable in a `L.TileLayer`.


## WMS in Leaflet

When somebody publishes a WMS service, most likely they link to something called a `GetCapabilities` document. For this tutorial, we'll use the demo map services from GeoServer, at https://demo.boundlessgeo.com/geoserver/web/. As you can see in that page, "WMS" links to the following URL:
When somebody publishes a WMS service, most likely they link to something called a `GetCapabilities` document. For this tutorial, we'll use the WMS offered by [*Mundialis*](https://www.mundialis.de) at http://ows.mundialis.de/services/service? . The service capabilities are described at the following URL:

https://demo.boundlessgeo.com/geoserver/ows?service=wms&version=1.3.0&request=GetCapabilities
http://ows.mundialis.de/services/service?request=GetCapabilities

Leaflet does not understand WMS `GetCapabilities` documents. Instead, you have to create a `L.TileLayer.WMS` layer, provide the base WMS URL, and specify whatever WMS options you need.

The base WMS URL is simply the `GetCapabilities` URL, without any parameters, like so:

https://demo.boundlessgeo.com/geoserver/ows?
http://ows.mundialis.de/services/service?

And the way to use that in a Leaflet map is simply:

var map = L.map(mapDiv, mapOptions);

var wmsLayer = L.tileLayer.wms('https://demo.boundlessgeo.com/geoserver/ows?', wmsOptions).addTo(map);
var wmsLayer = L.tileLayer.wms('http://ows.mundialis.de/services/service?', wmsOptions).addTo(map);

An instance of `L.TileLayer.WMS` needs at least one option: `layers`. Be careful, as the concept of "layer" in Leaflet is different from the concept of "layer" in WMS!

WMS servers define a set of *layers* in the service. These are defined in the `GetCapabilities` XML document, which most times is tedious and difficult to understand. Usually it's a good idea to use software such as [QGIS to see what layers are available in a WMS server](http://www.qgistutorials.com/en/docs/working_with_wms.html) to see the layer names available:

![Discovering WMS layers with QGIS](qgis-wms-layers.png)

We can see that the OpenGeo demo WMS has a WMS layer named `ne:ne` with a basemap. Let's see how it looks:
We can see that the *Mundialis* WMS has a WMS layer named `TOPO-OSM-WMS` with a basemap. Let's see how it looks:

var wmsLayer = L.tileLayer.wms('https://demo.boundlessgeo.com/geoserver/ows?', {
layers: 'ne:ne'
var wmsLayer = L.tileLayer.wms('http://ows.mundialis.de/services/service?', {
layers: 'TOPO-OSM-WMS'
}).addTo(map);

{% include frame.html url="wms-example1.html" %}


Or we can try the `nasa:bluemarble` WMS layer:
Or we can try the `SRTM30-Colored-Hillshade` WMS layer:

var wmsLayer = L.tileLayer.wms('https://demo.boundlessgeo.com/geoserver/ows?', {
layers: 'nasa:bluemarble'
var wmsLayer = L.tileLayer.wms('http://ows.mundialis.de/services/service?', {
layers: 'SRTM30-Colored-Hillshade'
}).addTo(map);

{% include frame.html url="wms-example2.html" %}


The `layers` option is a comma-separated list of layers. If a WMS service has defined several layers, then a request for a map image can refer to more than one layer.

For the example WMS server we're using, there is a `ne:ne_10m_admin_0_countries` WMS layer showing country landmasses and country names, and a `ne:ne_10m_admin_0_boundary_lines_land` WMS layer showing country boundaries. The WMS server will compose both layers in one image if we request both, separated with a comma:
For the example WMS server we're using, there is a `TOPO-WMS` WMS layer showing the world topography, and a `OSM-Overlay-WMS` WMS layer showing the names of places. The WMS server will compose both layers in one image if we request both, separated with a comma:

var countriesAndBoundaries = L.tileLayer.wms('https://demo.boundlessgeo.com/geoserver/ows?', {
layers: 'ne:ne_10m_admin_0_countries,ne:ne_10m_admin_0_boundary_lines_land'
var topographyAndPlaces = L.tileLayer.wms('http://ows.mundialis.de/services/service?', {
layers: 'TOPO-WMS,OSM-Overlay-WMS'
}).addTo(map);

Note this will request *one* image to the WMS server. This is different than creating a `L.TileLayer.WMS` for the countries, another one for the boundaries, and adding them both to the map. In the first case, there is one image request and it's the WMS server who decides how to compose (put on top of each other) the image. In the second case, there would be two image requests and it's the Leaflet code running in the web browser who decides how to compose them.
Note this will request *one* image to the WMS server. This is different than creating a `L.TileLayer.WMS` for the topography, another one for the places, and adding them both to the map. In the first case, there is one image request and it's the WMS server who decides how to compose (put on top of each other) the image. In the second case, there would be two image requests and it's the Leaflet code running in the web browser who decides how to compose them.

If we combine this with the [layers control](/examples/layers-control.html), then we can build a simple map to see the difference:

var basemaps = {
Countries: L.tileLayer.wms('https://demo.boundlessgeo.com/geoserver/ows?', {
layers: 'ne:ne_10m_admin_0_countries'
Topography: L.tileLayer.wms('http://ows.mundialis.de/services/service?', {
layers: 'TOPO-WMS'
}),

Boundaries: L.tileLayer.wms('https://demo.boundlessgeo.com/geoserver/ows?', {
layers: 'ne:ne_10m_admin_0_boundary_lines_land'
Places: L.tileLayer.wms('http://ows.mundialis.de/services/service?', {
layers: 'OSM-Overlay-WMS'
}),

'Countries, then boundaries': L.tileLayer.wms('https://demo.boundlessgeo.com/geoserver/ows?', {
layers: 'ne:ne_10m_admin_0_countries,ne:ne_10m_admin_0_boundary_lines_land'
'Topography, then places': L.tileLayer.wms('http://ows.mundialis.de/services/service?', {
layers: 'TOPO-WMS,OSM-Overlay-WMS'
}),

'Boundaries, then countries': L.tileLayer.wms('https://demo.boundlessgeo.com/geoserver/ows?', {
layers: 'ne:ne_10m_admin_0_boundary_lines_land,ne:ne_10m_admin_0_countries'
'Places, then topography': L.tileLayer.wms('http://ows.mundialis.de/services/service?', {
layers: 'OSM-Overlay-WMS,TOPO-WMS'
})
};

L.control.layers(basemaps).addTo(map);

basemaps.Countries.addTo(map);
basemaps.Topography.addTo(map);

Change to the "Countries, then boundaries" option, so you can see the boundaries "on top" of the landmasses, but the WMS server is clever enough to display building labels on top of that. It's up to the WMS server how to compose layers when asked for many.
Change to the "Topography, then places" option, so you can see the places "on top" of the topography, but the WMS server is clever enough to display building labels on top of that. It's up to the WMS server how to compose layers when asked for many.

{% include frame.html url="wms-example3.html" %}

Expand All @@ -109,8 +112,8 @@ Also note that Leaflet supports very few [coordinate systems](https://en.wikiped
crs: L.CRS.EPSG4326
});

var wmsLayer = L.tileLayer.wms('https://demo.boundlessgeo.com/geoserver/ows?', {
layers: 'nasa:bluemarble'
var wmsLayer = L.tileLayer.wms('http://ows.mundialis.de/services/service?', {
layers: 'TOPO-OSM-WMS'
}).addTo(map);

{% include frame.html url="wms-example-crs.html" %}
Expand All @@ -120,33 +123,25 @@ Also note that Leaflet supports very few [coordinate systems](https://en.wikiped

Leaflet doesn't have explicit support for TMS services, but the tile naming structure is so similar to the common `L.TileLayer` naming scheme, that displaying a TMS service is almost trivial.

Using the same OpenGeo WMS/TMS server demo, we can see there's a TMS endpoint at:
Let's consider a TMS server with the following endpoint:

https://demo.boundlessgeo.com/geoserver/gwc/service/tms/1.0.0
http://base_url/tms/1.0.0

Checking the [MapCache help about TMS](http://mapserver.org/mapcache/services.html) and the [TMS specification](https://wiki.osgeo.org/wiki/Tile_Map_Service_Specification) you can see that the URL for a map tile in TMS looks like:

http://base_url/tms/1.0.0/ {tileset} / {z} / {x} / {y} .png

To use the OpenGeo TMS services as a `L.TileLayer`, we can check the capabilities document (the same as the base endpoint, in our case [`https://demo.boundlessgeo.com/geoserver/gwc/service/tms/1.0.0`](https://demo.boundlessgeo.com/geoserver/gwc/service/tms/1.0.0)) to see what `tileset`s are available, and build our base URLs:
To use the TMS services as a `L.TileLayer`, we can check the capabilities document (the same as the base endpoint, in our case [`http://base_url/tms/1.0.0`](http://base_url/tms/1.0.0)) to see what `tileset`s are available, and build our base URLs:

https://demo.boundlessgeo.com/geoserver/gwc/service/tms/1.0.0/ne:ne@EPSG:900913@png/{z}/{x}/{y}.png

https://demo.boundlessgeo.com/geoserver/gwc/service/tms/1.0.0/nasa:bluemarble@EPSG:900913@jpg/{z}/{x}/{y}.jpg
http://base_url/tms/1.0.0/{example_layer}@png/{z}/{x}/{y}.png


And use the `tms:true` option when instantiating the layers, like so:

var tms_ne = L.tileLayer('https://demo.boundlessgeo.com/geoserver/gwc/service/tms/1.0.0/ne:ne@EPSG:900913@png/{z}/{x}/{y}.png', {
var tms_example = L.tileLayer('http://base_url/tms/1.0.0/example_layer@png/{z}/{x}/{y}.png', {
tms: true
}).addTo(map);

var tms_bluemarble = L.tileLayer('https://demo.boundlessgeo.com/geoserver/gwc/service/tms/1.0.0/nasa:bluemarble@EPSG:900913@jpg/{z}/{x}/{y}.jpg', {
tms: true
});

{% include frame.html url="wms-example4.html" %}


A new feature in **Leaflet 1.0** is the ability to use `{-y}` in the URL instead of a `tms: true` option, e.g.:

Expand Down