Is there a tool or script out there than can be used to create points along a polyline based on a distance in table?
What is the table structure? If they were easily spaced, then a simple densification would work, but obviously this is not the case
You could also look at this thread and the help file on discussion on linear referencing
Thanks for your reply. I will get more specific. I'm working with Sewer CCTV and Esri had created a script to use this data but it was having a lot of issues, mostly because it was the first release. They have reworked some things and I haven't got a chance to get back to it yet but hopefully that helps. If not, I may turn to linear referencing. However, I worry that when I rebuild the network that the routes would also be updated, perhaps I am wrong about how this works.
Normally, the Routes don't rebuild unless you make them rebuild. As a result, holding positions through events can be a challenge. But you can convert events to true points that are not relative to the route and then they will hold their position even if the route changes or you can calculate before and after XY coordinate values into the events and compare then to detect changes and make updates as necessary.
The Roads and Highways Extension does maintain updates as edits are made to Centerlines and registered event tables are synchronized with the edits according to the rules you define. But without that extension the event tables and routes can get out of sync.
That was my main fear of doing that. I actually checked with my account manager on that extension and wow...too pricey for my blood.
What Richard says is true, however, I do not find this a challenging thing to overcome (the price of the Highways Extension is). A general rule, the events will change location if you added length to the beginning of the route or some sort of alignment has occurred. When these conditions occur, I simply:
This is not really a hard process.... Our LRS rarely changes so this is not something I have to do a lot.
Back to the original question, you can fairly easily place a point along a line at a feature-specific distance using arcpy geometry objects - specifically, the positionAlongLine method in the Polyline object.
Returns a point on a line at a specified distance from the beginning of the line.
what about a specific distance rather than a percentage?
Since I use Linear Referencing I have no use for this function. It performs approximately 50 times slower than an LR event layer from a table based on other geometry operations I have tried. Your welcome to pursue it, but unless you can get 120K points to draw in under 30 seconds, I have you beat with my LR event layer.
Josh, positionAlongLine defaults to using an absolute distance. If you want to use a percentage, you would change the optional second parameter to True (I think).
Richard, this is clearly just one method, and for me using Python geometry objects is more flexible than finding the fastest pre-made tool. IMHO, it also directly answers the question, "how do I create points along a polyline based on distance," better than "read the help on Linear Referencing".
Actually, LR is more flexible than a python geometry object. I can chain point events together and create line segment events and a line segment event table can be displayed as either points or segments, depending on how I set up the Route Event layer. I can make the point fall on the line or offset to the side of the line with another event layer setting change. And with another setting change I can get tangent or normal angles to the line at each point automatically to set rotations relative to the line with no real effort. By setting up multiple layers I can make one LR table function as at least 5 different point or line segments layers simultaneously and do different geometry calculations from each layer that all write back to fields in one table. So, LR is much more than a fixed point on a line (although it can become that with a simple export in seconds).
I only pursue code as a replacement for built-in tools if the built-in tools cannot do the task required or the code can outperform the tools. Since python geometry does neither, I will promote LR until someone demonstrates they can beat it on one account or the other.
The Create Route tool is the starting point to create routes from lines. It is reasonable to assume the table mentioned in this post already has a Route ID and distance, so the field that defines that ID would be used with the Create Route tool. Some type of orientation has to be assumed for the way the distances increase and the tool has a variety of options for maintaining the measures so that they comply with that orientation. I personally use the Coordinate Priority option. Once the routes are built, right click the table and choose the Create Route Event layer menu item. The settings are pretty straight forward to choose the Routes, Route ID, and measure (distance) field. If you need a side offset you can apply that with a side distance field. Advanced settings let you get an error code for distances that fall off the line or get a tangent or normal angle in arithmetic or geographic angles.
As Darren says it is easy it is fairly easy.. As an example, I have an example of a function that I use in the field calculator that allows you to get the X or Y coordinate tool for polylines or polygon perimeters. It is much like the Calculate Geometry tool but allow for some fine tuning of the position and in what format to return (many threads contributed to its final form). But in any event, it could easy be put into use. The "shape" variable is either a shape like when running through a cursor or the shape field (!Shape!, usually) when using the field calculator
def pnt_along(shape, value, use_fraction, XorY): """ :Required: :-------- : shape field, value (planar distance or decimal fraction, 0-1), : use_fraction (True/False), XorY (X or Y): : :Returns: :------- : A point x meters, or x decimal fraction along a line. : User specifies whether X or Y coordinates. : :Useage: For field calculator... :------ : pnt_along(!Shape!, 100, False, 'X') #eg. X coordinate 100 m from start point : :Notes: Project the data prior to using absoulte distances. :----- : """ XorY = XorY.upper() if use_fraction and (value > 1.0): value = value/100.0 if shape.type.lower() == "polygon": shape = shape.boundary() pnt = shape.positionAlongLine(value, use_fraction) if XorY == 'X': return pnt.centroid.X else: return pnt.centroid.Y
in any event, enjoy... and thanks to the ideas of its predecessors
Absolute distances with the positionAlongLine method always have to be in meters. LR by default uses the length units of the original line when the Length option is checked in the Create Routes tool and that tool has the option to apply a conversion factor that can convert the measures to any units of measurement desired.
Wow, looks like I opened a can of worms on that one. They've released a new version of the CCTV processor that I am going to try out.
Richard, the units for positionAlongLine are determined by the spatial reference of the Polyline object. For example, the following snippet places a point 1000 feet from the start of the line, because "kentucky_line" uses the Kentucky State Plane US Feet projection:
>>> for row in arcpy.da.SearchCursor("kentucky_line", ["SHAPE@"]):
... point = row.positionAlongLine(1000)
>>> arcpy.CopyFeatures_management(point, 'in_memory\point')
Sorry about my bad assumption. The descriptions of some of the methods in the Geometry help suggest that they only return values in meters (getLength) and square meters (getArea) and the help document is far from clear about how any of the other functions behave with regard to units, so I thought this method might have a similar restriction. Anyway, I grant that LR and the postionAlongLine geometry function are equal as far as unit handling.
Darren: I am curious. What is the performance of your code example? How many points does it generate and how long does it take?
The following runs in 44 seconds (12 of which are tied up in CopyFeatures), placing 100,000 points.
>>> import cProfile
... def drawPoints():
... reps = 100000
... points = 
... with arcpy.da.SearchCursor("a_line",'SHAPE@') as cursor: # only one line
... for row in cursor:
... for i in range(reps):
... arcpy.CopyFeatures_management(points, r'in_memory\points')
Grief Richard....No the function isn't restricted on one planar measure. It uses the coordinate system of the incoming shape.
However, since you bring it up, It is common only to use projected data for such a function, since the position between two geodesic points (ie Long/Lat coordinates) need not be on the imaginary line connecting them but on the geodesic line.
There are other examples for this, but Josh's main issue is getting off topic.
Also, in Canada, we use metres (Canadian and world-wide spelling) or meters (US spelling) and my examples for teaching purposes and serves as a gentle reminder to ensure to use planar coordinates when trying to determine geometric properties of spatial features.
Sorry Josh...back to you
you acn use this python script to generate point along polyline . here i have taken distance 50.
import arcpy, math, datetime, numpy
start = datetime.datetime.now() # for calculating time of process
midpoint = "E:/test/testShape.shp"
polyline = "c:/arcgis/MyLR/baseroads.shp"
with arcpy.da.SearchCursor(polyline, "SHAPE@") as in_cursor, \
for row in in_cursor:
midpoint = row.positionAlongLine(50)
Retrieving data ...