Skip to content

Instantly share code, notes, and snippets.

@pLeBlanc93
Created April 7, 2020 00:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pLeBlanc93/d037d0c0ddb7455680b3047dbe1bd9cc to your computer and use it in GitHub Desktop.
Save pLeBlanc93/d037d0c0ddb7455680b3047dbe1bd9cc to your computer and use it in GitHub Desktop.
ArcGIS Pro Python toolbox for indentifying line vertices within tolerance

Information: The VertexChecker.pyt is a python toolbox to identify duplicate vertices along a line feature class. See "How coordinates are clustered" at the following link for more information: https://pro.arcgis.com/en/pro-app/help/data/topologies/topology-in-arcgis.htm

Instructions:

  1. Download VertexChecker.pyt file
  2. Open ArcGIS Pro
  3. Add a folder connection to the location of the VertexChecker.pyt
  4. Expand the VertexChecker.pyt in Catalog to see the Identify Duplicate Vertex script tool
  5. Double click the Identify Duplicate Vertex to open the script tool
  6. Add the line feature class as input to Line Layer parameter of the tool. Note: If there is a selection, only the selection will be honored.
  7. Specify an output point feature class
  8. Click Run

The output point feature class will mark the location of duplicate vertices along the line. In the attribute table of the output feature class, the ORIG_FID field is the objectid of the line feature and the VERTEX_PAIR field is the vertex pair that are considered duplicate along that line feature.

# -*- coding: utf-8 -*-
import os
from math import sqrt, hypot
from typing import Tuple
import arcpy
def compare(a: Tuple[int, int], b: Tuple[int, int], distance: float):
return hypot(a[0] - b[0], a[1] - b[1]) < distance
# Exact comparison
# return a == b
def collect(feature_class):
desc = arcpy.Describe(feature_class)
tolerance = 2 * sqrt(2) * desc.spatialReference.xyTolerance
with arcpy.da.SearchCursor(feature_class, ['OID@', 'SHAPE@']) as cursor:
for i, (oid, shape) in enumerate(cursor):
if not i % 100_000:
arcpy.AddMessage(f'{i:,}')
vertices = [(p.X, p.Y) for p in shape.getPart()[0]]
prev = vertices[0]
for j, curr in enumerate(vertices[1:]):
if compare(prev, curr, tolerance):
yield oid, f"{j}-{j+1}", curr
prev = curr
class Toolbox(object):
def __init__(self):
"""Define the toolbox (the name of the toolbox is the name of the
.pyt file)."""
self.label = "Toolbox"
self.alias = ""
# List of tool classes associated with this toolbox
self.tools = [IdentifyDuplicateVertices]
class IdentifyDuplicateVertices(object):
def __init__(self):
"""Define the tool (tool name is the name of the class)."""
self.label = "Identify Duplicate Vertices"
self.description = ""
self.canRunInBackground = False
def getParameterInfo(self):
"""Define parameter definitions"""
line = arcpy.Parameter(name='input_lines',
displayName='Line Layer',
direction='Input',
datatype='GPFeatureLayer',
parameterType='Required')
point = arcpy.Parameter(name='output_points',
displayName='Output Vertices',
direction='Output',
datatype='DEFeatureClass',
parameterType='Required')
point.value = 'memory/duplicate_vertices'
return [line, point]
def execute(self, parameters, messages):
"""The source code of the tool."""
line, point = [p.value for p in parameters]
path, name = os.path.split(point.value)
dupe_fc = arcpy.CreateFeatureclass_management(out_path=path,
out_name=name,
geometry_type='POINT',
spatial_reference=arcpy.Describe(line).spatialReference)[0]
arcpy.AddField_management(in_table=dupe_fc, field_name='ORIG_FID', field_type='LONG')
arcpy.AddField_management(in_table=dupe_fc, field_name='VERTEX_PAIR', field_type='TEXT', field_length=50)
with arcpy.da.InsertCursor(dupe_fc, ['ORIG_FID', 'VERTEX_PAIR', 'SHAPE@']) as cursor:
for row in collect(line):
cursor.insertRow(row)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment