I have three shapefiles:
- the first is a line
- the second contains a polygon
- and the third contains all intersections points of the shapefiles.
I have written an algorithm that adds the length of the line with those of the polygons when they intersect. This works.
Now I have a special case: the polygon looks like a "U" and the line intersects "U" in the middle.I now have four intersections, where I am not allowed to use the inner points. These are marked as red X in the sketch.
I solved the problem manually by creating a new column and marking exactly these points, which were not allowed to be used, with 1 and then deleting them.
Is there a function that could help me with my problem? Or does anyone know how to solve this step with ArcPy so that all intersection points that lie within can be marked?
I'm missing the forest through the trees right now.
The picture below is correct: the line was selected so that when obstacles (polygons) appear the line is deleted (dark red). Furthermore, the polygon parts that were used were selected correctly (purple). In this example, the inner points that cannot be reached were deleted manually.
See Python code:
# import shapefile and convert it from numpy array to dataframe
input = "C:/Users/mondr/OneDrive/Dokumente/ArcGIS/Projects/MyProject/Punkte_MultipartToSinglepart.shp"
arr = arcpy.da.TableToNumPyArray(input, ('ORIG_FID', 'X', 'Y'))
df = pd.DataFrame(arr, columns=['X','Y','ORIG_FID'])
#df['touchy'] = 0 #normally
df['touchy'] = [0,0,0,0,1,0,0,0,0,1,0,0] #manually
dfx = df
# get index of touchy rows
counter = 0
touchy_rows = df[df.touchy == 1].index
length_of_touchy_rows = len(touchy_rows)
#touchy_array = []
while counter < length_of_touchy_rows:
print(touchy_rows[counter], touchy_rows[counter+1])
dfx = dfx.drop(df.index[touchy_rows[counter]+1:touchy_rows[counter+1]])
counter = counter + 2
print(dfx)
#collects all FID's which are not to be deleted
index = dfx.index
where_clause = ""
for x in index[:-1]:
where_clause = where_clause + "FID = "+ str(x) + " or "
where_clause = where_clause + "FID = " +str(index[-1])
print(where_clause)
#update Points_MultipartToSinglepart according to dataframe
#mark
arcpy.SelectLayerByAttribute_management("Punkte_MultipartToSinglepart","NEW_SELECTION", where_clause)
#convert
arcpy.SelectLayerByAttribute_management("Punkte_MultipartToSinglepart","SWITCH_SELECTION", where_clause)
#delete
arcpy.DeleteFeatures_management("Punkte_MultipartToSinglepart")
The next image below shows how the algorithm currently selects the polygon sections without df[touchy]
:
The idea is to find the polygon segment that forms the start and end point of the cut points. This only works for this special case if I delete the points that lie inside manually (df[touchy]
).
How can I mark these inner points with ArcPy?
-
2The distance between the blue points, measured along the polygon border is what you are trying to calculate?Bera– Bera2021年08月20日 08:09:29 +00:00Commented Aug 20, 2021 at 8:09
-
1Yes, exactly.You can imagine that the polygons represent represent obstacles. Normally, I use the coordinates of the intersections to extract the polygon parts and those that are not connected to the start and end points are deleted. At the moment I can't think of anything creative to mark these inner red points.Madeira– Madeira2021年08月20日 08:45:51 +00:00Commented Aug 20, 2021 at 8:45
-
3Please replace the pictures of your code with the actual code as formatted text.PolyGeo– PolyGeo ♦2021年08月20日 09:40:03 +00:00Commented Aug 20, 2021 at 9:40
1 Answer 1
I can offer up an alternative approach to processing the data. Reviewing your images it appears the segments of the straight line that fall inside your polygon you drop and you follow the polygon edge.
A simple dropping of those would resolve most issues BUT as you have identified; when the polygon edge does a U-shape that logic breaks down.
I see you have approached your analysis as a python script in jupyter notebook (?) which suggests you are seeking a python based solution.
- Create a polyline version of your polygon.
- Union the lines to create a line dataset of the straight line and polygon edge (the polylines created in step #1) all cut up (think spaghetti!)
- Delete the straight line segments that are inside the polygon, you could identify these from their centroid being in the polygon.
- Extract the end vertices of the original straight line
- Convert your spaghetti (which has had a subset of straight segments deleted out) into a network, you can use the networkx module for that.
- Solve the shortest route between the end points (created from step #4). This will identify all the segments that are the straight lines and edges of the polygon.
- Optionally dissolve those segments to create a single continuous polyline
Basic sequence is shown below, the purple dashed line being the results of a shortest-path search.
-
Thank you for this perspective. I will implement these steps and enjoy the spaghetti and get back to you for feedback. PS. Yes, I use jupyter notebookMadeira– Madeira2021年08月20日 10:20:45 +00:00Commented Aug 20, 2021 at 10:20
Explore related questions
See similar questions with these tags.