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