使用OpenLayers 5显示地理参考图像 [英] Displaying georeferenced images using OpenLayers 5

查看:325
本文介绍了使用OpenLayers 5显示地理参考图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试开发一个用户可以对扫描的地图进行地理配准的应用程序.您可以在此处查看示例: https://codesandbox.io/s/2o99jvrnyy 有两张图片:

第一个图像已正确加载到地图上,但旋转的图像未正确加载.

我找不到有关OpenLayers 5是否可以处理具有存储在世界文件中的转换参数的图像的信息.可能是我遗漏了一些东西,但无法弄清楚是什么.

这是我的逻辑工作方式:

通过仿射变换使用4个点计算变换参数.您可以在 Affine.js 文件中查看逻辑.从源图像和地图中至少拾取4个点.然后使用这4个点计算转换参数.之后,我要计算图像的范围:

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];

世界文件参数按定义的此处进行计算.

可能的问题是旋转的图像在OpenLayers 5中作为静态图像加载时不会旋转,但找不到解决方法.

我尝试使用计算出的参数在QGIS和ArcMap中加载图像,并且都正确加载了这两个图像.您可以看到第二张图片的结果:

您可以在此处查看每个图像的参数:

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

解决方案

我意识到我的方法是错误的.无需计算地图投影中图像的范围并将其设置在图层中.我可以简单地添加一个转换函数,负责在图像投影和地图投影之间转换坐标.这样,图像层始终将其投影设置为图像投影,并将范围设置为以像素为单位的图像大小.

像这样添加转换功能:

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

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

再次从至少3个点计算仿射参数:

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

您可以在此处看到完整的示例- https://kw9l85y5po.codesandbox.io/

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:

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

解决方案

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/

这篇关于使用OpenLayers 5显示地理参考图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆