Як я можу знайти точку всередині багатокутника в PostGIS?


22

Як я можу знайти в PostGIS точку, яка гарантовано знаходиться в межах даного полігону?

Я знаю про ST_Centroidфункцію. Однак центроїд не завжди знаходиться в полігоні, див. Нижче:

центроїд, що лежить поза полігоном

Крім того, я хотів би уникати використання точки, яка знаходиться на межі полігона, а бажаю тієї, яка знаходиться всередині кордону (а не всередині отвору в полігонах у формі пончика).

Відповіді:


17

Якщо ви шукаєте функцію PostGIS, яка підкаже точку, яка знаходиться у вашому полігоні, функція ST_PointOnSurface може дати вам те, що вам потрібно.

SELECT 
   ST_AsText(ST_PointOnSurface('POLYGON((0 0, 0 5, 5 5, 5 0, 0 0))'::geometry));

   st_astext
----------------
 POINT(2.5 2.5)
(1 row)

6

Знайшов цю функцію у списку розсилки PostGIS. Я думаю, це те, що вам потрібно:

CREATE OR REPLACE FUNCTION point_inside_geometry(param_geom geometry)
  RETURNS geometry AS
$$
  DECLARE
     var_cent geometry := ST_Centroid(param_geom);
     var_result geometry := var_cent;
  BEGIN
  -- If the centroid is outside the geometry then 
  -- calculate a box around centroid that is guaranteed to intersect the geometry
  -- take the intersection of that and find point on surface of intersection
 IF NOT ST_Intersects(param_geom, var_cent) THEN
  var_result := ST_PointOnSurface(ST_Intersection(param_geom, ST_Expand(var_cent, ST_Distance(var_cent,param_geom)*2) ));
 END IF;
 RETURN var_result;
  END;
  $$
  LANGUAGE plpgsql IMMUTABLE STRICT
  COST 100;

Мені подобається, що це рішення дає точку, яка сама по собі ближче до центру, ніж ST_PointOnSurface, але вона також створює крапку, яка знаходиться ближче до краю полігону. Здається, ST_PointOnSurface вибирає точку, яка знаходиться якнайдалі від будь-яких ребер. Я гадаю, це питання смаку, наскільки правильно вибрати рішення.
dslh
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.