繁体   English   中英

Python中地理坐标中的区域元素

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM