0

I've been trying to write an ArcPy script that gets the nearest point to the endpoint of a line feature and puts the value of a certain attribute into a field of the new layer and updates the row. Been trying to figure this out for weeks but nothing is working for me. I can't use Arcade, I've tried doing spatial join and that also didn't work. My path and everything works perfectly and the layer is being created just fine. but the problem is that the rows that I want updated in the new layer are not updating at all. Here is my code but please assume that all parameters and paths pertaining to things like MakeFeature and SelectByLocation are correct, because I believe that they are since the new layer is being created successfully. I believe there is a flaw with my logic for updating the cursor but I'm not sure where.

 import arcpy
 import numpy as np
 arcpy.MakeFeatureLayer_management(parameter_drop, new_layer)
 arcpy.SelectLayerByLocation_management(new_layer, "within", parameter_poly)
 arcpy.AddMessage("Number of selected features: " + str(arcpy.GetCount_management(new_layer)[0]))
 arcpy.CopyFeatures_management(new_layer, parameter_out)
 arcpy.SelectLayerByLocation_management(parameter_SA, "WITHIN_A_DISTANCE", new_layer, "50 Feet")
 with arcpy.da.UpdateCursor(new_layer, ["SHAPE@", "ADDRESS_TDS_LOCATION_ID"]) as cursor:
 #get XY of endpoints on drop layer and loop through
 for row in cursor:
 #SHAPE@ method
 drop = row[0]
 end_x = drop.lastPoint.X
 end_y = drop.lastPoint.Y
 
 min_distance = float("inf")
 #get XY of SA Layer and loop through features in SA layer
 with arcpy.da.SearchCursor(parameter_SA, ["SHAPE@XY", "ADDRESS_UUID"]) as SA_cursor:
 for SA_row in SA_cursor:
 SA_x, SA_y = SA_row[0]
 distance = np.sqrt((SA_x - end_x) ** 2 + (SA_y - end_y) ** 2)
 
 if distance < min_distance:
 row[1] = SA_row[1]
 min_distance = distance
 
 cursor.updateRow(row)
Vince
20.5k16 gold badges49 silver badges65 bronze badges
asked Feb 7, 2023 at 14:42
2
  • A quick review of your code it seems fine to me, but my question why always the lastpoint, what about the firstpoint? I think to improve this question you need to add some images of your data and a sketch of what YOU think should be correct? Commented Feb 7, 2023 at 15:48
  • Numpy function might produce array not scalar value. Try [0] after it when computing distance. Much faster is using Near tool, selection and join field. Commented Feb 8, 2023 at 4:26

1 Answer 1

1

I would approach the problem in a different way were I you.

You could pull out the point geometry and whatever attributes you want into a list with a search cursor - creating something like [id,attribute1,x,y,z]. Then during the update cursor just go through each line's end point and find the closest point with good old-fashioned math (if it's all numeric data then using numpy arrays can make it faster and easier to find the closest point. Once you do that you've got the attributes in list format, so it should be faster than having nested cursors (I don't recommend doing this)

Here's the pseudocode:

 pointfeature = yourpointfeature
 pt_fields = ["OBJECTID", "feature1", "Shape@X", "Shape@Y"]
 pt_list = []
 with arcpy.da.SearchCursor(pointfeature, fields) as cursor:
 for row in cursor:
 pt_list.append([row[0],row[1], row[2]])
 #Then use this list during your main cursor loop:
 with arcpy.da.SearchCursor(parameter_SA, ["SHAPE@XY", "ADDRESS_UUID"]) as SA_cursor:
 for SA_row in SA_cursor:
 SA_x, SA_y = SA_row[0]
 min_dist = 1000.1
 min_pt = "something"
 for item in pt_list:
 dist = sqrt( (SA_x - pt_list[1])**2 + (SA_y - pt_list[2])**2 )
 if dist < min_dist:
 min_dist = dist
 min_pt = item

... and so on. (I'm too lazy to finish it out, but I think it would work - if it's only a slow implementation to solve the problem at hand)

answered Feb 7, 2023 at 15:48
2
  • Thank you. So far I did get it working but its fairly slow, depending how many rows it has to fill. What I do now is store the final value of row[1] in a list and then after I use an Update Cursor to put the contents of the list into the row of the new layer attribute table. I will try using numpy arrays for distance calculations and see if it runs faster. What exactly would I be storing in the numpy array? The data for calculating distance is all numeric. Commented Feb 7, 2023 at 20:35
  • I think after writing your list - "pt_list" in the above code, pt_array = np.asarray(pt_list), and try the same routines with the array instead of the list. I suspect the impact won't be that great. Beyond that you can try putting in timestamps in around your code to see where it slows down. Or a more sophisticated method of timing your code. Just thought of something - were you only looking at the end points of each line? In that case using some sophistication to only pull the first and last vertex from each line for comparison will save you time. Also, for giggles ask OpenAI's chatGPT Commented Mar 13, 2023 at 17:48

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.