0

I made a webgis that manages WMS layers in different projections with OpenLayers 4 and proj4js. Sometimes (e.g. for historical maps) the overlay is not perfectly aligned with baselayer and a need a function that can move the WMS layer a bit in map units or pixels, so the user can align the area of interest and pick coordinates from map.

I found this answer:

How to move WMS layers independently using OpenLayers 3 (with GeoServer)

But I can't apply in my case because I don't manage the server and the layer is not a vector origin.

How does OpenLayers draw the map in the canvas?

I'd expect there's some point in the code in which I could add a delta-x and delta-y to the layer image that has been retrieved from WMS.

Any suggestions and links to doc?

As suggested by @TomazicM here is my code (simplified, I have more than one layer for each group)

var projUTM32 = 'EPSG:25832';
proj4.defs(projUTM32, '+proj=utm +zone=32 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs');

var projExtent = ol.proj.get('EPSG:3857').getExtent();
var startResolution = ol.extent.getWidth(projExtent) / 256;
var resolutions = new Array(25);
for (var i = 0, ii = resolutions.length; i < ii; ++i) {
    resolutions[i] = startResolution / Math.pow(2, i);
}

var tileGrid = new ol.tilegrid.TileGrid({
    extent: projExtent,
    resolutions: resolutions,
    tileSize: [1024, 1024]
});

// background layer example
var tileserverOSM = "https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png";
var lyr_OpenStreetMap_1 = new ol.layer.Tile({
    source: new ol.source.OSM(({
        url: tileserverOSM,
        attributions: [new ol.Attribution({html: '<a href="http://www.openstreetmap.org" target="_blank">&copy Openstreetmap Contributors</a>'})],
        projection: proj3857,
    })),
    title: "OpenStreetMap",
    opacity: 1.000000,
    maxResolution: 600

});

// overlay layer example
var mywmslayer = new ol.layer.Tile({
    source: new ol.source.TileWMS(({
        url: "https://wms.myserver.wms/",
        attributions: [new ol.Attribution({html: '<a href="https://wms.myserver.wms/credits.html" target="_blank">Credits</a>'})],
        projection: projUTM32,
        reprojectionErrorThreshold: 3,
        params: {
            "LAYERS": "Layer1",
            "TILED": "false",
            "VERSION": "1.3.0"},
        tileGrid: tileGrid,
    })),
    title: "WMS overlay",
    opacity: 0.700000,
    maxResolution: 5,
    minResolution: 0
});

mywmslayer.setVisible(true);

var layersBackground = [lyr_OpenStreetMap_1];
var layersOverlay = [mywmslayer];

// create group with all background layers
grpBackground = new ol.layer.Group({
    'title': 'Background',
    'fold': 'open',
    layers: layersBackground
});

// create group with all overlay layers
grpOverlay = new ol.layer.Group({
    'title': 'Overlay',
    'fold': 'closed',
    layers: layersOverlay
});


var container = document.getElementById('popup');
var content = document.getElementById('popup-content');
var closer = document.getElementById('popup-closer');

closePopup = function () {
    container.style.display = 'none';
    closer.blur();
    return false;
};
closer.addEventListener('click', function (event) {
    closePopup();
})

var overlayPopup = new ol.Overlay({
    element: container
});

var map = new ol.Map({
    controls: ol.control.defaults({attribution: false}).extend([
        expandedAttribution, new measureControl(), new geolocateControl()
    ]),

target: document.getElementById('map'),
renderer: 'canvas',
overlays: [overlayPopup],
layers: [grpBackground, grpOverlay],
view: new ol.View({
    projection: 'EPSG:25832',
    maxZoom: 22, minZoom: 4,
    center: center,
    zoom: zoom,
    rotation: rotation,
    moveTolerance: 10

})
});
3
  • Coding question on GIS SE site should include relevant existing code in the body of the question, otherwise it's most likely to be closed as not compliant with the site policy. Please edit your question and add relevant existing code.
    – TomazicM
    Apr 7, 2022 at 13:02
  • 1
    To offset in projection units you could use a custom image (or tile) load function and offset the bbox in the request url, e.g. offset by 100km codesandbox.io/s/wms-image-forked-4g57jf?file=/main.js To offset in pixels you could wrap the source in ol.source.Raster and offset the ImageData (which needs CORS access), e.g. offset by 10 pixels codesandbox.io/s/wms-image-forked-moi1gb?file=/main.js
    – Mike
    Apr 7, 2022 at 16:21
  • Thank-you @Mike offset in projection units will be fine, I'll give it a try (I've already used a custom tile function in the past as a workaround to slow response, you see the placeholder in my code). The offset should be adjusted by the user clicking on a 4-sided arrow buttons: not sure if reload the tile layer at every click will be feasible.
    – amefad
    Apr 12, 2022 at 15:36

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.