문제 설명
GeoPandas를 사용하여 Python에서 GRASS 벡터 데이터 소스 읽기 (Read GRASS vector datasources in Python using GeoPandas)
GRASS GIS
벡터 레이어를 GeoPandas Dataframe
으로 읽으려고 합니다.
나는 GRASS GIS를 읽기 위해 (작동하는) "hackish" 방법을 만들었습니다.
벡터 레이어를 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
, 내가 원했지만 ...
GDAL‑OGR Python
인터페이스에서 읽은 OGR 데이터 소스를 GeoPandas
에 직접 전달할 수 있는 방법이 있는지 궁금합니다. 그렇지 않다면 내가 만든 "해시 방법"을 개선하기 위한 제안이 있습니까? 내 문제를 설명하기 위해 코드에 몇 가지 인라인 주석을 추가했습니다.
참조 솔루션
방법 1:
I just got a reply from the Issue I opened on GitHub, problem solved by enabling the OGR_GRASS
driver in Fiona
, the code below works just fine:
import fiona
import geopandas as gpd
fiona.supported_drivers["OGR_GRASS"] = "r"
gdf = gpd.read_file('/GRASSDB/LOCATION_NAME/MAPSET/vector/layername/head')