PostGIS - Holen Sie sich einen Punkt innerhalb einer Linie oder eines Polygons

10

Ich muss den Mittelpunkt einer Linie oder eines Polygons markerfür meine App ermitteln. Wenn Sie auf eine Markierung klicken, wird die Geometrie angezeigt (Linie oder Polygon). Ich habe es immer ST_Centroidzum Laufen gebracht.

Das Ergebnis ist, was ich erwartet habe, einige Polygone oder Linien, deren Schwerpunkte außerhalb der Geometrie liegen, unnest zu erwarten. Was ich für diese Linien oder Polygone möchte, ist, den "Mittelpunkt" zu erhalten, aber innerhalb der Geometrie.

Wie kann ich das machen? Gibt es eine Lösung?

Jose Hermosilla Rodrigo
quelle

Antworten:

9

Aus dem Dokument: ST_PointOnSurface - Gibt einen PUNKT zurück, der garantiert auf der Oberfläche liegt.

WKT
quelle
4
Für Zeilen ST_LineInterpolatePoint mit Bruchteil 0,5 sollte perfekt sein postgis.net/docs/manual-2.1/ST_LineInterpolatePoint.html
user30184
ST_PointOnSurface () funktioniert mit Linien! (thx Postgis)
WKT
Ja! Sie haben Recht @ user30184, weil es den Anschein hat, dass ST_PointOnSurface () für Linien einen beliebigen Punkt einnimmt. Ich bin mir nicht sicher, aber im Dokumentbeispiel wird der erste Punkt eines LineString verwendet.
Jose Hermosilla Rodrigo
7

In meinem Fall habe ich jede Geometrie in Disctint-Tabellen. Was ich getan habe war:

  1. Für Linien -> ST_LineInterpolatePoint()mit 0,5 Faktor.
  2. Für Polygone -> Testen Sie, ob ST_Centroid()sich innerhalb der Geometrie befindet. Wenn ja, ST_Centroid()ist die beste Wahl, wenn nicht ich wähle PointOnSurface().

Hier ist die Abfrage:

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
quelle
5
&& Operator prüft nur bbox. Möglicherweise möchten Sie ST_intersects () verwenden.
WKT
Du hast recht. Ich lag falsch. Ich werde meine Antwort aktualisieren. Vielen Dank!
Jose Hermosilla Rodrigo