0
votes

I am trying to show a WMTS layer, on an existing Open Street Map layer, using Open Layers. The WMTS layer is loaded, but it is in the wrong position (and the scale is off too).

I started with the official example, and adapted it to show the new WMTS, but I cannot get it to load correctly. The way I understand it there should be several sets of images for different coordinate systems, and the matrixSet switches between these. In the GetCapabilities xml the epsg:4326 is listed (and if I don't provide it, it does not load at all), so it should be available. My original OSM map should also be epsg:4326. I do not understand why the maps are not matching up and I would really appreciate your help!

This is my code thus far:

<div id="map" class="map" style="height: 500px; width:100%"></div>
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.4.3/build/ol.js">
<script type="text/javascript">

var projection = ol.proj.get('EPSG:4326');
var projectionExtent = projection.getExtent();
var size = ol.extent.getWidth(projectionExtent) / 256;
var resolutions = new Array(14);
var matrixIds = new Array(14);
for (var z = 0; z < 14; ++z) 
{
  // generate resolutions and matrixIds arrays for this WMTS
  resolutions[z] = size / Math.pow(2, z);
  matrixIds[z] = z;
}

var map = new ol.Map(
{
    projection: 'EPSG:4326',
    target: 'map',
    layers: [
        new ol.layer.Tile(
        {
            source: new ol.source.OSM(),
        }),
        new ol.layer.Tile(
        {
            opacity: 0.7,
            source: new ol.source.WMTS(
            {
                url:
                  'https://service.pdok.nl/hwh/luchtfotorgb/wmts/v1_0', //?&request=GetTile&service=wmts
                layer: 'Actueel_ortho25',
                matrixSet: 'EPSG:4326',
                format: 'image/png',
                projection: 'EPSG:4326',
                tileGrid: new ol.tilegrid.WMTS(
                {
                    origin: ol.extent.getTopLeft(projectionExtent),
                    resolutions: resolutions,
                    matrixIds: matrixIds,
                }),
                style: 'default',
                wrapX: true,
            }),
        })
    ],
    view: new ol.View(
    {
        center: ol.proj.fromLonLat([5, 52]),
        zoom: 4
    })
});
</script>
1

1 Answers

1
votes

If you check the capabilities https://service.pdok.nl/hwh/luchtfotorgb/wmts/v1_0?&request=GetCapabilities you can see the EPSG:4326 matrix does not start at the top left of the global EPSG:4326 projection (which would be at 90, -180)

<TopLeftCorner>53.637608 3.013754</TopLeftCorner>

so it is using a custom tile grid. The easiest solution is to let OpenLayers parse the capabilities and set up the required options

<meta charset="UTF-8">
<html>
<head>
    <title>OSM test</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.5.0/css/ol.css" type="text/css">
    <script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.5.0/build/ol.js"></script>
<style>
  html, body, .map {
  margin: 0;
  padding: 0;
  width: 100%;
  height: 100%;
}
</style>
</head>
<body>
<div id="map" class="map""></div>
<script type="text/javascript">

fetch('https://service.pdok.nl/hwh/luchtfotorgb/wmts/v1_0?&request=GetCapabilities')
  .then(function (response) {
    return response.text();
  })
  .then(function (text) {
    var result =  new ol.format.WMTSCapabilities().read(text);
    var options = ol.source.WMTS.optionsFromCapabilities(result, {
      layer: 'Actueel_ortho25',
      matrixSet: 'EPSG:4326',

    });

    options.wrapX = true;
    var map = new ol.Map(
    {
      projection: 'EPSG:4326',
      target: 'map',
      layers: [
        new ol.layer.Tile(
        {
            source: new ol.source.OSM(),
        }),
        new ol.layer.Tile(
        {
            opacity: 0.7,
            source: new ol.source.WMTS(options),
        })
      ],
      view: new ol.View(
      {
        center: ol.proj.fromLonLat([5, 52]),
        zoom: 4
      })
    });

  });

</script>
</body>
</html>