Đọc dữ liệu thô vào geopandas


12

Có thể đọc dữ liệu thô vào a geopandas GeoDataFrame, a la a pandas DataFramekhông?

Ví dụ, các công việc sau:

import pandas as pd
import requests
data = requests.get("https://data.cityofnewyork.us/api/geospatial/arq3-7z49?method=export&format=GeoJSON")
pd.read_json(io.BytesIO(r.content))

Sau đây không:

import geopandas as gpd
import requests
data = requests.get("https://data.cityofnewyork.us/api/geospatial/arq3-7z49?method=export&format=GeoJSON")
gpd.read_file(io.BytesIO(r.content))

Nói cách khác, có thể đọc dữ liệu không gian địa lý trong bộ nhớ mà không lưu dữ liệu đó vào đĩa trước không?

Câu trả lời:


14

Bạn có thể chuyển json trực tiếp đến hàm tạo GeoDataFrame:

import geopandas as gpd
import requests
data = requests.get("https://data.cityofnewyork.us/api/geospatial/arq3-7z49?method=export&format=GeoJSON")
gdf = gpd.GeoDataFrame(data.json())
gdf.head()

Đầu ra:

                                            features               type
0  {'type': 'Feature', 'geometry': {'type': 'Poin...  FeatureCollection
1  {'type': 'Feature', 'geometry': {'type': 'Poin...  FeatureCollection
2  {'type': 'Feature', 'geometry': {'type': 'Poin...  FeatureCollection
3  {'type': 'Feature', 'geometry': {'type': 'Poin...  FeatureCollection
4  {'type': 'Feature', 'geometry': {'type': 'Poin...  FeatureCollection

Đối với các định dạng tệp đơn được hỗ trợ hoặc shapefiles được nén, bạn có thể sử dụng fiona.BytesCollectionGeoDataFrame.from_features:

import requests
import fiona
import geopandas as gpd

url = 'http://www.geopackage.org/data/gdal_sample.gpkg'
request = requests.get(url)
b = bytes(request.content)
with fiona.BytesCollection(b) as f:
    crs = f.crs
    gdf = gpd.GeoDataFrame.from_features(f, crs=crs)
    print(gdf.head())
và đối với các shapefiles được nén (được hỗ trợ kể từ fiona 1.7.2 )
url = 'https://www2.census.gov/geo/tiger/TIGER2010/STATE/2010/tl_2010_31_state10.zip'
request = requests.get(url)
b = bytes(request.content)
with fiona.BytesCollection(b) as f:
    crs = f.crs
    gdf = gpd.GeoDataFrame.from_features(f, crs=crs)
    print(gdf.head())

Bạn có thể tìm hiểu những định dạng mà Fiona hỗ trợ bằng cách sử dụng một cái gì đó như:

import fiona
for name, access in fiona.supported_drivers.items():
    print('{}: {}'.format(name, access))

Và một cách giải quyết khó khăn để đọc dữ liệu được nén trong bộ nhớ trong fiona 1.7.1 trở về trước:

import requests
import uuid
import fiona
import geopandas as gpd
from osgeo import gdal

request = requests.get('https://github.com/OSGeo/gdal/blob/trunk/autotest/ogr/data/poly.zip?raw=true')
vsiz = '/vsimem/{}.zip'.format(uuid.uuid4().hex) #gdal/ogr requires a .zip extension

gdal.FileFromMemBuffer(vsiz,bytes(request.content))
with fiona.Collection(vsiz, vsi='zip', layer ='poly') as f:
    gdf = gpd.GeoDataFrame.from_features(f, crs=f.crs)
    print(gdf.head())

Điều này làm việc cho GeoJSON, trả lời câu hỏi. Nhưng điều này sẽ không hoạt động đối với các định dạng tệp không gian địa lý khác, những thứ như shapefiles hoặc KML hoặc KMZ. Bạn có biết một cách giải quyết cho những trường hợp đó không?
Aleksey Bilogur

Một chút làm rõ là theo thứ tự. GeoPandas và Fiona không hỗ trợ shapefiles và KML, nhưng họ không thể hỗ trợ đầy đủ một API như Thành phố New York. Ngoài ra, BytesCollectionhoàn toàn hoạt động, nhưng có lẽ sẽ bị xóa trong phiên bản tương lai có lợi cho một trong các tùy chọn trong github.com/Toblerity/Fiona/issues/409 .
sgillies

Cảm ơn. @sgillies điều này nên được mở như một yêu cầu tính năng trên geopandas, hoặc sẽ tốt hơn để chờ đợi những thay đổi bạn đề cập ở đây ?
Aleksey Bilogur

@sgillies bạn nêu Fiona hỗ trợ KML trong nhận xét của bạn ở trên, nhưng DriverError: unsupported driver: 'KML'được nêu ra khi cố gắng mở KML vì nó không nằm trong lệnh supported_drivers(sử dụng Fiona 1.7.1) và tôi nhận thấy một số vấn đề. thiếu hỗ trợ KML (# 23 & # 97). Fiona có hỗ trợ KML không?
dùng2856

3

fiona.BytesCollectiondường như không hoạt động cho TopoJSONở đây một giải pháp hiệu quả cho tất cả mà không cần gdal:

import fiona
import geopandas as gpd
import requests

# parse the topojson file into memory
request = requests.get('https://vega.github.io/vega-datasets/data/us-10m.json')
visz = fiona.ogrext.buffer_to_virtual_file(bytes(request.content))

# read the features from a fiona collection into a GeoDataFrame
with fiona.Collection(visz, driver='TopoJSON') as f:
    gdf = gpd.GeoDataFrame.from_features(f, crs=f.crs)

Với geopandas==0.4.0, Fiona==1.8.4và Python 3, tôi nhận được DriverError: unsupported driver: 'TopoJSON'.
edesz

Bạn đúng rồi. Nó đã hoạt động cho đến ít nhất là phiên bản 1.7.13củaFiona
Mattijn

Thật không may là điều này không hoạt động. Tôi đã cố gắng làm theo ví dụ của bạn trên GitHub cho các âm mưu choropleth của Altair nhưng điều đó cũng gây ra lỗi chính xác tương tự ở dòng này gdf = gpd.read_file(counties, driver='TopoJSON'). Tôi nghĩ rằng việc sử dụng with fiona.Collection...có thể làm việc nhưng thật đáng buồn là nó không.
edesz

@edesz đây là một lỗi và sẽ được sửa trong Fiona 1.8.5, xem: github.com/Toblerity/Fiona/issues/721
Mattijn


2

Khi sử dụng Fiona 1.8, điều này có thể (phải?) Được thực hiện bằng dự án đó MemoryFilehoặcZipMemoryFile .

Ví dụ:

import fiona.io
import geopandas as gpd
import requests

response = requests.get('http://example.com/Some_shapefile.zip')
data_bytes = response.content

with fiona.io.ZipMemoryFile(data_bytes) as zip_memory_file:
    with zip_memory_file.open('Some_shapefile.shp') as collection:
      geodf = gpd.GeoDataFrame.from_features(collection, crs=collection.crs)

0

Cách dễ nhất là nhập URL GeoJSON trực tiếp vào gpd.read (). Tôi đã thử trích xuất một shapefile từ một zip trước khi sử dụng BytesIO & zipfile và gặp vấn đề với gpd (cụ thể là Fiona) chấp nhận các đối tượng giống như tệp.

import geopandas as gpd
import David.SQL_pull_by_placename as sql
import os

os.environ['PROJ_LIB'] = r'C:\Users\littlexsparkee\Anaconda3\Library\share\proj'

geojson_url = f'https://github.com/loganpowell/census-geojson/blob/master/GeoJSON/500k/2018/{sql.state}/block-group.json?raw=true'
census_tracts_gdf = gpd.read_file(geojson_url)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.