【问题标题】:Read GRASS vector datasources in Python using GeoPandas使用 GeoPandas 在 Python 中读取 GRASS 矢量数据源
【发布时间】:2019-06-05 19:49:19
【问题描述】:

我正在尝试将GRASS GIS 矢量图层读入GeoPandas Dataframe

因为我无法在Fiona see related issue 中启用GRASS GIS(只读)驱动程序

我做了一个“hackish”方法(有效)将GRASS GIS 矢量图层读入GeoPandas Dataframe


import os
from osgeo import ogr
import pandas as pd
from shapely import wkt
import geopandas as gpd


def grass2gpd(layername, grassdb, location_name, mapset):
    datafile = os.path.join(GRASSDB, LOCATION_NAME, MAPSET, 'vector', layername, 'head')
    driver = ogr.GetDriverByName('GRASS')
    # here the data is read in readonly mode, but also the GDAL GRASS driver has no write capabilities
    # I am not sure at the end of the method on how to properly close the datasource (and, actually, if I have to ... )  
    dataSource = driver.Open(datafile, 0)     
    layer = dataSource.GetLayer() 
    srs = layer.GetSpatialRef().ExportToWkt()
    lyrDefn = layer.GetLayerDefn() 
    fieldnames = []
    for i in range( lyrDefn.GetFieldCount() ):  
        fieldnames.append(lyrDefn.GetFieldDefn(i).GetName() )
    # hack to avoid to call `layer.ResetReading()` and iterate again over the features
    #
    # I first build a list of dictionaries
    # each element of the list is of the form:
    # {geom: WKT_Geometry
    #  attr: {field_1: val, field_2: val, ..., field_N: val}}
    # So the attr key is a dictionary itself
    # the nested loop first get the feature then create a dictionary of attributes looping over the list of fields
    # 
    wktgeom = [{'geom':feature.GetGeometryRef().ExportToWkt(), 
                'attr':{i:feature.GetField(i) for i in fieldnames}} for feature in layer] 
    # At this point I should close or unlink the datasource, but I can't find the right method to do it
    #
    # Create a dataframe from the list of dictionaries
    #
    df = pd.DataFrame(wktgeom)
    # convert the WKT string to a shapely WKT object
    # concatenate a Geometry dataframe with an attribute dataframe 
    df_geom = pd.concat([df['geom'].apply(wkt.loads),  
                        pd.DataFrame(list(df['attr'].values))], 
                       axis=1, sort=False)
    # transform the pandas dataframe into a geopandas dataframe
    gdf = gpd.GeoDataFrame(df_geom, geometry='geom', crs=srs)
    return gdf

运行它例如:


GRASSDB="/home/epinux/Data/grassdata"
LOCATION_NAME="lonlat"
MAPSET="PERMANENT"

layername="img_left_filteredBS"

gdf = grass2gpd(layername=layername, 
                grassdb=GRASSDB, 
                location_name=LOCATION_NAME, 
                 mapset=MAPSET)
type(gdf)

# returns
# geopandas.geodataframe.GeoDataFrame

该方法将返回一个geopandas.geodataframe.GeoDataFrame,正如我想要的,但是...

我想知道是否存在一种方法可以直接传递到GeoPandas 一个由GDAL-OGR Python 接口读取的OGR 数据源。如果没有,您对改进我提出的“hackish 方法”有什么建议吗?我在代码中添加了一些内联 cmets,试图解释我的担忧。

【问题讨论】:

    标签: python gdal geopandas ogr grass


    【解决方案1】:

    刚刚收到Issue I opened on GitHub的回复,问题通过在Fiona中启用OGR_GRASS驱动解决了,下面的代码就可以了:

    import fiona
    import geopandas as gpd
    
    fiona.supported_drivers["OGR_GRASS"] = "r" 
    gdf = gpd.read_file('/GRASSDB/LOCATION_NAME/MAPSET/vector/layername/head')
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-25
      • 1970-01-01
      • 2021-05-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多