简体   繁体   English

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

[英]Area elements in geographic coordinates in Python

I have a need to do some integration/summation over gridded weather data (rainfall), in standard geographic coordinates.我需要在标准地理坐标中对网格化天气数据(降雨)进行一些积分/求和。 I therefore need to calculate area elements associated with each of my grid points.因此,我需要计算与我的每个网格点相关的区域元素。 Basically the real areas of the grid cells.基本上是网格单元的真实区域。 We're talking a standard, equally-spaced, rectilinear lat/lon grid here.我们在这里谈论的是标准的、等距的、直线的纬度/经度网格。

How can I do this in Python?我怎样才能在 Python 中做到这一点?

I know I can get them reasonably accurately just using a spherical coordinates approximation, but this has to be super standard, so might as well use a package with a proper Earth shape model in it.我知道我可以仅使用球坐标近似值就可以相当准确地得到它们,但这必须是超标准的,所以不妨使用一个包含适当地球形状模型的包。 However I've searched around a lot and not found much on how to do this basic task in the common geospatial packages.但是,我进行了很多搜索,但没有找到很多关于如何在常见的地理空间包中执行此基本任务的信息。 Seems like it's generally hidden under the hood or something, handled internally.似乎它通常隐藏在引擎盖或其他东西下,在内部处理。 I'm sure it can be dug out somehow though.我相信它可以以某种方式被挖出来。

Edit: A hand-crafted solution is here: How to calculate size in m2 of each lat/long grid square , but I'd rather use a standard library if possible.编辑:这里有一个手工制作的解决方案: How to calculate size in m2 of each lat/long grid square ,但如果可能的话,我宁愿使用标准库。

See pyproj.Geod.inv , that can be used to return the distance (in meters) between 2 points (in lon/lat).请参阅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's answer is great and concise, but for my own curiosity I wanted to see how it compared to a more accurate calculation (their answer assumes the grid cells are small enough to approximate as squares): 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)

Output:输出:

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

Pretty close!很接近了! It obviously depends on the size of the grid steps though.这显然取决于网格步长的大小。 I'm still curious about other answers to the question, I did say "area elements" in the question, I guess I was imagining extracting Jacobian factors from some coordinate transform in eg pyproj.我仍然对这个问题的其他答案感到好奇,我确实在问题中说了“面积元素”,我想我是在想象从 pyproj 中的某个坐标变换中提取雅可比因子。 The shape integrals here should be more accurate of course due to finite size, but I guess I thought it would be faster and easier to get the Jacobian factors... seems like they aren't easily exposed though?由于尺寸有限,这里的形状积分当然应该更准确,但我想我认为获得雅可比因子会更快更容易......看起来它们不容易暴露吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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