0

There are maps on OpenLayers 6 and proj4js that manages WMS layers in different projections. Sometimes (e.g. for plan maps) the overlay is not aligned with base layer and a need a function that can move and rotate the WMS layer, so the user can align the layer.

I found this answers:

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 offset and rotate to the layer image that has been retrieved from WMS.

The solution proposed in the second answer solves only half of the problem (displacement), but the rotation problem remains unresolved...

const source = new ImageWMS({
  url: 'https://ahocevar.com/geoserver/wms',
  params: {LAYERS: 'topp:states'},
  ratio: 1,
  serverType: 'geoserver',
  imageLoadFunction: function (image, src) {
    const offsetX = 100000;
    const offsetY = 100000;
    const url = new URL(src);
    const params = url.searchParams;
    const oldParams = params.toString();
    const bbox = params.get('BBOX').split(',').map(Number);
    bbox[0] -= offsetX;
    bbox[1] += offsetY;
    bbox[2] -= offsetX;
    bbox[3] += offsetY;
    params.set('BBOX', bbox.toString());
    const newParams = params.toString();
    image.getImage().src = src.replace(oldParams, newParams);
  },
});
3
  • This example might help you in the right direction: codesandbox.io/s/reprojection-image-z0uit
    – TomazicM
    Apr 19, 2023 at 8:12
  • Thank you @TomazicM, this is the right recipe to solve the problem!
    – neadmin
    Apr 19, 2023 at 9:20
  • I don't seem to understand how reprojection works, or for global projections, this method requires improvement: codesandbox.io/s/… In any case, I am grateful to you for the example
    – neadmin
    Apr 19, 2023 at 13:43

1 Answer 1

0

For user controlled fine alignment you could translate the layer canvas context before rendering the layer. The important part of the code would look like

wmsLayer.on('prerender', function (event) {
  const resolution =
    event.frameState.pixelRatio * event.frameState.viewState.resolution;
  event.context.save();
  event.context.translate(offsetX / resolution, offsetY / resolution);
});

wmsLayer.on('postrender', function (event) {
  event.context.restore();
});

Example https://codesandbox.io/s/wms-image-forked-71k9nh?file=/main.js

If you need to set an anchor for scaling or rotation that could be done by clicking on the map with a modifier key such alt, control or shift, for example:

map.on('click', function(event){
  if (platformModifierKeyOnly(event)){
    anchor = event.coordinate;
    wmsLayer.changed();
  }
});
8
  • I suppose rotate could also be done this way?
    – TomazicM
    Apr 19, 2023 at 9:38
  • It seems this does not work correctly when you do offset and then zoom in. Something with the extent goes wrong.
    – TomazicM
    Apr 19, 2023 at 9:45
  • You could also scale and rotate, but you would also need to set an anchor coordinate for those, which would need the getRenderPixel method as in openlayers.org/en/latest/examples/layer-swipe.html and take care to do multiple changes in the correct order (e.g. translate to anchor point, scale and rotate, translate back) or have a good understanding of transform matrixes.
    – Mike
    Apr 19, 2023 at 9:56
  • If the zoom in you will be unable to offset beyond what the WMS is serving for the viewport.
    – Mike
    Apr 19, 2023 at 10:05
  • 1
    Yes, if you want to rotate around that point it helps to know it, but there is no guarantee that is where rotation will need to be centered, the correct point might a corner of the image, or anywhere. Here the anchor is initially set at the extent center, but can be changed with Ctrl-click on the map codesandbox.io/s/wms-image-move-rotate-prerender-forked-bx1j21
    – Mike
    Apr 19, 2023 at 14:07

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.