Yüklenen sıkıştırılmış şekil dosyasından Django Uygulamasındaki Geopandas DataFrame'e

Jan 05 2021

Bir şekil dosyasındaki binlerce noktayı hızlıca filtreleyebileceğim bir noktaya gelmeye çalışıyorum. Benim Django uygulama sıkıştırılmış dosya en azından içeren yüklemesi için sıkıştırılmış shape, sorar .shp, .shxve .dbfdosyaları. Django görünümüme girdikten sonra, zip dosyası aşağıdaki gibidir:

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'ın verimli filtreleme / maskeleme için en iyi seçenek olduğunu varsayarsak (yanılıyorsam, önerilere kesinlikle açığım), mevcut durumdan Geopandas DataFrame'e nasıl geçeceğimi bilmiyorum. read_file()Yöntemi kullanmaya çalıştığımda

import geopandas as gpd
gpd.read_file(request.FILES['file'].file)

Şu hatayı alıyorum:

fiona.errors.DriverError: no driver

geopandas.read_file() Docs açıkladık:

read()Açılacak dosyanın veya URL'nin mutlak veya göreli yolu veya bir yöntem içeren herhangi bir nesne (açık bir dosya veya StringIO gibi)

Sahip olduğum şeyi read_file()yöntem için uygun bir biçime nasıl alacağımdan emin değilim .

Not: Yapmak istediğim maskeleme ve filtreleme, geometri değil öznitelik verileri üzerindedir.

Yanıtlar

4 user2856 Jan 05 2021 at 06:19

Sen kullanabilirsiniz fiona.io.ZipMemoryFileve gpd.GeoDataFrame.from_features.

Misal:

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())

Not Başlangıçta içermiyordu BytesCollectionyorumunda belirtildiği fiona olarak geliştirici önceki yanıt sınıfı olasılıkla kaldırılmış olacağını. Ancak, kullanırsanız, ihtiyacınız olmamalı ZipMemoryFile. Bu benim için çalışıyor:

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())
1 GISUser9 Jan 06 2021 at 00:04

@ user2856'nın cevabı beni bir çözüme götürdü. Bunu bilmiyordum fiona.io.ZipMemoryFileve bu beni bu cevaba götürdü . İki çözümü birleştirmek bana verdi:

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())

Artık şekil dosyası verilerim bir GeoDataFrame'de var.

Merak eden biri için BytesCollectionbunun yerine onunla gitmemin sebebi işe memfile.open()gidememiş olmam memfile.open(). .open()Yöntemin bir 'yol' konumsal bağımsız değişkeni eksik olduğunu söyleyen bir hata verir .