如何使用python生成常规地理网格?

时间:2016-10-31 12:38:10

标签: python google-maps geopy

我想检索特定地图区域上的常规网格的所有纬度/经度坐标对。我找到了geopy库,但根本无法解决这个问题。

例如,我有一个矩形地理区域,由其在纬度/经度坐标中的四个角描述,我试图计算间距为例如1的网格。 1km覆盖这个区域。

1 个答案:

答案 0 :(得分:16)

初步考虑

如何定义特定区域会略有不同。如果它只是一个矩形区域(注意:投影中的矩形在地球表面上不一定是矩形的!),您可以使用所需的步长在两个坐标维度中从最小值到最大值迭代。如果您手头有任意多边形,则需要测试生成的点相交,并且只返回此条件成立的坐标对。

计算常规网格

规则网格不等于投影中的常规网格。您正在谈论纬度/经度对,它是一种极地坐标系,以近似于地球表面形状的度数度量。在纬度/经度(EPSG:4326)中,距离不是以米/公里/英里为单位,而是以度为单位。

此外,我假设您想要计算一个网格,其水平为"水平"与赤道平行的台阶(即纬度)。对于其他网格(例如旋转的矩形网格,垂直于经度的垂直线等),您需要花费更多精力来改变形状。

问问自己:您想要以度数还是以米为单位创建规则间隔的网格?

以度为单位的网格

如果你想以度为单位,你可以简单地迭代:

stepsize = 0.001
for x in range(lonmin, lonmax, stepsize):
    for y in range(latmin, latmax, stepsize):
        yield (x, y)

但是:一定要知道,在地球表面上以度为单位的长度(以米为单位)是不一样的。例如,靠近赤道的0.001度的纬度覆盖了表面上不同的距离,以米为单位。

以米为单位的网格

如果您想要以米为单位,则需要将输入区域的纬度/经度边界(地图上的特定区域)投影到支持以米为单位的距离的坐标系中。您可以使用Haversine formula作为粗略近似来计算纬度/经度对之间的距离,但这不是您可以使用的最佳方法。

更好的是搜索合适的投影,将您感兴趣的区域转换为该投影,通过直接迭代创建网格,获取点,并将它们投影回纬度/经度对。例如,适用于欧洲的预测是EPSG:3035。顺便说一句,谷歌地图使用EPSG:900913作为他们的网络地图服务。

在python中,您可以使用库shapelypyproj来处理地理形状和投影:

import shapely.geometry
import pyproj

# Set up projections
p_ll = pyproj.Proj(init='epsg:4326')
p_mt = pyproj.Proj(init='epsg:3857') # metric; same as EPSG:900913

# Create corners of rectangle to be transformed to a grid
nw = shapely.geometry.Point((-5.0, 40.0))
se = shapely.geometry.Point((-4.0, 41.0))

stepsize = 5000 # 5 km grid step size

# Project corners to target projection
s = pyproj.transform(p_ll, p_mt, nw.x, nw.y) # Transform NW point to 3857
e = pyproj.transform(p_ll, p_mt, se.x, se.y) # .. same for SE

# Iterate over 2D area
gridpoints = []
x = s[0]
while x < e[0]:
    y = s[1]
    while y < e[1]:
        p = shapely.geometry.Point(pyproj.transform(p_mt, p_ll, x, y))
        gridpoints.append(p)
        y += stepsize
    x += stepsize

with open('testout.csv', 'wb') as of:
    of.write('lon;lat\n')
    for p in gridpoints:
        of.write('{:f};{:f}\n'.format(p.x, p.y))

此示例生成此均匀间隔的网格:

Regular Grid in Spain