6 votos

PostGIS ST_Intersects no devuelve el resultado esperado

Quiero buscar objetos que tengan al menos un punto dentro de un rectángulo. En función del tamaño del rectángulo, PostGIS a veces devuelve el objeto contenido y a veces no.

create table t1 (id integer not null primary key, coords geography(linestring));
insert into t1 values (1, 'linestring(9.4 48.5, 9.2 48.6, 9.0 48.8)')

Así que la tabla contiene una cadena de líneas, que consiste en 3 coordenadas (en algún lugar de la zona de Stuttgart).

Ahora quiero buscar todos los objetos que tengan al menos un punto dentro de un rectángulo determinado. Utilizo un polígono para este límite. La siguiente consulta devuelve la cadena de líneas de arriba:

select t.id, st_astext(t.coords) from t1 t
where ST_Intersects(
    ST_GeogFromText('POLYGON((-110.0 49.0, 10.0 49.0, 10.0 47.0, -110.0 47.0, -110.0 49.0))'),
    t.coords)

> 1, LINESTRING(9.4 48.5,9.2 48.6,9 48.8)

En la siguiente consulta, acabo de modificar el borde derecho (este) del rectángulo y lo he movido de lon=10,0 a lon=20,0. Esta consulta no devuelve ningún resultado:

select t.id, st_astext(t.coords) from t1 t
where ST_Intersects(
    ST_GeogFromText('POLYGON((-110.0 49.0, 20.0 49.0, 20.0 47.0, -110.0 47.0, -110.0 49.0))'),
    t.coords)

¿Qué estoy haciendo mal?

Algunos datos sobre mi entorno:

SELECT version() || ' ' || postgis_full_version();
PostgreSQL 12.3 (Debian 12.3-1.pgdg100+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit POSTGIS="3.0.1 ec2a9aa" [EXTENSION] PGSQL="120" GEOS="3.7.1-CAPI-1.11.1 27a5e771" PROJ="Rel. 5.2.0, September 15th, 2018" LIBXML="2.9.4" LIBJSON="0.12.1" LIBPROTOBUF="1.3.1" WAGYU="0.4.3 (Internal)"

6voto

Braiam Puntos 120

La geografía utiliza grandes círculos en lugar de líneas rectas para conectar dos puntos. Un arco de círculo máximo es la línea que cruza la superficie de la tierra y un plano que pasa por los dos puntos y el centro de la tierra.

En consecuencia, una coordenada ligeramente al norte de la coordenada de uno de los 2 puntos conectados estará "por encima" (al norte) del arco del círculo máximo cerca de los 2 puntos, pero estará "por debajo" (al sur) de él más lejos.

Al mover la caja de intersección más al este, también has movido la distancia entre tu línea y el borde de la caja y ahora está fuera de ella.

Esta situación es similar a la de Correo electrónico: contiene alguna ilustración para representar el comportamiento observado.

Cuantifiquemos la diferencia. El primer paso es segmentar el polígono (es decir, añadir más vértices para que su forma de gran círculo se conserve al proyectarlo), y luego evaluar dónde están las intersecciones entre una línea norte-sur que pasa por la longitud 9,2

  1. utilizando los polígonos originales:

    WITH bb (geog) as (VALUES (ST_Segmentize(ST_GeogFromText('POLYGON((-110.0 49.0, 10.0 49.0, 10.0 47.0, -110.0 47.0, -110.0 49.0))'),1000))), blade(geog) as (VALUES (ST_GeogFromText('LINESTRING(9.2 0, 9.2 80)'))) SELECT st_asText(st_intersection(bb.geog,blade.geog)) FROM bb, blade; st_astext

    LINESTRING(9.2 47.6795376273658,9.2 49.6740119023496)

  2. utilizando el polígono extendido:

    WITH bb (geog) as (VALUES (ST_Segmentize(ST_GeogFromText('POLYGON((-110.0 49.0, 20.0 49.0, 20.0 47.0, -110.0 47.0, -110.0 49.0))'),1000))), blade(geog) as (VALUES (ST_GeogFromText('LINESTRING(9.2 0, 9.2 80)'))) SELECT st_asText(st_intersection(bb.geog,blade.geog)) FROM bb, blade; st_astext

    LINESTRING(9.2 56.0310479315236,9.2 57.8695612625077)

vemos que la intersección entre ambos se encuentra mucho más al norte

A continuación encontrará una ilustración visual

Original vs extended polygon

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