6 votos

Cómo encontrar 2º orden polígono de los vecinos? (y 3ª, 4ª, etc.)

Tengo un shapefile de polígonos contiguos y para cada par de polígonos, necesito saber cuántos polígonos están entre ellos, a raíz de un vecino/limítrofes enfoque. El resultado es probable que sea un no-espacial de la tabla.

Por ejemplo, para este grupo de polígonos:

1]

El resultado sería algo como esto:

2] y así sucesivamente...

Puedo utilizar ArcGIS o QGIS para que.

Mi idea de la solución hasta ahora:

Un modelo en el que, para cada polígono, corro Polígono Vecinos (Análisis), en combinación con todos los vecinos y ejecute de nuevo, hasta que todos hay un solo polígono. Sin embargo, tengo poco conocimiento en codificación/secuencias de comandos, así que no estoy seguro sobre cómo construir este modelo exactamente y si hay una manera más sencilla.

5voto

traveler Puntos 56

Disculpas por una solución mediante un conjunto de diferentes tecnologías, pero esto es algo que es muy adecuado para SQL. Una serie de auto-combinaciones puede ser utilizado para encontrar la más cercana a los vecinos. Ejemplo de abajo es el uso de PostgreSQL y PostGIS utilizando municipio de Nueva Jersey de datos.

WITH camden AS (
 SELECT shape 
   FROM municipalities
  WHERE mun = 'CAMDEN CITY'
)
SELECT mun AS Neighbors
  FROM municipalities
  JOIN camden ON ST_Touches(camden.shape, municipalities.shape)
 ;

Produce:

"WOODLYNNE BORO"
"COLLINGSWOOD BORO"
"HADDON TWP"
"GLOUCESTER CITY"
"OAKLYN BORO"
"PENNSAUKEN TWP"

He seleccionado sólo de Camden de la Ciudad utilizando una expresión CTE ("con la" declaración") y, a continuación, unido a que a los municipios de la tabla de uso de un espacio en función de como el predicado de combinación. ST_Touches devuelve TRUE si el toque de características.

Esto puede ser ampliado a todos los municipios, con un auto unirse.

SELECT a.mun AS Municipality
 , b.mun AS Neighbors
FROM municipalities a
JOIN municipalities b ON ST_Touches(a.shape, b.shape)
;

Se produce el siguiente (muestras de dos de los municipios de resultados):

"HAMMONTON TOWN"; "HAMILTON TWP"
"HAMMONTON TOWN"; "MULLICA TWP"
"HAMMONTON TOWN"; "WASHINGTON TWP"
"HAMMONTON TOWN"; "SHAMONG TWP"
"HAMMONTON TOWN"; "FOLSOM BORO"
"HAMMONTON TOWN"; "WINSLOW TWP"
"HAMMONTON TOWN"; "WATERFORD TWP"
"RANDOLPH TWP";   "MINE HILL TWP"
"RANDOLPH TWP";   "PARSIPPANY-TROY HILLS TWP"
"RANDOLPH TWP";   "DOVER TOWN"
"RANDOLPH TWP";   "DENVILLE TWP"
"RANDOLPH TWP";   "ROXBURY TWP"
"RANDOLPH TWP";   "ROCKAWAY TWP"
"RANDOLPH TWP";   "CHESTER TWP"
"RANDOLPH TWP";   "MENDHAM TWP"
"RANDOLPH TWP";   "MORRIS TWP"
"RANDOLPH TWP";   "VICTORY GARDENS BORO"

Se puede ir aún más una vez que usted está trabajando en SQL. Ir un paso más y calcular las direcciones (Noroeste, Sudeste, etc.) utilizando ST_Azimuth:

 SELECT a.mun AS Municipality
      , b.mun AS Neighbors
      , ST_Azimuth( ST_Centroid(a.shape)
                  , ST_Centroid(b.shape) ) / (2*pi())*360 AS direction
   FROM municipalities a
   JOIN municipalities b ON ST_Touches(a.shape, b.shape)
   ;

Agrega la "dirección" de la columna:

"CAMDEN CITY"; "COLLINGSWOOD BORO"; 129.847424758369
"CAMDEN CITY"; "OAKLYN BORO"; 149.434213414794
"CAMDEN CITY"; "GLOUCESTER CITY"; 190.159321103297
"CAMDEN CITY"; "PENNSAUKEN TWP"; 54.1779392174728
"CAMDEN CITY"; "HADDON TWP"; 131.032906760376

He aquí una presentación que me dio, que habla de alejarse de los SIG de Escritorio y confiando más en lo que su base de datos espaciales puede hacer por usted.

Espero que esto ayude!

Actualización: aquí está el uso de una CTE Recursiva para determinar la vecina polígonos. Soy nuevo utilizando NJ municipio de datos, recortadas apenas en el Condado de Camden, el uso de Camden de la Ciudad como el punto de partida.

CREATE TABLE public.camden_neighbor AS 
WITH RECURSIVE neighbors (mun_code, shape, depth, path, cycle) AS (
 SELECT m.mun_code, m.shape, 0
      , array[m.mun_code::text], false
   FROM municipalities m
  WHERE m.mun = 'CAMDEN CITY'
  UNION ALL
  SELECT DISTINCT m.mun_code, m.shape, nm.depth+1
      , path || m.mun_code::text
      , m.mun_code = ANY(path)
   FROM municipalities m, neighbors nm
  WHERE ST_Touches(m.shape, nm.shape)
    AND NOT m.mun_code = ANY(path)
    AND nm.depth < 5
)
SELECT DISTINCT mun_code, MIN(depth) as depth
 from neighbors
 group by mun_code
ORDER BY 2, 1
;

Cribbed de la documentación de PostgreSQL en Cte Recursiva, yo uso una profundidad, la ruta y el ciclo de la columna para determinar el Orden y si el que actualmente se evaluó el registro ha visto antes. A partir de ahí, los resultados son de peluche en una nueva, no-espacial de la tabla. Yo entonces vinculado a la tabla a los datos espaciales en un SIG mediante el "mun_code" como un campo de clave.

Camden Neighbors calculated using SQL, displayed in ArcGIS

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