绘制时转换为 OSGB 的纬度/经度具有偏移量

问题描述

如果我采用一组经纬度点,使用 cartopy 的“transform_points”方法将它们转换为 OSGB crs,然后绘制它们,与直接绘制经纬度相比,它们会发生偏移。如果我将它们转换回纬度/经度,它们的绘图就可以了。如果我将它们转换为 UTM 坐标,它们的绘图就可以了。我错过了什么吗? 示例代码

import numpy as np
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
from cartopy.io.img_tiles import OSM

# set up figure and background map tile
fig = plt.figure()
ax = plt.axes(projection=OSM().crs)
ax.set_extent((-2.473911,-2.410147,50.567006,50.605896))
ax.add_image(imagery,14)

# Plot some test points using lat/long (PlateCarree) crs
test_lonlat = np.array([[-2.464482,-2.432523,-2.437892],[50.593243,50.596390,50.573177]])
plt.plot(test_lonlat[0],test_lonlat[1],'r:+',transform=ccrs.PlateCarree())

# Transform to OSGB coords and plot
test_OS = ccrs.OSGB().transform_points(ccrs.PlateCarree(),test_lonlat[0],test_lonlat[1])
plt.plot(test_OS[:,0],test_OS[:,1],'kx-',transform=ccrs.OSGB())
plt.show()

感谢您的建议。

使用单点的简单示例

fig = plt.figure(figsize=[7,7])
ax = plt.axes(projection=OSM().crs)
ax.set_extent((-2.435,-2.405,50.575,50.595))
ax.add_image(OSM(),14)

# Simpler test of OSGB crs
# Take point at end of outer breakwater: OS (370783,76226) or lat/long (-2.414343,50.584978)
point_os = [370774.0,76221.0]
point_lonlat = [-2.414278,50.584971]

# Plot each on OSM tile - both look ok but small error
plt.plot(point_os[0],point_os[1],'r+',transform=ccrs.OSGB(),markersize=15)
plt.plot(point_lonlat[0],point_lonlat[1],'kx',transform=ccrs.PlateCarree(),markersize=10)

# Convert lat/long to OSGB and plot - Now offset by ~50 m to NW
point_os_new = ccrs.OSGB().transform_point(point_lonlat[0],ccrs.PlateCarree())
plt.plot(point_os_new[0],point_os_new[1],'m^',markersize=10)

# Print both sets of OS coords
print(f'Original point: {point_os}')
print(f'Transformed point: {point_os_new}')

解决方法

当你用这行代码创建一个 axes 来绘图时

ax = plt.axes(projection=OSM().crs)

您应该使用 cartopy.crs.Mercator 投影坐标在其上绘图,因为 OSM().crs 是墨卡托。

这部分代码:

# Transform to OSGB coords and plot
test_OS = ccrs.OSGB().transform_points(ccrs.PlateCarree(),\
    test_lonlat[0],test_lonlat[1])
plt.plot(test_OS[:,0],test_OS[:,1],'kx-',transform=ccrs.OSGB())

使用 OSGB 坐标绘制墨卡托投影。那是错误的部分。

正确的代码行应该是

test2_OS = OSM().crs.transform_points(ccrs.PlateCarree(),test_lonlat[1])
ax.plot(test2_OS[:,test2_OS[:,transform=OSM().crs)

gb_south

编辑 1

我上面图中的平铺图像是 OSM(),通过 ax.add_image(OSM(),14)。 OP面临的问题是数据和轴之间没有使用匹配的坐标系,或者错误的值。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...