PostGIS - Obtenez un point à l'intérieur d'une ligne ou d'un polygone

10

J'ai besoin d'obtenir le point central d'une ligne ou d'un polygone pour créer markermon application. Ainsi, lorsque vous cliquez sur un marqueur, la géométrie apparaît (ligne ou polygone). J'avais l'habitude ST_Centroidde le faire fonctionner.

Le résultat est ce à quoi je m'attendais à dénouer certains polygones ou lignes dont les centroïdes sont hors de la géométrie. Ce que je voudrais pour ces lignes ou polygones, c'est d'avoir le "point le plus central" mais à l'intérieur de la géométrie.

Comment puis-je faire ceci? Y a-t-il une solution?

Jose Hermosilla Rodrigo
la source

Réponses:

9

De la doc: ST_PointOnSurface - Retourne un POINT garanti pour se trouver sur la surface.

WKT
la source
4
Pour les lignes ST_LineInterpolatePoint avec la fraction 0,5 devrait être parfait postgis.net/docs/manual-2.1/ST_LineInterpolatePoint.html
user30184
ST_PointOnSurface () fonctionne avec Lines! (thx Postgis)
WKT
Oui! Vous avez raison @ user30184 car il semble que pour les lignes ST_PointOnSurface () prend un point arbitraire, je ne suis pas sûr mais dans l'exemple de doc prend le premier point d'une LineString.
Jose Hermosilla Rodrigo
7

Dans mon cas, j'ai chaque géométrie dans des tables de disctint. Ce que j'ai fait, c'est:

  1. Pour les lignes -> ST_LineInterpolatePoint()avec facteur 0,5.
  2. Pour les polygones -> Testez si se ST_Centroid()trouve à l'intérieur de sa géométrie. Si oui, ST_Centroid()c'est le meilleur choix, sinon je choisis PointOnSurface().

Voici la requête:

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
Jose Hermosilla Rodrigo
la source
5
L'opérateur && ne vérifie que la bbox. Vous pouvez utiliser ST_intersects ().
WKT
Vous avez raison. J'avais tort. Je mettrai à jour ma réponse. Merci!
Jose Hermosilla Rodrigo