Get projected coordinates from geometric coordinates

倖福魔咒の 提交于 2019-12-08 11:50:34

问题


I have a map figure rendered with Cartopy and Matplotlib. I have a specific geometric coordinate (in lat/lon) and I would like to know the pixel coordinate closest to this geometric coordinate's projection (if it is visible), for instance to draw a graphic over the coordinate on the map.

(Note I don't want to draw with Matplotlib; I'm exporting the figure as a bitmap image and drawing in a different part of the pipeline.)

This documentation suggests it might be something like this:

import cartopy, matplotlib.pyplot

fig = matplotlib.pyplot.figure()
ax = fig.add_axes([0, 0, 1, 1], projection=cartopy.crs.Orthographic())
ax.add_feature(cartopy.feature.LAND, facecolor='black')

# Print the location of New York City in display coordinates
lon, lat = -74.0060, 40.7128
trans = cartopy.crs.Geodetic()._as_mpl_transform(ax)
x, y = trans.transform((lon, lat))
print(x, y)

# Or this way
projx, projy = ax.projection.transform_point(lon, lat, cartopy.crs.Geodetic())
x, y = ax.transData.transform((projx, projy))
print(x, y)

Though interestingly, if I plot this point, the figure centers on and zooms into Manhattan, and then the output display coordinates are indeed in the center of the figure at (640, 480).

matplotlib.pyplot.plot(lon, lat, marker='o', color='red', markersize=12,
    alpha=0.7, transform=cartopy.crs.Geodetic())

回答1:


I just found that the transforms are not properly set until the figure is in its final state. So the key is to first draw the figure,

fig.canvas.draw()

or at least apply the aspect properly.

ax.apply_aspect()

Then you will get the correct pixel coordinates out,

import matplotlib.pyplot as plt
import cartopy
import cartopy.crs as ccrs

fig = plt.figure()
ax = fig.add_axes([0, 0, 1, 1], projection=ccrs.PlateCarree())
ax.add_feature(cartopy.feature.LAND, facecolor='black')
ax.set_global()

# before being able to call any of the transforms, the figure needs to be drawn
fig.canvas.draw()
# or
# ax.apply_aspect()

# Print the location of New York City in display coordinates
lon, lat = -74.0060, 40.7128
trans = ccrs.PlateCarree()._as_mpl_transform(ax)
x, y = trans.transform_point((lon, lat))
print(x,y)

plt.show()

This prints:

188.43377777777778 312.3783111111111

Note that those coordinates refer to the pixels from the lower left corner.




回答2:


In my sample code I failed to specify the extent of the map. If I add

ax.set_global()

then the transformed coordinates are sensible.

I presented two ways to compute the transformed coordinates, but the way with _as_mpl_transform() seems to return the center point when New York City is not visible. The way with ax.projection.transform_point() returns NaN when off-screen.



来源:https://stackoverflow.com/questions/55998371/get-projected-coordinates-from-geometric-coordinates

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