Как я могу найти точку внутри многоугольника в 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, кажется, выбирает точку, которая находится как можно дальше от любых ребер. Я полагаю, это дело вкуса, если вы выберете правильное решение.
2011 г.
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.