PostGIS: Annäherung einer Hausnummer aus dem Adressbereich

8

Ich entwickle einen Reverse-Geocoder für Kanada. Bisher kann ich bei gegebener Breite die nächstgelegene Straße (Liniensegment) finden, die die Richtung des Liniensegments und die Adressbereiche für beide Straßenseiten enthält. Ich versuche jetzt herauszufinden, wie ich die nächstgelegene Hausnummer programmgesteuert an den angegebenen Lat / Lng-Punkt annähern kann.

Hier ist ein Beispiel für eine Zeile mit den Straßendaten:

-[ RECORD 1 ]-
[...]
l_adddirfg | Same Direction
l_hnumf    | 3219
l_hnuml    | 3235
l_stname_c | Breen Road North-west
r_adddirfg | Same Direction
r_hnumf    | 3224
r_hnuml    | 3236
r_stname_c | Breen Road North-west
the_geom   | 0105000020E610000001000000010200000002000000B0F6990E78885CC088DF2B5F3C8C49400875B39A89885CC0A0BCA6AC4B8C4940

Bei einer Lat / Lng-Koordinate, die in der Nähe des Liniensegments "the_geom" liegt, kann eine Person visuell erkennen, auf welcher Straßenseite sich der Punkt befindet (linke oder rechte Seite) und wie weit er sich entlang des Segments befindet Annäherung an eine Hausnummer. Wenn der Punkt beispielsweise auf der rechten Seite liegt, drei Viertel der Straße hinunter, würde ich die Felder r_hnumf (rechte Seite, erste Nummer) und r_hnuml (rechte Seite, letzte Nummer) verwenden ... Die Adresse ist wahrscheinlich in der Nähe zu:

3232 Breen Road North-west

Was ich suche, ist eine bewährte Methode, um dies entweder in PostGIS (für das ich neu bin) oder in der Anwendungsschicht zu berechnen / zu approximieren, sobald die Zeile abgerufen wurde.

Vielen Dank!

René Fournier
quelle

Antworten:

11

Die Lösung kann vollständig in PostGIS erstellt werden.

Wenn Sie einen Punkt (Hausstandort, ich habe ihn als PUNKT modelliert) und ein Straßensegment (Straßensegment, das diesem Punkt am nächsten liegt, als LINESTRING modelliert) angegeben haben, fragen Sie:

  • Wie erkennt man, ob der Punkt links von einem Straßensegment liegt?

Eine mögliche Lösung besteht darin, den Punkt auf dem Straßensegment zu bestimmen, der dem Haus am nächsten liegt, und dann zu bestimmen, ob dieser Punkt links oder rechts vom Haus liegt (der Operator &<gibt true zurück, wenn sich das erste Geometrieargument überlappt oder links davon liegt das zweite Geometrieargument). &<funktioniert eigentlich mit Begrenzungsrahmen, aber da wir mit Punkten arbeiten, sollte dies keine Rolle spielen.

osm=# select 'POINT(4 1)'::geometry &< st_closestpoint('LINESTRING(1 1,2 3,6 6)'::geometry, 'POINT(4 1)'::geometry) as houseIsOnLeft;
 houseisonleft 
---------------
 f
(1 row)
  • Wie weit ist das Haus auf dem Straßensegment

Dies bedeutet wiederum, wie weit (ein Wert zwischen 0 und 1) auf dem Straßensegment der Punkt auf der Straße ist, der dem Haus am nächsten liegt. Dafür gibt es eine integrierte Funktion namens st_line_locate_point :

osm=# select st_line_locate_point('LINESTRING(1 1,2 3,6 6)'::geometry, 'POINT(2 1)'::geometry);
 st_line_locate_point 
----------------------
   0.0618033988749895
(1 row)

osm=# select st_line_locate_point('LINESTRING(1 1,2 3,6 6)'::geometry, 'POINT(5 6)'::geometry);
 st_line_locate_point 
----------------------
    0.889442719099992
(1 row)

Diagramm von Linestring und Punkt oben verwendet

diciu
quelle