Is there a way to connect all points in a shapefile to each other with lines?

3214
8
07-26-2016 07:24 AM
TravisGallo
New Contributor II

I need to create lines between all points. For example, point A -> B, C, D, E and point B->A, C, D, E and point C -> A, B, D, E and so on for all of my points (like a big spider web or hub graph). Is there a way to do this in ArcMap 10?

0 Kudos
8 Replies
NeilAyres
MVP Frequent Contributor

The only tool (I think) in the current toolbox would be XY table to Line.

But for that to work you need a FromXY and ToXY in the same row of each record.

So, what I would do would be a little MS access magic.

Get your point data into a pgdb (access).

Use AddXY or Calculate geometry to get 2 columns in the attribute table of the XY coordinates.

Open the db in access.

Create a query by adding the attribute table twice with no join.

If you view this you will see you have a cross join where all records are linked to all records.

Filter this so you don't have A -> A.

In the output make table query, do some column name changes so you have columns like FromX, FromY, ToX, ToY etc.

Bring the new table into ArcMap and use the XY table to Line tool.

Be aware that if you have a lot of input records, the cross join will create input record length ^ 2 output records.

ChrisDonohue__GISP
MVP Frequent Contributor

Just a thought - this is almost like creating a TIN (triangulated irregular network), but without the vertical dimension.  Maybe someone can run with this - I'm can't quite figure out the rest  (not enough caffeine yet ) - would it be possible to go from a TIN to polygons then to lines?

Chris Donohue, GISP

0 Kudos
JakeSkinner
Esri Esteemed Contributor

Hi Travis,

You could do this using python.  Below is an example that performs this on a feature class called 'testPts' and creates a line feature class (i.e. Line_A, Line_B, ...).

import arcpy
from arcpy import env
env.workspace = r"D:\temp\python\test.gdb"
env.overwriteOutput = 1

fc = "testPts"

idList = []

with arcpy.da.SearchCursor(fc, ["ID"]) as cursor:
    for row in cursor:
        idList.append(row[0])

del cursor

for id in idList:
    arcpy.MakeFeatureLayer_management("testPts", "testPtsLyr", "ID = '{0}'".format(id))
    coordList = []
    features = []
    with arcpy.da.SearchCursor("testPtsLyr", ["ID", "SHAPE@XY"]) as cursor:
        for row in cursor:            
            geom = row[1]            
    del cursor

    firstTime = True
    with arcpy.da.SearchCursor("testPts", ["ID", "SHAPE@XY"]) as cursor:
        for row in cursor:
            if row[0] != id:
                coordList.append(geom)
                coordList.append(row[1])
                feature_info = map(list, coordList)
                feature_info2 = []
                feature_info2.append(feature_info)
                for feature in feature_info2:                    
                    # Create a Polyline object based on the array of points
                    # Append to the list of Polyline objects
                    features.append(arcpy.Polyline(arcpy.Array([arcpy.Point(*coords) for coords in feature])))
                if firstTime:
                    # Create polyline feature class (i.e. Line_A)
                    arcpy.CopyFeatures_management(features, "Line_" + str(id))
                    firstTime = False
                else:
                    # Append additional lines to feature class
                    arcpy.Append_management(features, "Line_" + str(id))
                features = []
                coordList = []                
                        
    del cursor
DarrenWiens2
MVP Honored Contributor

I'd go with Python, too, although you can simplify it down to:

>>> fc = 'points' # feature class
... sr = arcpy.Describe(fc).spatialReference # spatial reference
... lines = [] # output line list
... geoms = [i[0] for i in arcpy.da.SearchCursor(fc,'SHAPE@',spatial_reference=sr)] # point geometries
... for geom1 in geoms: # loop through points
...    for geom2 in geoms: # compare to points
...        if not geom1.equals(geom2): # if not the same
...            lines.append(arcpy.Polyline(arcpy.Array([[geom1.centroid,geom2.centroid]]),sr)) # create line
... arcpy.CopyFeatures_management(lines,r'in_memory\lines') # output to feature class

Of course, this removes the feature of a line ID.

TravisGallo
New Contributor II

Thank you both Darren and Jake. I have never used Python but have some basic programming skills (R). I have been playing around with this, but seem to be stuck on Darren's code at the loop. I am using ArcGIS 10, and I don't think I can loop with the arcpy.SearchCursor function. Any advice on a workaround for this method. Thanks again for helping out with this.

0 Kudos
DanPatterson_Retired
MVP Esteemed Contributor

did you add

import arcpy

to the top of the script?  I think it is pretty safe to assume that that is needed if you are getting some form of error

DarrenWiens2
MVP Honored Contributor

Oh, if you're back at 10.0, the arcpy data access module didn't exist.

Consult the help for reading and writing geometries at 10.0 with normal cursors.

TravisGallo
New Contributor II

Thank you Darren. I almost have this figured out using R. When I do I will post my code here for anyone that may find it useful.

0 Kudos