GeoDjango modell-API¶
Detta dokument utforskar detaljerna i GeoDjango Model API. I detta avsnitt kommer vi att använda följande geografiska modell av en ”ZIP-kod” och en ”digital höjdmodell” som exempel:
from django.contrib.gis.db import models
class Zipcode(models.Model):
code = models.CharField(max_length=5)
poly = models.PolygonField()
class Elevation(models.Model):
name = models.CharField(max_length=100)
rast = models.RasterField()
Spatiala fälttyper¶
Spatiala fält består av en serie geometriska fälttyper och en rasterfälttyp. Var och en av geometrifälttyperna motsvarar OpenGIS Simple Features-specifikationen [1]. Det finns ingen sådan standard för rasterdata.
GeometryField
¶
Basklass för geometriska fält.
PointField
¶
Lagrar en :klass:`~django.contrib.gis.geos.Point`.
LineStringField
¶
Lagrar en :klass:`~django.contrib.gis.geos.LineString`.
PolygonField
¶
Lagrar en :klass:`~django.contrib.gis.geos.Polygon`.
MultiPointField
¶
Lagrar en :klass:`~django.contrib.gis.geos.MultiPoint`.
MultiLineStringField
¶
Lagrar en :klass:`~django.contrib.gis.geos.MultiLineString`.
MultiPolygonField
¶
GeometryCollectionField
¶
Lagrar en :klass:`~django.contrib.gis.geos.GeometryCollection`.
RasterField
¶
Lagrar en :klass:`~django.contrib.gis.gdal.GDALRaster`.
RasterField
är för närvarande endast implementerat för PostGIS backend.
Alternativ för rumslig fältindelning¶
Förutom de vanliga Alternativ för fält som finns tillgängliga för Django-modellfält, har spatiala fält följande ytterligare alternativ. Alla är valfria.
srid
¶
- BaseSpatialField.srid¶
Ställer in SRID [2] (Spatial Reference System Identity) för geometrifältet till det angivna värdet. Standardvärdet är 4326 (även känt som `WGS84`__, enheterna är i grader av longitud och latitud).
Välja en SRID¶
Att välja en lämplig SRID för din modell är ett viktigt beslut som utvecklaren bör överväga noga. SRID är en heltalsspecifikation som motsvarar det projektionssystem som kommer att användas för att tolka data i den rumsliga databasen. [Projektionssystem ger sammanhang åt de koordinater som anger en plats. Även om detaljerna i `geodesi`__ ligger utanför ramen för denna dokumentation, är det allmänna problemet att jorden är sfärisk och att representationer av jorden (t.ex. papperskartor, webbkartor) inte är det.
De flesta känner till hur man använder latitud och longitud för att referera till en plats på jordens yta. Latitud och longitud är dock vinklar, inte avstånd. Med andra ord, medan den kortaste vägen mellan två punkter på en plan yta är en rak linje, är den kortaste vägen mellan två punkter på en krökt yta (som jorden) en båge i en stor cirkel. [4] Det krävs alltså ytterligare beräkningar för att få fram avstånd i plana enheter (t.ex. kilometer och miles). Att använda ett geografiskt koordinatsystem kan medföra komplikationer för utvecklaren i ett senare skede. SpatiaLite har t.ex. inte möjlighet att utföra avståndsberäkningar mellan geometrier som använder geografiska koordinatsystem, t.ex. att konstruera en fråga för att hitta alla punkter inom 8 km från en länsgräns som lagrats som WGS84. [5]
Delar av jordens yta kan projiceras på ett tvådimensionellt, eller kartesiskt, plan. Projicerade koordinatsystem är särskilt lämpliga för regionspecifika tillämpningar, t.ex. om du vet att din databas endast kommer att omfatta geometrier i ”Norra Kansas”, kan du överväga att använda ett projektionssystem som är specifikt för den regionen. Dessutom definieras projicerade koordinatsystem i kartesiska enheter (t.ex. meter eller fot), vilket underlättar avståndsberäkningar.
Observera
Om du vill utföra godtyckliga avståndsfrågor med hjälp av icke-punktgeometrier i WGS84 i PostGIS och du vill ha anständig prestanda, aktivera nyckelordet GeometryField.geography
så att geography database type används istället.
Mer om detta:
`spatialreference.org`__: En Django-driven databas med rumsliga referenssystem.
”Koordinatsystemet för det statliga planet”: En webbplats som täcker de olika projektionssystem som används i USA. En stor del av de amerikanska rumsliga data som påträffas kommer att vara i ett av dessa koordinatsystem snarare än i ett geografiskt koordinatsystem som WGS84.
rumsligt_index
¶
- BaseSpatialField.spatial_index¶
Standardvärdet är True
. Skapar ett spatialt index för det angivna geometriska fältet.
Observera
Detta skiljer sig från fältalternativet db_index
eftersom spatiala index skapas på ett annat sätt än vanliga databasindex. Spatiala index skapas vanligtvis med hjälp av en variant av R-trädet, medan vanliga databasindex vanligtvis använder B-träd.
Alternativ för geometrifält¶
Det finns ytterligare alternativ tillgängliga för Geometry-fält. Alla följande alternativ är valfria.
dim
¶
- GeometryField.dim¶
Detta alternativ kan användas för att anpassa koordinatdimensionen i geometrifältet. Som standard är den inställd på 2, för att representera tvådimensionella geometrier. För spatiala backends som stöder detta kan den sättas till 3 för tredimensionellt stöd.
Observera
För närvarande är 3D-stödet begränsat till PostGIS- och SpatiaLite-backends.
geografi
¶
- GeometryField.geography¶
Om detta alternativ är inställt på True
skapas en databaskolumn av typen geography i stället för geometry. Se avsnittet geography type nedan för mer information.
Observera
Geografistödet är begränsat till PostGIS och tvingar SRID att vara 4326.
Geografi Typ¶
Geografitypen ger inbyggt stöd för rumsliga egenskaper som representeras med geografiska koordinater (t.ex. WGS84-längdgrad/latitud). [6] Till skillnad från planet som används av en geometrityp, använder geografin en sfärisk representation av sina data. Avstånds- och mätoperationer som utförs på en geografikolumn använder automatiskt beräkningar av storcirkelbågar och returnerar linjära enheter. Med andra ord, när ST_Distance
anropas på två geografier returneras ett värde i meter (i motsats till grader om det anropas på en geometrikolumn i WGS84).
Eftersom geografiska beräkningar kräver mer matematik är endast en delmängd av PostGIS rumsliga uppslagsord tillgängliga för den geografiska typen. I praktiken innebär detta att utöver distance lookups är endast följande ytterligare spatial lookups tillgängliga för geografiska kolumner:
täckt av
täcken
Om du behöver använda en spatial lookup eller aggregat som inte stöder geografin som indata kan du använda databasfunktionen Cast
för att konvertera geografikolumnen till en geometrityp i frågan:
from django.contrib.gis.db.models import PointField
from django.db.models.functions import Cast
Zipcode.objects.annotate(geom=Cast("geography_field", PointField())).filter(
geom__within=poly
)
För mer information, PostGIS-dokumentationen innehåller ett användbart avsnitt om att avgöra ”när man ska använda geografisk datatyp över geometrisk datatyp <https://postgis.net/docs/using_postgis_dbmanagement.html#PostGIS_GeographyVSGeometry>`_.
Fotnoter