💻 Vektor Data I/O#
Et av de første trinnene i mange analysearbeidsflyter er å lese data fra en fil, et av de siste trinnene skriver ofte data til en fil. Til skrekk og gru for mange geoinformatikkforskere, finnes det mange filformater for GIS-data: den gamle og forhatte, men også elskede og etablerte ESRI Shapefile, den universelle Geopackage (GPKG), og den web-optimaliserte GeoJSON er bare noen av de mer kjente eksemplene.
De fleste av dagens Python GIS-pakker er avhengige av GDAL/OGR-bibliotekene, som det finnes moderne grensesnitt for i form av Python-pakkene fiona og rasterio.
I dag skal vi konsentrere oss om vektordata, så la oss først ta en nærmere titt på fionas egenskaper, og deretter importere og eksportere data ved hjelp av geopandas, som bruker fiona.
Definere en konstant for datamappen
For å gjøre det lettere å håndtere stiene til inngangs- og utgangsdatafiler, er det en god vane å definere en konstant som peker på datamappen øverst i en notatbok:
import pathlib
NOTEBOOK_PATH = pathlib.Path().resolve()
DATA_MAPPE = NOTEBOOK_PATH / "data"
Filformater#
Fiona kan lese (nesten) alle geospatiale filformater, og skrive mange av dem. For å finne ut nøyaktig hvilke (det kan avhenge av den lokale installasjonen og versjonen), kan vi skrive ut listen over dens filformatdrivere:
import fiona
fiona.supported_drivers
---------------------------------------------------------------------------
ModuleNotFoundError Traceback (most recent call last)
Cell In[2], line 1
----> 1 import fiona
2 fiona.supported_drivers
ModuleNotFoundError: No module named 'fiona'
Hint
I denne listen markerer r
filformater som Fiona kan lese, og w
formater det kan skrive. En a
markerer formater som Fiona kan appendere (legge til) nye data til eksisterende filer.
Merk at hver av de listede ‘formatene’ faktisk er navnet på driverimplementasjonen, og mange av driverne kan åpne flere relaterte filformater.
Mange flere ‘eksotiske’ filformater kan kanskje ikke vises i denne listen over din lokale installasjon, fordi du må installere ekstra biblioteker. Du kan finne en fullstendig liste over filformater som støttes av GDAL/OGR (og Fiona) på nettsiden: gdal.org/drivers/vector/.
Lesing og skriving av romlige data#
Fiona gir tilgang til geodatafiler på et lavt nivå. Dette er noen ganger nødvendig, men i typiske analysearbeidsflyter er det mer praktisk å bruke et høyere-nivå bibliotek. Den mest brukte for geospatiale/romlige vektordata er geopandas. Som nevnt ovenfor, bruker den Fiona for lesing og skriving av filer, og støtter dermed de samme filformatene.
For å lese data fra en GeoPackage -fil til en geopandas.GeoDataFrame
(en romlig versjon av en pandas.DataFrame
), bruk geopandas.read_file()
:
import geopandas
kommuner = geopandas.read_file(
DATA_MAPPE / "kommuner" / "kommuner.gpkg"
)
kommuner.head()
gml_id | lokalId | navnerom | versjonId | oppdateringsdato | gyldigFra | datauttaksdato | navn | språk | kommunenummer | kommunenavn | samiskForvaltningsområde | geometry | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | kommune.1 | 0466e7c3-6a23-4b70-97d4-cf81f949490b | https://data.geonorge.no/sosi/inndelinger/innd... | 3 | 2023-11-28T17:47:39 | 2024-01-01 | 2024-03-04T12:27:57 | Ibestad | nor | 5514 | Ibestad | False | MULTIPOLYGON (((589669.263 7630312.979, 589669... |
1 | kommune.2 | 0f821a2d-a307-41ec-9b64-f01c80e39357 | https://data.geonorge.no/sosi/inndelinger/innd... | 4 | 2023-11-07T23:33:28 | 2023-11-07 | 2024-03-04T12:27:57 | Rendalen | nor | 3424 | Rendalen | False | MULTIPOLYGON (((327391.890 6869419.570, 327363... |
2 | kommune.3 | 251a3fdd-ac96-4ef2-badb-a9b75e6ab2e6 | https://data.geonorge.no/sosi/inndelinger/innd... | 3 | 2023-11-28T15:42:05 | 2024-01-01 | 2024-03-04T12:27:57 | Rakkestad | nor | 3120 | Rakkestad | False | MULTIPOLYGON (((284560.990 6591094.550, 284575... |
3 | kommune.4 | 2758a7b8-edba-4d6a-936e-4754ce03ca8f | https://data.geonorge.no/sosi/inndelinger/innd... | 3 | 2023-11-28T15:56:10 | 2024-01-01 | 2024-03-04T12:27:57 | Nordre Follo | nor | 3207 | Nordre Follo | False | MULTIPOLYGON (((269615.270 6638265.470, 269615... |
4 | kommune.5 | 340fff7f-b153-4a87-814d-12ca4f2d1682 | https://data.geonorge.no/sosi/inndelinger/innd... | 4 | 2023-11-07T23:33:28 | 2023-11-07 | 2024-03-04T12:27:57 | Overhalla | nor | 5047 | Overhalla | False | MULTIPOLYGON (((359415.100 7152572.930, 359412... |
Å lese en lokal GPKG-fil er mest sannsynlig den enkleste oppgaven for en GIS-pakke. Imidlertid kan geopandas også lese Shapefiles innenfor en ZIP-arkiv, og/eller direkte fra en Internett-URL. For eksempel, nedlasting, utpakking og åpning av et datasett av NUTS-regioner fra European Union’s GISCO/eurostat download page er en linje med kode:
nuts_regions = geopandas.read_file("https://gisco-services.ec.europa.eu/distribution/v2/nuts/shp/NUTS_RG_60M_2021_3035.shp.zip")
nuts_regions.head()
NUTS_ID | LEVL_CODE | CNTR_CODE | NAME_LATN | NUTS_NAME | MOUNT_TYPE | URBN_TYPE | COAST_TYPE | geometry | |
---|---|---|---|---|---|---|---|---|---|
0 | DE149 | 3 | DE | Sigmaringen | Sigmaringen | 4.0 | 3 | 3 | POLYGON ((4272515.778 2791989.118, 4291502.208... |
1 | DE211 | 3 | DE | Ingolstadt, Kreisfreie Stadt | Ingolstadt, Kreisfreie Stadt | 4.0 | 2 | 3 | POLYGON ((4430560.572 2849070.969, 4426522.606... |
2 | DE212 | 3 | DE | b'4dfc6e6368656e2c204b726569736672656965205374... | b'4dfc6e6368656e2c204b726569736672656965205374... | 4.0 | 1 | 3 | POLYGON ((4426190.454 2780289.957, 4425325.775... |
3 | DE213 | 3 | DE | Rosenheim, Kreisfreie Stadt | Rosenheim, Kreisfreie Stadt | 4.0 | 2 | 3 | POLYGON ((4470814.937 2743662.905, 4477767.129... |
4 | DE214 | 3 | DE | b'416c74f67474696e67' | b'416c74f67474696e67' | 4.0 | 2 | 3 | POLYGON ((4539906.565 2792493.475, 4525936.167... |
Skrive romlige data til en fil#
Å skrive data til en fil er like enkelt: bruk bare to_file()
metoden til en GeoDataFrame
.
Hvis vi vil beholde en lokal kopi av NUTS-region datasettet vi nettopp åpnet ‘on-the-fly’ fra en internettadress kan vi lagre dataene til en GeoJSON-fil (filformatet blir gjettet fra filnavnet). Før vi gjør det må vi sikre oss at datatypene er riktig formatert (ofte når data komprimeres, sånn som med NUTS-dataene, blir formateringen forenklet). Først kan vi sjekke hva slags datatype de ulike kolonnene har:
print(nuts_regions.dtypes)
NUTS_ID object
LEVL_CODE int64
CNTR_CODE object
NAME_LATN object
NUTS_NAME object
MOUNT_TYPE float64
URBN_TYPE int64
COAST_TYPE int64
geometry geometry
dtype: object
Her ser vi at vi har mange kolonner av typen object
, noe som bør endres. I dette tilfellet inneholder alle de gjeldende kolonnene tekststrenger, så vi kan endre de til str
før vi lagrer:
nuts_regions = nuts_regions.astype({col: 'str' for col in nuts_regions.select_dtypes(include='object').columns})
nuts_regions.to_file(DATA_MAPPE / "europe_nuts_regions.geojson")
NUTS_ID object
LEVL_CODE int64
CNTR_CODE object
NAME_LATN object
NUTS_NAME object
MOUNT_TYPE float64
URBN_TYPE int64
COAST_TYPE int64
geometry geometry
dtype: object
Note
Lesing og skriving av romlige data fra eller til en fil er nesten identisk for alle filformater som støttes av geopandas, fiona, og GDAL. Sjekk ut geopandas’ dokumentasjon for tips om hvordan du kan finjustere lesing eller skriving av en fil, og hvordan du kan bruke forskjellige filtre.
Lesing og skriving fra og til databaser (RDBMS)#
Geopandas har innebygd støtte for lese/skrive-tilgang til PostgreSQL/PostGIS-databaser, ved hjelp av dens geopandas.read_postgis()
funksjon og GeoDataFrame.to_postgis()
metode. For databasetilkoblingen kan du bruke, for eksempel, sqlalchemy
-pakken.
# Siden dette ikke er en ekte database, må informasjonen endres hvis den skal kjøre
'''
import sqlalchemy
DB_CONNECTION_URL = "postgresql://myusername:mypassword@myhost:5432/mydatabase";
db_engine = sqlalchemy.create_engine(DB_CONNECTION_URL)
countries = geopandas.read_postgis(
"SELECT name, geometry FROM countries",
db_engine
)
countries.to_postgis(
"new_table",
db_engine
)
'''
'\nimport sqlalchemy\nDB_CONNECTION_URL = "postgresql://myusername:mypassword@myhost:5432/mydatabase";\ndb_engine = sqlalchemy.create_engine(DB_CONNECTION_URL)\n\ncountries = geopandas.read_postgis(\n "SELECT name, geometry FROM countries",\n db_engine\n)\ncountries.to_postgis(\n "new_table", \n db_engine\n)\n'
Lesing av data direkte fra en WFS (Web feature service) endepunkt#
Geopandas kan også lese data direkte fra en WFS-endepunkt, som for eksempel geodata-APIene til Kartverket. Å konstruere en gyldig WFS-URI (adresse) er ikke en del av dette kurset (men sjekk, for eksempel, egenskapene til et lag lagt til QGIS).
Følgende kode laster et administrative enheter for Norge. Parameterne kodet inn i WFS-adressen spesifiserer lagets navn og det forespurte referansesystemet.
administrative_enheter = geopandas.read_file(
"https://wfs.geonorge.no/skwms1/wfs.administrative_enheter?"
"service=WFS"
"&version=2.0.0"
"&request=GetFeature"
"&srsname=EPSG:25833"
"&restrictToRequestBBOX=258331"
"&typename=app:Kommune"
)
administrative_enheter.head()
gml_id | lokalId | navnerom | versjonId | oppdateringsdato | gyldigFra | datauttaksdato | navn | språk | kommunenummer | kommunenavn | samiskForvaltningsområde | geometry | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | kommune.1 | 0466e7c3-6a23-4b70-97d4-cf81f949490b | https://data.geonorge.no/sosi/inndelinger/innd... | 3 | 2023-11-28T17:47:39 | 2024-01-01 | 2024-03-04T12:27:57 | [Ibestad] | [nor] | 5514 | Ibestad | False | MULTIPOLYGON (((589669.263 7630312.979, 589669... |
1 | kommune.2 | 0f821a2d-a307-41ec-9b64-f01c80e39357 | https://data.geonorge.no/sosi/inndelinger/innd... | 4 | 2023-11-07T23:33:28 | 2023-11-07 | 2024-03-04T12:27:57 | [Rendalen] | [nor] | 3424 | Rendalen | False | MULTIPOLYGON (((327391.890 6869419.570, 327363... |
2 | kommune.3 | 251a3fdd-ac96-4ef2-badb-a9b75e6ab2e6 | https://data.geonorge.no/sosi/inndelinger/innd... | 3 | 2023-11-28T15:42:05 | 2024-01-01 | 2024-03-04T12:27:57 | [Rakkestad] | [nor] | 3120 | Rakkestad | False | MULTIPOLYGON (((284560.990 6591094.550, 284575... |
3 | kommune.4 | 2758a7b8-edba-4d6a-936e-4754ce03ca8f | https://data.geonorge.no/sosi/inndelinger/innd... | 3 | 2023-11-28T15:56:10 | 2024-01-01 | 2024-03-04T12:27:57 | [Nordre Follo] | [nor] | 3207 | Nordre Follo | False | MULTIPOLYGON (((269615.270 6638265.470, 269615... |
4 | kommune.5 | 340fff7f-b153-4a87-814d-12ca4f2d1682 | https://data.geonorge.no/sosi/inndelinger/innd... | 4 | 2023-11-07T23:33:28 | 2023-11-07 | 2024-03-04T12:27:57 | [Overhalla] | [nor] | 5047 | Overhalla | False | MULTIPOLYGON (((359415.100 7152572.930, 359412... |
administrative_enheter.plot()
<Axes: >
