Zurück zum Katalog
Season 44 15 Episoden 1h 0m 2026

GeoDjango and PostGIS

v6.0 — 2026 Edition. Ein umfassender Audiokurs zur Entwicklung räumlicher Webanwendungen mit GeoDjango und PostGIS. Aufgenommen im Jahr 2026, behandelt GeoDjango Version 6.0.

Geodatenanalyse Räumliche Webanwendungen Datenbanken
GeoDjango and PostGIS
Aktuelle Wiedergabe
Click play to start
0:00
0:00
1
Die Leistungsfähigkeit räumlicher Web-Frameworks
Diese Episode stellt GeoDjango und PostGIS als leistungsstarke Kombination für die Entwicklung geografischer Webanwendungen vor. Du erfährst, warum herkömmliche Datenbanken mit räumlichen Daten zu kämpfen haben und wie räumliche Erweiterungen dieses Problem lösen.
3m 39s
2
PostGIS Geometry vs Geography
Diese Episode untersucht PostGIS-Datentypen und konzentriert sich insbesondere auf den Unterschied zwischen Geometry- und Geography-Typen. Du lernst, wann du kartesische Mathematik auf einer flachen Ebene im Vergleich zu Berechnungen auf einer kugelförmigen Erde anwenden solltest.
3m 46s
3
Einrichtung deiner räumlichen Umgebung
Diese Episode behandelt die Ersteinrichtung eines GeoDjango- und PostGIS-Projekts. Du erfährst, wie du die PostGIS-Erweiterung aktivierst und deine Django-Einstellungen konfigurierst, um eine Verbindung zu einem räumlichen Backend herzustellen.
4m 07s
4
Koordinatenreferenzsysteme und SRIDs
Diese Episode schlüsselt Koordinatenreferenzsysteme und SRIDs auf. Du lernst, was WGS84 ist und warum die korrekte Projektion deiner Kartendaten für genaue Entfernungsmessungen entscheidend ist.
3m 56s
5
Entwurf geografischer Modelle
Diese Episode zeigt, wie man geografische Modelle in GeoDjango entwirft. Du lernst, wie du PointField- und MultiPolygonField-Attribute definierst, um räumliche Daten in deiner Django-Anwendung zu speichern.
4m 13s
6
Die GDAL und OGR API
Diese Episode stellt die GDAL und OGR API-Wrapper innerhalb von GeoDjango vor. Du erfährst, wie du externe Vektordateien wie Shapefiles nativ in Python untersuchen und lesen kannst, bevor du sie importierst.
3m 32s
7
Einlesen räumlicher Daten mit LayerMapping
Diese Episode behandelt die Automatisierung von Importen räumlicher Daten. Du lernst, wie du das LayerMapping-Dienstprogramm verwendest, um externe Shapefile-Daten mühelos direkt in deine GeoDjango-Modelle zu mappen.
4m 28s
8
Die GEOS API: Pythonische Geometrie
Diese Episode konzentriert sich auf die GEOS API für die pythonische Geometriemanipulation. Du lernst, wie du topologische Operationen wie Vereinigungen und Schnittmengen im Arbeitsspeicher durchführst, ohne die Datenbank abzufragen.
3m 44s
9
Meisterung von Spatial Lookups
Diese Episode erklärt geografische Query-Lookups im Django ORM. Du lernst, wie du räumliche Filter verwendest, um Beziehungen zu finden, wie zum Beispiel, welche Punkte innerhalb bestimmter Grenzen liegen.
4m 09s
10
High-Performance Distanzabfragen
Diese Episode befasst sich mit hochperformanten Umkreis- und Distanzabfragen. Du lernst, wie du Distance-Lookups und das geografische Distance-Objekt verwendest, um nahegelegene Orte effizient zu finden.
4m 00s
11
Geografische Datenbankfunktionen
Diese Episode untersucht räumliche Datenbankfunktionen, die über GeoDjango zugänglich sind. Du lernst, wie du Flächen berechnest, Zentroide extrahierst und GeoJSON direkt auf der Datenbankebene generierst.
4m 15s
12
Rasterdaten in PostGIS
Diese Episode führt in PostGIS-Raster und GeoDjango RasterFields ein. Du lernst, wie du kontinuierliche räumliche Daten wie Höhenmodelle oder Temperaturkarten speicherst und abfragst.
4m 27s
13
Geolokalisierung mit GeoIP2
Diese Episode behandelt die IP-basierte Geolokalisierung mit dem GeoIP2-Modul von GeoDjango. Du lernst, wie du Benutzer-IP-Adressen mithilfe von MaxMind-Datensätzen Städten und Ländern zuordnest.
4m 11s
14
Testen räumlicher Anwendungen
Diese Episode konzentriert sich auf das Testen räumlicher Anwendungen in GeoDjango. Du lernst, wie du deine Test-Suite konfigurierst, mit PostGIS-Template-Datenbanken umgehst und Benutzerberechtigungen einrichtest.
3m 38s
15
Deployment von GeoDjango-Anwendungen
Diese Episode schließt die Serie ab, indem sie Deployment-Überlegungen für GeoDjango-Apps diskutiert. Du erfährst mehr über GDAL-Thread-Sicherheit und wie du deine WSGI-Prozesse konfigurierst, um Abstürze zu vermeiden.
4m 09s

Episoden

1

Die Leistungsfähigkeit räumlicher Web-Frameworks

3m 39s

Diese Episode stellt GeoDjango und PostGIS als leistungsstarke Kombination für die Entwicklung geografischer Webanwendungen vor. Du erfährst, warum herkömmliche Datenbanken mit räumlichen Daten zu kämpfen haben und wie räumliche Erweiterungen dieses Problem lösen.

Herunterladen
Hallo, hier ist Alex von DEV STORIES DOT EU. GeoDjango und PostGIS, Folge 1 von 15. Hast du schon mal versucht, die Entfernung zwischen zwei Latitude- und Longitude-Punkten mit einer normalen SQL Query zu berechnen? Meistens schreibst du dann einen riesigen, fehleranfälligen Block an Trigonometrie, nur um herauszufinden, welches Café am nächsten ist. Standard-Datenbanken verstehen den physischen Raum einfach nicht. Genau diese Datenlücke schließen wir heute in The Power of Spatial Web Frameworks. Viele denken, geografische Daten zu speichern bedeutet einfach, einer Database Table zwei Decimal-Columns hinzuzufügen – eine für Latitude und eine für Longitude. Das ist ein weit verbreitetes Missverständnis. Wenn du ein Routing-System für Essenslieferungen baust und das nächste Restaurant für einen Kunden finden musst, behandelt eine Standard-Datenbank diese Koordinaten als beliebige Floating-Point-Zahlen. Sie weiß nicht, dass die Erde eine Kugel ist. Sie kann Boundaries, Intersections oder reale Entfernungen nicht effizient berechnen. Du bist gezwungen, Tausende von Records in deinen Application Memory zu laden und die Berechnungen selbst durchzuführen. Hier kommt eine Spatial Database ins Spiel. PostGIS ist eine Spatial Extension für die PostgreSQL-Datenbank. Sie verändert die grundlegende Art, wie Daten gespeichert werden. Statt zwei separater Number-Columns speicherst du ein einziges Geometry- oder Geography-Objekt. Eine Spatial Database versteht die Mathematik der physischen Welt nativ. Sie weiß, was ein Point, eine Line und ein Polygon sind. Wenn du alle Restaurants im Umkreis von zwei Kilometern um einen User finden willst, nutzt PostGIS spezielle Spatial Indexes, um die Antwort sofort auf Datenbankebene zu finden. Aber eine smarte Datenbank ist nur die halbe Miete. Du musst diese Spatial Logic noch mit deiner Web Application verbinden. Das bringt uns zu GeoDjango. GeoDjango ist ein erstklassiges Geographic Framework, das direkt in Django integriert ist. Es fungiert als Brücke zwischen deiner Spatial Database und deiner Application Logic. GeoDjango erweitert Djangos standardmäßigen Object-Relational Mapper, sodass er PostGIS-Geometries versteht. Du interagierst mit geografischen Daten genau so, wie du mit regulären Database Models interagierst. Anstatt rohe Spatial SQL Queries zu schreiben, nutzt du Python. Du kannst Datenbankergebnisse basierend auf Spatial Relationships filtern, zum Beispiel prüfen, ob das Delivery-Zone-Polygon eines Restaurants den Point einer bestimmten User-Adresse enthält. GeoDjango übersetzt deinen Python-Code in die korrekten PostGIS Queries. Es enthält sogar Map Widgets für das Django Administration Panel, sodass du geografische Daten direkt out of the box visuell erstellen und bearbeiten kannst. Zusammen bilden PostGIS und GeoDjango einen unglaublich leistungsfähigen Stack. PostGIS übernimmt die schwere mathematische Arbeit auf dem Storage Layer, und GeoDjango bietet das saubere Python Interface, um diese Daten an deine User auszuliefern. Du hörst auf, dich mit komplexer Trigonometrie herumzuschlagen, und fängst an, echte Location-Aware Features zu bauen. Hier ist die wichtigste Erkenntnis. Die wahre Power eines Spatial Frameworks ist nicht nur das Zeichnen von Lines auf einer Web Map. Sie besteht darin, komplexe Spatial Mathematics komplett aus deinem Application Code in eine Database Engine auszulagern, die speziell dafür gebaut wurde, Geometry zu verstehen. Wenn du diese Deep Dives hilfreich findest, kannst du die Show unterstützen, indem du auf Patreon nach DevStoriesEU suchst. Das war's für heute. Danke fürs Zuhören – geh und bau etwas Cooles.
2

PostGIS Geometry vs Geography

3m 46s

Diese Episode untersucht PostGIS-Datentypen und konzentriert sich insbesondere auf den Unterschied zwischen Geometry- und Geography-Typen. Du lernst, wann du kartesische Mathematik auf einer flachen Ebene im Vergleich zu Berechnungen auf einer kugelförmigen Erde anwenden solltest.

Herunterladen
Hallo, hier ist Alex von DEV STORIES DOT EU. GeoDjango und PostGIS, Folge 2 von 15. Der kürzeste Weg zwischen zwei Punkten auf der Erde ist keine Gerade, sondern eine Kurve. Wenn deine Datenbank Längen- und Breitengrade wie ein gewöhnliches X- und Y-Grid behandelt, werden deine Distance Queries komplett falsch sein. Um das zu beheben, musst du den Unterschied zwischen den PostGIS-Datentypen Geometry und Geography verstehen. Standardmäßig arbeiten Spatial Databases auf einer flachen, zweidimensionalen Ebene. Das ist der Geometry-Typ. Er nutzt standardmäßige kartesische Mathematik. Wenn du die Entfernung zwischen zwei Punkten herausfinden willst, zieht die Datenbank im Grunde eine gerade Linie und wendet den Satz des Pythagoras an. Dieser Ansatz ist für lokale Daten unglaublich schnell und hochpräzise. Wenn du einen Häuserblock mappst, die Wände eines Gebäudes plottest oder die genaue Grenze eines kleinen Parks trackst, ist die Erdkrümmung vernachlässigbar. Eine flache Karte funktioniert hier perfekt. Entwickler gehen oft davon aus, dass sie den Geometry-Typ für alles verwenden können. Sie speichern globale GPS-Koordinaten, also Längen- und Breitengrade, in einer flachen Geometry-Column. Wenn sie die Datenbank anweisen, eine Entfernung zu berechnen, gibt sie eine bedeutungslose Zahl in Grad zurück, statt in Metern oder Meilen. Um mit dem Geometry-Typ reale Entfernungen über große Gebiete zu bekommen, musst du deine Daten ständig in spezifische, lokalisierte Map-Projections übersetzen. Genau deshalb bietet PostGIS den Geography-Typ an. Der Geography-Typ modelliert die Erde als Kugel. Genauer gesagt nutzt er nativ das Spatial Reference System WGS84. Wenn du Koordinaten in einer Geography-Column speicherst, versteht die Datenbank, dass die Oberfläche gekrümmt ist. Wenn du sie nach einer Entfernung fragst, zieht sie keine flache Linie. Sie berechnet eine Großkreisroute. Denk mal daran, eine Flugroute von New York nach London zu messen. Wenn du den Geometry-Typ auf einer unprojizierten flachen Standardkarte verwendest, berechnet die Datenbank eine gerade Linie, die direkt durch das Grid schneidet. Wenn du den Geography-Typ verwendest, berechnet die Datenbank die echte kürzeste Entfernung entlang der Erdkrümmung und zeichnet den Großkreis über dem Atlantik nach. Noch besser: Der Geography-Typ gibt diese Entfernung automatisch in Metern zurück. Du umgehst komplett die Notwendigkeit, komplexe Map-Projections selbst zu managen. Hier ist die wichtigste Erkenntnis. Du könntest schlussfolgern, dass Geography der überlegene Typ ist und Geometry komplett ersetzen sollte. Das ist falsch. Entfernungen auf einer Kugel zu berechnen, erfordert aufwendige Trigonometrie. Das erfordert deutlich mehr Processing Power als Flat-Plane-Mathematik, was Operationen auf Geography-Typen langsamer macht. Außerdem unterstützt PostGIS viel weniger Spatial Functions für Geography als für Geometry. Viele fortgeschrittene geometrische Operationen lassen sich einfach nicht auf sphärische Mathematik übertragen. Deine Wahl hängt komplett von der physischen Spannweite deiner Daten ab. Nutze den Geography-Typ, wenn deine Application Punkte global speichert und genaue Entfernungen ohne Projection-Management-Overhead braucht. Nutze den Geometry-Typ, wenn deine Daten auf eine bestimmte lokale Region beschränkt sind, oder wenn du die absolute maximale Performance und die komplette Suite an Spatial Functions brauchst. Der Typ, den du wählst, definiert die Form der Welt, in der deine Datenbank lebt. Danke, dass du ein paar Minuten mit mir verbracht hast. Bis zum nächsten Mal, mach's gut.
3

Einrichtung deiner räumlichen Umgebung

4m 07s

Diese Episode behandelt die Ersteinrichtung eines GeoDjango- und PostGIS-Projekts. Du erfährst, wie du die PostGIS-Erweiterung aktivierst und deine Django-Einstellungen konfigurierst, um eine Verbindung zu einem räumlichen Backend herzustellen.

Herunterladen
Hallo, hier ist Alex von DEV STORIES DOT EU. GeoDjango und PostGIS, Folge 3 von 15. Um deine Standard-Datenbank in eine Spatial Engine zu verwandeln, brauchst du genau drei SQL-Wörter. Aber wenn du sie im falschen Kontext ausführst, schlägt deine Django-Application schon bei der allerersten Migration fehl. Heute konzentrieren wir uns komplett auf das Setup deiner Spatial Environment. Wir starten auf dem Database Layer. Du hast PostgreSQL bereits am Laufen und eine leere Datenbank für dein neues Projekt erstellt. In dieser Phase ist die Datenbank noch absoluter Standard. Sie versteht nur Text, Integers, Dates und standardmäßige relationale Typen. Sie hat keine Ahnung, was eine Koordinate oder eine geografische Boundary ist. Um das zu ändern, musst du PostGIS aktivieren. Hier stolpern viele, weil sie annehmen, dass die Installation der PostGIS-Packages auf ihrem Server automatisch jede Datenbank spatially aware macht. Das ist nicht der Fall. Die Spatial Extension muss direkt in der spezifischen Datenbank erstellt werden, die dein Projekt nutzen wird. Du musst dich direkt mit dieser neuen Datenbank verbinden, entweder über einen Database Client oder die Command Line. Sobald du verbunden bist, führst du den Command aus, um die Extension namens postgis zu erstellen. Diese drei SQL-Wörter transformieren die Environment sofort. PostgreSQL führt den Command aus und lädt hunderte von Spatial Functions und spezialisierten Datentypen in dein Schema. Außerdem wird eine wichtige System Table generiert, die die Spatial Reference Systems speichert. Diese liefern die mathematischen Formeln, die nötig sind, um globale Koordinaten auf einen flachen Screen zu projizieren. Wenn die Datenbank vorbereitet ist, wechselst du rüber zu deinem Django-Projekt. Du bootstrapst ein Standard-Projekt und erstellst eine neue Application. Nennen wir diese App world. Öffne nun dein Settings-File. Es sind zwei bestimmte Modifikationen nötig, um Django und PostGIS zu verbinden. Finde zuerst dein installed apps Array. Du musst das Modul namens django punkt contrib punkt gis hinzufügen. Dieses Modul ist der Core von GeoDjango. Es lädt die Python-Wrapper für die zugrundeliegenden Geographic Libraries und stellt die Spatial Fields und Geographic Database Lookups bereit, die du später nutzen wirst, um Queries zu schreiben. Du hängst auch deine neue world App an diese Liste an, damit Django weiß, dass es ihre Models tracken soll. Hier ist der entscheidende Punkt. Die zweite Modifikation passiert in deinem Database Configuration Dictionary. Django routet den gesamten Database Traffic über ein Engine Backend. Wenn du die Engine auf dem Default PostgreSQL Backend belässt, behandelt Django deine Spatial Database wie eine Standard Relational Database. Es wird nicht wissen, wie man einen Geographic Shape serialisiert oder eine Bounding Box Query sicher parst. Du musst die Engine explizit auf das GeoDjango PostGIS Backend zeigen lassen. Du änderst den Engine-Value auf django punkt contrib punkt gis punkt db punkt backends punkt postgis. Der Rest des Connection Dictionarys bleibt identisch. Du übergibst weiterhin Database Name, User, Password, Host und Port, genau wie du es bei einem Standard-Setup tun würdest. Wenn du deine initialen Migrations ausführst, übernimmt dieses neue Backend. Es verbindet sich mit PostgreSQL und checkt sofort, ob die PostGIS Extension vorhanden ist. Wenn du vergessen hast, die Extension in der Datenbank zu erstellen, fängt das Backend die fehlenden Spatial Types ab und wirft einen Error. Ist die Extension vorhanden, ist die Connection erfolgreich. Du hast nun eine komplette Spatial Pipeline. Die wahre Power dieser spezifischen Configuration ist, dass, sobald das postgis Backend angebunden ist, die massive Komplexität von Spatial Database Queries komplett hinter dem vertrauten Django Object Relational Mapper verborgen bleibt. Das war's für diese Folge. Danke fürs Zuhören und keep building!
4

Koordinatenreferenzsysteme und SRIDs

3m 56s

Diese Episode schlüsselt Koordinatenreferenzsysteme und SRIDs auf. Du lernst, was WGS84 ist und warum die korrekte Projektion deiner Kartendaten für genaue Entfernungsmessungen entscheidend ist.

Herunterladen
Hallo, hier ist Alex von DEV STORIES DOT EU. GeoDjango und PostGIS, Folge 4 von 15. Versuch mal, den Grundriss eines Gebäudes anhand von Längen- und Breitengraden zu messen – deine Zahlen werden völlig nutzlos sein. Das liegt daran, dass Längen- und Breitengrade lediglich Winkel vom Erdmittelpunkt sind, keine physischen Entfernungen. Um diese Winkel in nutzbare Maßeinheiten wie Meter oder Fuß umzuwandeln, brauchst du ein Coordinate Reference System und eine SRID. Eine Koordinate wie 48 Grad Nord und 2 Grad Ost ist einfach nur ein Paar roher Zahlen. Ohne Kontext weiß deine Datenbank nicht, wie sie diese Zahlen auf die physische Welt mappen soll. Dieser Kontext kommt vom Spatial Reference System Identifier, meistens einfach SRID genannt. Eine SRID ist einfach ein Integer, der deine rohen Koordinatendaten mit einem spezifischen mathematischen Modell der Erde verknüpft. Standardmäßig verwenden GeoDjango Geometry Fields eine SRID von 4326. Dieser Integer repräsentiert das WGS84-Koordinatensystem. Es ist das Standardmodell, das von GPS-Satelliten und den meisten Web Mapping Libraries verwendet wird. Es speichert Daten in Form von Breiten- und Längengraden. WGS84 eignet sich hervorragend, um Orte überall auf der Welt genau zu lokalisieren. Allerdings ist es ein geografisches System, was bedeutet, dass es die Erde als dreidimensionale Form modelliert. Hier ist der springende Punkt. Du kannst flache Entfernungen oder Flächen nicht präzise mit Gradangaben berechnen. Die physische Entfernung zwischen zwei Längengraden schrumpft, wenn du dich vom Äquator in Richtung der Pole bewegst. Wenn du versuchst, alle Cafés im Umkreis von 500 Metern um einen Punkt mit der SRID 4326 zu finden, muss die Datenbank on the fly komplexe sphärische Berechnungen durchführen, was langsam und oft ungenau ist. Um das zu lösen, nutzt du Projected Coordinate Systems. Ein Projected System flacht einen bestimmten Teil der gekrümmten Erde mathematisch auf ein zweidimensionales Grid ab. Sobald der Bereich abgeflacht ist, wechseln die Koordinaten von Winkeln zu Standard-Längeneinheiten wie Metern oder Fuß. Das macht Entfernungsberechnungen mit grundlegender Geometrie schnell und genau. Deine Wahl der SRID hängt komplett vom Scope deiner Anwendung ab. Wenn du ein globales Flugverfolgungssystem baust, speicherst du deine Daten mit WGS84 und der SRID 4326. Deine Punkte erstrecken sich über die ganze Welt, also brauchst du ein globales System, auch wenn die Entfernungsberechnungen etwas komplexer sind. Wenn du eine lokale Stadtplanungs-Anwendung baust, um exakte Grundstücksgrenzen zu messen, ist die Verwendung von WGS84 ein Fehler. Stattdessen weist du deinem Spatial Field ein lokales Projected Coordinate System zu. Zum Beispiel könntest du ein spezifisches State Plane Coordinate System mit seiner eigenen, einzigartigen SRID verwenden. Diese lokalen Systeme sind hochgradig maßgeschneidert. Sie minimieren die Verzerrung, die beim Abflachen einer Kugel entsteht, aber eben nur für diese spezifische geografische Zone. Wenn du deine Models in GeoDjango aufsetzt, definierst du die SRID direkt am Spatial Field. Wenn du nichts machst, ist der Default 4326. Wenn du eine lokalisierte Projection in Metern willst, übergibst du diesen spezifischen Integer an die Field Definition. GeoDjango behandelt dann alle Geometrien in dieser Column entsprechend diesem spezifischen mathematischen Modell. Die richtige SRID stellt sicher, dass deine Entfernungsberechnungen sich nicht verzerren, wenn sich deine Daten weiter vom Äquator entfernen. Danke fürs Einschalten. Bis zum nächsten Mal!
5

Entwurf geografischer Modelle

4m 13s

Diese Episode zeigt, wie man geografische Modelle in GeoDjango entwirft. Du lernst, wie du PointField- und MultiPolygonField-Attribute definierst, um räumliche Daten in deiner Django-Anwendung zu speichern.

Herunterladen
Hallo, hier ist Alex von DEV STORIES DOT EU. GeoDjango und PostGIS, Folge 5 von 15. Du möchtest deiner Anwendung Standortdaten hinzufügen und denkst daher vielleicht daran, zwei einfache Float Fields für Längen- und Breitengrad in deine Datenbank einzufügen. Aber damit schließt du dich komplett von fortgeschrittenen Spatial Queries, Distanzberechnungen und geometrischen Intersections aus. Um diese Features freizuschalten, brauchst du richtige Spatial Types. Das bringt uns zum Thema: Designing Geographic Models. Der Wechsel von Standard-Django- zu GeoDjango-Models erfordert nur eine kleine Anpassung deiner Imports. Anstatt die Standard-Django-Database-Models zu verwenden, importierst du Models aus dem geographic contrib module. Dieses Custom Module bietet ein Drop-in Replacement. Es gibt dir Zugriff auf jeden Standard-Django-Field-Type, wie Characters und Integers, und führt gleichzeitig nahtlos Spatial Types in genau dieselbe Class Definition ein. Nehmen wir ein Szenario, in dem du ein WorldBorder-Model baust, um Länderdaten zu speichern. Du definierst die Model Class genau wie jede andere. Du vergibst ein Character Field für den Ländernamen, ein Integer Field für die Einwohnerzahl und ein Float Field für die Gesamtfläche. Um die eigentliche Kartengeometrie zu verarbeiten, fügst du direkt daneben ein Geographic Field hinzu. Für ein Land würdest du ein MultiPolygonField verwenden. Während ein PointField perfekt ist, um ein einzelnes Koordinatenpaar wie eine Hauptstadt zu speichern, kann ein MultiPolygonField komplexe Staatsgrenzen darstellen, inklusive Nationen mit mehreren voneinander getrennten Landmassen oder vorgelagerten Inseln. Wenn du dieses Spatial Field an dein Model anhängst, definierst du im Hintergrund ein Koordinatensystem. Jedes Geographic Field basiert auf einem Spatial Reference System Identifier, bekannt als SRID. Die SRID sagt der Datenbank, wie die rohen Koordinatenzahlen auf die tatsächliche Form der Erde projiziert werden sollen. Wenn du diesen Wert nicht explizit setzt, setzt GeoDjango die SRID standardmäßig auf 4326. Dieser spezifische Integer bezieht sich auf den WGS84-Standard, was genau dasselbe Koordinatensystem ist, das auch von Standard-GPS-Hardware verwendet wird. Wenn deine Source Data auf einer anderen lokalen Projektion basiert, übergibst du einfach den Ziel-Integer an den SRID-Parameter direkt in der Field Definition. Hier wird es interessant. Developer, die mit dem Django ORM vertraut sind, wissen: Um eine Column schnell abfragen zu können, musst du explizit ein Database Index Flag an die Field Definition übergeben. Weil Spatial Queries von Natur aus rechenintensiv sind, nimmst du vielleicht an, dass du manuell spezielle Indexes für deine Geometry Columns konfigurieren musst. Musst du aber nicht. Geographic Fields in GeoDjango funktionieren anders. Sie enthalten einen spezifischen Parameter für Spatial Indexing, und der steht standardmäßig auf true. Wenn du deine Migrations ausführst, sagt GeoDjango der zugrunde liegenden Datenbank automatisch, dass sie einen speziellen Spatial Index erstellen soll. Du bekommst High-Performance Bounding Box Queries und Geographic Intersection Lookups direkt out of the box, mit null extra Konfiguration. Die wahre Stärke, Models auf diese Weise zu designen, ist, dass es Spatial Data komplett entmystifiziert. Ein riesiges, komplexes Polygon, das einen Kontinent repräsentiert, wird einfach zu einer weiteren Property an deinem Python-Objekt, bereit, zusammen mit einer einfachen Einwohnerzahl gespeichert und abgefragt zu werden. Das war's für heute. Danke fürs Zuhören – geh und bau etwas Cooles.
6

Die GDAL und OGR API

3m 32s

Diese Episode stellt die GDAL und OGR API-Wrapper innerhalb von GeoDjango vor. Du erfährst, wie du externe Vektordateien wie Shapefiles nativ in Python untersuchen und lesen kannst, bevor du sie importierst.

Herunterladen
Hallo, hier ist Alex von DEV STORIES DOT EU. GeoDjango und PostGIS, Folge 6 von 15. Du bekommst eine riesige Geodatei – ein ESRI Shapefile oder ein GeoJSON – und musst wissen, welche Attribute sie enthält. Dein erster Instinkt ist vielleicht, ein schweres Desktop-GIS-Programm zu installieren, nur um mal reinzuschauen. Das musst du aber nicht. GeoDjango kann diese Dateien nativ direkt in der Python Shell über die GDAL und OGR API lesen. Wenn Geoinformationssysteme ein Werkzeugkasten sind, ist die Geospatial Data Abstraction Library der universelle Übersetzer. Technisch gesehen verarbeitet GDAL Rasterdaten wie Satellitenbilder, während der Partner OGR Vektordaten wie Points, Lines und Polygons verarbeitet. GeoDjango packt einen pythonischen Wrapper um die OGR Library und gibt dir so einen direkten Weg, fast jedes Vektor-Dateiformat auf dem Planeten zu inspizieren. Angenommen, du hast ein Shapefile mit den Grenzen aller Länder der Welt heruntergeladen. Bevor du ein Script schreibst, um diese Daten einzulesen, musst du genau wissen, wie sie strukturiert sind. Du startest, indem du das DataSource-Objekt aus dem GeoDjango-GDAL-Modul importierst. Du erstellst eine neue Data Source, indem du ihr den Dateipfad deines Shapefiles übergibst. Dieses Objekt repräsentiert nun deinen gesamten heruntergeladenen Geodatensatz. Eine Data Source organisiert ihre Geoinformationen in Layern. Du kannst die Data Source nach der Anzahl ihrer Layer fragen. Ein ESRI Shapefile enthält traditionell nur einen Layer, aber Formate wie GeoPackages können Dutzende enthalten. Du rufst diesen ersten Layer über seinen Index ab, genau so, als würdest du ein Item aus einer Standard Python List ziehen. Hier ist die wichtigste Erkenntnis. Das Layer-Objekt ist der Ort, an dem die eigentliche Introspection stattfindet. Es fungiert als Container für einzelne Geodatensätze, die die API Features nennt. Du kannst den Layer bitten, seine gesamte Feature-Anzahl zurückzugeben. Bei unserer Weltgrenzen-Datei sollte die Anzahl ungefähr der Anzahl der Länder auf der Erde entsprechen. Du kannst den Layer auch nach seinem Geometry Type fragen. Das bestätigt, ob die Daten aus Points, Lines oder Polygons bestehen. Bei Ländergrenzen wird sich der Typ typischerweise als MultiPolygon zurückmelden. Als Nächstes musst du wissen, welche Metadaten an diese Shapes angehängt sind. Du kannst den Layer nach seinen Fields fragen. Das gibt eine List von Strings zurück, die die Attribut-Spaltennamen repräsentieren. Vielleicht siehst du Namen, die einem internen Ländercode, einem gebräuchlichen Namen und einer Bevölkerungszahl entsprechen. Du kannst sogar noch ein Level tiefer gehen. Indem du über seinen Index auf ein einzelnes Feature aus dem Layer zugreifst, kannst du ein einzelnes Land inspizieren. Du kannst dieses spezifische Feature nach dem Wert seines Common Name Fields fragen. Du kannst auch auf das spezifische Geometry Object dieses Features zugreifen und es bitten, seine Koordinaten als Well-Known Text oder GeoJSON auszugeben. Du hast nun genau erfasst, welche Shapes die Datei enthält, die Namen ihrer Attribute und die Struktur ihrer Records. Das alles hast du rein über Python gemacht, ohne ein Datenbank-Import-Script zu schreiben oder dich auf externe Visualisierungssoftware zu verlassen. Der GDAL Wrapper verwandelt deine Standard Python Shell in eine explorative Linse für Geodaten, die es dir erlaubt, fremde Dateien zu validieren, bevor auch nur ein einziger Record deine Datenbank berührt. Das war's für diese Folge. Danke fürs Zuhören und keep building!
7

Einlesen räumlicher Daten mit LayerMapping

4m 28s

Diese Episode behandelt die Automatisierung von Importen räumlicher Daten. Du lernst, wie du das LayerMapping-Dienstprogramm verwendest, um externe Shapefile-Daten mühelos direkt in deine GeoDjango-Modelle zu mappen.

Herunterladen
Hallo, hier ist Alex von DEV STORIES DOT EU. GeoDjango und PostGIS, Folge 7 von 15. Der manuelle Import Tausender geografischer Polygone und ihrer Metadaten könnte Tage dauern. Deine Source Files haben kryptische Spaltennamen und nicht übereinstimmende Datentypen, aber deine Datenbank verlangt eine strikte Struktur. Die Lösung ist das LayerMapping-Utility von GeoDjango, das diesen gesamten Ingestion-Prozess mit genau einem einzigen Dictionary abwickelt. Wenn du mit Spatial Data arbeitest, bekommst du oft Vektordateien wie ESRI Shapefiles. Diese Dateien enthalten sowohl die geometrischen Formen von Orten als auch die zugehörigen Attributdaten. Externe Dateien passen jedoch selten genau zu deinem Datenbankschema. Ein Shapefile könnte eine Population-Spalte mit der Abkürzung POP2005 und einen Country Code als ISO2 haben. Dein sauberes Django-Model, nennen wir es WorldBorder, hat klar benannte, streng typisierte Fields für genau diese Attribute. Du bist vielleicht versucht, manuelle SQL-Importe oder Datenbank-Tools wie pgAdmin zu nutzen, um diese Daten in PostGIS zu pushen. LayerMapping ist ein völlig anderer Ansatz. Es ist ein programmatisches Python-Script-Utility. Es lebt direkt in deinem Django-Projekt und bindet externe Spatial Files direkt an deinen Object Relational Mapper an. Hier ist der entscheidende Punkt. Der Kern von LayerMapping ist ein einfaches Python-Dictionary. Die Keys dieses Dictionarys sind die Namen deiner sauberen Django-Model-Fields. Die Values sind die rohen String-Namen der Attribute in deinem Source File. Zum Beispiel mappt dein Dictionary den Namen des Django-Model-Fields auf das Shapefile-Attribut NAME. Es mappt das Population-Field deines Models auf POP2005 und das ISO-Code-Field auf ISO2. Außerdem mappst du das Geometry-Field deines Models auf den Geometry-Typ des Shapefiles, der normalerweise durch einen String wie MULTIPOLYGON repräsentiert wird. Um das zu automatisieren, schreibst du ein kurzes Python-File, typischerweise ein Load-Script genannt. In diesem Script importierst du dein WorldBorder-Model und das LayerMapping-Tool. Du definierst dein Mapping-Dictionary. Dann erstellst du eine neue LayerMapping-Instanz. Dieser Instanz übergibst du drei obligatorische Informationen. Erstens, dein Django-Model. Zweitens, den Filepath zu deinem Source-Shapefile. Drittens, das Mapping-Dictionary, das du gerade erstellt hast. Du kannst auch optionale Arguments übergeben, um das Ingestion-Verhalten zu steuern. Wenn deine Source-Daten bereits in genau dem Spatial Reference System vorliegen, das deine Datenbank erwartet, kannst du dem Utility sagen, dass es keine Koordinatentransformationen durchführen soll. Das überspringt unnötige Berechnungen und beschleunigt den Import. Schließlich rufst du die save-Methode deiner LayerMapping-Instanz auf. Wenn du dieses Script ausführst, übernimmt das Utility komplett. Es öffnet das Shapefile, iteriert durch jedes einzelne Geographic Feature und nutzt dein Dictionary, um die unordentlichen File-Attribute mit deinen strikten Model-Fields abzugleichen. Es übersetzt die rohe Geometry automatisch in ein Format, das PostGIS versteht, und speichert die Records in deiner Datenbank. Du kannst die save-Methode anweisen, beim ersten Fehler, auf den sie stößt, eine Exception zu werfen, oder du lässt sie durchlaufen und loggst problematische Features einfach in dein Terminal. Das Wichtigste, was du mitnehmen solltest, ist, dass LayerMapping die starre Struktur externer Spatial Files komplett vom sauberen Design deiner Datenbank entkoppelt, sodass du massive Datasets mit nur ein paar Zeilen Python einlesen kannst. Bevor wir zum Schluss kommen: Wenn dir die Show gefällt und du uns unterstützen möchtest, kannst du das tun, indem du auf Patreon nach DevStoriesEU suchst. Das war's für diese Folge. Danke fürs Zuhören und keep building!
8

Die GEOS API: Pythonische Geometrie

3m 44s

Diese Episode konzentriert sich auf die GEOS API für die pythonische Geometriemanipulation. Du lernst, wie du topologische Operationen wie Vereinigungen und Schnittmengen im Arbeitsspeicher durchführst, ohne die Datenbank abzufragen.

Herunterladen
Hallo, hier ist Alex von DEV STORIES DOT EU. GeoDjango und PostGIS, Folge 8 von 15. Vielleicht denkst du, dass du jedes Mal, wenn du zwei Polygone zusammenführen oder eine räumliche Schnittmenge finden willst, eine Query schreiben und auf die Antwort der Datenbank warten musst. Tatsächlich kannst du komplexe räumliche Berechnungen direkt in deiner Python-Shell durchführen, ohne jemals eine Datenbankverbindung anzufassen. Genau darum geht es heute: Die GEOS API und Pythonic Geometry. Ein häufiges Missverständnis bei GeoDjango ist, dass PostGIS das komplette räumliche Heavy Lifting übernimmt. PostGIS ist zwar unglaublich mächtig, aber die GEOS API erlaubt es dir, geometrische Operationen komplett im lokalen Memory durchzuführen. GEOS steht für Geometry Engine Open Source. Es ist eine hochoptimierte C++-Library, aber GeoDjango gibt dir einen mächtigen Wrapper namens GEOSGeometry-Objekt. Mit diesem Objekt kannst du Geometrien rein in Python erstellen, manipulieren und analysieren. Hier wird es interessant. Ein GEOSGeometry-Objekt fühlt sich nicht wie ein klobiger Wrapper um eine C-Library an. Es verhält sich exakt wie ein nativer Python-Container. Wenn du einen LineString mit zehn Punkten hast, kannst du die Standard-Python-Length-Funktion darauf anwenden, um zu sehen, dass er zehn Koordinaten hat. Du kannst mit einer Standard-For-Loop über ein Polygon iterieren, um seine einzelnen Ringe zu extrahieren, oder einen Index nutzen, um dir einen bestimmten Punkt aus einer MultiPoint-Geometrie zu schnappen. Sie verhalten sich genau wie vertraute Listen oder Tupel von Koordinaten. Die wahre Power entfaltet sich, wenn du topologische Operationen anwendest. Angenommen, du baust eine Logistik-Applikation und hast zwei überlappende Lieferzonen, die als GEOS-Polygone definiert sind. Du musst die genaue Fläche finden, in der sich diese beiden Zonen überlappen. Du musst diese Zonen nicht in einem Model speichern und eine Datenbank-Query ausführen. Stattdessen kannst du den Overlap sofort In-Memory generieren. Zuerst instanziierst du zwei GEOSGeometry-Objekte, die deine Lieferzonen repräsentieren. Dann kannst du einfach die Intersection-Methode auf dem ersten Polygon aufrufen und das zweite Polygon als Argument übergeben. Weil die API zutiefst pythonic ist, kannst du auch einfach den bitweisen AND-Operator nutzen. Du tippst buchstäblich Polygon eins, ein Ampersand und Polygon zwei. Das gibt ein brandneues GEOSGeometry-Objekt zurück, das die exakte überlappende Form darstellt. Du hast Zugriff auf eine ganze Suite dieser räumlichen Operationen. Wenn du die Fläche finden musst, die von der ersten Lieferzone abgedeckt wird, aber strikt außerhalb der zweiten liegt, nutzt du die Difference-Methode oder den regulären Python-Minus-Operator. Wenn du sie zu einer einzigen massiven Zone mergen willst, nutzt du die Union-Methode oder den bitweisen OR-Pipe-Operator. Du kannst sogar neue Shapes aus dem Nichts generieren. Wenn du die Buffer-Methode auf einer Point-Geometrie mit einem Width-Argument aufrufst, berechnet und liefert das sofort ein Polygon zurück, das einen perfekten Kreis um diesen Punkt darstellt. Weil alles auf der zugrunde liegenden C++-Engine basiert, laufen diese Berechnungen extrem schnell ab. Das Key-Takeaway hier ist, dass die GEOS API dir eine unabhängige In-Memory Spatial Engine gibt, mit der du Geometrien validieren, Buffer berechnen und Intersections finden kannst, bevor auch nur ein einziges Byte an Daten jemals deine Datenbank erreicht. Das war's für diese Folge. Bis zum nächsten Mal!
9

Meisterung von Spatial Lookups

4m 09s

Diese Episode erklärt geografische Query-Lookups im Django ORM. Du lernst, wie du räumliche Filter verwendest, um Beziehungen zu finden, wie zum Beispiel, welche Punkte innerhalb bestimmter Grenzen liegen.

Herunterladen
Hallo, hier ist Alex von DEV STORIES DOT EU. GeoDjango und PostGIS, Folge 9 von 15. Vergiss das Schreiben riesiger Koordinaten-Vergleiche. Du hast eine User Location und eine Delivery Zone und musst wissen, ob sie sich überschneiden. Das mathematisch zu lösen bedeutet, hunderte Polygonkanten in deiner Application Logic zu überprüfen. Stattdessen reduziert GeoDjango das komplett auf eine Datenbankoperation. Heute meistern wir Spatial Lookups. Wenn du schon mal Django benutzt hast, kennst du die Double-Underscore-Syntax zum Filtern von Querysets. Du hängst so etwas wie Double-Underscore exact oder Double-Underscore in an einen Feldnamen an. GeoDjango erweitert genau diese Syntax, um komplexe topologische PostGIS-Beziehungen auszuführen. Topologische Beziehungen sind einfach nur Regeln darüber, wie Geometrien sich den Raum teilen. Berühren sie sich? Überlappen sie sich? Liegt eine vollständig innerhalb der anderen? GeoDjango gibt dir dedizierte Lookup-Typen, um diese Fragen direkt in deinen ORM-Queries zu stellen. Der häufigste und fehlerverzeihendste Spatial Lookup ist intersects. Wenn du ein Geometry-Feld mit Double-Underscore intersects filterst, gibt die Datenbank Datensätze zurück, bei denen die beiden Geometrien irgendeinen Teil des Raums teilen. Sie können sich kreuzen, sich an einer Grenze berühren, oder die eine kann die andere komplett umschließen. Solange es irgendeinen gemeinsamen Raum gibt, wird intersects zu true evaluiert. Oft brauchst du mehr Präzision als eine einfache Intersection. Du brauchst strikte Grenzen. Hier kommen contains und within ins Spiel. Entwickler verwechseln diese beiden ständig. Hier ist die wichtigste Erkenntnis: Der Unterschied ist rein richtungsbezogen. Wenn Geometrie A Geometrie B contains, dann ist Geometrie B within Geometrie A. Stell dir eine Kiste und eine Murmel vor. Die Kiste contains die Murmel. Die Murmel ist within der Kiste. Du wählst den Lookup basierend darauf, welche Geometrie in deiner Datenbankspalte steht und welche Geometrie du als Filter-Argument übergibst. Schauen wir uns ein konkretes Szenario an. Du hast eine Datenbanktabelle mit Häusern, und jedes Haus hat eine Point Geometry, die seinen Standort repräsentiert. Die Stadt hat gerade ein neues Polygon veröffentlicht, das ein ausgewiesenes Überschwemmungsgebiet definiert. Du musst alle Häuser finden, die exakt innerhalb dieses Risikogebiets liegen. Du fragst nicht das Überschwemmungsgebiet ab und schaust, was es contains. Du fragst die Häuser ab. Du rufst filter auf dem House-Model auf, referenzierst das Point-Geometry-Feld, hängst Double-Underscore within an und übergibst das Polygon des Überschwemmungsgebiets als Wert. Wenn du diese Query ausführst, übersetzt Django deinen Double-Underscore-Lookup in einen nativen PostGIS-Funktionsaufruf, genauer gesagt ST_Within. Die Database Engine evaluiert die Geometrien mithilfe ihrer optimierten Spatial Indexes. Sie prüft, ob jede einzelne Koordinate des Haus-Points im Inneren des Überschwemmungsgebiet-Polygons liegt. Wenn das Haus exakt auf der Grenzkante des Polygons liegt, gilt es nicht als within. Striktes Containment bedeutet, dass das Innere der ersten Geometrie vollständig im Inneren der zweiten Geometrie liegen muss. Wenn du das Szenario umdrehst, sagen wir, du fragst eine Datenbanktabelle mit Nachbarschaften ab, um diejenige zu finden, die eine bestimmte User Location umgibt, nutzt du Double-Underscore contains. Du filterst das Nachbarschafts-Polygon-Feld, hängst Double-Underscore contains an und übergibst den User-Point. Die Logik ist unter der Haube identisch, aber die Reihenfolge der Spatial Arguments, die an PostGIS übergeben werden, ist vertauscht. Diese direktionale Logik zu verstehen, verhindert Silent Failures und leere Querysets. Indem du PostGIS-Operationen direkt auf Django Keyword Arguments mappst, filterst du riesige Spatial Datasets effizient, ohne Raw SQL schreiben zu müssen. Die Geometrie, gegen die du filterst, diktiert immer die Richtung deines Spatial Lookups. Danke fürs Einschalten. Bis zum nächsten Mal!
10

High-Performance Distanzabfragen

4m 00s

Diese Episode befasst sich mit hochperformanten Umkreis- und Distanzabfragen. Du lernst, wie du Distance-Lookups und das geografische Distance-Objekt verwendest, um nahegelegene Orte effizient zu finden.

Herunterladen
Hallo, hier ist Alex von DEV STORIES DOT EU. GeoDjango und PostGIS, Folge 10 von 15. Radius-Queries sind das A und O standortbasierter Anwendungen. Wenn du sie falsch schreibst, berechnet deine Datenbank die exakte Entfernung zu jeder einzelnen Row in deiner Table, was einen massiven Full Scan erzwingt. Wenn du sie richtig schreibst, dauert es nur Millisekunden. High-Performance Distance Queries machen den Unterschied zwischen einer App, die sofort reagiert, und einer, die unter Last abstürzt. Ein häufiger Fehler von Developern ist es, Spatial Queries genauso zu behandeln wie einfache Mathe. Der naive Ansatz ist, die genaue Entfernung von deinem Target Point zu jedem anderen Punkt in der Datenbank zu berechnen und dann alles herauszufiltern, was größer als dein maximaler Radius ist. Das solltest du niemals tun. Echte Entfernungen auf einer Kugel zu berechnen, ist extrem rechenintensiv. Wenn deine Query filtert, indem sie zuerst die Distanz berechnet, kann die Datenbank ihre Spatial Indexes nicht nutzen. Sie wird gezwungen, jede einzelne Row zu checken. Um Queries schnell zu halten, musst du auf index-backed Lookups setzen. Bevor wir uns die Database Lookups ansehen, brauchst du einen Weg, Distanzen in deinem Python-Code klar auszudrücken. GeoDjango bietet das Distance-Objekt, das meistens einfach als Großbuchstabe D importiert wird. Du initialisierst es mit einer Unit und einem Value. Wenn du diesem Objekt zum Beispiel das Argument m i gleich fünf übergibst, erzeugt das eine Messung von exakt fünf Meilen. Du kannst Kilometer, Meter oder sogar Grad verwenden. Das normalisiert die Messung in Python, bevor die Query überhaupt die Datenbank erreicht. Stell dir ein Szenario vor, in dem du ein Feature implementierst, das alle Coffeeshops im Umkreis von fünf Meilen um den aktuellen GPS-Ping eines Users findet. Du hast den Location Point des Users und willst dein Coffeeshop-Model abfragen. Du könntest den distance less-than-or-equal Lookup verwenden. Du schreibst einen Query-Filter, bei dem auf dein Coffeeshop-Location-Field ein doppelter Unterstrich folgt, dann das Wort distance, ein Unterstrich und die Buchstaben l t e. Du übergibst ihm ein Tuple, das den User Point und dein auf fünf Meilen gesetztes Distance-Objekt enthält. Das funktioniert. Es wird in eine Datenbankfunktion übersetzt, die checkt, ob die Distanz kleiner oder gleich fünf Meilen ist. Aber je nach deinem Spatial Backend und wie deine Columns aufgesetzt sind, macht dieser Lookup vielleicht immer noch mehr mathematische Arbeit als unbedingt nötig, indem er exakte Distanzen berechnet, bevor er den finalen Vergleich macht. Hier ist die wichtigste Erkenntnis. Du musst selten die exakte Distanz kennen, um einen Radius zu filtern. Du musst nur wissen, ob das Objekt innerhalb des Kreises liegt. Hier wird der dwithin Lookup essenziell. Statt distance less-than-or-equal hängst du einen doppelten Unterstrich und das Wort dwithin an dein Location-Field an. Du übergibst genau denselben User Point und das Fünf-Meilen-Distance-Objekt. Unter der Haube wird das direkt an die PostGIS-Funktion ST DWithin geroutet. Diese Funktion ist hochoptimiert. Sie macht zuerst einen schnellen Bounding-Box-Check, der deine Spatial Indexes perfekt nutzt. Sie zieht ein grobes Quadrat um deinen Fünf-Meilen-Radius und verwirft sofort alle Punkte außerhalb dieses Quadrats, ohne komplexe sphärische Mathe zu machen. Sie führt nur für die wenigen Punkte, die nahe am Rand des Kreises innerhalb dieses Quadrats liegen, präzise, teure Berechnungen durch. Wenn deine Database Table Geography Columns statt einfacher Geometry Columns nutzt, kümmert sich PostGIS automatisch um die Erdkrümmung und hält die Index-Nutzung trotzdem blitzschnell. Die wertvollste Angewohnheit in der Spatial Programming ist die Erkenntnis, dass der Check, ob ein Punkt innerhalb einer Shape liegt, immer billiger ist, als ein Maßband herauszuholen, um die exakte Distanz dazwischen zu berechnen. Danke, dass du ein paar Minuten mit mir verbracht hast. Bis zum nächsten Mal, mach's gut.
11

Geografische Datenbankfunktionen

4m 15s

Diese Episode untersucht räumliche Datenbankfunktionen, die über GeoDjango zugänglich sind. Du lernst, wie du Flächen berechnest, Zentroide extrahierst und GeoJSON direkt auf der Datenbankebene generierst.

Herunterladen
Hallo, hier ist Alex von DEV STORIES DOT EU. GeoDjango und PostGIS, Folge 11 von 15. Du hast eine Datenbank voller riesiger, komplexer Polygone, und dein Frontend muss nur einen Pin in der Mitte von jedem anzeigen. Wenn du diese rohen Polygone nach Python holst, um den Center zu berechnen, ziehst du Megabytes an nutzlosen Koordinatendaten über das Netzwerk. Die Lösung ist, diese Mathematik mit Geographic Database Functions runter in die Datenbank zu pushen. Es gibt zwei Wege, um in GeoDjango an Spatial Information wie Area oder einen Center Point zu kommen. Der erste ist, den Database Record zu queryn, die komplette Geometry in ein Python GEOS Object zu ziehen und darauf auf eine Property wie dot area zuzugreifen. Mach das nicht, es sei denn, du brauchst die komplette Geometry wirklich in Python. Die Boundary von einem Nationalpark zu fetchen, kann bedeuten, dass du zehntausende Vertices in den Memory laden musst, nur um eine einzige Zahl zu berechnen. Der zweite, viel effizientere Weg ist, PostGIS zu sagen, dass es die Antwort berechnen und nur das finale Result zurücksenden soll. Genau hier werden Geographic Database Functions in Kombination mit der Django ORM annotate Methode essenziell. Schauen wir uns ein praktisches Szenario an. Du baust eine API, die Nationalparks auflistet. Für die List View braucht die Client Application nur den Parknamen, seine gesamte Area und eine einzelne Center Coordinate, um einen Map Pin zu setzen. Sie braucht nicht das komplexe Boundary Polygon. In deinem Django Queryset nutzt du die annotate Methode. Du sagst ihr, sie soll ein neues Attribute erstellen, vielleicht park area genannt, und setzt es gleich der Area Function, die auf deine Geometry Column angewendet wird. Daneben erstellst du ein weiteres Attribute namens center point, das gleich der Centroid Function auf derselben Geometry Column gesetzt wird. Zum Schluss beschränkst du den Query Output auf nur den Namen und deine zwei neuen Annotations. Wenn diese Query ausgeführt wird, liest PostGIS die rohen Geometry Daten von der Disk. Es führt hochoptimierte interne Routinen aus, um die Spatial Area zu berechnen und den mathematischen Center Point zu finden. Dann gibt es genau drei Dinge über das Netzwerk an deine Django Application zurück: einen Text String für den Namen, eine Zahl für die Area und eine Single Point Geometry für den Center. Du umgehst die Bandbreiten- und Memory-Kosten für die Übertragung des großen Polygons komplett. Diese Strategie gilt für viele Spatial Operations. Du kannst die Transform Function innerhalb einer Annotation nutzen, um Coordinates von deiner Database Storage Projection direkt in die Projection zu konvertieren, die deine Web Map braucht, wie Web Mercator. Die Datenbank übernimmt die Mathematik, bevor Python die Daten überhaupt sieht. Du kannst auch die AsGeoJSON Function verwenden. Das weist PostGIS an, die Spatial Data direkt in der Datenbank in einen Standard JSON Text String zu formatieren. Wenn Django ihn empfängt, ist es einfach nur Text, der direkt an dein Frontend weitergegeben werden kann, wodurch der Python Serialization Overhead komplett vermieden wird. Du kannst auch Aggregate Functions auf komplette Querysets anwenden. Die Extent Function schaut sich eine Gruppe von Geometries an und gibt eine einzelne Bounding Box zurück, die alle abdeckt. Wenn ein User nach allen Parks in einer bestimmten Region sucht, gibt dir das Zurückgeben des Extents die exakten Coordinates, die du brauchst, um die Frontend Map automatisch so zu zoomen, dass alle Results perfekt reinpassen. Hier ist die wichtigste Erkenntnis. Deine Spatial Database ist eine hochspezialisierte Computation Engine, nicht nur ein Storage Container. Behalte deine schweren Spatial Computations innerhalb von PostGIS und bewege nur die berechneten Antworten über das Netzwerk zu Python. Das war's für diese Folge. Bis zum nächsten Mal!
12

Rasterdaten in PostGIS

4m 27s

Diese Episode führt in PostGIS-Raster und GeoDjango RasterFields ein. Du lernst, wie du kontinuierliche räumliche Daten wie Höhenmodelle oder Temperaturkarten speicherst und abfragst.

Herunterladen
Hallo, hier ist Alex von DEV STORIES DOT EU. GeoDjango und PostGIS, Folge 12 von 15. Vector Shapes sind super, wenn du eine saubere Linie um eine Stadtgrenze ziehen oder eine User Location genau bestimmen willst. Aber was passiert, wenn du etwas mappen musst, das keine harten Grenzen hat, wie die schwankende Temperatur über einen Kontinent oder die Höhe eines ganzen Gebirges? Du kannst nicht für jedes einzelne Grad Temperatur ein Polygon zeichnen. Hier kommt Raster Data in PostGIS ins Spiel. Wenn du es gewohnt bist, mit Punkten, Linien und Polygonen zu arbeiten, erfordert Raster Data ein gewisses Umdenken. Raster Data besteht nicht aus diskreten Formen. Es ist ein kontinuierliches Grid aus Pixeln, genau wie ein digitales Foto. Aber anstelle von roten, grünen und blauen Farbwerten enthält jedes Pixel einen spezifischen numerischen Data Point. Diese Daten könnten Niederschlag, Bodentyp oder Höhe sein. Das gesamte Grid ist durch Georeferencing mathematisch mit der realen Welt verknüpft. Das bedeutet, dass die Datenbank genau weiß, wo jedes einzelne Pixel auf der Map liegt. In GeoDjango beinhaltet das Handling dieser Daten hauptsächlich zwei Komponenten: das RasterField und das GDALRaster Object. RasterField ist der Database Column Type. Du fügst es deinem Django Model genauso hinzu wie ein Geometry Field. Das teilt PostGIS mit, intern Speicherplatz für Grid Data zu reservieren. Aber du interagierst nicht direkt mit den rohen Database Bytes. Wenn du ein Raster aus der Datenbank holst oder bevor du eines einfügst, nutzt du GDALRaster. Das ist ein Python Wrapper um die zugrundeliegenden Geospatial Libraries. Er erlaubt dir, die Raster Properties zu inspizieren, wie die Scale, das Coordinate Reference System und die tatsächlichen Werte in seinen Bands. Ein Band ist einfach ein einzelner Data Layer im Grid. Ein Standardbild hat drei Bands für Farbe, aber eine Elevation Map hat typischerweise nur ein Band, das die Höhe repräsentiert. Stell dir ein konkretes Szenario vor. Du baust eine Application für Wanderer und hast ein Digital Elevation Model von einem Gebirge. Dieses Elevation Model wird normalerweise als GeoTIFF-File bereitgestellt. Zuerst definierst du ein Django Model für dein Gebirge und gibst ihm ein RasterField. Dann instanziierst du in deinem Python-Code ein GDALRaster, indem du ihm den File Path zu deinem GeoTIFF übergibst. Django lädt das File als GDALRaster Object in den Memory. Du weist dieses Object dem RasterField in deinem Mountain Model zu und rufst save auf. PostGIS nimmt dieses Grid und speichert es. Wenn nun ein Wanderer seine GPS-Route hochlädt, kannst du die Datenbank queryen, um genau herauszufinden, in welches Pixel seine Koordinaten fallen. Du extrahierst den Elevation Value, der in diesem spezifischen Pixel gespeichert ist. Wenn du dieses Field wieder aus der Datenbank ausliest, gibt dir Django wieder ein GDALRaster Object. Du kannst dieses Object nach seiner Width, seiner Height oder seinem Spatial Extent abfragen. Du kannst direkt in Python auf die rohen Pixel Data Arrays zugreifen, um Berechnungen durchzuführen, bevor du die Daten an dein Application Frontend sendest. Hier ist die wichtigste Erkenntnis: Du nutzt Vectors für Dinge, die an einem bestimmten Ort existieren, und du nutzt Rasters für Dinge, die überall in einem Gebiet existieren. Indem du beides in PostGIS kombinierst, kann deine Application diskrete Objekte, wie einen Wanderweg, mit kontinuierlichen Umgebungen verknüpfen, wie der tatsächlichen Höhe des Bodens unter den Füßen. Wenn du helfen willst, die Show am Laufen zu halten, kannst du auf Patreon nach DevStoriesEU suchen – deine Unterstützung bedeutet uns sehr viel. Das war's für diese Folge. Danke fürs Zuhören und keep building!
13

Geolokalisierung mit GeoIP2

4m 11s

Diese Episode behandelt die IP-basierte Geolokalisierung mit dem GeoIP2-Modul von GeoDjango. Du lernst, wie du Benutzer-IP-Adressen mithilfe von MaxMind-Datensätzen Städten und Ländern zuordnest.

Herunterladen
Hallo, hier ist Alex von DEV STORIES DOT EU. GeoDjango und PostGIS, Folge 13 von 15. Was ist, wenn du wissen musst, wo ein User ist, um ihm lokalen Content auszuliefern, er dir aber keine GPS-Permissions erteilt hat? Seine eingehende IP-Adresse liefert die Antwort. Das ist Geolocation mit GeoIP2. Um das gleich vorwegzunehmen: IP-Geolocation ist kein präziser Coordinate Lookup wie bei einer Browser Geolocation API. Es ist eine Annäherung. Wenn du eine IP-Adresse nachschlägst, fragst du ein statisches Dataset ab, das zugewiesene IP-Blöcke geografischen Gebieten zuordnet. Du bekommst fast immer das richtige Land und oft auch die richtige Stadt, aber es wird nicht die tatsächliche Adresse des Users finden. Stell dir ein Szenario vor, in dem ein Besucher auf deiner E-Commerce-Site landet. Du willst ihn automatisch zum lokalisierten Storefront seines Landes redirecten oder das Zentrum einer Map per Default auf seine Region setzen, rein basierend auf seiner eingehenden IPv4- oder IPv6-Adresse. GeoDjango bietet das GeoIP2-Objekt speziell an, um diesen Offline-Lookup zu handhaben. Bevor du irgendwelche Logik schreiben kannst, brauchst du die richtigen Bausteine. Zuerst installierst du die geoip2 Python-Library in deinem Environment. Zweitens brauchst du die eigentlichen Daten. GeoIP2 verlässt sich auf MaxMind-Datasets, typischerweise die kostenlosen GeoLite2 City oder Country Databases. Du lädst diese Files, die eine mmdb-Extension haben, herunter und legst sie auf deinem Server ab. Schließlich definierst du in deinen Django Settings eine Variable namens GEOIP_PATH und lässt sie auf das Directory zeigen, das diese Files enthält. Django erwartet, in diesem Ordner spezifisch benannte Files wie GeoLite2-City dot mmdb zu finden. Wenn das Setup abgeschlossen ist, erfordert die Nutzung des Tools nur noch wenige Schritte. Du importierst das GeoIP2-Objekt aus dem django contrib gis geoip2 Modul und instanziierst es. Du extrahierst den eingehenden IP-Adressen-String aus deinen Request Headers und übergibst ihn an eine der Lookup-Methoden. Wenn du nur eine grobe Routing-Logik brauchst, rufst du die country-Methode auf. Du übergibst die IP-Adresse, und sie gibt ein Dictionary zurück, das den Country Code und den Country Name enthält. Wenn du mehr Granularität brauchst, um eine Map zu zentrieren, rufst du stattdessen die city-Methode auf. Diese gibt ein reichhaltigeres Dictionary zurück, das den Stadtnamen, die Region und die ungefähren Longitude- und Latitude-Werte enthält. Die city-Methode beinhaltet auch die Länderdaten, du musst also immer nur einen Call machen. Wenn du einfach nur die Koordinaten willst, um sie in eine andere Funktion einzuspeisen, gibt es dedizierte Methoden wie coords, die ein einfaches Tuple aus Longitude und Latitude zurückgeben. Du musst Fehler auch elegant abfangen. Wenn du eine ungültige IP-Adresse übergibst, oder eine Adresse, die einfach nicht in der MaxMind Database vorhanden ist, gibt GeoIP2 kein leeres Dictionary zurück. Es wirft eine GeoIP2Exception. Du musst deine Lookup Calls in einen try-Block wrappen und eine Default Fallback Location für deinen Storefront bereitstellen, wenn der Lookup fehlschlägt. Hier ist die wichtigste Erkenntnis. Der Code selbst ist im Grunde nur ein optimierter File Reader. Deine Geolocation-Genauigkeit hängt komplett von der Frische der Database ab, die in deinem GEOIP_PATH Directory liegt. IP Allocations ändern sich ständig. Wenn du ein Routing-System um GeoIP2 herum baust, musst du das Herunterladen neuer Database Files regelmäßig automatisieren, sonst werden deine lokalisierten Redirects langsam und stillschweigend inkorrekt. Das war's für diese Folge. Bis zum nächsten Mal!
14

Testen räumlicher Anwendungen

3m 38s

Diese Episode konzentriert sich auf das Testen räumlicher Anwendungen in GeoDjango. Du lernst, wie du deine Test-Suite konfigurierst, mit PostGIS-Template-Datenbanken umgehst und Benutzerberechtigungen einrichtest.

Herunterladen
Hallo, hier ist Alex von DEV STORIES DOT EU. GeoDjango und PostGIS, Folge 14 von 15. Spatial Applications zu testen, hat einen besonderen Haken: Deine automatisierte Testdatenbank muss komplexe Spatial Extensions auf C-Ebene installieren, bevor der allererste Test überhaupt läuft. Wenn deine automatisierte Pipeline wegen Permission Errors sofort abstürzt, liegt das wahrscheinlich genau daran. Heute schauen wir uns das Testing von Spatial Applications an. Die erste Voraussetzung ist reine Konfigurationssache. Wenn du Tests ausführst, erstellt Django eine parallele Testdatenbank, um deine Produktionsdaten zu schützen. Für GeoDjango muss diese Testdatenbank spatial sein. Das bedeutet, dass deine Datenbank-Settings explizit eine Spatial Engine verwenden müssen, wie zum Beispiel das PostGIS-Backend von GeoDjango. Du kannst nicht das Standard-Postgres-Backend verwenden und später einfach Spatial Fields hinzufügen. Das Spatial Backend sagt dem Django Test Runner nämlich, dass er nach den benötigten Spatial Features suchen und sie initialisieren soll. Hier ist der entscheidende Punkt. Der Standard-Django Test Runner erstellt eine frische Datenbank, führt deine Migrations aus und startet das Testing. Aber für eine GeoDjango-Application reicht es nicht aus, nur eine frische Datenbank zu erstellen. Die Datenbank muss zusätzlich die PostGIS-Extension laden. Das ist keine Standard-SQL-Tabelle. Es ist eine Extension auf Systemebene. Standardmäßig schränkt PostgreSQL aus Sicherheitsgründen ein, wer Extensions erstellen darf. Meistens braucht man dafür einen Datenbank-User mit Superuser Privileges. Genau hier scheitern Continuous Integration Pipelines häufig. Du fährst einen Postgres-Container hoch, übergibst einen Standard-Datenbank-User und sagst Django, dass es die Tests ausführen soll. Django verbindet sich, versucht die Testdatenbank zu bauen, will den Befehl zum Erstellen der PostGIS-Extension ausführen und stößt auf einen Permission Denied Error. Um das in einer automatisierten Pipeline zu fixen, muss der Datenbank-User, der die Tests ausführt, die nötigen Privileges haben. Der einfachste Ansatz in einer isolierten Throwaway-Umgebung ist, dem Test-User vorübergehend Superuser Roles zu geben. Wenn deine Security Policies den Superuser-Zugriff selbst in einem temporären Container verbieten, musst du PostgreSQL so konfigurieren, dass der spezifische Test-User ein Trusted Owner der Testdatenbank ist und explizit die PostGIS-Extension erstellen darf. Sobald die Datenbank gebaut ist, muss GeoDjango wissen, womit es arbeitet. Verschiedene Versionen von PostGIS unterstützen unterschiedliche Spatial Functions. Im Normalbetrieb fragt GeoDjango die Datenbank ab, um die installierte PostGIS-Version herauszufinden. In einer Testumgebung kannst du diese Query jedoch umgehen, indem du ein spezifisches Setting namens PostGIS Version definierst. Das gibst du als Tuple aus drei Zahlen an, die die Major-, Minor- und Patch-Versions repräsentieren. Dieses Setting explizit zu setzen, kann die Test-Initialisierung beschleunigen und dient als Fail-Safe, falls die Datenbankverbindung beim anfänglichen Version Check Probleme macht. Beim Ausführen von Spatial Tests geht es nicht darum, andere Assertions zu schreiben. Es ist primär eine Infrastruktur-Herausforderung. Das wichtigste Takeaway ist: Wenn dein Testdatenbank-User keine Extensions on the fly erstellen kann, werden deine Tests gar nicht erst starten. Fixe die Privileges deines Test-Users, um PostGIS zu bootstrappen, und der Rest deiner Pipeline wird sich genau wie eine Standard-Django Test Suite verhalten. Danke, dass du ein paar Minuten mit mir verbracht hast. Bis zum nächsten Mal, mach's gut.
15

Deployment von GeoDjango-Anwendungen

4m 09s

Diese Episode schließt die Serie ab, indem sie Deployment-Überlegungen für GeoDjango-Apps diskutiert. Du erfährst mehr über GDAL-Thread-Sicherheit und wie du deine WSGI-Prozesse konfigurierst, um Abstürze zu vermeiden.

Herunterladen
Hallo, hier ist Alex von DEV STORIES DOT EU. GeoDjango und PostGIS, Folge 15 von 15. Deine Spatial-App läuft perfekt auf deinem Laptop. Du pushst sie auf einen Production-Server, der Traffic schießt in die Höhe, und plötzlich stürzt die Application ohne Fehlermeldung ab. Kein Standard-Python-Traceback, nur tote Prozesse. Das Problem ist ein Threading-Konflikt tief in einer C-Library. Beim Deployen von GeoDjango-Applications musst du genau diese Falle vermeiden. Das Deployen einer Spatial-Web-Application ist fast identisch mit dem Deployen eines Standard-Django-Projects. Das Routing, die Database-Connections und die Server-Architektur folgen genau denselben Regeln. Aber GeoDjango hat eine versteckte Variable. Diese Variable ist die Geospatial Data Abstraction Library, allgemein bekannt als GDAL. GDAL ist eine riesige, hochoptimierte C-Library, die das Heavy Lifting für geografische Datenformate und Koordinatentransformationen übernimmt. Hier ist die wichtigste Erkenntnis: GDAL ist nicht thread-safe. Das erklärt, warum dein Code lokal funktioniert, aber auf dem Server abstürzt. Der lokale Django-Development-Server verarbeitet Requests sequenziell. Er triggert selten gleichzeitige Zugriffe auf die C-Library. Production-WSGI-Server sind anders aufgebaut. Um hohen Traffic effizient zu verarbeiten, starten Server wie Apache mit mod_wsgi typischerweise mehrere Threads innerhalb eines einzigen Prozesses. Python verlässt sich normalerweise auf den Global Interpreter Lock, um zu verhindern, dass Threads kollidieren. C-Libraries verwalten ihren Speicher jedoch komplett außerhalb der Kontrolle von Python. Wenn zwei WSGI-Threads versuchen, gleichzeitig eine GDAL-Funktion auszuführen, greifen sie ohne Safety-Checks auf denselben Memory-Space zu. Ein Thread korrumpiert die Daten, die der andere Thread gerade nutzt. Weil das auf dem C-Level passiert, kann Python keine Standard-Exception werfen. Das Ergebnis ist ein Segmentation Fault. Der Server-Prozess stirbt sofort ab und reißt alle aktiven User-Requests mit sich runter. Um das zu lösen, musst du ändern, wie dein WSGI-Server Concurrency handhabt. Du musst dich auf Prozesse statt auf Threads verlassen. Betriebssysteme isolieren Prozesse voneinander und geben jedem Prozess seinen eigenen, dedizierten Speicherbereich. Wenn du eine Geographic-App mit viel Traffic über Apache und mod_wsgi in Production pushst, regelst du das in der Daemon-Configuration. Anstatt eine kleine Anzahl von Prozessen mit einem großen Thread-Pool zu konfigurieren, beschränkst du die Threads. Du öffnest dein Apache-Config-File und suchst die WSGI-Daemon-Process-Directive. Neben dem Application-Namen fügst du einen Parameter hinzu, der die Threads explizit auf genau eins setzt. Danach skalierst du die Application, indem du die Anzahl der Prozesse erhöhst, um den erwarteten Load zu bewältigen. Die gleiche Logik gilt, wenn du einen Server wie Gunicorn benutzt. Du musst ihn an Standard-Worker-Prozesse binden. Du vermeidest jede Worker-Class, die Threading oder asynchrone Event-Loops einführt, weil sie unweigerlich dieselben GDAL-Kollisionen triggern werden. Deinen WSGI-Server in ein Multi-Process, Single-Threaded Model zu zwingen, garantiert, dass GDAL niemals mit sich selbst kollidiert. Der absolut wichtigste Schritt, um eine GeoDjango-App production-ready zu machen, ist die Isolierung deiner C-Libraries von Threaded Concurrency. Damit schließen wir unsere gesamte Serie über GeoDjango und PostGIS ab. Der beste Weg, diese Konzepte zu festigen, ist, die offizielle Django-Documentation durchzulesen und hands-on etwas zu bauen. Wenn ihr Ideen habt, welche Technology wir als Nächstes behandeln sollen, besucht devstories dot eu und schlagt ein Thema vor. Danke fürs Zuhören. Macht's gut, Leute.