Polygonverschneidung

Werbung
Polygonverschneidung
mit SQL
Sarah Tauscher, Karl Neumann
Inhalt
1. Motivation
2. Polygonverschneidung
3. Modellierung und Hilfsanfragen
4. SQL-Anfrage zur Polygonverschneidung
5. Zusammenfassung und Ausblick
Motivation
• Komplexe Analysen in SQL ohne Rekursion und
Objektorientierung angeblich nicht möglich
• Möglich sind
– Modellierung von Geometrien
– Funktionen die durch einfache Formeln darstellbar
sind z.B. Punktabstand
– Funktionen für die einfache Summenformeln
existieren z.B. Länge von Linien, Umfang und Fläche
von Polygonen
– Polygonverschneidung?
2
Polygonverschneidung
• Verknüpfung mehrerer Layer
– Schnitt
– Vereinigung
– Subtraktion
• Objektmodellierung
– Üblich: topologisches Modell
– Hier: objektorientiert
• Simple Features
• Gerichtete Kanten
3
Polygonverschneidung
• Vorgehen
entry
1) Schnittpunkte berechnen
•
Geradengleichung
2) Schnittpunkte klassifizieren
•
•
Rotationswinkel < 180
→ exit
Rotationswinkel > 180
→ entry
exit
entry
exit
3) Jeweils die Polygonkante
verfolgen, für die der
Schnittpunkt “entry” ist
4
Polygonverschneidung
• Sliverpolygone
– Kleine Fläche
– Lange, dünne Form
→ Verhältnis vom
Umfang zur Fläche
• Sonderfälle
– Überlappende Kanten
– Schnittpunkte auf
Stützpunkten
5
Modellierung von Polygonen
• Einfachste relationale Modellierung von
Polygonen: Liste der Stützpunkte
– Relationenschema
id
position
x
y
– Bedingungen
• Position beginnt bei 1 und die Punkte liegen “dicht”
• Umlaufrichtung für alle Polygone gleich z.B. gegen den
Uhrzeigersinn
6
Modellierung von Polygonen
• Schnittpunkte
– Geradengleichung y = m x + b
• xs = (p1.b - p2.b) / (p2.m - p1.m)
ys = (p2.m*p1.b - p1.m*p2.b) / (p2.m - p1.m)
• Überprüfung ob der Schnittpunkt auf den
Kanten liegt
– Daten die für die weitere Berechnung
notwendig sind
• IDs der Polygone
• Koordinaten
• Position auf den Kanten
2
pos1 = 5,5
pos2 = 2,8
1
pos1 = 5,3
5
pos2 = 1,3
7
Modellierung von Polygonen
• Verwendete Daten
– Schnittpunkt der Geraden (xs+ys)
• Aufeinanderfolgende Punkte (1+1)
• Steigung (2+4)
• Achsenabschnitt (2+2)
– Lage des Schnittpunktes
• Aufeinanderfolgende Punkte 8
• xs 2, ys 2
→ Modellierung der Polygone als Liste von Kanten
id
edgeId
startX
startY
endX
endY
m
b
8
Hilfsanfragen
• SQL-Anfrage zur Schnittpunktberechnung
CREATE VIEW Schnitt AS
SELECT p1.id, p2.id, pos1, pos2, xs, ys
FROM
Polygon p1, Polygon p2
WHERE (xs
( BETWEEN p1.startX AND p1.end
OR xs BETWEEN p1.endX AND p1.startX)
AND
( BETWEEN p2.startX AND p2.END
(xs
OR xs BETWEEN p2.endX AND p2.startX)
AND (ys
( BETWEEN p1.startY AND p1.endY
OR ys BETWEEN p1.endY AND p2.startY)
AND (ys
( BETWEEN p2.startY AND p2.endY
OR ys BETWEEN p2.endY AND p2.startY)
AND p1.id < p2.id AND p1.m <> p2.m
9
Hilfsanfragen
• Punkt-in-Polygon-Test
– Halbstrahlverfahren
– Problemfälle
• Punkt hat dieselbe y-Koordinate
wie ein Stützpunkt
SELECT in.startX, in.startY
FROM Polygon in
WHERE (SELECT count(*)
FROM Polygon out
WHERE xs > in.startX
AND (in.startY BETWEEN out.startY AND out.endY
OR in.startY BETWEEN out.endY AND out.startY))
AND out.m <>0 ) % 2 = 1
10
Kanten des Schnittpolygons
• 8 Fälle (4 für jedes Polygon)
– Zwischen zwei Stützpunkten
– Zwischen zwei Schnittpunkten
– Zwischen Stütz- und Schnittpunkt
– Zwischen Schnitt- und Stützpunkt
3
2
4
• 2 Sonderfälle
– Schnittpunkt zu Stützpunkt mit
kleinster Position
1
→10 Anfragen mit UNION verbunden
11
Kanten des Schnittpolygons
• Kante zwischen zwei Schnittpunkten
SELECT [neue ID], s1.pos1, s1.pos2,
festlegen der
s1.x as startx, s1.y as starty,
Reihenfolge
s2.x as endx, s2.y as endy
FROM Schnitt s1, Schnitt s2
nur Schnittpunkte
WHERE s1.pos1 < s2.pos1
eines Polygonpaares
AND s1.id1 = s2.id1
kein Schnittpunkt
AND s1.id2 = s2.id2
dazwischen
AND NOT EXISTS
(SELECT * FROM Schnitt s3
WHERE s3.pos1 BETWEEN s1.pos1 AND s2.pos1
AND s1.id1 = s3.id1 AND s1.id2 = s3.id2)
Punkte liegen
AND [Mittelpunkt in Polygon mit Id2]
auf einer Kante
AND ceil(s1.pos1) > s2.pos1
12
Kanten des Schnittpolygons
• Kante zwischen zwei Stützpunkten
SELECT [neue ID],
p.edgeId as pos1, s1.pos2,
für Ordnung
p.startx, p.starty,
bzgl. des
p.endx, p.endy
2.Polygon
FROM Polygon p, Schnitt s1
WHERE NOT EXISTS
(SELECT * FROM Schnitt s
WHERE s.pos1 BETWEEN p.edgeId
AND p.edgeId+1
AND s1.id1= s.id1 AND s1.id2= s2.id2)
AND
[Anfangspunkt in Polygon mit Id2]
AND
s1.id1 = p.id
AND
s1.pos1 = (SELECT max(pos1)…)
vorangegangener
Schnittpunkt
13
Kanten des Schnittpolygons
• Kante zwischen Schnittpunkt und Stützpunkt mit
kleinster Position
SELECT [neue ID], s1.pos1, s1.pos2,
s1.x as startx, s1.y as starty,
p.startx as endx, p.starty as endy
Schnittpunkt
FROM Schnitt s1, Polygon p
mit größter
Position
WHERE s1.id1 = p.id
kleinste
Position
AND p.edgeId = 1
AND s1.pos1 = (SELECT max(pos1) FROM Schnitt s2
WHERE s1.id1 = s2.id1AND s1.id2 = s2.id2)
AND s1.pos1 > (SELECT max(edgeId) FROM Polygon p2
WHERE p2.id = p.id) kein Stützpunkt
dazwischen
AND [Stützpunkt in Polygon mit Id2]
14
Ordnung der Kanten
• Bestimmen der ganzzahligen Position der Kante
– Zählen der Kanten, die eine kleinere Position haben
– Self-Join des Anfrageergebnisses mit Gruppierung
SELECT
FROM
WHERE
AND
GROUP BY
r1.id, count(*) as edgeId,
r1.startX, r1.startY, r1.endX, r1.endY
Result r1, Result r2
r1.id = r2.id
(r1.pos1 > r2.pos1
OR (r1.pos1 = r2.pos1
AND r1.pos2 >= r2.pos2))
r1.id, r1.pos1, r1.pos2,
r1.startX, r1,startY, r1.endX, r1.endY
15
Zusammenfassung
• Polygonverschneidung in SQL ist möglich:
+ Schnittpunkte-Sicht
+ Self-Join
16
Ausblick
• Sonderfallbehandlung
– Überlappende Kanten
– Schnittpunkt = Stützpunkt
– Parallelen zur y-Achse
– Punkt-in-Polygon
• Überprüfung ob Sliverpolygone
• Laufzeitexperimente
17
Herunterladen