2

I want to update a Line feature's start and end. I got Point of first and last. BUt, I can't update them.

What is wrong ? (I'm using ArcGIS 10.2)

   rows = arcpy.UpdateCursor(srcFile)
   feat = row.getValue(shapeName)

   bufFeat1=feat.firstPoint.X
   bufFeat2=feat.firstPoint.Y
   bufFeat3=feat.lastPoint.X
   bufFeat4=feat.lastPoint.Y

   row.firstPoint.X=bufFeat3
   row.firstPoint.Y=bufFeat4
   row.lastPoint.X=bufFeat1
   row.lastPointY=bufFeat2

   rows.update(row)
3
  • 1
    Are you receiving an error? If so, update the question to reflect the error you are receiving. If your results are not what you are expecting, add what you expect and what the results you receive are. Adding a few additional details will make it easier to troubleshoot.
    – MaryBeth
    Commented Feb 15, 2016 at 16:45
  • 1
    I don't think you can update the first and last points like this. I think you actually need to reconstruct the entire line by passing in the array of points, where you can update the first and last point of an arcpy.Array.
    – crmackey
    Commented Feb 15, 2016 at 17:00
  • Thank you for everyone.Finally I found solution in this site. I was mistaken in my understanding.Iwant behavior like "FlipLine" by feature.But only changes start and end point,it makes strange form The Details list it in an answer column.
    – Tomy373
    Commented Feb 19, 2016 at 4:15

2 Answers 2

5

The problem is that I think you need to rebuild the entire line, because you are using the Shape field itself. That is because the shape field itself is referring to an actual geometry (arcpy.Polyline in this case). Also, I would recommend that you use the arcpy.da Cursors since you have version 10.2.

Here is how I would tackle this problem. Looks like you want to snap the first and last points of all lines to a single geometry (or maybe use a where clause to work on a subset of features)? First, I would start with a function that will do that:

def moveFirstAndLastPoints(in_lines, featToSnapTo, where_clause=''):
    """snaps line endpoints to a feature's first and last points

    in_lines -- target lines to change
    featToSnapTo -- feature to snap lines to first and last point
        (should be line)
    where_clause -- optional where clause to target specific features
    """
    with arcpy.da.UpdateCursor(in_lines, ['SHAPE@'], where_clause=where_clause) as rows:
        for r in rows:
            # create array for all parts
            allParts = arcpy.Array()

            # iterate through each part (may or may not want to do this by part)
            for part in r[0]:
                # create new array to store arcpy.Polyline()
                array = arcpy.Array([p for p in part])
                array.replace(0, featToSnapTo.firstPoint)
                array.replace(array.count-1, featToSnapTo.lastPoint)
                allParts.append(array)

            # now make into new line to replace geometry
            rows.updateRow((arcpy.Polyline(allParts),))
    return

Next, you need to get the feature you want to snap to as a Geometry. So I would do that like this:

# get a feature (first and only feature in this shapefile)
with arcpy.da.SearchCursor("testForSnapping", ['SHAPE@']) as rows:
    feat = [r[0] for r in rows][0]

Then I would call the function to move the first and last points:

moveFirstAndLastPoints("lines_copy", feat)

And if you're in ArcMap, you may need to call arcpy.RefreshActiveView() (or hit the refresh button) to see your changes. Here are screenshots of before and after in ArcMap (lines_copy was a copy of lines_original):

Before running the code: enter image description here

And After (this is a horrible example of test geometry to use for this, but should demonstrate the point): enter image description here

And here is the full code I used in ArcMap (I did not include the where clause parameter in here, but if you copy and paste the function by itself you can implement this): enter image description here

0

Thank you so much for everyone. I found sample scripts in this site. My probrem was settled in the following scripts.

def FlipLine(InPolyline):
    Part = InPolyline.getPart(0) # only the first part
    rPnts=arcpy.Array()
    for i in range(len(Part)): rPnts.append(Part[len(Part)-i-1]) # flip the points in the array
    OutShape = arcpy.Polyline(rPnts)
    return OutShape

    #main scripts
    for row in rows:
        if row.getValue(resPoint_eZ) > row.getValue(resPoint_sZ):
            feat = row.getValue(shapeName)
            row.setValue(shapeName,FlipLine(feat))    

        rows.updateRow(row)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.