Search code examples
javascriptopenlayersprojectionopenlayers-5

Superpose two maps with different projections?


I am attempting to superpose two different maps, but I am unable to superpose them and I have no idea on how to fix this issue.

    let bottom_left = ol.proj.fromLonLat([5.009752942020352, 45.356001339311526])
    let top_right = ol.proj.fromLonLat([11.484374748007156, 48.387198495867985])

    var projection = ol.proj.get('EPSG:2056');
    var projectionExtent = [bottom_left[0], bottom_left[1], top_right[0], top_right[1]] // projection.getExtent();
    var size = ol.extent.getWidth(projectionExtent) / 1940;
    var resolutions = new Array(14);
    var matrixIds = new Array(14);

    for (var z = 0; z < 14; ++z) {
        resolutions[z] = size / Math.pow(2, z);
        matrixIds[z] = z;
    }

    // Tweak otherwise it does not work...
    resolutions = [8000, 3200, 1600, 640, 320, 160, 80, 64, 48, 32, 16, 8, 4, 2, 1].map(x => x / 21.6 )

    let tilegrid = new ol.tilegrid.WMTS({
        origin: ol.extent.getTopLeft(projectionExtent),
        resolutions: resolutions,
        matrixIds: matrixIds
    })


    var map = new ol.Map({
        target: 'map',
        layers: [
            new ol.layer.Tile({
                source: new ol.source.XYZ({
                extent: projectionExtent,
                url: 'https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png',
                })
            }),
            new ol.layer.Tile({
                opacity: 0.7,
                source: new ol.source.WMTS({
                    url: 'https://sitn.ne.ch/mapproxy95/service',
                    layer: 'plan_cadastral_20180628', // 'plan_ville',
                    matrixSet: 'EPSG2056',
                    format: 'image/png',
                    projection: projection,
                    tileGrid: tilegrid,
                    style: 'default',
                    wrapX: true,
                    crossOrigin: "anonymous"
                })
            })
        ],
        view: new ol.View({
            center: [773332, 5941674],
            zoom: 8,
        })
    });

As you can see the two maps almost superpose, but it seems the whole projection of either the swiss map or the open street map is wrong.

enter image description here


Solution

  • EPSG:2056 must be defined using proj4 for the layer to reproject correctly over the OSM layer. To ensure the WMTS layer was set up correctly I let OpenLayers obtain the options by parsing the WMTS capablities.

      proj4.defs("EPSG:2056","+proj=somerc +lat_0=46.95240555555556 +lon_0=7.439583333333333 +k_0=1 +x_0=2600000 +y_0=1200000 +ellps=bessel +towgs84=674.374,15.056,405.346,0,0,0,0 +units=m +no_defs");
      ol.proj.proj4.register(proj4);
    
      let bottom_left = ol.proj.fromLonLat([5.009752942020352, 45.356001339311526])
      let top_right = ol.proj.fromLonLat([11.484374748007156, 48.387198495867985])
    
      var projectionExtent = [bottom_left[0], bottom_left[1], top_right[0], top_right[1]];
    
      var parser = new ol.format.WMTSCapabilities();
      var map;
    
      fetch('https://sitn.ne.ch/mapproxy95/service/?Service=WMTS&Request=GetCapabilities').then(function(response) {
        return response.text();
      }).then(function(text) {
        var result = parser.read(text);
        var options = ol.source.WMTS.optionsFromCapabilities(result, {
          layer: 'plan_cadastral_20180628', // 'plan_ville',
          matrixSet: 'EPSG2056',
          format: 'image/png',
          style: 'default',
          crossOrigin: 'anonymous'
        });
    
        var map = new ol.Map({
          target: 'map',
          layers: [
            new ol.layer.Tile({
              extent: projectionExtent,
              source: new ol.source.XYZ({
                url: 'https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png',
              })
            }),
            new ol.layer.Tile({
              extent: projectionExtent,
              opacity: 0.7,
              source: new ol.source.WMTS(options)
            })
          ],
          view: new ol.View({
            center: [773332, 5941674],
            zoom: 8,
          })
        });
    
      });
    html, body, .map {
        margin: 0;
        padding: 0;
        width: 100%;
        height: 100%;
    }
    <link href="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/css/ol.css" rel="stylesheet" />
    <script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/build/ol.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.5.0/proj4.js"></script>
    <div id="map" class="map"></div>