Muestreo de puntos a lo largo de una costa que envuelve postes con PostGIS

11

Estoy trabajando en una tarea que requiere que obtenga puntos de muestra cada 1000 km a lo largo de las costas, y me he encontrado con un problema con la Antártida. Por lo que puedo decir, parece ser un problema con el uso de la geometría en las funciones, cuando realmente creo que la geografía debería usarse para esta operación.

Uso de la función de esta pregunta muy similar , soy capaz de producir un resultado que tiene este aspecto: Mal resultado.

Como puede ver, ST_AddMeasure()y ST_LocateAlong()no parece tratar la geometría de forma esférica, lo que resulta en muchos puntos que se encuentran en el Polo Sur. Incluso se agregó un punto en el clip a lo largo de la línea de fecha (lado izquierdo). Según la documentación de estas dos funciones, solo se puede utilizar la geometría .

El código utilizado para generar el polígono y los puntos se puede encontrar aquí , pero este es el SQL utilizado para generar los puntos:

CREATE TABLE atest AS WITH line AS 
  (SELECT
      id,
      ST_ExteriorRing((ST_Dump(geom)).geom) AS geom
    FROM line_sample_test),
linemeasure AS
    (SELECT
        ST_AddMeasure(line.geom, 0, (ST_Length(line.geom))::int) AS linem,
    generate_series(0, (ST_Length(line.geom))::int, 10) AS i
FROM line),

geometries AS (
    SELECT
        i,
        ST_LocateAlong(linem, i) AS geom 
    FROM linemeasure)

SELECT
    * from geometries;

¿Cómo puedo generar puntos cada 1000 km a lo largo de esta costa?

jczaplew
fuente
¿Has probado ST_Segmentize? También solo puede funcionar en geometrías, pero al menos parece una forma más rápida de generar los puntos. De todos modos, ¿por qué no simplemente eliminar puntos en el poste? Se parece más a un efecto secundario de la proyección utilizada que a un error.
lynxlynxlynx
55
Según su imagen, parece que tiene su geometría en EPSG: 4326. La Antártida se adapta mejor a una proyección estereográfica polar como EPSG: 3031. Incluso entonces, parece que necesitará lidiar con una línea de corte hacia el poste y viceversa, a lo largo de la línea de fecha.
Toby Speight

Respuestas:

3

Como se sugiere en uno de los comentarios, primero transformaría la geometría de entrada en una proyección estereográfica polar.

Además, querrás usarlo ST_Buffer(con una cantidad de 0) para deshacerte de la línea de corte resultante.

Entonces esto obtendría el resultado deseado:

-- ST_Transform(geom,3031) reprojects to south polar stereographic,
-- in meters.  ST_Buffer(...) doesn't change the shape, but removes
-- the cut line to the pole (at 180 degrees).
WITH line AS (
    SELECT ST_ExteriorRing(
        ST_Buffer(ST_Transform(geom, 3031), 0)
    ) AS geom
    FROM line_sample_test
),

-- This just generates a table of numbers.  In this case, from 0
-- to the geometry length, counting by 1,000,000 (1000 km).
linemeasure AS (
    SELECT generate_series(0, ST_Length(geom)::int, 1000000) AS i
    FROM line
),

-- Convert those values to a fraction of the overall length (for
-- use as input to ST_LineInterpolatePoint)
linefraction AS (
    SELECT i / ST_Length(geom) AS fraction
    FROM line, linemeasure
),

-- Do the interpolation
geometries AS (
    SELECT ST_LineInterpolatePoint(l.geom, lf.fraction) AS geom
    FROM linefraction lf, line l
),

-- Convert back to EPSG:4326 (i.e. lat/lon coords)
geometries_4326 AS (
    SELECT ST_Transform(geom, 4326) AS geom FROM geometries
)
SELECT * FROM geometries_4326

Tenga en cuenta que esta consulta asume que solo hay una fila en la line_sample_testtabla, por lo tanto, ajuste según sea necesario para sus datos de entrada reales.

csd
fuente
No conocía el ST_Buffer(geom, 0)truco para eliminar la línea de corte, ¡eso es útil!
Toby Speight