Shapefile以2D网格为稀疏矩阵

时间:2016-03-30 19:37:04

标签: python numpy geospatial sparse-matrix shapefile

我在使用NumPy进行地理空间计算的所有固定库中都变得越来越好。

采用shapefile(其范围是整个地球)的最简单方式是什么,并从中构造一个稀疏矩阵,表示具有指定分辨率的纬度 - 经度网格,矩阵在shapefile的多边形内的所有网格点上的条目1,在其他地方的0?

我知道如何使用GeoPandas或Fiona读取shapefile;我被卡住的地方是"转换为稀疏矩阵"部分。 "光栅化"似乎需要另一个螺栓固定,而不是让我控制网格分辨率,并且不能吐出除TIFF之外的任何东西,这不是很有用。

1 个答案:

答案 0 :(得分:1)

这是一种方法:

  1. 创建空稀疏矩阵
  2. 编写一个函数,将随机点发送给" small"积分
  3. 对于每个多边形,均匀地对边界框中的所有点进行采样。对于落入Polygon的每个点,应用上面的函数来获得标准key并使用键和值1更新稀疏矩阵。
  4. 我不确定它是否属于直截了当的类别,但可以使用osgeoscipy在python中完成。当然,如果你有大的多边形,采样将非常慢,但由于你使用的是稀疏矩阵,我认为这不是问题。您可以调整分辨率并使用osgeo中的投影。

    from itertools import product
    from scipy.sparse import dok_matrix
    import numpy as np
    
    # https://pcjericks.github.io/py-gdalogr-cookbook
    from osgeo import ogr
    
    # DATA:
    # http://www.naturalearthdata.com/downloads/110m-cultural-vectors/
    
    SHP_FNAME = 'ne_110m_admin_0_countries.shp'
    
    driver = ogr.GetDriverByName('ESRI Shapefile')
    data = driver.Open(SHP_FNAME, 0)
    layer = data.GetLayer()
    
    XDIAM = 360.0
    YDIAM = 180.0
    XRES = YRES = 10 ** 2
    dX = XDIAM / XRES
    dY = YDIAM / YRES
    
    def to_key(pt):
        x, y = pt
        x -= x % dX - XDIAM / 2
        y -= y % dY - YDIAM / 2
        return (x / dX, y / dY)
    
    def geom_to_keys(g):
        xmin, xmax, ymin, ymax = g.GetEnvelope()
        print xmax, ymax, xmin, ymin
        xs = np.linspace(xmin, xmax, (xmax - xmin) / dX)
        ys = np.linspace(ymin, ymax, (ymax - ymin) / dY)
        for x, y in product(xs, ys):
            point = ogr.Geometry(ogr.wkbPoint)
            point.AddPoint(x, y)
            if g.Contains(point):
                yield to_key((x, y))
    
    smatrix = dok_matrix((XRES + 1, YRES + 1), np.int8)
    
    one = np.int8(1)
    
    for feature in layer:
        geom = feature.GetGeometryRef()
        if geom.Area() > 1000:
            continue
            # sampling is slow for large polygons
    
        for key in geom_to_keys(geom):
            smatrix.update({
                key : one,
                })
    
    if XRES * YRES < 10 ** 6 + 1:
        from matplotlib import pyplot as plt
        plt.pcolor(smatrix.toarray().transpose())
        plt.show()
    

    这是一张照片;我省略了几个大国来加快速度。

    you can try it here