Django एप्लिकेशन में अपलोड किए गए ज़िप्ड शेपफाइल से लेकर जियोपैन्डस डेटाफ्रेम तक

Jan 05 2021

मैं एक ऐसे बिंदु पर जाने की कोशिश कर रहा हूं, जहां मैं एक आकृति में हजारों बिंदुओं को जल्दी से छान सकता हूं। मेरे Django ऐप्लिकेशन को अपलोड करने के लिए ज़िपित शेपफ़ाइल, जहां ज़िपित फ़ाइल है कम से कम के लिए पूछता है .shp, .shxऔर .dbfफ़ाइलें। एक बार मेरे Django दृश्य में, ज़िप फ़ाइल इस प्रकार है:

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()विधि के साथ कोई भी वस्तु (जैसे एक खुली फ़ाइल या स्ट्रिंग)

मुझे यकीन नहीं है कि read_file()विधि के लिए मेरे पास एक उपयुक्त प्रारूप कैसे है ।

नोट: मैं जिस मास्किंग और फ़िल्टरिंग को करने जा रहा हूं, वह विशेषता डेटा पर है न कि ज्यामिति पर।

जवाब

4 user2856 Jan 05 2021 at 06:19

आप उपयोग कर सकते हैं 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())
1 GISUser9 Jan 06 2021 at 00:04

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

अब मेरे पास जियोडाटाफ्रेम में मेरा आकार डेटा है।

किसी के लिए भी जो जिज्ञासु है, वह कारण जिसके BytesCollectionबजाय मैं गया था memfile.open(), क्योंकि मैं memfile.open()काम नहीं कर पाया । यह यह कहते हुए एक त्रुटि फेंक देगा कि .open()विधि एक 'पथ' स्थितीय तर्क को याद कर रही थी।