Geopackage med Python

I detta inlägg försöker jag dokumentera enklast möjliga sättet att lägga till punkter i ett geopackage. Heter det förresten en eller ett geopackage(-fil)?

På sikt så vill jag använda detta för att spara data till en fil direkt från en Raspberry Pi med ansluten GPS.

Hur GPS ansluts och hur man läser data från denna har jag skrivit om tidigare, men nu vill jag kunna spara till något annat än en textfil.

Detta innebär lite fler utmaningar, men det är inte oöverkomligt.

För det första behöver man ha GDAL/OGR installerat med python-bindningar. För geopackage behöver GDAL även ”libsqlite3”.

from osgeo import ogr, osr

# Skapa koordinatsystem för lagrets koordinater
srs = osr.SpatialReference()
srs.ImportFromEPSG(4326)

# Skapa "driver" för geopackage
gpkgDrv = ogr.GetDriverByName("GPKG")
# Skapa en datakälla
dS = gpkgDrv.CreateDataSource("filnamn.gpkg")
# Skapa själva lagret med en geometri
lr = dS.CreateLayer("filnamn.gpkg", srs, ogr.wkbPoint)
# Skapa eventuella attribut, upprepa för flera fält
fD = ogr.FieldDefn("textfält", ogr.OFTString)
lr.CreateField(fD)
# Hämta lagerdefinition
lD = lr.GetLayerDefn()

# Objektet...
ft  = ogr.Feature(lD)
# Nästa rad skapar en enskild punkt
punkt = ogr.Geometry(ogr.wkbPoint)
# och lägger till en position i X, Y
punkt.AddPoint(15,55)
# Tilldela objektet positionen
ft.SetGeometry(punkt)
# Tilldela objektet attribut, upprepa för alla attribut
ft.SetField("textfält", "attributvärde")
# Skapa objektet i lagret
lr.CreateFeature(ft)

# Stäng filen och frigör resurser
dS.Destroy()

Koden ovan skapar ett geopackage med en punkt, men vill man ha flera så behöver man göra lite anpassningar.

För att det skall gå att upprepa så skall ”ft” objektet skapas på nytt, för varje gång ett nytt objekt skall läggas till. Det block som inleds med # Objektet… skall därför upprepas för varje punkt som skall läggas till.

Nu har jag lagt till kommentarer vid varje rad i koden ovan så det ser mer ut än vad det är. Nu kan jag använda detta för att skapa en ”skrivare” för geopackage i mina pythonskript.

Vill man använda andra attributtyper än ”text” så kan man använda OFTInteger, OFTReal, OFTDate, med flera typer. Vissa av dessa har ytterligare egenskaper som kan eller bör sättas.

För att skapa funktioner så börjar jag med att ”bryta ut” det som jag vill kunna ändra i variabler.

EPSG = 4326
filnamn = "filnamn.gpkg"
attrNamn = ["namn1", "namn2"]
attrTyp = [ogr.OFTString, ogr.OFTString]
lon = 15.2 # nytt värde för varje punkt
lat = 55.3 # nytt värde för varje punkt
attrVarde = ["Värde1", "Värde2"] # ny lista för varje punkt

Sedan kan man skicka dessa variabler med anrop av funktioner som skapar lagret, lägger till punkter och sedan avslutar.

skapaLager(EPSG, filnamn, attrNamn, attrTyp)
# Upprepa för varje punkt
nyPunkt(lon, lat, attrVarde)
avslutaLager()

Själva funktionerna kan du nog själv lista ut hur de kan skrivas… eller?

Tänk bara på att deklarera eventuella ”globala” variabler om du inte är fruktansvärt kreativ med anropen.

Ja, ja! Okej då! Här kommer mina funktioner.

def skapaLager(EPSG, filnamn, attrNamn, attrTyp):
   gpkgDrv = ogr.GetDriverByName("GPKG")
   global dS
   dS = gpkgDrv.CreateDataSource(filnamn)
   global lr
   srs = osr.SpatialReference()
   srs.ImportFromEPSG(EPSG)
   lr = dS.CreateLayer(filnamn, srs, ogr.wkbPoint)
   for namn, typ in zip(attrNamn, attrTyp):
     fD = ogr.FieldDefn(namn, typ)
     lr.CreateField(fD)
 
def nyPunkt(lon, lat, attrNamn, attrVarde):
   global lr
   lD = lr.GetLayerDefn()
   ft = ogr.Feature(lD)
   punkt = ogr.Geometry(ogr.wkbPoint)
   punkt.AddPoint(lon, lat)
   ft.SetGeometry(punkt)
   for namn, varde in zip(attrNamn, attrVarde):
     ft.SetField(namn, varde)
   lr.CreateFeature(ft)
 
def avslutaLager():
   global dS
   dS.Destroy()
Annonser

Taggar:,

Kommentera

Fyll i dina uppgifter nedan eller klicka på en ikon för att logga in:

WordPress.com Logo

Du kommenterar med ditt WordPress.com-konto. Logga ut / Ändra )

Twitter-bild

Du kommenterar med ditt Twitter-konto. Logga ut / Ändra )

Facebook-foto

Du kommenterar med ditt Facebook-konto. Logga ut / Ändra )

Google+ photo

Du kommenterar med ditt Google+-konto. Logga ut / Ändra )

Ansluter till %s

%d bloggare gillar detta: