Pertanyaan PostGIS - Solusi pencocokan rute


Kami sedang membangun aplikasi di mana saya seorang pengemudi dan saya melakukan perjalanan dari titik A ke titik B. Pada jalan saya dapat menemukan penumpang yang melakukan perjalanan di rute yang sama.

Kami menggunakan PostgreSQL dengan ekstensi PostGIS.

Setelah googling banyak saya telah menemukan bahwa kita dapat menggunakan linestring untuk mencapai ini. Saya tidak sepenuhnya yakin apakah pendekatan ini akan berhasil.

Misalkan saya memiliki koordinat sumber dan tujuan saya.

    var RouteCoordinates = [
      {lat: 37.772, lng: -122.214},
      {lat: 21.291, lng: -157.821},
      {lat: -18.142, lng: 178.431},
      {lat: -27.467, lng: 153.027}
    ];

Saya harus menyimpan ini sebagai hal terpenting dalam DB saya.

Setelah memeriksa apakah seorang penumpang juga masuk ke rute ini, tetapi karena kami tahu sumber dan tujuannya tidak akan persis sama dengan string garis saya, tetapi mereka akan dekat. Misalnya sekitar radius 1 km

enter image description here

Seperti yang Anda lihat sumber dan tujuan saya adalah garis itu. Dan ketika saya bepergian saya ingin memilih semua orang yang (sumber dan tujuan) dekat dengan rute saya (dalam radius tertentu)

Jika saya ingin mencari lokasi tertentu di DB saya dalam radius tertentu saya akan melakukan query seperti ini

SELECT id, name, address, geom  
FROM Seattle_Starbucks  
WHERE ST_DWithin(geom, ST_MakePoint(-122.325959,47.625138)::geography, 1000);

Sekarang saya dapat mencapai solusi saya karena saya baru memposting GIS yang sedikit membingungkan

  1. Bagaimana cara menyimpan semua semua sumber dan tujuan saya di DB

ANS: Saya perlu mengkonversikan ke linestring menggunakan fungsi ini ST_MakeLine dan kemudian simpan, bukan?

  1. Bagaimana cara menanyakannya berdasarkan kebutuhan saya seperti yang saya sebutkan di atas

Bisakah Anda memberi saya wawasan tentang cara mencapainya. Bantuan Anda sangat dihargai. Terima kasih


7
2017-09-14 12:46


asal


Jawaban:


Beberapa pendapat tentang pertanyaan Anda:

Saya perlu mengkonversi ke linestring menggunakan fungsi ini ST_MakeLine dan   lalu simpan, kan?

Ya, untuk menggabungkan beberapa titik menjadi LINESTRING Kamu dapat memakai ST_MakeLine:

SELECT ST_AsText( 
       ST_MakeLine(ARRAY[ST_MakePoint(-122.21,37.77),
                         ST_MakePoint(-157.82,21.29),
                         ST_MakePoint(178.43,-18.14),
                         ST_MakePoint(153.02,-27.46)]));

                              st_astext                              
---------------------------------------------------------------------
 LINESTRING(-122.21 37.77,-157.82 21.29,178.43 -18.14,153.02 -27.46)
(1 Zeile)

Bagaimana cara menanyakannya berdasarkan kebutuhan saya seperti yang saya sebutkan di atas

Buat buffer pada setiap titik Anda LINESTRING dan periksa apakah ada geometri lain di dalamnya.

Pertama, Anda harus membagi kekalahan Anda LINESTRING ke POINTs menggunakan ST_DumpPoints ...

db=# SELECT ST_AsText((ST_DumpPoints('LINESTRING(-122.21 37.77,-157.82 21.29,178.43 -18.14,153.02 -27.46)'::GEOMETRY)).geom);
      st_astext       
----------------------
 POINT(-122.21 37.77)
 POINT(-157.82 21.29)
 POINT(178.43 -18.14)
 POINT(153.02 -27.46)
(4 Zeilen)

.. dan kemudian digunakan ST_Buffer untuk membuat buffer di sekitar setiap titik. ST_Buffer mengembalikan geometri dengan area di sekitar titik Anda (atau jenis geometri lainnya). Misalnya, mengambil titik pertama dari rute Anda (jika saya tidak berpindah x dan y, di suatu tempat di San Francisco) POINT(-122.21 37.76):

enter image description here

db=# SELECT ST_AsText(                                                         
       ST_Buffer('POINT(-122.21 37.76)'::GEOMETRY,0.0001, 'quad_segs=16'));

Mengembalikan geometri ini:

POLYGON((-122.2099 37.76,-122.209900481527 37.759990198286,-122.209901921472 37.7599804909678,-122.209904305966 37.7599709715323,-122.209907612047 37.7599617316568,-122.209911807874 37.7599528603263,-122.209916853039 37.7599444429767,-122.209922698955 37.7599365606716,-122.209929289322 37.7599292893219,-122.209936560672 37.7599226989547,-122.209944442977 37.7599168530388,-122.209952860326 37.7599118078736,-122.209961731657 37.7599076120467,-122.209970971532 37.7599043059664,-122.209980490968 37.759901921472,-122.209990198286 37.7599004815273,-122.21 37.7599,-122.210009801714 37.7599004815273,-122.210019509032 37.759901921472,-122.210029028468 37.7599043059664,-122.210038268343 37.7599076120467,-122.210047139674 37.7599118078736,-122.210055557023 37.7599168530388,-122.210063439328 37.7599226989547,-122.210070710678 37.7599292893219,-122.210077301045 37.7599365606716,-122.210083146961 37.7599444429767,-122.210088192126 37.7599528603263,-122.210092387953 37.7599617316568,-122.210095694034 37.7599709715323,-122.210098078528 37.7599804909678,-122.210099518473 37.759990198286,-122.2101 37.76,-122.210099518473 37.760009801714,-122.210098078528 37.7600195090322,-122.210095694034 37.7600290284677,-122.210092387953 37.7600382683432,-122.210088192126 37.7600471396737,-122.210083146961 37.7600555570233,-122.210077301045 37.7600634393284,-122.210070710678 37.7600707106781,-122.210063439328 37.7600773010453,-122.210055557023 37.7600831469612,-122.210047139674 37.7600881921264,-122.210038268343 37.7600923879533,-122.210029028468 37.7600956940336,-122.210019509032 37.760098078528,-122.210009801714 37.7600995184727,-122.21 37.7601,-122.209990198286 37.7600995184727,-122.209980490968 37.760098078528,-122.209970971532 37.7600956940336,-122.209961731657 37.7600923879533,-122.209952860326 37.7600881921264,-122.209944442977 37.7600831469612,-122.209936560672 37.7600773010453,-122.209929289322 37.7600707106781,-122.209922698955 37.7600634393284,-122.209916853039 37.7600555570233,-122.209911807874 37.7600471396737,-122.209907612047 37.7600382683432,-122.209904305966 37.7600290284677,-122.209901921472 37.7600195090322,-122.209900481527 37.760009801714,-122.2099 37.76))

enter image description here

Jika Anda bertanya-tanya tentang bentuk buffer ini, silakan baca ini menjawab.

Dan menggunakan kueri ini Anda dapat memeriksa apakah geometri lain ada di dalam buffer ini (ST_Within):

db=# SELECT
       ST_Within('POINT(-122.21 37.76)'::GEOMETRY,
          ST_Buffer('POINT(-122.21 37.76)'::GEOMETRY,0.0001, 'quad_segs=16'));
 st_within 
-----------
 t
(1 Zeile)

Untuk mengumpulkan semuanya, Anda dapat menggunakan CTE (alias DENGAN klausa) dan tulis sesuatu seperti ini:

WITH j AS (
  SELECT
    (ST_DumpPoints('LINESTRING(-122.21 37.77,-157.82 21.29,178.43 -18.14,153.02 -27.46)'::GEOMETRY)).geom AS g)
SELECT id, name, address, geom
FROM Seattle_Starbucks
WHERE ST_Within(geom,ST_Buffer(j.g,0.0001, 'quad_segs=16'))

0
2018-05-09 08:34