Does anyone know how to create a centre line between two polylines which are parallel BUT NOT at any points.
I have two cable route which are parallel but sometimes they are not as they have been modify to skip obstacles on the seabed. I need to create a center line between these two polylines.
I do not have arcinfo.
Thanks a lot
Solved! Go to Solution.
With a bit of Python coding you should be able to do it.
To create point features from your lines' vertices without an Advanced Licence, you need to iterate the feature parts of each line and write the points to a different feature class. There is an example how to do this here (Read polyline geometry) and write to the new feature class with the Insert Cursor. For your situation where the vertices might be far apart, you probably need to break the line features up into equal length smaller segments - for this you can use the positionAlongLine method (find usage instructions on this page) in an iteration to determine how far along the line the point should be.
Once you have your segmented feature points for each line (in different feature classes), you can check which two points from each line points feature class are the closest to one another, take the geometric centre of them and create an array of these points to create a line feature again.
You can try this code to create the centre line points:
import arcpy # point layers loaded in your dataframe pnts1 = arcpy.mapping.Layer("line1_pnts") pnts2 = arcpy.mapping.Layer("line2_pnts") # create search cursor to iterate through first layer scur = arcpy.SearchCursor(pnts1) row = scur.next() closestPnt = 0 closestPntID = 0 cenPnts = [] ctr=0 while row: shp = row.shape geom = shp.getPart() print "Geom1 - " + str(row.FID) + ": " + str(geom.X) + ":" + str(geom.Y) mindist = 9999 tmpdist = 9999 # search cursor for feature in second line point layer scur2 = arcpy.SearchCursor(pnts2) row2 = scur2.next() geom2X = 0 geom2Y = 0 while row2: shp2 = row2.shape geom2 = shp2.getPart() # check distance between points first and second layer and find closest point tmpdist = shp.distanceTo(shp2) if tmpdist < mindist: mindist = tmpdist closestPnt = shp2 closesPntID = row2.FID geom2X = geom2.X geom2Y = geom2.Y row2 = scur2.next() del scur2 print "Geom2 - " + str(closesPntID) + ": " + str(closestPnt.getPart().X) + ":" + str(closestPnt.getPart().Y) print "Dist: " + str(mindist) if shp != closestPnt: # calculate geometric centre of two points closest to each other cenX = (geom.X + geom2X) / 2 cenY = (geom.Y + geom2Y) / 2 midpnt = arcpy.Point(cenX, cenY) # create mid line point ptGeometry = arcpy.PointGeometry(point) print "Mid1 >> " + str(cenX) + ":" + str(cenY) # add point to array cenPnts.append(midpnt) row = scur.next() ctr += 1 del scur # write list of points to new point feature class ("cenlinepnts" - create point feature class and load into dataframe) for centre line inscur = arcpy.InsertCursor("cenlinepnts") insrow = inscur.newRow() for p in cenPnts: insrow.shape = p inscur.insertRow(insrow) del inscur
There might be more efficient ways, but for this you don't need an Advanced licence.
With a bit of Python coding you should be able to do it.
To create point features from your lines' vertices without an Advanced Licence, you need to iterate the feature parts of each line and write the points to a different feature class. There is an example how to do this here (Read polyline geometry) and write to the new feature class with the Insert Cursor. For your situation where the vertices might be far apart, you probably need to break the line features up into equal length smaller segments - for this you can use the positionAlongLine method (find usage instructions on this page) in an iteration to determine how far along the line the point should be.
Once you have your segmented feature points for each line (in different feature classes), you can check which two points from each line points feature class are the closest to one another, take the geometric centre of them and create an array of these points to create a line feature again.
You can try this code to create the centre line points:
import arcpy # point layers loaded in your dataframe pnts1 = arcpy.mapping.Layer("line1_pnts") pnts2 = arcpy.mapping.Layer("line2_pnts") # create search cursor to iterate through first layer scur = arcpy.SearchCursor(pnts1) row = scur.next() closestPnt = 0 closestPntID = 0 cenPnts = [] ctr=0 while row: shp = row.shape geom = shp.getPart() print "Geom1 - " + str(row.FID) + ": " + str(geom.X) + ":" + str(geom.Y) mindist = 9999 tmpdist = 9999 # search cursor for feature in second line point layer scur2 = arcpy.SearchCursor(pnts2) row2 = scur2.next() geom2X = 0 geom2Y = 0 while row2: shp2 = row2.shape geom2 = shp2.getPart() # check distance between points first and second layer and find closest point tmpdist = shp.distanceTo(shp2) if tmpdist < mindist: mindist = tmpdist closestPnt = shp2 closesPntID = row2.FID geom2X = geom2.X geom2Y = geom2.Y row2 = scur2.next() del scur2 print "Geom2 - " + str(closesPntID) + ": " + str(closestPnt.getPart().X) + ":" + str(closestPnt.getPart().Y) print "Dist: " + str(mindist) if shp != closestPnt: # calculate geometric centre of two points closest to each other cenX = (geom.X + geom2X) / 2 cenY = (geom.Y + geom2Y) / 2 midpnt = arcpy.Point(cenX, cenY) # create mid line point ptGeometry = arcpy.PointGeometry(point) print "Mid1 >> " + str(cenX) + ":" + str(cenY) # add point to array cenPnts.append(midpnt) row = scur.next() ctr += 1 del scur # write list of points to new point feature class ("cenlinepnts" - create point feature class and load into dataframe) for centre line inscur = arcpy.InsertCursor("cenlinepnts") insrow = inscur.newRow() for p in cenPnts: insrow.shape = p inscur.insertRow(insrow) del inscur
There might be more efficient ways, but for this you don't need an Advanced licence.
Thank you very much for your reply. I will have a look to this solution.
Cheers,
Francesca
Another possibility is to use some of the Cartography tools, like Merge Divided Roads or Collapse Dual LInes to Centerlines:
One caution - I would definitely check the output closely, as I found found at times both tools to occasionally produce small areas of bizarre results for no apparent reason. As one example, on a long curve it created a centerline that cut across one of the input curve line segments - a "shortcut" - instead of between the curved segments as expected.
Chris Donohue, GISP
Thank you Chris for your reply, but if I understand well this Cartography specific tool is available with the advanced licence which I do not have.
Thank you anyway.
Cheers,
Francesca