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.