Tìm hình học gần nhất trong PostGIS


16

Tôi đã xem qua "API" các chức năng của PostGIS và tôi nhận thấy rằng hầu hết chúng đều có hai yếu tố để so sánh. Ví dụ: hàm ST_Distance lấy hai thành phần hình học / địa lý để tìm khoảng cách.

Không có chức năng để làm một cái gì đó như: "Đưa ra một hình học G, cho tôi hình học GClosest gần nhất trong Bảng T trong đó G.id <> GClosest.id"

Tôi nhận ra rằng tôi có thể viết một hàm PL / PGQuery để lặp lại bảng và gọi ST_Distance trên mỗi phần tử, nhưng tôi hy vọng có một giải pháp tốt hơn, hiệu quả hơn.


1
Nếu bạn đang quan tâm đến khoảng cách đến hình học gần nhất, kiểm tra gis.stackexchange.com/questions/11979/...
Underdark

cho tôi biết nếu tôi hiểu đúng ... bạn muốn tính năng tiếp theo có cùng khoảng cách so với gần nhất?
falcacibar

Câu trả lời:


7

Câu hỏi của bạn cũng có thể được trả lời bằng một truy vấn (mặc dù phức tạp) như sau đây trả về toàn bộ bản ghi và khoảng cách đến hình học tham chiếu. Xin lưu ý rằng nếu có nhiều hơn một bản ghi khớp với khoảng cách tối thiểu thì tất cả chúng sẽ được trả về.

SELECT 
  i.*,
  md.min_distance
FROM
  address AS i, 
  (SELECT 
     ga.address_geom,
     min( ST_Distance(
            ga.address_geom,
            gb.address_geom)
        ) AS min_distance
   FROM
     address AS ga,
     address AS gb 
   WHERE 
     ga.id <> gb.id 
   AND 
     ga.id = 3
   GROUP BY 
     ga.address_geom
  ) AS md 
WHERE 
  ST_Distance( i.address_geom, md.address_geom) = md.min_distance;

Tôi đã kiểm tra truy vấn này trên bảng địa chỉ và nó hoạt động. Trong truy vấn trên tôi đang tìm kiếm điểm gần nhất với id = 3.


Đây là thông tin tốt - cảm ơn bạn ... Tôi hiểu hàm tổng hợp min (..) theo định nghĩa, nhưng tôi bối rối về cách nó được sử dụng trong ví dụ của bạn. st_distance (X, Y) có hai loại hình học và trả về một khoảng cách giữa chúng, là một giá trị duy nhất. Tại sao sau đó bạn gọi một hàm tổng hợp trên kết quả giá trị đơn đó? Có lẽ tôi đang hiểu sai về tuyên bố chọn bên trong ...
Jmoney38

Nhóm theo trên hình dạng ga là hằng số cho toàn bộ tập kết quả (nhớ ga được chọn bởi id = 3) vì vậy về cơ bản nó không làm gì cả. Đó chỉ là một mẹo để có sẵn hình dạng ga trong trạng thái ổn định của truy vấn bên ngoài mà không cần nối lại bảng hai lần nữa. Hôm nay tôi đã nghĩ rằng có lẽ tôi có thể thoát khỏi truy vấn bẩm sinh hoàn toàn bằng cách sử dụng mệnh đề phân vùng . Điều đó cũng sẽ cải thiện hiệu suất. Tôi sẽ thử nó và cho bạn biết.
unicoletti

Thật không may, các chức năng cửa sổ đã được giới thiệu trong 8.4 và bây giờ tôi không có quyền truy cập vào một máy chủ có cả postgis và phiên bản đó vì vậy tôi không thể kiểm tra truy vấn được viết lại bằng mệnh đề partion.
unicoletti

7

George MacKerron đã viết một hàm Neighbor Neighbor đơn giản mà tôi thấy khá hữu ích. Hàm này trả về ID của hàng xóm gần nhất với một tính năng nhất định:

create or replace function 
  nn(nearTo                   geometry
   , initialDistance          real
   , distanceMultiplier       real 
   , maxPower                 integer
   , nearThings               text
   , nearThingsIdField        text
   , nearThingsGeometryField  text)
 returns integer as $$
declare 
  sql     text;
  result  integer;
begin
  sql := ' select ' || quote_ident(nearThingsIdField) 
      || ' from '   || quote_ident(nearThings)
      || ' where st_dwithin($1, ' 
      ||   quote_ident(nearThingsGeometryField) || ', $2 * ($3 ^ $4))'
      || ' order by st_distance($1, ' || quote_ident(nearThingsGeometryField) || ')'
      || ' limit 1';
  for i in 0..maxPower loop
     execute sql into result using nearTo              -- $1
                                , initialDistance     -- $2
                                , distanceMultiplier  -- $3
                                , i;                  -- $4
    if result is not null then return result; end if;
  end loop;
  return null;
end
$$ language 'plpgsql' stable;

Ví dụ sử dụng:

SELECT id, nn(pt_geom,0.00001,2,100,'nw_node','node_id','node_geom') FROM my_point_table;

... Chọn nút gần nhất trong bảng nw_node cho mỗi mục trong my_point_table.

Ngoài ra còn có một chức năng chung hơn trên trang web Boston GIS .


Tôi quan tâm nhiều hơn đến cách tạo truy vấn 1: N truy vấn theo nghĩa chung hơn. Ví dụ: thay vì tìm phần tử gần nhất với hình học G, tôi có thể muốn tìm phần tử đầu tiên trùng với G. Cảm ơn bạn về thông tin, bất kể. Liên kết đến Boston GIS rất hữu ích! Tôi đã in một số tờ cheat :-)
Jmoney38

Có lẽ bạn có thể viết lại câu hỏi của mình để làm cho nó rõ ràng hơn một chút, @ Jmoney48. Vì vậy, bạn không quan tâm đến vấn đề hàng xóm gần nhất một cách cụ thể mà là làm thế nào để so sánh một hình học với tất cả các hình học trong một bảng?
underdark

LUÔN LUÔN sử dụng chức năng chung của trang web Boston GIS, đơn giản là cực kỳ chậm đối với các bảng lớn và nỗ lực áp dụng nó không lớn hơn.
Vladtn
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.