Interpolating points along line in Python for ArcGIS Desktop?
In case this is helpful to others, i was able to create the following python code using arcpy which will place points at a specified interval based on an input line feature layer.
import arcpy
line_lyr = 'my_line'
pt_lyr = "my_point"
interval = 200
insertCursor = arcpy.da.InsertCursor(pt_lyr, ["SHAPE@XY"]) # this is the pre-existing pt feature class
with arcpy.da.SearchCursor(line_lyr, ['OID@','SHAPE@','NAME']) as searchCursor: # this is the line feature on which the points will be based
for row in searchCursor:
lengthLine = round(row[1].length) # grab the length of the line feature, i'm using round() here to avoid weird rounding errors that prevent the numberOfPositions from being determined
if int(lengthLine % interval) == 0:
numberOfPositions = int(lengthLine // interval) - 1
else:
numberOfPositions = int(lengthLine // interval)
print "lengthLine", lengthLine
print "numberOfPositions", numberOfPositions
if numberOfPositions > 0: # > 0 b/c we don't want to add a point to a line feature that is less than our interval
for i in range(numberOfPositions): # using range, allows us to not have to worry about
distance = (i + 1) * interval
xPoint = row[1].positionAlongLine(distance).firstPoint.X
yPoint = row[1].positionAlongLine(distance).firstPoint.Y
xy = (xPoint, yPoint)
insertCursor.insertRow([xy])
I am not sure what is your workflow, but for interpolation of Z's between known values (all at existing vertices) I used ArcObjects IZ.InterpolateZsBetween. I've been trying to interpolate with Calibration tool previously, however this tool have a bug. I'm not sure if it fits your purpose, but see code below for IZ.InterpolateZsBetween.
# import arcobjects liberaries
esriSystem = GetModule("C:/Program Files (x86)/ArcGIS/Desktop10.0/com/esriSystem.olb")
esriGeometry = GetModule("C:/Program Files (x86)/ArcGIS/Desktop10.0/com/esriGeometry.olb")
esriDataSourcesGDB = GetModule("C:/Program Files (x86)/ArcGIS/Desktop10.0/com/esriDataSourcesGDB.olb")
esriGeoDatabase = GetModule("C:/Program Files (x86)/ArcGIS/Desktop10.0/com/esriGeoDatabase.olb")
# open geodatabase and featureclass
pWSF = CreateObject(esriDataSourcesGDB.FileGDBWorkspaceFactory, interface=esriGeoDatabase.IWorkspaceFactory)
pWS = pWSF.OpenFromFile(str(DbPath), 0)
pFWS = pWS.QueryInterface(esriGeoDatabase.IFeatureWorkspace)
pFClass = pFWS.OpenFeatureClass(str(fcName))
# set update cursor on the featureclass
pFCursor = pFClass.Update(None, True)
pFeat = pFCursor.NextFeature()
# loop trough features in featureclass
while pFeat:
pShape = pFeat.ShapeCopy # clone shape of current feature
pIZ = pShape.QueryInterface(esriGeometry.IZ2) #set IZ interface on the data - allow for interpolation of the Z value
IPointCollection = pShape.QueryInterface(esriGeometry.IPointCollection) # set IPointCollection interface on the data - allow for points manipulation within the point collection
IPoint = CreateObject(esriGeometry.Point, interface=esriGeometry.IPoint) # create Point object with IPoint interface
pStart = 0 # set pStart parameter to index[0]
# loop trough IPointCollection within the polyline, find pStart and pEnd point within the polyline for IZ.InterpolateZsBetween
for i in range(IPointCollection.PointCount):
Point = IPointCollection.QueryPoint(i, IPoint) # query for point within the IPointCollection at index i and insert it in to IPoint
# selection of the pStart and pEnd properties based on points Z value and interpolation of the vertexes within the polyline
if i==0: # skip value at index[0]
pass
elif IPoint.Z != 0: # assign pEnd and pStart if Z value of the point (vertex) is larger than 0.01 (0.01 not 0 as 0 in arcgis is returned in python as 4.54747350886e-013)
pEnd = i
pIZ.InterpolateZsBetween(0,pStart,0,pEnd) # program assumes that is dealing with single part polylines
pFeat.Shape = pIZ
pFCursor.UpdateFeature(pFeat)
pStart = pEnd
pFeat = pFCursor.NextFeature()