16.5. Lesson: Geometrieaufbau
In diesem Kapitel gehen wir näher darauf ein, wie einfach Geometrien in SQL erstellt werden. In der Realität wird man wahrscheinlich ein GIS wie QGIS mit seinen Digitalisierungshilfen verwenden, um komplexe Geometrien zu erstellen; trotzdem ist das Verständnis für die Erstellung von Abfragen und für die Nachvollziehbarkeit wie die Daten aufgebaut ist nützlich.
Ziel dieser Lektion: Ein besseres Verständnis wie man räumliche Objekte direkt in PostgreSQL/PostGIS erstellt.
16.5.1. Erstellen von Linien
Lassen Sie uns unsere address Datenbank an die anderen Datenbanken anpassen; sie soll eine Einschränkung bezüglich der Geometrie, einen Index und einen Eintrag in der geometry_columns Tabelle erhalten.
16.5.2. Try Yourself
Verändern Sie die Tabelle streets so, dass sie eine Geometriespalte des Typs ST_LineString enthält.
Vergessen Sie dabei nicht, die geometry_columns Tabelle zu aktualisieren!
Fügen Sie auch eine Einschränkung ein, die verhindert, dass andere Geometrien als Linien oder NULL hinzugefügt werden.
Erstellen Sie einen räumlichen Index über die neue Geometriespalte
Answer
alter table streets add column the_geom geometry;
alter table streets add constraint streets_geom_point_chk check
(st_geometrytype(the_geom) = 'ST_LineString'::text OR the_geom IS NULL);
insert into geometry_columns values ('','public','streets','the_geom',2,4326,
'LINESTRING');
create index streets_geo_idx
on streets
using gist
(the_geom);
Lassen Sie uns nun eine Linie in unsere Tabelle streets einfügen. In diesem Fall aktualisieren wir einen vorhandenen Straßen-Datensatz:
update streets
set the_geom = 'SRID=4326;LINESTRING(20 -33, 21 -34, 24 -33)'
where streets.id=2;
Sehen Sie sich die Ergebnisse in QGIS an. (Sie müssen unter Umständen mit der rechten Maustaste auf den streets-Layer im ‚Layer‘ Bereich klicken und dann ‚Auf den Layer zoomen‘ auswählen.)
Erstellen Sie noch ein Paar Einträge für Straßen - einige in QGIS und einige aus der Kommandozeile.
16.5.3. Erstellung von Polygonen
Die Erstellung von Polygonen ist genauso einfach. Dabei muss man daran denken, dass Polygone definitionsgemäß mindestens vier Stützpunkte haben, wobei der erste und letzte übereinander liegen:
insert into cities (name, the_geom)
values ('Tokyo', 'SRID=4326;POLYGON((10 -10, 5 -32, 30 -27, 10 -10))');
Bemerkung
Ein Polygon erfordert doppelte Klammern um seine Koordinatenliste. Dies erlaubt es, komplexe Polygone mit mehreren unverbundenen Flächen einzufügen. Zum Beispiel
insert into cities (name, the_geom)
values ('Tokyo Outer Wards',
'SRID=4326;POLYGON((20 10, 20 20, 35 20, 20 10),
(-10 -30, -5 0, -15 -15, -10 -30))'
);
Nach dem Abschlusses dieses Schrittes, können Sie die Städte in QGIS einladen und nachvollziehen, was sich verändert hat. Öffnen Sie dazu die Attributtabelle und wählen den neuen Eintrag aus. Beachten Sie, wie die neuen Polygone sich wie ein einziges Polygon verhalten.
16.5.4. Übernung: Anbindung Städte an Personen
Gehen Sie für diese Übung wie folgt vor:
Löschen Sie alle Daten aus der Tabelle people.
Fügen Sie eine Spalte mit einem Fremdschlüssel in der Tabelle people ein, der eine Referenz zum Primärschlüssel der Tabelle cities herstellt.
Nutzen Sie QGIS, um einige Städte zu erfassen.
Verwenden Sie SQL um einige neue Datensätze zu people hinzuzufügen. stellen Sie sicher, dass jeder Datensatz eine zugehörige Straße und Stadt enthält.
Ihr aktualsiertes Schema zu people sollte in etwa so aussehen:
\d people
Table "public.people"
Column | Type | Modifiers
-----------+-----------------------+--------------------------------------------
id | integer | not null
| | default nextval('people_id_seq'::regclass)
name | character varying(50) |
house_no | integer | not null
street_id | integer | not null
phone_no | character varying |
the_geom | geometry |
city_id | integer | not null
Indexes:
"people_pkey" PRIMARY KEY, btree (id)
"people_name_idx" btree (name)
Check constraints:
"people_geom_point_chk" CHECK (st_geometrytype(the_geom) =
'ST_Point'::text OR the_geom IS NULL)
Foreign-key constraints:
"people_city_id_fkey" FOREIGN KEY (city_id) REFERENCES cities(id)
"people_street_id_fkey" FOREIGN KEY (street_id) REFERENCES streets(id)
Answer
delete from people;
alter table people add column city_id int not null references cities(id);
(capture cities in QGIS)
insert into people (name,house_no, street_id, phone_no, city_id, the_geom)
values ('Faulty Towers',
34,
3,
'072 812 31 28',
1,
'SRID=4326;POINT(33 33)');
insert into people (name,house_no, street_id, phone_no, city_id, the_geom)
values ('IP Knightly',
32,
1,
'071 812 31 28',
1,F
'SRID=4326;POINT(32 -34)');
insert into people (name,house_no, street_id, phone_no, city_id, the_geom)
values ('Rusty Bedsprings',
39,
1,
'071 822 31 28',
1,
'SRID=4326;POINT(34 -34)');
If you’re getting the following error message:
ERROR: insert or update on table "people" violates foreign key constraint
"people_city_id_fkey"
DETAIL: Key (city_id)=(1) is not present in table "cities".
then it means that while experimenting with creating polygons for the cities table, you must have deleted some of them and started over. Just check the entries in your cities table and use any id which exists.
16.5.5. Unser Schema
Aktuell sollte unser Schema wie folgt aussehen:
16.5.6. Try Yourself
Erstellen Sie Stadtgrenzen indem Sie die minimale konvexe Hülle um alle Adressen einer Stadt und einen Puffer darum ermitteln.
16.5.7. Zugriff auf Unter-Objekte
Die SFS-Model Funktionen bieten eine große Bandbreite an Optionen zum Zugriff auf Sub-Objekte der SFS Geometrien. Wenn man den ersten Stützpunkt aller Polygone in der Tabelle myPolygonTable selektieren möchte, geht man wie folgt vor:
Umwandeln der Polygongrenze in eine Linie:
select st_boundary(geometry) from myPolygonTable;
Auswahl des ersten Stützpunktes der resultierenden Linie:
select st_startpoint(myGeometry) from ( select st_boundary(geometry) as myGeometry from myPolygonTable) as foo;
16.5.8. Datenverarbeitung
PostGIS unterstützt alle zum OGC SFS/MM Standard konforme Funktionen. Alle diese Funktionen starten mit ST_
.
16.5.9. Ausschneiden
Um einen Teil unsrer Daten auszuschneiden, können wir die ST_INTERSECT()
Funktion verwenden. To avoid empty geometries, use:
where not st_isempty(st_intersection(a.the_geom, b.the_geom))
select st_intersection(a.the_geom, b.the_geom), b.*
from clip as a, road_lines as b
where not st_isempty(st_intersection(st_setsrid(a.the_geom,32734),
b.the_geom));
16.5.10. Geometrien aus anderen Geometrien erstellen
Man möchte aus einer gegebenen Tabelle mit Punkten eine Linie generieren. Die Ordnung der Punkte ist durch ihre id vorgegeben. Eine andere Methode zur Ordnung könnte ein Zeitstempel sein, den man z.B. bei der Aufzeichnung von Wegpunkten im GPS-Empfänger erhält.
Um eine Linie aus einem neuen Punktlayer ‚points‘ zu erstellen, kann man das folgende Kommando ausführen:
select ST_LineFromMultiPoint(st_collect(the_geom)), 1 as id
from (
select the_geom
from points
order by id
) as foo;
Um die Arbeitsweise zu testen ohne einen neuen Layer zu erstellen, kann man das Kommando auf den ‚people‘ Layer anwenden, obwohl das kein wirklich sinnvolles Ergebnis liefert.
16.5.11. Geometriebereinigung
You can get more information for this topic in this blog entry.
16.5.12. Unterschiede zwischen Tabellen
Um den Unterschied zwischen zwei Tabellen mit derselben Struktur herauszufinden, kann man das PostgreSQL Schlüsselwort EXCEPT
verwenden:
select * from table_a
except
select * from table_b;
Im Ergebnis erhält man alle Datensätze aus table_a die nicht in table_b gespeichert sind.
16.5.13. Tablespaces
Man kann durch die Erstellung von Tablespaces vorgeben, wo Postgres seine Daten speichern soll:
CREATE TABLESPACE homespace LOCATION '/home/pg';
Wenn man eine Datenbank erstellt, kann man vorgeben welcher Tablespace genutzt werden soll, z.B.:
createdb --tablespace=homespace t4a
16.5.14. In Conclusion
Sie haben gelernt, wie man komplexere Geometrien mit Hilfe von PostGIS Anweisungen erstellt. Dies dient vor allem der Verbesserung Ihres Hintergrundwissens bei der Arbeit mit räumlichen Datenbanken über eine GIS Oberfläche. Normalerweise müssen Sie diese Anweisungen nicht manuell eingeben. Trotzdem hilft ein generelles Verständnis ihrer Struktur bei der Nutzung von GIS, insbesondere wenn Fehler auftreten, die ohne dieses Wissen unverständlich erscheinen.