Làm cách nào để xác định và đơn giản hóa các cụm điểm liên quan đến thời gian trong PostGIS?


11

Tôi mới bắt đầu làm việc với các cơ sở dữ liệu không gian và tôi muốn viết một truy vấn SQL (PostGIS) để tự động khái quát hóa các rãnh GPS thô (với tần suất theo dõi cố định). Điều đầu tiên tôi quan tâm là một truy vấn xác định các điểm dừng ở dạng truy vấn như "x điểm trong khoảng cách y mét" để thay thế các đám mây điểm lớn bằng các điểm đại diện. Tôi đã nhận ra để chụp các điểm trong một khoảng cách nhất định và đếm những người bị gãy. Trong hình bên dưới, người ta có thể thấy một bản nhạc ví dụ thô (các điểm đen nhỏ) và tâm của các điểm được chụp dưới dạng các vòng tròn màu (kích thước = số điểm được chụp).

nhập mô tả hình ảnh ở đây

CREATE table simplified AS 
 SELECT count(raw.geom)::integer AS count, st_centroid(st_collect(raw.geom)) AS center
   FROM raw
  GROUP BY st_snaptogrid(raw.geom, 500, 0.5)
  ORDER BY count(raw.geom) DESC;

Tôi sẽ khá hài lòng với giải pháp này, nhưng có một vấn đề về thời gian: Hình ảnh theo dõi như một bản nhạc cả ngày trong một thành phố mà người đó có thể quay lại những nơi đã đến trước đó. Trong ví dụ của tôi, vòng tròn màu xanh đậm đại diện cho nhà của người mà anh ta đã truy cập hai lần nhưng tất nhiên truy vấn của tôi bỏ qua điều đó.

Trong trường hợp này, truy vấn tinh vi chỉ nên thu thập các điểm có dấu thời gian liền kề (hoặc id), để nó tạo ra hai điểm đại diện ở đây. Ý tưởng đầu tiên của tôi là sửa đổi truy vấn của tôi thành phiên bản 3d (thời gian là chiều thứ ba), nhưng dường như nó không hoạt động.

Có ai có lời khuyên nào cho tôi không? Tôi hy vọng rằng câu hỏi của tôi là rõ ràng.


Cảm ơn bạn cho ý tưởng dòng. Tôi nhận ra để thực hiện và đơn giản hóa một linestring như bạn có thể thấy trong ảnh chụp màn hình bên dưới (dấu chấm là điểm gốc). nhập mô tả hình ảnh ở đây Điều tôi vẫn cần là xác định nơi nghỉ ngơi (> x điểm trong bán kính <x mét), lý tưởng là một điểm với thời gian đến và thời gian rời đi ... còn ý tưởng nào khác không?


2
Bạn có thực sự cần các điểm cho các mục đích khác? Mặt khác, có vẻ như có thể chỉ cần tạo các dòng từ các điểm, và sau đó đơn giản hóa / khái quát hóa các dòng đó sẽ phục vụ mục đích của bạn.
Anthony -GISCOE-

2
Đó là một vấn đề hấp dẫn. Bạn có thể có thể lượm lặt một số ý tưởng từ cơ bản cùng một câu hỏi đã được hỏi trên trang Mathicala tại mathicala.stackexchange.com/questions/2711 . Không phải tất cả các câu trả lời khai thác kích thước thời gian của dữ liệu (nhưng của tôi thì có :-).
whuber

@ Anthony-GISCOE- đó là một cách tiếp cận thú vị. Trong trường hợp cần có các tính năng điểm, các tính năng mới có thể được tạo từ các đỉnh của các dòng tổng quát hoặc dọc theo các dòng như ở đây gis.stackexchange.com/questions/27102/ . Tôi biết, những điều đó vẫn không phải là điểm ban đầu!
andytilia

@ Anthony: Tôi hoàn toàn cần điểm "đại diện" của bất kỳ chỗ đứng nào và ít nhất là bắt đầu - và thời gian kết thúc ...
Berlin_J

1
và nó sẽ thực sự hữu ích khi có một giải pháp hậu kỳ :)
Berlin_J

Câu trả lời:


4

Nếu bạn thực sự cần tất cả các điểm để trực quan hóa, thì bạn có thể tạo một dòng và st_simplify (đó là triển khai Douglas Peucker) sẽ thực hiện công việc khá độc đáo.

Trong một số trường hợp, bạn thậm chí không cần lưu trữ tất cả các điểm, vì vậy bạn có thể thực hiện lọc trước khi lưu dữ liệu điểm, ví dụ: khi đối tượng không di chuyển, không lưu trữ nó. Bạn có thể áp dụng DouglasPeucker hoặc một số bộ lọc cơ bản khác trước khi thêm điểm vào DB. Ngoài ra, một số nhà cung cấp GPS (như API vị trí Android) có thể tự động lọc ban đầu dựa trên thời gian và khoảng cách tối thiểu. Trong một số trường hợp, bạn giữ dữ liệu trùng lặp: được lọc trước để hiển thị nhanh và nhật ký đầy đủ để lưu trữ. Lưu trữ đồng bằng là khá rẻ hiện nay.


3

Trong khi đó, tôi tìm thấy một giải pháp cho vấn đề của mình:

Đầu tiên, tôi xác định "loại khoảng cách" cho mọi điểm. Nếu điểm gần hơn x mét đến điểm tiếp theo, nó được xác định là "dừng", nếu không là "di chuyển". Sau đó, tôi bắt đầu một chức năng cửa sổ như thế này:

     SELECT t1.id, t1.dist_type, t1."time", t1.the_geom, t1.group_flag, sum(t1.group_flag) OVER (ORDER BY t1.id) AS group_nr
FROM ( SELECT distances.id, distances.the_geom, distances."time", distances.dist_type, 
                CASE
                    WHEN lag(distances.dist_type) OVER (ORDER BY distances.id) = distances.dist_type THEN NULL::integer
                    ELSE 1
                END AS group_flag
           FROM distances) t1;

Bảng kết quả trông như sau:

nhập mô tả hình ảnh ở đây

Bước tiếp theo đơn giản sẽ nhóm các điểm "dừng", xác định trọng tâm của các nhóm điểm này và lấy dấu thời gian tối thiểu và tối đa khi đến và rời thời gian.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.