Tengo cientos de polígonos que representan rangos geográficos de plantas en todo el mundo. Para cada especie tengo tanto un archivo de formas como una colección de hallazgos como puntos.
Me gustaría encontrar analíticamente cada par de especies que comparten el límite de su área de distribución al menos en un punto. O, mejor aún, qué especie tiene un límite en cierta proximidad de otra especie. ¿Alguna idea de cómo hacer esto? Uso QGIS y prefiero Perl, pero la solución en cualquier otro idioma también estaría bien.
Respuestas
¿Demasiados anuncios?Si pones tu shapefile de polígonos en spatialite, esto es fácil. Digamos que su tabla de polígonos de especies tiene columnas "pk" como clave primaria, "nombre_de_especies" y "geometría" (que se crea cuando se importa un shapefile en spatialite) entonces necesita una consulta como:
SELECT s1.pk, s1.species_name, s2.pk, s2.species_name
FROM species AS s1, species AS s2
WHERE s1.pk <> s2.pk AND
ST_Intersects(s1.geometry, s2.geometry);
Me gustaría mencionar algunos puntos:
- Esta consulta se ejecutará lentamente, ya que comprueba la intersección de cada polígono con todos los demás. Usted dice que tiene varios centenares de polígonos, lo que significaría varias decenas de miles de exploraciones de la base de datos. Ese número probablemente esté bien, pero si crece más, entonces querrá añadir un índice espacial a la tabla y utilizarlo en la consulta.
- Si quiere saber si los bordes se tocan, pero los polígonos sí no se superponen, entonces sustituye el ST_Intersects() por ST_Touches().
- También puede encontrar con pares no se tocan en absoluto con ST_Disjoint()
- Y para encontrar esos pares de polígonos que están a una distancia entre sí, pruebe, en la cláusula WHERE:
ST_Distance(s1.geometry, s2.geometry) < your_threshold;
No estoy seguro de que sus polígonos de alcance tengan límites compartidos exactamente precisos, como las fronteras de los países.
Si es así, y si trabajas con GeoJSON y/o JavaScript, te recomiendo encarecidamente el libro de Mike Bostock TopoJSON que extrae la topología de un objeto GeoJSON encontrando todos los límites exactamente compartidos. Esto da como resultado un archivo más pequeño, ya que las coordenadas de las polilíneas compartidas sólo tienen que escribirse una vez. También utiliza la codificación delta para reducir aún más el tamaño del archivo.