업로드 된 압축 shapefile에서 Django 애플리케이션의 Geopandas DataFrame으로
shapefile에서 수천 개의 포인트를 빠르게 필터링 할 수있는 지점에 도달하려고합니다. 내 장고 응용 프로그램은 압축 파일이 적어도 포함 업로드에 압축 Shape 파일, 요청 .shp
, .shx
및 .dbf
파일을. 내 Django보기에서 zip 파일은 다음과 같습니다.
request.FILES['file']
> <InMemoryUploadedFile: test.zip (application/x-zip-compressed)>
type(request.FILES['file'])
> <class 'django.core.files.uploadedfile.InMemoryUploadedFile'>
request.FILES['file'].file
> <_io.BytesIO object at 0x0000028E29F8FE00>
Geopandas가 효율적인 필터링 / 마스킹을위한 최선의 옵션이라고 가정하고 (내가 틀렸다면 제안을받을 수 있습니다) 현재 상태에서 Geopandas DataFrame으로 이동하는 방법을 잘 모르겠습니다. read_file()
방법 을 사용하려고 할 때
import geopandas as gpd
gpd.read_file(request.FILES['file'].file)
다음과 같은 오류가 발생합니다.
fiona.errors.DriverError: no driver
geopandas.read_file()
워드 프로세서 상태 :
열려는 파일 또는 URL에 대한 절대 또는 상대 경로 또는
read()
메서드가 있는 개체 (예 : 열린 파일 또는 StringIO)
내가 가진 것을 read_file()
방법에 적합한 형식으로 얻는 방법을 모르겠습니다 .
참고 : 수행하려는 마스킹 및 필터링은 지오메트리가 아닌 속성 데이터에 대한 것입니다.
답변
당신은 사용할 수 있습니다 fiona.io.ZipMemoryFile
및 gpd.GeoDataFrame.from_features
.
예:
import geopandas as gpd
import io
from fiona.io import ZipMemoryFile
# Just to create a BytesIO object for the demo,
# similar to your request.FILES['file'].file
zipshp = io.BytesIO(open('test.zip', 'rb').read())
with (ZipMemoryFile(zipshp)) as memfile:
with memfile.open() as src:
crs = src.crs
gdf = gpd.GeoDataFrame.from_features(src, crs=crs)
print(gdf.head())
참고 BytesCollection
로 피오나 개발자가 이전 답변 에 대한 의견에서 클래스가 더 이상 사용되지 않을 것이라고 언급했듯이 원래는 포함하지 않았습니다 . 그러나 사용하는 경우 ZipMemoryFile
. 이것은 나를 위해 작동합니다.
import geopandas as gpd
import io
import fiona
zipshp = io.BytesIO(open('test.zip', 'rb').read())
with fiona.BytesCollection(zipshp.read()) as src:
crs = src.crs
gdf = gpd.GeoDataFrame.from_features(src, crs=crs)
print(gdf.head())
@ user2856의 대답은 해결책에 대한 절반을 얻었습니다. 나는 그것에 대해 알지 못했을 것이고 fiona.io.ZipMemoryFile
, 그것은 나를 이 대답으로 이끌었다 . 두 솔루션을 결합하면 다음과 같은 이점이 있습니다.
with ZipMemoryFile(request.FILES['file'].file) as memfile:
with fiona.BytesCollection(memfile._initial_bytes) as f:
gdf = gpd.GeoDataFrame.from_features(f, crs='epsg:4326')
print(gdf.head())
이제 GeoDataFrame에 shapefile 데이터가 있습니다.
호기심이 많은 분들에게 BytesCollection
대신 같이 갔던 이유는 일을 memfile.open()
할 수 없었기 때문 memfile.open()
입니다. .open()
메서드에 '경로'위치 인수가 없다는 오류가 발생합니다 .