1
votes

We have a custom OSM-like tile source which we serve as both a WMTS and WMS service using Mapproxy and showcase in an Openlayers viewer.

We add a layer switcher control to flick between the 2 layers and they display fine except for a small 1-pixel offset. After playing around to try and make up for the offset using the "precompose" event and setting the "event.frameState.pixelRatio" of the WMS layer, I see that the offset is different at certain zoom levels.

For example, at zooms 3 and 6 we have to apply a (0,-1) offset and for zooms 7, 10, 11 etc. we have to apply a (0,1) offset to the WMS layer to match the WMTS layer.

I'm guess some rounding error is involved which is unavoidable with WMS calls? Or can this 1-pixel offset issue be resolved?

In QGIS, when I bring in both layers, they appear toalign perfectly.

1

1 Answers

1
votes

As an experiment you might want to see how layers constructed from basic XYZ sources with custom tile urls behave with each of your sources. I don't have the details of your layers but for the WMTS you would use the tileUrlFunction coordinate[0] to index the matrix id, with [1] and [2] giving the column and row. For WMS the parameters in the url would probably be fixed apart from the BBOX which can be calculated from the tileUrlFunction coordinate. Here are examples of WMTS and WMS sources implemented in that way:

source1: new ol.source.XYZ({
             attributions: [attribIGN],
             tileGrid: new ol.tilegrid.TileGrid({ resolutions: resolutions,
                                                  origin: origin, tileSize: tileSize }),
             tileUrlFunction: function(coordinate) {
                 return "https://wxs.ign.fr/" + keyIGN +
                        "/geoportail/wmts?layer=GEOGRAPHICALGRIDSYSTEMS.MAPS" +
                        "&style=normal&tilematrixset=PM&Service=WMTS&Request=GetTile&Version=1.0.0" +
                        "&Format=image%2Fjpeg&TileMatrix=" + ignMatrixIds[coordinate[0]] +
                        "&TileCol=" + coordinate[1] + "&TileRow=" + (-(coordinate[2]+1));
             },
         }),

source2: new ol.source.XYZ({
             attributions: [attribOSM],
             tileGrid: new ol.tilegrid.TileGrid({ resolutions: resolutions,
                                                  origin: origin, tileSize: tileSize }),
             tileUrlFunction: function(coordinate) {
                 return "http://129.206.228.72/cached/osm?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&FORMAT=image%2Fpng" +
                        "&TRANSPARENT=true&LAYERS=osm_auto%3Aall&WIDTH=256&HEIGHT=256&SRS=EPSG%3A900913&STYLES=&BBOX=" +
                        this.getTileGrid().getTileCoordExtent(coordinate).toString();
             },
         }),