3 votos

¿Selección de polígonos en contacto mediante PostGIS para atlas QGIS?

Tengo una capa poligonal PostGIS donde cada característica representa una página de un atlas en el compositor de impresión QGIS.

enter image description here

CREATE TABLE public.composer (
gid serial NOT NULL,
geom geometry(Polygon, 31256),
page_number varchar(8),
page_north varchar(8),
page_west varchar(8),
page_south varchar(8),
page_east varchar(8),
CONSTRAINT composer_pkey PRIMARY KEY (gid));
;

INSERT INTO public.composer (geom, page_number) VALUES
(ST_GeometryFromText('Polygon((0 0, 300 0, 300 200, 0 200, 0 0))', 31256), 'A-A'),
(ST_GeometryFromText('Polygon((300 0, 600 0, 600 200, 300 200, 300 0))', 31256), 'A-B'),
(ST_GeometryFromText('Polygon((0 0, 300 0, 300 -200, 0 -200, 0 0))', 31256), 'A-C'),
(ST_GeometryFromText('Polygon((300 0, 600 0, 600 -200, 300 -200, 300 0))', 31256), 'A-D')
;

Lo que quiero hacer es insertar los números de las características que se tocan en los atributos de cada característica.

¿Puede alguien ayudarme con la consulta SQL?

Hacerlo manualmente es bastante aburrido, ya que mi atlas contiene unas 100 características.

3voto

MBCook Puntos 8316

Esto es un poco complicado, porque sus polígonos no están normalizados en términos de orientación o punto de partida: algunos están orientados en el sentido contrario a las agujas del reloj, comenzando en la parte inferior izquierda, mientras que otros están orientados en el sentido de las agujas del reloj, comenzando en la parte superior izquierda. Esto significa que no puedes usar simples llamadas basadas en índices a ST_PointN para extraer la arista que representa una arista específica de un polígono.

¿Cómo solucionarlo? Yo ejecutaría un simple

UPDATE composer SET geom = ST_Envelope(geom);

Ahora todos tus polígonos estarán orientados en el sentido de las agujas del reloj, empezando por la parte inferior izquierda. Con estos polígonos normalizados, sabemos que:

  • el borde occidental está definido por los puntos 0 y 1
  • el borde norte está definido por los puntos 1 y 2
  • el borde oriental está definido por los puntos 2 y 3
  • el borde sur está definido por los puntos 3 y 4

De este modo, puede utilizar ST_PointN para extraer los dos puntos extremos que definen cada una de las aristas. Un par de "gotchas": ST_PointN utiliza índices que empiezan en 1, no en 0, y sólo se ejecuta en LineStrings, no en polígonos. Por lo tanto, utilizamos ST_Boundary para obtener la línea que representa el anillo exterior de nuestro polígono. Ahora, podemos sacar los puntos finales de cada arista y volver a unir la tabla consigo misma:

UPDATE composer c
SET page_west = 
    (SELECT page_number FROM composer west 
     WHERE west.gid != c.gid
     AND   ST_Intersects(west.geom, ST_PointN(ST_Boundary(c.geom), 1))
     AND   ST_Intersects(west.geom, ST_PointN(ST_Boundary(c.geom), 2))),
    page_north =  
    (SELECT page_number FROM composer north
     WHERE north.gid != c.gid 
     AND   ST_Intersects(north.geom, ST_PointN(ST_Boundary(c.geom), 2))
     AND   ST_Intersects(north.geom, ST_PointN(ST_Boundary(c.geom), 3))),
    page_east =  
    (SELECT page_number FROM composer east 
     WHERE east.gid != c.gid 
     AND   ST_Intersects(east.geom, ST_PointN(ST_Boundary(c.geom), 3))
     AND   ST_Intersects(east.geom, ST_PointN(ST_Boundary(c.geom), 4))),
    page_south =  
    (SELECT page_number FROM composer south 
     WHERE south.gid != c.gid         
     AND   ST_Intersects(south.geom, ST_PointN(ST_Boundary(c.geom), 4))
     AND   ST_Intersects(south.geom, ST_PointN(ST_Boundary(c.geom), 5)));

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