I am trying to automatically identify identical vertices within a polyline and remove them without converting the vertices to points first. I have converted the vertices to XY points and identified a significant number of identical vertices, greater than 4000, that will need to be removed. I believe I can use itertools combined with a search cursor and an update cursor using the SHAPE@ variable to identify identical vertices and delete one. I have tried various bits of code and methods, but with little success. Using itertools "overlap" did not identify the identical points in XY so I believe I will need to use the itertools "equal", but am really a bit lost at this point. I am using ArcGIS 10.2.2 and do not have access to any extensions. I would like to incorporate this into a larger Python script I am writing.
4 Answers
There are several ways of doing this. If you know ArcObjects and a bit of VBA you could knock a simple update script together calling the ITopologicalOperator.Simplify() method. But you mentioned python so I guess ArcObjects is not a solution for you?
Well how about this: create an update cursor python script which steps through, gets the polyline geometry explodes that into an array of X,Y then add these to a Set, duplicates are removed when adding to a Set then reconstruct the array and turn that back into a polyline which you use to update the geometry? That would be a python solution that you could wrap into a python script tool.
there is something inside of QGIS that may be able to help you out. inside the experimental plugins there is a generalizer plugin. I have used it before to accomplish what you are looking to do. have a look at this post for a more detailed answer. if you elect to go with this make sure you enable expermental plugins by Plugins→settings→show also experimental plugins. you should then be able to search for generalizer and install!
The Find Identical (Data Management) tool will create a table listing identical features, but not delete them. This is useful if you want to just look over the duplicates.
The Delete Identical (Data Management) tool does the same thing as Find Identical, but this tool actually deletes the features.
-
Thank you for the suggestion, unfortunately I do not have access to those tools. Do you have any other recommendations.– AshleighCommented Dec 2, 2014 at 17:15
-
1Repair geometry will get rid of them if they are truly duplicate vertices. resources.arcgis.com/en/help/main/10.2/index.html#//… available at all license levels. Commented Dec 3, 2014 at 6:58
-
1This probably wouldn't solve the problem even if asker did have access. Those tools look at the entire feature, not individual vertices. They could apply if vertices were converted to points first, but asker specifically stated not wanting to do that.– Chris WCommented Dec 4, 2014 at 21:18
The following code is what I have used per Hornbydd's reccomendation. I have not tested this extensively but it seems to work.
import arcpy
import numpy
from arcpy import da
# Read the parameter values:
# 1: input river shapefile
# 2: output point shapefile with no overlapping points
# 3: output line shapefile with no overlapping vertices
#
infc = arcpy.GetParameterAsText(0)
outfc = arcpy.GetParameterAsText(1)
outfc2 = arcpy.GetParameterAsText(2)
fields = ["LineID","SHAPE@X","SHAPE@Y","SHAPE@Z"]
outfields = ["SHAPE@X","SHAPE@Y","SHAPE@Z"]
SR = arcpy.Describe(infc).spatialReference
#stores fields in an array, enter "print array" to validate array data if not working
array = arcpy.da.FeatureClassToNumPyArray(infc,fields,spatial_reference=SR,explode_to_points=True)
# convert the array to set to remove duplicate features
# array arrangement = (ID,X,Y,Z)
SETarray = set(array)
# convert set back to a numpyarray to build a new point file
array_new = numpy.array(list(SETarray))
# point file will be converted to a polyline with pointstoline_management
# creating table problem, something wrong with the "array_new" array
arcpy.da.NumPyArrayToFeatureClass(array_new,outfc,outfields,SR)
# this will convert the shapefile points back into lines
arcpy.PointsToLine_management(outfc,outfc2,"LineID")