1 votos

Creación de una cuadrícula de puntos irregulares con números de fila y columna proporcionados en PostGIS

Quiero crear una cuadrícula irregular de puntos a través de PostGIS, utilizando las cuatro coordenadas de las esquinas (puntos) proporcionadas, y el número de puntos-filas y puntos-columnas.

Las cuatro esquinas pueden ser o no perpendiculares entre sí (ver imagen, 7 filas, 5 columnas). El terreno se considera plano. ¿Cuál podría ser el enfoque más fácil para resolver esto, dentro de PostGIS?

enter image description here

1voto

Cyril Puntos 141

Por lo tanto, hay muchas maneras de resolver su pregunta y este enfoque es uno de ellos.

Crear una función divertida llamada ST_RegularPointsGridOfCornerPoints

DROP FUNCTION ST_RegularPointsGridOfCornerPoints

CREATE OR REPLACE FUNCTION ST_RegularPointsGridOfCornerPoints(
    geom GEOMETRY,
    r bigint,
    c bigint)
RETURNS GEOMETRY AS  
$BODY$
WITH 
    tbla AS (SELECT ST_Boundary(ST_Union(geom)) geom FROM (SELECT ((ST_DelaunayTriangles(ST_Collect(geom)))) geom) foo),            
    tblb AS (SELECT row_number() over() AS id,
             ST_MakeLine(pt1, pt2) geom FROM (SELECT ST_PointN(geom, generate_series(1, ST_NPoints(geom)-1)) pt1,
     ST_PointN(geom, generate_series(2, ST_NPoints(geom))) pt2 FROM tbla) AS geom),
    tblc AS (SELECT generate_series (0,r-1) as steps),
    tbld AS (SELECT steps AS stp1, ST_LineInterpolatePoint(geom, steps/(SELECT count(steps)::float-1 FROM tblc)) geom1 FROM tblc, tblb WHERE tblb.id 
IN (2) GROUP BY tblc.steps, geom),
    tble AS (SELECT steps AS stp2, ST_LineInterpolatePoint(ST_Reverse(geom), steps/(SELECT count(steps)::float-1 FROM tblc)) geom2 FROM tblc, tblb 
WHERE tblb.id IN (4) GROUP BY tblc.steps, geom),
    tblf AS (SELECT row_number() over() AS id, ST_MakeLine(geom1, geom2) geom FROM tbld JOIN tble ON true AND stp1=stp2),
    tblg AS (SELECT generate_series (0,c-1) as steps)
      (SELECT ST_LineInterpolatePoint(geom, steps/(SELECT count(steps-1)::float-1 FROM tblg)) geom FROM tblg, tblf geom);
$BODY$
LANGUAGE SQL

Ejecutar

SELECT ST_RegularPointsGridOfCornerPoints(ST_Union(geom), 7, 5) geom FROM <name_table>

Vea el resultado - Desafortunadamente algo salió mal y no funciona en todas las versiones de builds de PostgreSQL (Por ejemplo, para PostgreSQL 14.0, compilado por Visual C++ build 1914, 64-bit y superior debería funcionar :-))... Recuerde mi comentario, su futuro no ha llegado todavía :-(...

En consecuencia, por ahora, ejecute el cuerpo de la función como un CTE y establezca los valores requeridos de las columnas y filas, por ejemplo, como se especifica en su pregunta para su ejemplo. La arquitectura del código SQL se muestra a continuación:

create table <name_table> AS
WITH 
    tbla AS (SELECT ST_Boundary(ST_Union(geom)) geom FROM (SELECT ((ST_DelaunayTriangles(ST_Collect(geom)))) geom FROM layer_1) foo),           
    tblb AS (SELECT row_number() over() AS id,
             ST_MakeLine(pt1, pt2) geom FROM (SELECT ST_PointN(geom, generate_series(1, ST_NPoints(geom)-1)) pt1,
     ST_PointN(geom, generate_series(2, ST_NPoints(geom))) pt2 FROM tbla) AS geom),
    tblc AS (SELECT generate_series (0,4) as steps),
    tbld AS (SELECT steps AS stp1, ST_LineInterpolatePoint(geom, steps/(SELECT count(steps)::float-1 FROM tblc)) geom1 FROM tblc, tblb WHERE tblb.id 
IN (2) GROUP BY tblc.steps, geom),
    tble AS (SELECT steps AS stp2, ST_LineInterpolatePoint(ST_Reverse(geom), steps/(SELECT count(steps)::float-1 FROM tblc)) geom2 FROM tblc, tblb 
WHERE tblb.id IN (4) GROUP BY tblc.steps, geom),
    tblf AS (SELECT row_number() over() AS id, ST_MakeLine(geom1, geom2) geom FROM tbld JOIN tble ON true AND stp1=stp2),
    tblg AS (SELECT generate_series (0,6) as steps)
      (SELECT ST_LineInterpolatePoint(geom, steps/(SELECT count(steps-1)::float-1 FROM tblg)) geom FROM tblg, tblf);

La figura de abajo muestra el resultado, deberías obtener el mismo para ti...

enter image description here

La cifra

Por desgracia, sólo me apetecen funciones divertidas y personalizables y no siempre son sencillas :-(...

P.D. En las siguientes preguntas, intenta presentar el código SQL y una explicación de lo que te impidió obtener el resultado esperado...

Soluciones geoespaciales originales...

Traducido con www.DeepL.com/Translator (versión gratuita)

0voto

dr_jts Puntos 61

Una forma elegante de hacerlo es transformar una cuadrícula de puntos cuadrados en el cuadrilátero requerido. Dado que la transformación no conserva las líneas paralelas, un transformación proyectiva normalmente es necesario. Esto es complejo de derivar. Pero esta respuesta describe una inteligente y sencilla transformación del cuadrado unitario en un cuadrilátero arbitrario. El diagrama siguiente muestra cómo utiliza una combinación de tres vectores derivados de los vértices del cuadrilátero.

Quadrilateral transformation

Aquí está SQL implementando la transformación, con un ejemplo de cuadrilátero:

WITH quad AS (SELECT 
  5 AS LLx, 5 AS LLy,
  10 AS ULx, 30 AS ULy,
  25 AS URx, 25 AS URy,
  30 AS LRx, 0 AS LRy
),
vec AS (
  SELECT  LLx AS ox, LLy AS oy,
          ULx - LLx AS ux, ULy - LLy AS uy, 
          LRx - LLx AS vx, LRy - LLy As vy, 
          URx - LLx - ((ULX - LLx) + (LRx - LLx)) AS wx, 
          URy - LLy - ((ULy - LLy) + (LRy - LLy)) AS wy 
  FROM quad
),
grid AS (SELECT x / 10.0 AS x, y / 10.0 AS y 
  FROM        generate_series(0, 10) AS sx(x)
  CROSS JOIN  generate_series(0, 10) AS sy(y)
)
SELECT ST_Point(ox + ux * x + vx * y + wx * x * y, 
                oy + uy * x + vy * y + wy * x * y) AS geom
  FROM vec CROSS JOIN grid;

El resultado es:

enter image description here

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X