Displaying georeferenced images using OpenLayers 5

主宰稳场 提交于 2019-12-24 21:25:45

问题


I'm trying to make an application where the user can georeference scanned maps. You can look at an example here: https://codesandbox.io/s/2o99jvrnyy There are two images:

  • assets/test.png - without rotation
  • assets/test_rotation.png - with rotation

The first image is loaded correctly on the map but the one with rotation is not.

I can't find information on whether OpenLayers 5 can handle images with transformation parameters stored in world file. Probably I'm missing something but can't figure out what.

This is how my logic works:

Transformation parameters are calculated with affine transformation using 4 points. You can see the logic in Affine.js file. At least 4 points are picked up from the source image and the map. Then using these 4 points the transformation parameters are calculated. After that I'm calculating the extent of the image:

width = image.width in pixels
height = image.height in pixels
width *= Math.sqrt(Math.pow(parameters.A, 2) + Math.pow(parameters.D, 2));
height *= Math.sqrt(Math.pow(parameters.B, 2) + Math.pow(parameters.E, 2));

// then the extent in projection units is
extent = [parameters.C, parameters.F - height, parameters.C + width, parameters.F];

World file parameters are calculated as defined here.

Probably the problem is that the image with rotation is not rotated when loaded as static image in OpenLayers 5, but can't find a way to do it.

I tried to load both images in QGIS and ArcMap with calculated parameters and both of them are loaded correctly. You can see the result for the second picture:

You can see the parameters for each image here:

Image: test.png
Calculated extent: [436296.79726721847, 4666723.973240128, 439864.3389057907, 4669253.416495154]
Calculated parameters (for world file):
3.8359372067274027
-0.03146800786355865
-0.03350636818089405
-3.820764346376064
436296.79726721847
4669253.416495154

Image: test_rotation.png
Calculated extent: [437178.8291026594, 4667129.767589236, 440486.91675884253, 4669768.939256327]
Calculated parameters (for world file):
3.506332904308879
-1.2831186688536016
-1.3644002712982917
-3.7014921022625864
437178.8291026594
4669768.939256327

回答1:


I realized that my approach was wrong. There is no need to calculate the extent of the image in map projection and set it in the layer. I can simply add a transformation function responsible for transforming coordinates between image projection and map projection. This way the image layer has always it's projection set to image projection and extent set to the size of the image in pixels.

The transformation function is added like this:

import { addCoordinateTransforms } from 'ol/proj.js';

addCoordinateTransforms(
  mapProjection,
  imageProjection,
  coords => {
    // forward
    return Affine.transform(coords);
  },
  coords => {
    // inverse
  }
)

Affine parameters are again calculated from at least 3 points:

// mapPoints - coordinates in map projection
// imagePoints - coordinates in image projection
Affine.calculate(mapPoints, imagePoints);

You can see a complete example here - https://kw9l85y5po.codesandbox.io/



来源:https://stackoverflow.com/questions/52904587/displaying-georeferenced-images-using-openlayers-5

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!