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)));