LayerMapping verktyg för dataimport¶
Klassen LayerMapping ger ett sätt att mappa innehållet i vektorbaserade rumsliga datafiler (t.ex. shapefiler) till GeoDjango-modeller.
Detta verktyg växte fram ur författarens personliga behov av att eliminera kodupprepningen som gick ut på att dra ut geometrier och fält från ett vektorlager, konvertera till ett annat koordinatsystem (t.ex. WGS84) och sedan infoga i en GeoDjango-modell.
Observera
Användning av LayerMapping kräver GDAL.
Varning
GIS-datakällor, såsom shapefiler, kan vara mycket stora. Om du märker att LayerMapping använder för mycket minne ska DEBUG sättas till False i inställningarna. När DEBUG är True loggar Django automatiskt varje SQL-fråga – och när SQL-satser innehåller geometrier kan detta förbruka mer minne än vanligt.
Exempel¶
Du behöver en GDAL-stödd datakälla, t.ex. en shapefil (här använder vi en enkel polygon-shapefil,
test_poly.shp, med tre funktioner):
>>> from django.contrib.gis.gdal import DataSource
>>> ds = DataSource("test_poly.shp")
>>> layer = ds[0]
>>> print(layer.fields) # Exploring the fields in the layer, we only want the 'str' field.
['float', 'int', 'str']
>>> print(len(layer)) # getting the number of features in the layer (should be 3)
3
>>> print(layer.geom_type) # Should be 'Polygon'
Polygon
>>> print(layer.srs) # WGS84 in WKT
GEOGCS["GCS_WGS_1984",
DATUM["WGS_1984",
SPHEROID["WGS_1984",6378137,298.257223563]],
PRIMEM["Greenwich",0],
UNIT["Degree",0.017453292519943295]]
Nu definierar vi vår motsvarande Django-modell (se till att använda
migrate):from django.contrib.gis.db import models class TestGeo(models.Model): name = models.CharField(max_length=25) # corresponds to the 'str' field poly = models.PolygonField(srid=4269) # we want our model in a different SRID def __str__(self): return "Name: %s" % self.name
Använd
LayerMappingför att extrahera alla funktioner och placera dem i databasen:
>>> from django.contrib.gis.utils import LayerMapping
>>> from geoapp.models import TestGeo
>>> mapping = {
... "name": "str", # The 'name' model field maps to the 'str' layer field.
... "poly": "POLYGON", # For geometry fields use OGC name.
... } # The mapping is a dictionary
>>> lm = LayerMapping(TestGeo, "test_poly.shp", mapping)
>>> lm.save(verbose=True) # Save the layermap, imports the data.
Saved: Name: 1
Saved: Name: 2
Saved: Name: 3
Här transformerade LayerMapping de tre geometrierna från shapefilen i deras ursprungliga spatiala referenssystem (WGS84) till det spatiala referenssystemet för GeoDjango-modellen (NAD83). Om inget spatialt referenssystem är definierat för lagret använder du nyckelordet source_srs med ett SpatialReference-objekt för att ange ett.
aPI LayerMapping API¶
- class LayerMapping(model, data_source, mapping, layer=0, source_srs=None, encoding=None, transaction_mode='commit_on_success', transform=True, unique=True, using='default')[source]¶
Följande är de argument och nyckelord som kan användas vid instansiering av LayerMapping objekt.
Argument |
Beskrivning |
|---|---|
|
Den geografiska modellen, inte en instans. |
|
Sökvägen till den OGR-stödda datakällfilen (t.ex. en shapefil). Accepterar även instanser av |
|
En ordbok: nycklarna är strängar som motsvarar modellfältet och värdena motsvarar strängfältsnamn för OGR-objektet, eller om modellfältet är geografiskt bör det motsvara OGR:s geometrityp, t.ex. |
Argument för nyckelord |
|
|---|---|
|
Indexet för det lager som ska användas från datakällan (standardvärde 0) |
|
Använd detta för att ange källans SRS manuellt (vissa shapefiler levereras till exempel utan filen |
|
Anger teckenkodsningen för strängarna i OGR-datakällan. Till exempel är |
|
Kan vara |
|
Om detta anges till False inaktiveras koordinattransformationer. Med andra ord infogas geometrier i databasen utan ändringar från deras ursprungliga tillstånd i datakällan. |
|
Om detta anges till namnet, eller en tuppel med namn, från den angivna modellen skapas modeller som är unika endast för det angivna namnet eller de angivna namnen. Geometrier från varje objekt läggs till i samlingen som är kopplad till den unika modellen. Tvingar transaktionsläget till |
|
Anger den databas som ska användas vid import av rumsliga data. Standard är |
save() Nyckelord Argument¶
- LayerMapping.save(verbose=False, fid_range=False, step=False, progress=False, silent=False, stream=sys.stdout, strict=False)[source]¶
Metoden save() accepterar även nyckelord. Dessa nyckelord används för att styra utdata-loggning, felhantering och import av specifika intervall av objekt.
Spara sökordsargument |
Beskrivning |
|---|---|
|
Kan anges med ett snitt eller en tuppel av objekt-ID:n |
|
När detta nyckelord anges skrivs statusinformation ut med antalet objekt som behandlats och sparats. Som standard skrivs förloppsinformation ut för var 1 000:e bearbetat objekt, men detta standardvärde kan åsidosättas genom att ange ett heltal för önskat intervall. |
|
Som standard skrivs icke-fatala felmeddelanden ut till |
|
Om det anges med ett heltal kommer transaktioner att ske vid varje stegintervall. Om t.ex. |
|
Statusinformation skrivs till detta filhandtag. Standardvärdet är |
|
Körningen av modellmappningen avbryts vid det första fel som påträffas. Standardvärdet ( |
|
Om den är inställd kommer information att skrivas ut efter varje modellsparning som utförs i databasen. |
Felsökning¶
Minnet tar slut¶
Som anges i varningen i början av detta avsnitt lagrar Django alla SQL-frågor när DEBUG=True. Sätt DEBUG=False i inställningarna så bör den stora minnesanvändningen upphöra när LayerMapping-skript körs.
MySQL: max_allowed_packet fel¶
Om du stöter på följande fel när du använder LayerMapping och MySQL:
OperationalError: (1153, "Got a packet bigger than 'max_allowed_packet' bytes")
Lösningen är då att öka värdet för inställningen max_allowed_packet i MySQL-konfigurationen. Standardvärdet kan till exempel vara så lågt som en megabyte – inställningen kan ändras i MySQL-konfigurationsfilen (my.cnf), i avsnittet [mysqld]:
max_allowed_packet = 10M