enter image description here

i like to get the neighbors of the Parcels "P1" like following :

From B1 to B2 => P5

B2 => P4

From B2 to B3 => P3

From B3 to B4 => P2

From B4 to B1 => P6

i like to make this process automatic by a GIS software like ArcGIS or Postgis, i have thought to make a buffer of the parcel P1 , to get the lines of the boundary of P1 but i will not get the parcel P4 as neighbor .

any solution to get the neighbors like described above.

  • 1
    This will need some topology-enabled GIS software for sure. So either PostGIS 2, GRASS (has topology, but not sure how to utilize it) or ArcGIS I suppose.
    – Crischan
    May 20, 2012 at 0:39
  • 1
    In Esri's workstation/coverage days this was a SELECT ADJACENT using the ARC (rather than NODE) option to get neighbours that shared a line rather than a node. I could not find a desktop/geodatabase equivalent in a quick search just now so am interested to see what this question uncovers.
    – PolyGeo
    May 20, 2012 at 7:31

3 Answers 3


I have tried to make the possible solution simpler but it seems to be the only solution, but i like to have any suggestions .

  • from polygons make lines (arcs) => lines.
  • buffer polygons with 3m => polygon_buffer.
  • make spatial join between polygon_buffer and lines with "one to many" , to get all the polygons touching the lines => sp_lines_buffer.
  • for every polygon get its boundary lines, from "sp_lines_buffer" to get neighbor polygon for every line.

For Arc based adjacent it's enough , but for adding node based adjacent , we need to add those steps:

  • from polygons get vertices => nodes.

  • make spatial join between polygon_buffer and nodes with "one to many" , to get all the polygons touching the nodes => sp_nodes_buffer.

  • take a node based neighbors only if the number of neighbors per node is > 3. if not we will ignore the node.


I would think using intersects would work. Let's say pid is your parcel ids

SELECT p1.pid, array_agg(b2.pid) As neighbors 
FROM parcels As p1 INNER JOIN parcels As b2 ON ST_Intersects(p1.geom, b2.geom)
WHERE p1.pid != b2.pid
GROUP BY p1.pid

If you would prefer a string instead of an array and are using PostgreSQL 9.0+, you can use

string_agg(b2.pid, ',') As neighbors

For lower versions of PostgreSQL


You do not mention the version of ArcGIS for Desktop that you are using but, since 10.1, there has been a Polygon Neighbors tool which I think would make this much easier to do:

Creates a table with statistics based on polygon contiguity (overlaps, coincident edges, or nodes).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.