Leaflet part 3 - NieneB/webmapping_for_developers GitHub Wiki

Changing the projection

In this step we will change the map projection and add some Dutch reference maps.

Publieke Dienstverlening Op de Kaart (PDOK) (or Public Service on the Map) is a Dutch government initiative to provide a wide range of geographic web services. Many of these services provide data sets that are available under an open license. Typically, you would use a desktop GIS application or the OpenLayers JavaScript library to use these services. This is the where the Open Geospatial Consortium (OGC) standards for geographic web services were first implemented. Nevertheless, there are a number of ways you can just as well use Leaflet to consume these geographic web services for your online mapping application and leverage the potential of the wealth of data available from PDOK.

There is one caveat: maps from Google, Bing, OpenStreetMap come in the Web Mercator projection, whereas for the Netherlands the projection used is Rijksdriehoekstelsel (RD) or Amersfoort New. Each spatial reference system is identified by a code. The code for Web Mercator is EPSG:3857. The code for Amersfoort New is EPSG:28992. A third spatial reference system to keep in mind is WGS-84, the coordinates used by GPS systems that are recorded in longitude and latitude, identified by the code EPSG:4326.

The geographic web services from PDOK come in the Amersfoort RDNew projection by default, whereas Leaflet expects map tiles in the Web Mercator projection. Furthermore, the zoom levels for the Dutch tiling scheme are at different map scales.

rdnew

So lets change our Leaflet map projection to RDNew! We need some extra plugins to do the heavy lifting for us, Proj4js and Proj4Leaflet:

<script src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.5.0/proj4.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/proj4leaflet/1.0.2/proj4leaflet.js"></script>

▶️ Add the plugins of these 2 libraries to your html document:

<body>
    <h1>Example</h1>
    <div id="map"></div>
    <script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet-hash/0.2.1/leaflet-hash.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.5.0/proj4.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/proj4leaflet/1.0.2/proj4leaflet.js"></script>
    <script>
            //...
    </script>
</body>

Now, we can define the projection and the Dutch tiling scheme in our own code.

▶️ Add the following code to your script:

let RDnew = new L.Proj.CRS( 'EPSG:28992','+proj=sterea +lat_0=52.15616055555555 +lon_0=5.38763888888889 +k=0.9999079 +x_0=155000 +y_0=463000 +ellps=bessel +units=m +towgs84=565.2369,50.0087,465.658,-0.406857330322398,0.350732676542563,-1.8703473836068,4.0812 +no_defs',
    {
        resolutions: [3440.640, 1720.320, 860.160, 430.080, 215.040, 107.520, 53.760, 26.880, 13.440, 6.720, 3.360, 1.680, 0.840, 0.420, 0.210],
        bounds: L.bounds([-285401.92, 22598.08], [595401.9199999999, 903401.9199999999]),
        origin: [-285401.92, 22598.08]
    }
);

ℹ️ With let RDnew = L.Proj.CRS we make a variable with a new Coordinate Reference System.

ℹ️ The string we give is the official definition of the Rijksdriehoekstelsel. See also the official documentation on EPSG

ℹ️ at resolutions are the scales per zoom level. (Which are different then the webmercator scales and zoom levels!! ) so we define 15 zoom levels here. For a comparison between Webmercator and RDNew zoom levels and scales you can have a look here

Now we only have to tell our map to use the custom defined Coordinate reference system.

▶️ Add the option of the CRS to your map object and point it to the RDnew object we made.

let map = L.map('map', {
    crs: RDnew,
    zoom: 12, //Zoom scale RD new
    center: [51.9741, 5.6688] //webmercator coördinates
});

‼️ The map will use the zoom levels of the RDnew projection but the coordinates of the center are still in WGS84. Leaflet will solve this automagically.

Now we are ready to use a background map of PDOK, instead of the Open Street Map background. We're all set to add the reference map BRT Achtergrondkaart from PDOK using the TMS protocol.

▶️ Remove the OSM background map we used before.

▶️ Add the BRT background map to your map.

let pdokachtergrondkaart = new L.TileLayer('http://geodata.nationaalgeoregister.nl/tms/1.0.0/brtachtergrondkaart/{z}/{x}/{y}.png', {
    minZoom: 0,
    maxZoom: 13,
    tms: true,
    attribution: 'Map data: <a href="http://www.kadaster.nl">Kadaster</a>'
});

pdokachtergrondkaart.addTo(map);

▶️ Adjust the zoom level to match with your chosen view again.

PDOK provides a few styles of the map:

  • grijs
  • kleur
  • pastel
  • water

See the PDOK for the available TMS tile urls.

‼️ Did you see that your markers, circle and polygon are still on the right location? Even though you gave the coordinates in WGS84 system. Leaflet transforms these coordinates on the fly! How awesome is that?!

What is a TMS?

The tiles PDOK provide are are TMS. A Tile Map Service is NOT a OGC standard. But a OSGEO community standard. Like the XYZ scheme (from google and osm) it is widely used on the web. The difference between XYZ and a TMS is the origin. For a XYZ scheme it is top left, for the TMS it is bottom left. Therefore the y-axes has to be flipped. Leaflet solves this with our tms: true property.

TMS - Tile map service. Our tiled services.

A TMS does not support the geodata information behind the tiles. (a WMTS does! See next paragraph)

The TMS protocol fills a gap between the very simple standard used by OpenStreetMap and the complexity of the Web Map Service standard, providing simple urls to tiles while also supporting alternate spatial referencing system.

OGC - WMS, WMTS and WFS services

Showing large amounts of geo data on the web requires some tricks. Actually the raster tiles, XYZ and TMS, are one of these tricks. A lot of geo data is converted into an png image and transferred over the web. Keep in mind it is only an image and the objects properties are lost. We can see it is a house, a tree or a road. Because we can interpret the colors and meanings. But the computer does not know what it shows.

The geo domain also has developed some good standards to transfer geo data over the web. This is the where the Open Geospatial Consortium (OGC) standards for geographic web services were first implemented. They offer services to supply maps as image on the web but also services to request feature data behind the map. The problem is these service work good in GIS software, but it is not always as convenience to use on the web. There is a big wall between those two domains. Recent years a lot more standards have been added by the OGC which are much more web compliant.

muur

For now have a look at the following standards, which are mainly used in the GIS domain.

WMS, short for 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. It request one image from the servers given a specific bounding box. Can be slow when requesting too large areas. Does not need caching on the server side.

Possible requests:

  • GetCapabilities
  • GetMap
  • GetFeatureInfo
  • GetLegendGraphic
  • DescribeLayer

WMTS - Web map tile service. Same principle as a WMS but now pre-rendered tiles are prepared. So rendering is done before hand and not on the fly. Takes more storage (cache) on the server side.

Possible requests:

  • GetCapabilities
  • GetTile
  • GetFeatureInfo
  • GetLegendGraphic

WFS - Web Feature Service. To request the actual geographic features as vectors for requesting, manipulation and analyzing.

Possible requests:

  • GetCapabilities
  • GetFeature
  • DescribeFeatureType

Data comes back as an GML or JSON for example.

Adding a WMS from CBS

PDOK publishes also the CBS (centraal bureau voor statestiek) data as WMS and WFS services. Have a look at https://www.pdok.nl/geo-services/-/article/cbs-wijken-en-buurten .

When a WMS is published it comes with a 'GetCapabilities' document, which describes which data layers and styles are available in the service.

▶️ Have a look at the CBS Neighborhoods WMS data from 2018:

https://geodata.nationaalgeoregister.nl/wijkenbuurten2018/wms?&request=GetCapabilities&service=WMS

There are 3 layers available:

  • cbs_buurten_2018 the neighborhoods
  • cbs_wijken_2018 the districts
  • gemeenten2018 the municipalities

Per LAYER there are multiple styles available giving you the CBS statistical data!

▶️ Find the dataset that is of interest to you!

▶️ Now add this WMS layer to your map. Replace the styles parameter with the style layer you want to add:

// ADD a WMS layer
let cbs = L.tileLayer.wms('https://geodata.nationaalgeoregister.nl/wijkenbuurten2018/wms', {
        'layers': 'cbs_buurten_2018',
        'styles': 'wijkenbuurten2018:wijkenbuurten_thema_buurten_gemeentewijkbuurt_percentage_eenpersoonshuishoudens',
        'srs': 'EPSG:28992',
        'format': 'image/png',
        'transparent': true,
         'opacity': 0.5
    }).addTo(map);

On PDOK.nl and nationaalgeoregister.nl we can find many more WMS and WFS services!

Until now we only put images on our map, as tiles and as WMS image. Let's see how to add more complicated vector data with GeoJSON and a WFS service in Leaflet part 4

➡️ To Leaflet part 4.

⚠️ **GitHub.com Fallback** ⚠️