Okay I get it.So maybe I'm wrong, but it looks like you are attempting to directly set the .firstpoint and .lastpoints coordinates. However these are read-only properties of an existing feature, and not directly "writable". You would have to cycle through all the vertices and alter them that way. Seems that maybe one method would be:1. For each feature, you get the correct start/end coordinates (you got this from the near tool).2. For each feature you retrieve their current (but offset) start/end coordinates3. Cycle through the features points, and alter as necessary. Can you use the .replace method (part of the geometry Array) to quickly retrieve the geometry of the start and end? Obviously the start would be index of 0, but can you do an index of -1 like in Python (to get the last)? Dunno... Otherwise you could loop through all the vertices - the start point is obvious, but to find the end you might need to continuously compare each vertex with the known location (step #2).So this might help, but I wrote some code a long while back that did something similar. In my case, I had an stream layer that, for complicated reasons, had some small "skips" in it, that basically made for a bunch of unconnected stream segments. My approach was to just insert little "connector arcs" instead of move the existing vertices, but... Here is an excerpt of that code:#NOTE: Due to small inconsistencies in how the "SIMPLIFY" method of the StreamToFeature tool behaves, there are
# some occasional gaps in the stream network along the fishnet boundary. We need to fix these issues
# to preserve topological connectivity. My solution is to insert a connector arc (with the correct directionality)
# to bridge the gap (which is occasionally larger than gp.cellsize!). I explored other methods such as using the
# "integrate" tool (didn't fix everything with a tolerance of gp.cellsize, and many unintended problems as well).
# I also thought of just moving the start or end node of the gaped features (quite a bit more complex than just inserting
# a connector arc). Using the "SIMPLIFY" parameter is about a 25% disk space savings, but there would still be a few
# disconnected arcs using the "NO_SIMPLIFY" method (where the stream exactly parallels the fishnet tile boundary.
# Anyway, this is what I came up with...
#Process: Dissolves prelimStreamsFC by GRID_CODE (fixes 99% of the tile boundary issues)
streamDissolve1FC = gdbPath + "\\stream_dislv1"
gp.Dissolve_management(prelimStreamsFC, streamDissolve1FC, "GRID_CODE", "", "SINGLE_PART", ""); showGpMessage()
#Process: Make a baseline copy (before we mess with it!)
baseCopyFC = gdbPath + "\\baseline_copy"
gp.Select_analysis(streamDissolve1FC, baseCopyFC, ""); showGpMessage()
#Process: Figures out what stream reaches are still disconnected
streamIdFreqTbl = gdbPath + "\\stream_id_freq"
gp.Frequency_analysis(streamDissolve1FC, streamIdFreqTbl, "GRID_CODE", ""); showGpMessage()
#Process: Build an SQL string and also a Python dictionary so we can select the problem features
streamIdFreqString = ""
streamIdFreqDict = {}
searchRows = gp.searchcursor(streamIdFreqTbl, "FREQUENCY > 1")
searchRow = searchRows.next()
while searchRow:
streamIdFreqString = streamIdFreqString + str(searchRow.GRID_CODE) + ","
streamIdFreqDict[searchRow.GRID_CODE] = searchRow.FREQUENCY
searchRow = searchRows.next()
del searchRow
del searchRows
#Process: Loads the firstpoint and lastpoint XY pairs into a dictionary keyed by GRID_CODE
vectorSelectorDict = {}
searchRows = gp.searchcursor(streamDissolve1FC, "GRID_CODE in (" + streamIdFreqString[:-1] + ")")
searchRow = searchRows.next()
while searchRow:
firstPointX = searchRow.getvalue(shapeFieldName).firstpoint.x
firstPointY = searchRow.getvalue(shapeFieldName).firstpoint.y
lastPointX = searchRow.getvalue(shapeFieldName).lastpoint.x
lastPointY = searchRow.getvalue(shapeFieldName).lastpoint.y
if vectorSelectorDict.has_key(searchRow.GRID_CODE) == False:
vectorSelectorDict[searchRow.GRID_CODE] = []
vectorSelectorDict[searchRow.GRID_CODE].append([firstPointX,firstPointY,lastPointX,lastPointY])
else:
vectorSelectorDict[searchRow.GRID_CODE].append([firstPointX,firstPointY,lastPointX,lastPointY])
searchRow = searchRows.next()
del searchRow
del searchRows
#Process: Figures out what lastpoint and first point combinations are closest together (since we don't
#inherently know what arc segment is furthest upstream) Preserving correct directionality and connectivity is critical!!!
vectorConnectorDict = {}
for gridCode in vectorSelectorDict.keys():
gridCodeFeatureCount = streamIdFreqDict[gridCode]
if gridCodeFeatureCount == 2:
distance1 = math.sqrt(math.pow(vectorSelectorDict[gridCode][0][2] - vectorSelectorDict[gridCode][1][0],2) + math.pow(vectorSelectorDict[gridCode][0][3] - vectorSelectorDict[gridCode][1][1],2))
distance2 = math.sqrt(math.pow(vectorSelectorDict[gridCode][1][2] - vectorSelectorDict[gridCode][0][0],2) + math.pow(vectorSelectorDict[gridCode][1][3] - vectorSelectorDict[gridCode][0][1],2))
if distance1 > float(gp.cellsize) and distance2 > float(gp.cellsize):
message = "ERROR: Grid Code " + str(gridCode) + " - distance1 (" + str(distance1) + ") and distance2 (" + str(distance2) + ") are both more than gp.cellsize!"; showPyMessage()
if distance1 < distance2:
vectorConnectorDict[gridCode] = [vectorSelectorDict[gridCode][0][2],vectorSelectorDict[gridCode][0][3],vectorSelectorDict[gridCode][1][0],vectorSelectorDict[gridCode][1][1]]
else:
vectorConnectorDict[gridCode] = [vectorSelectorDict[gridCode][1][2],vectorSelectorDict[gridCode][1][3],vectorSelectorDict[gridCode][0][0],vectorSelectorDict[gridCode][0][1]]
else:
message = "ERROR: The frequency count of Grid Code " + str(gridCode) + " is " + str(gridCodeFeatureCount) + "!"; showPyMessage()
#Process: Construct the connector arcs!
gp.AddField_management(streamDissolve1FC, "CON_FLG", "SHORT"); showGpMessage()
insertRows = gp.insertcursor(streamDissolve1FC)
for gridCode in vectorConnectorDict.keys():
lineArray = gp.createobject("Array")
startPoint = gp.createobject("Point")
startPoint.x = vectorConnectorDict[gridCode][0]
startPoint.y = vectorConnectorDict[gridCode][1]
lineArray.add(startPoint)
endPoint = gp.createobject("Point")
endPoint.x = vectorConnectorDict[gridCode][2]
endPoint.y = vectorConnectorDict[gridCode][3]
lineArray.add(endPoint)
insertRow = insertRows.newrow()
insertRow.GRID_CODE = gridCode
insertRow.CON_FLG = 1
insertRow.setvalue(shapeFieldName,lineArray)
insertRows.insertrow(insertRow)
lineArray.removeall()
del insertRow
del insertRows
del startPoint
del endPoint
del lineArray