[英]Area elements in geographic coordinates in Python
我需要在標准地理坐標中對網格化天氣數據(降雨)進行一些積分/求和。 因此,我需要計算與我的每個網格點相關的區域元素。 基本上是網格單元的真實區域。 我們在這里談論的是標准的、等距的、直線的緯度/經度網格。
我怎樣才能在 Python 中做到這一點?
我知道我可以僅使用球坐標近似值就可以相當准確地得到它們,但這必須是超標准的,所以不妨使用一個包含適當地球形狀模型的包。 但是,我進行了很多搜索,但沒有找到很多關於如何在常見的地理空間包中執行此基本任務的信息。 似乎它通常隱藏在引擎蓋或其他東西下,在內部處理。 我相信它可以以某種方式被挖出來。
編輯:這里有一個手工制作的解決方案: How to calculate size in m2 of each lat/long grid square ,但如果可能的話,我寧願使用標准庫。
請參閱pyproj.Geod.inv ,它可用於返回 2 個點(以經度/緯度為單位)之間的距離(以米為單位)。
g=Geod(ellps='WGS84')
lon2D,lat2D = np.meshgrid(np.arange(0,20,0.1),np.arange(30,45,0.1))
_,_, distEW = g.inv(lon2D[:,:-1],lat2D[:,1:], lon2D[:,1:], lat2D[:,1:])
_,_, distNS = g.inv(lon2D[1:,:],lat2D[1:,:], lon2D[1:,:], lat2D[:-1,:])
pixel_area = distEW[1:,:] * distNS[:,1:]
Olivier 的回答非常簡潔,但出於我自己的好奇心,我想看看它與更准確的計算相比如何(他們的回答假設網格單元足夠小,可以近似為正方形):
import numpy as np
from pyproj import Geod
from shapely.geometry import LineString, Point, Polygon
lons = np.arange(0,20,0.1)
lats = np.arange(30,45,0.1)
# Fast way, square approx of grid cells
geod = Geod(ellps="WGS84")
lon2D,lat2D = np.meshgrid(lons, lats)
_,_, distEW = geod.inv(lon2D[:,:-1],lat2D[:,1:], lon2D[:,1:], lat2D[:,1:])
_,_, distNS = geod.inv(lon2D[1:,:],lat2D[1:,:], lon2D[1:,:], lat2D[:-1,:])
square_area = distEW[1:,:] * distNS[:,1:]
# Slower way, geodesic areas
def stack_coords(x, y):
"""Stacks coordinate lists into a 2D array of coordinate pairs,
flattened to list of coordinate pairs"""
out = np.vstack(np.stack(np.meshgrid(x, y), axis=2))
return out
def get_lat_squares(lats, lons):
"""Construct shapely Polygons for a single longitude but
every latitude.
Area is constant with longitude so just copy results.
"""
lats_0 = lats[:-1]
lats_1 = lats[1:]
lons_0 = lons[0:1]
lons_1 = lons[1:2]
c1 = stack_coords(lons_0, lats_0)
c2 = stack_coords(lons_1, lats_0)
c3 = stack_coords(lons_1, lats_1)
c4 = stack_coords(lons_0, lats_1)
squares = []
for p1, p2, p3, p4 in zip(c1, c2, c3, c4):
squares.append(Polygon([p1, p2, p3, p4]))
return squares
def get_areas(lats, lons):
squares = get_lat_squares(lats, lons)
geod = Geod(ellps="WGS84")
areas = []
for square in squares:
area = geod.geometry_area_perimeter(square)[0]
areas.append(area)
return np.array(areas)
geodesic_areas = get_areas(lats, lons)
for a1, a2 in zip(geodesic_areas, square_area[:,0]):
print(a1, a2)
輸出:
106904546.2618103 106850809.52460858
106798611.31295013 106744711.14938568
106692351.02400208 106638287.58503169
106585765.66596985 106531539.10307406
106478855.51091766 106424465.9760592
...
88300037.70746613 88224423.89253764
88150258.98899078 88074508.72317643
88000204.78475189 87924318.28878595
87849875.51327515 87773853.00843135
很接近了! 這顯然取決於網格步長的大小。 我仍然對這個問題的其他答案感到好奇,我確實在問題中說了“面積元素”,我想我是在想象從 pyproj 中的某個坐標變換中提取雅可比因子。 由於尺寸有限,這里的形狀積分當然應該更准確,但我想我認為獲得雅可比因子會更快更容易......看起來它們不容易暴露嗎?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.