PostGIS - получить точку внутри линии или многоугольника

10

Мне нужно получить центральную точку линии или многоугольника markerдля моего приложения. Чтобы при нажатии на маркер появилась геометрия (линия или многоугольник). Раньше я ST_Centroidзаставлял это работать.

Результатом является то, что я ожидал, если бы не несколько полигонов или линий, центроиды которых находятся вне геометрии. Что я хотел бы для этих линий или полигонов, так это получить «самую центральную точку», но внутри геометрии.

Как я могу это сделать? Есть ли решение?

Хосе Эрмосилла Родриго
источник

Ответы:

9

Из документа: ST_PointOnSurface - возвращает точку, гарантированно лежащую на поверхности.

WKT
источник
4
Для строк ST_LineInterpolatePoint с дробью 0.5 должно быть идеально подходит postgis.net/docs/manual-2.1/ST_LineInterpolatePoint.html
user30184
ST_PointOnSurface () работает с линиями! (Thx Postgis)
WKT
Да! Вы правы @ user30184, потому что кажется, что для линий ST_PointOnSurface () принимает произвольную точку, я не уверен, но в примере с документом берется первая точка LineString.
Хосе Эрмосилья Родриго
7

В моем случае каждая геометрия представлена ​​в разных таблицах. То, что я сделал, было:

  1. Для линий -> ST_LineInterpolatePoint()с коэффициентом 0,5.
  2. Для полигонов -> Проверить, ST_Centroid()находится ли внутри его геометрия. Если это так, ST_Centroid()это лучший выбор, если не я выбираю PointOnSurface().

Вот запрос:

SELECT
    CASE WHEN (SELECT the_geom FROM points WHERE gid = d.gid) IS NOT NULL
    THEN (SELECT the_geom FROM points WHERE gid = d.gid)
    WHEN (SELECT the_geom FROM lines WHERE gid = d.gid) IS NOT NULL
    THEN ST_LineInterpolatePoint((SELECT the_geom FROM lines WHERE gid = d.gid), 0.5)
    WHEN (SELECT the_geom FROM polygons WHERE gid = d.gid AND ST_Intersects(ST_Centroid(the_geom),the_geom)) IS NOT NULL
    THEN ST_Centroid((SELECT the_geom FROM polygons WHERE gid = d.gid))
    ELSE ST_PointOnSurface((SELECT the_geom FROM polygons WHERE gid = d.gid))
    END AS center
FROM someTable d
Хосе Эрмосилла Родриго
источник
5
&& оператор проверяет только bbox. Вы можете использовать ST_intersects ().
WKT
Вы правы. Я был неправ. Я обновлю свой ответ. Спасибо!
Хосе Эрмосилья Родриго