PostGIS: Mendekati nomor rumah dari kisaran alamat

8

Saya sedang mengembangkan reverse-geocoder untuk Kanada. Sejauh ini, mengingat lat / lng, saya dapat menemukan jalan terdekat (segmen garis), yang mencakup arah segmen garis dan rentang alamat untuk kedua sisi jalan. Saya sekarang mencoba mencari cara terbaik untuk secara program memperkirakan jumlah rumah terdekat ke titik lat / lng yang diberikan.

Berikut adalah contoh baris yang berisi data jalan:

-[ 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

Jadi, mengingat koordinat lat / lng yang terletak di dekat segmen garis "the_geom", seseorang dapat mengetahui secara visual di sisi jalan mana titik tersebut berada (sisi kiri atau kanan), dan seberapa jauh sepanjang segmen itu - dengan demikian mendekati nomor rumah. Misalnya, jika titik terletak di sisi kanan, tiga perempat di jalan, saya akan menggunakan bidang r_hnumf (sisi kanan, angka pertama) dan r_hnuml (sisi kanan, angka terakhir) ... Alamat jalan mungkin dekat untuk:

3232 Breen Road North-west

Apa yang saya cari adalah praktik terbaik dalam menghitung / memperkirakan hal ini di PostGIS (yang baru bagi saya), atau di lapisan aplikasi setelah baris diambil.

Terima kasih!

René Fournier
sumber

Jawaban:

11

Solusinya dapat dibangun seluruhnya di PostGIS.

Diberi titik (lokasi rumah, saya telah memodelkannya sebagai POINT) dan ruas jalan (ruas jalan terdekat dengan titik ini, dimodelkan sebagai LINESTRING) Anda bertanya:

  • Cara mengetahui apakah titik berada di sebelah kiri segmen jalan

Solusi yang mungkin adalah menentukan titik pada ruas jalan yang paling dekat dengan rumah dan kemudian menentukan apakah titik ini terletak di kiri atau kanan rumah (operator &<mengembalikan true jika argumen geometri pertama tumpang tindih atau di sebelah kiri argumen geometri kedua). &<sebenarnya bekerja dengan kotak pembatas tetapi karena kami bekerja dengan poin ini seharusnya tidak masalah.

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)
  • Seberapa jauh rumah di segmen jalan

Sekali lagi ini berarti seberapa jauh (nilai antara 0 dan 1) pada ruas jalan adalah titik di jalan yang paling dekat dengan rumah. Ada fungsi bawaan untuk itu, yang disebut 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)

Diagram linestring dan titik yang digunakan di atas

diciu
sumber