Menemukan garis terdekat diberi 2 poin menggunakan PostGIS?


9

Saya memiliki tabel t yang berisi kolom line_positionsyang bertipe baris. Diberikan 2 poin saya ingin menemukan garis terdekat yang cukup dekat (kurang dari 10km) dan yang tidak melewati terlalu dekat dengan titik yang ingin saya hindari (minimum 20km). Saat ini saya gunakan

SELECT t.*
FROM path t
WHERE
  ST_DWithin(ST_GeographyFromText('Point(69.835 22.596)'), t.line_positions, 10000, FALSE)  AND
  ST_DWithin(ST_GeographyFromText('Point(69.856 22.519)'), t.line_positions, 10000, false) AND
  NOT ST_DWithin(ST_GeographyFromText('Point(-79.804 9.141)'), t.line_positions, 20000, false)
ORDER BY
  ST_Distance(ST_GeographyFromText('Point(69.835 22.576)'), t.line_positions, false) +
  ST_Distance(ST_GeographyFromText('Point(69.856 22.519)'), t.line_positions, false)
  ASC
LIMIT 1

Ada indeks inti ix_path_line_positionspada kolom line_positions.

Ia bekerja tetapi lambat, antara 3s dan 30s untuk hanya 100000 baris di t.

jelaskan analisis memberi:

Limit  (cost=9.95..9.95 rows=1 width=1432) (actual time=21729.253..21729.254 rows=1 loops=1)
   ->  Sort  (cost=9.95..9.95 rows=1 width=1432) (actual time=21729.251..21729.251 rows=1 loops=1)
         Sort Key: ((_st_distance('0101000020E61000003D0AD7A370755140FA7E6ABC74933640'::geography, line_positions, '0'::double precision, false) + _st_distance('0101000020E6100000105839B4C8765140BE9F1A2FDD843640'::geography, line_positions, '0'::double precision, false)))
         Sort Method: top-N heapsort  Memory: 26kB"
         ->  Index Scan using ix_path_line_positions on path t  (cost=0.28..9.94 rows=1 width=1432) (actual time=93.490..21710.562 rows=690 loops=1)
           Index Cond: ((line_positions && '0101000020E61000003D0AD7A3707551407F6ABC7493983640'::geography) AND (line_positions && '0101000020E6100000105839B4C8765140BE9F1A2FDD843640'::geography))
           Filter: (('0101000020E61000003D0AD7A3707551407F6ABC7493983640'::geography && _st_expand(line_positions, '10000'::double precision)) AND ('0101000020E6100000105839B4C8765140BE9F1A2FDD843640'::geography && _st_expand(line_positions, '10000'::double precision)) AND _st_dwithin('0101000020E61000003D0AD7A3707551407F6ABC7493983640'::geography, line_positions, '10000'::double precision, false) AND _st_dwithin('0101000020E6100000105839B4C8765140BE9F1A2FDD843640'::geography, line_positions, '10000'::double precision, false) AND ((NOT ('0101000020E6100000FA7E6ABC74F353C0D578E92631482240'::geography && _st_expand(line_positions, '20000'::double precision))) OR (NOT (line_positions && '0101000020E6100000FA7E6ABC74F353C0D578E92631482240'::geography)) OR (NOT _st_dwithin('0101000020E6100000FA7E6ABC74F353C0D578E92631482240'::geography, line_positions, '20000'::double precision, false))))
           Rows Removed by Filter: 15365
Planning time: 0.491 ms
Execution time: 21729.321 ms

Bagaimana saya bisa memperbaikinya? Sebagai gantinya menggunakan perhitungan geometri (tetapi lintasan saya dapat menjangkau beberapa ribu km, apakah jarak yang dihitung akan benar)? Menggunakan <-> operator KNN (tapi karena saya memesan pada jumlah 2 jarak, sepertinya tidak menggunakan indeks inti sih)?


Anda dapat mencoba meningkatkan parameter work_mem , sebelum mengeksekusi kode. MisalnyaSET work_mem TO '200MB';
Yaroslav

Jawaban:


1

Apakah dua poin yang diberikan selalu dalam jarak 10 km satu sama lain. Jika demikian, Anda bisa mencoba membuat dua poin menjadi satu baris dan melakukan satu ST_DWithin alih-alih dua. Itu mungkin sedikit memperbaiki keadaan.

SELECT t.*
FROM path t
WHERE
  ST_DWithin(ST_GeomFromText('LINESTRING(69.835 22.596,69.856 22.519)'), t.line_positions, 10000, FALSE)  
  NOT ST_DWithin(ST_GeographyFromText('Point(-79.804 9.141)'), t.line_positions, 20000, false)
ORDER BY
  ST_Distance(ST_GeographyFromText('Point(69.835 22.576)'), t.line_positions, false) +
  ST_Distance(ST_GeographyFromText('Point(69.856 22.519)'), t.line_positions, false)
  ASC
LIMIT 1

Tidak, 2 poin tidak berada dalam jarak 10 km satu sama lain, mereka dapat berjarak ribuan km. Kendalanya adalah keduanya berjarak kurang dari 10 km dari garis, tetapi bisa sangat jauh karena garisnya membentang ribuan km.
Go4It
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.