• Empleos
  • Sobre nosotros
  • profesionales
    • Inicio
    • Empleos
    • Cursos y retos
  • empresas
    • Inicio
    • Publicar vacante
    • Nuestro proceso
    • Precios
    • Evaluaciones
    • Nómina
    • Blog
    • Comercial
    • Calculadora de salario

0

178
Vistas
Las pruebas de PostGIS si el punto se cruza con el polígono escalado a veces obtienen una respuesta incorrecta

Necesito un algoritmo en el que pueda verificar si un punto cae dentro de un polígono dentro de una tolerancia pequeña (lo que significa que el punto está completamente dentro del polígono o lo suficientemente cerca del borde). Para implementar esto, estaba planeando usar la función st_scale para expandir el polígono por un factor, luego verificar el punto con st_within . Tenga en cuenta que no puedo usar st_buffer porque st_buffer espera un radio absoluto del búfer pero necesito un radio relativo (por ejemplo, determine si el punto está dentro del polígono o dentro del polígono que se ha ampliado en un 5%).

Para lograr esto, he escrito el siguiente código de prueba. Tomo un polígono, lo amplío en un 5 % y luego pruebo si el centroide del polígono original se encuentra dentro del polígono ampliado:

 SELECT ST_within( st_centroid(polygon), st_scale( polygon, 'POINT(1.05 1.05)'::geometry, st_centroid(polygon) ));

Sin embargo, a veces esta función falla sin razón aparente (lo que significa que dice que el centroide del polígono no está dentro del polígono ampliado) y no tengo idea de por qué. Parece que tiene errores, pero no puedo imaginar que haya encontrado un error en postGIS.

Pasando casos de prueba:

 -- drawing a 1x1 box at the origin of the xy plane SELECT ST_Within( st_centroid('MULTIPOLYGON(((0 0, 1 0, 1 1, 0 1, 0 0)))'::geometry), st_scale( 'MULTIPOLYGON(((0 0, 1 0, 1 1, 0 1, 0 0)))'::geometry, 'POINT(1.05 1.05)'::geometry, st_centroid('MULTIPOLYGON(((0 0, 1 0, 1 1, 0 1, 0 0)))'::geometry)) ); -- box in the first quadrant at an origin of (10, 10) SELECT ST_Within( st_centroid('MULTIPOLYGON(((10 10, 11 10, 11 11, 10 11, 10 10)))'::geometry), st_scale( 'MULTIPOLYGON(((10 10, 11 10, 11 11, 10 11, 10 10)))'::geometry, 'POINT(1.05 1.05)'::geometry, st_centroid('MULTIPOLYGON(((10 10, 11 10, 11 11, 10 11, 10 10)))'::geometry)) );

Caso de prueba fallido:

 -- 1x1 box with the bottom left corner at (98, 28) SELECT ST_within( st_centroid('MULTIPOLYGON(((98 28,99 28,99 29,98 29,98 28)))'::geometry), st_scale( 'MULTIPOLYGON(((98 28,99 28,99 29,98 29,98 28)))'::geometry, 'POINT(1.05 1.05)'::geometry, st_centroid('MULTIPOLYGON(((98 28,99 28,99 29,98 29,98 28)))'::geometry)) );

Curiosamente, sin embargo, convertir la forma escalada en WKT y luego volver a una geometría SÍ funciona.

 -- 1x1 box with the bottom left corner at (98, 28) SELECT ST_within( st_centroid('MULTIPOLYGON(((98 28,99 28,99 29,98 29,98 28)))'::geometry), st_geomfromewkt(st_asewkt(st_scale( 'MULTIPOLYGON(((98 28,99 28,99 29,98 29,98 28)))'::geometry, 'POINT(1.05 1.05)'::geometry, st_centroid('MULTIPOLYGON(((98 28,99 28,99 29,98 29,98 28)))'::geometry)))) );

Entonces, sí, ¿qué está pasando aquí???? ¿He encontrado un error en PostGIS?

over 3 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

Creo que has encontrado un error en versiones anteriores de postgis. Usé docker y algunos servidores para probar con varias versiones de postgres y postgis. Con la versión 3.1.4 el código funciona correctamente.

En el pasado, me he topado con algunos casos de esquina donde postgis dio resultados inesperados. Esas estaban relacionadas con GEOS , que según el manual es la librería que implementa la función ST_Within , pero en este caso la librería GEOS es la misma en todas las pruebas.

Por lo que muestra su consulta de trabajo que se transforma en ewkt y retrocede, esto debería estar relacionado con una operación interna en postgis que se corrigió. Lo intenté pero no encontré un error que pudiera relacionarme con esto.

Os dejo dos de las pruebas que he hecho:

postgres 12, postgis 3.0.0

El error está presente:

 test=# select postgis_full_version(); postgis_full_version ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- POSTGIS="3.0.0 r17983" [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)" TOPOLOGY (1 row) test=# SELECT ST_within( st_centroid('MULTIPOLYGON(((98 28,99 28,99 29,98 29,98 28)))'::geometry), st_scale( 'MULTIPOLYGON(((98 28,99 28,99 29,98 29,98 28)))'::geometry, 'POINT(1.05 1.05)'::geometry, st_centroid('MULTIPOLYGON(((98 28,99 28,99 29,98 29,98 28)))'::geometry)) ); st_within ----------- f (1 row)

postgres 13, postgis 3.1.4

El código funciona como se esperaba:

 test=# select postgis_full_version(); postgis_full_version ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- POSTGIS="3.1.4 ded6c34" [EXTENSION] PGSQL="130" 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.5.0 (Internal)" TOPOLOGY (1 row) test=# SELECT ST_within( st_centroid('MULTIPOLYGON(((98 28,99 28,99 29,98 29,98 28)))'::geometry), st_scale( 'MULTIPOLYGON(((98 28,99 28,99 29,98 29,98 28)))'::geometry, 'POINT(1.05 1.05)'::geometry, st_centroid('MULTIPOLYGON(((98 28,99 28,99 29,98 29,98 28)))'::geometry)) ); st_within ----------- t (1 row)
over 3 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Nuestro proceso Comercial
Legal
Términos y condiciones Política de privacidad
© 2025 PeakU Inc. All Rights Reserved.

Andres GPT

Recomiéndame algunas ofertas
Necesito ayuda