8 votos

Eliminación de vértices colineales con ArcMap

Estoy buscando una herramienta o script de ArcGIS que elimine todos los vértices colineales en características de línea. He probado la herramienta Simplificar línea y Generalizar en la barra de herramientas avanzada. Las herramientas funcionan más o menos, pero convierten las curvas en segmentos añadiendo vértices. Quiero mantener intactas las curvas originales.

También he probado varios transformadores Generalizar en FME, pero obtengo resultados similares. ¿Alguna idea?

He aquí un ejemplo del antes y el después de lo que intento conseguir. Esto se hizo mediante la eliminación de los vértices manualmente.

Antes de enter image description here

En enter image description here

0 votos

He añadido un par de imágenes para mostrar lo que estoy tratando de llegar. Esencialmente eliminar sólo los vértices que no son necesarios para preservar la forma de la línea.

0 votos

¿Has visto a desktop.arcgis.com/es/arcmap/10.3/tools/cartography-toolbox/ Trate de encontrar la mejor tolerancia para mantener las curvas. Otra herramienta que puede utilizar es ET geotools.

2voto

Alex Tereshenkov Puntos 13433

He escrito un pequeño script en Python que utiliza arcpy para actualizar las formas de las características de una clase de características polilínea.

Haga una copia de seguridad de sus datos antes de ejecutar esta función, ya que modifica las funciones existentes.

  1. El script funciona tanto para líneas de una parte como de varias partes.
  2. Puede elegir qué hacer con las curvas: o bien se conservan sin eliminar los vértices redundantes que pueda tener esta característica concreta O bien se densifican con el valor de distancia especificado. Busque el .densify() método en arcpy.Geometry objeto. También puede utilizar la función Herramienta Densify GP para fijar sus curvas antes de ejecutar este script si desea experimentar con los valores de desviación.
  3. Sólo se admiten clases de características polilíneas (no puntos/polígonos). No obstante, podría ampliarse para admitir polígonos.

El código:

import arcpy

#----------------------------------------------------------------------
def are_collinear(p1, p2, p3, tolerance=0.5):
    """return True if 3 points are collinear.
    tolerance value will decide whether lines are collinear; may need
    to adjust it based on the XY tolerance value used for feature class"""
    x1, y1 = p1[0], p1[1]
    x2, y2 = p2[0], p2[1]
    x3, y3 = p3[0], p3[1]
    res = x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2)
    if -tolerance <= res <= tolerance:
        return True

#----------------------------------------------------------------------
def get_redundant_vertices(vertices):
    """get redundant vertices from a line shape vertices"""
    indexes_of_vertices_to_remove = []
    start_idx, middle_index, end_index = 0, 1, 2
    for i in range(len(vertices)):
        p1, p2, p3 = vertices[start_idx:end_index + 1]
        if are_collinear(p1, p2, p3):
            indexes_of_vertices_to_remove.append(middle_index)

        start_idx += 1
        middle_index += 1
        end_index += 1
        if end_index == len(vertices):
            break
    return indexes_of_vertices_to_remove

#----------------------------------------------------------------------
def clean_geometries(fc, densify_curves=False):
    """clean polyline features in the fc removing redundant vertices"""
    in_sr = arcpy.Describe(fc).spatialReference.factoryCode

    with arcpy.da.UpdateCursor(fc, ['SHAPE@', 'OID@']) as ucur:
        for row in ucur:
            print "OBJECTID", row[1]
            cleaned_parts = []
            shape = row[0]

            if 'curvePaths' in shape.JSON:
                if densify_curves:
                    shape = shape.densify('DISTANCE', 1, 1)
                else:
                    continue

            for part in range(shape.partCount):
                vertices = [(p.X, p.Y) for p in shape.getPart(part)]
                if len(vertices) < 3:  #polyline's part consists of 2 vertices
                    continue
                vertices_to_remove = get_redundant_vertices(vertices)
                vertices_to_keep = [
                    val for idx, val in enumerate(vertices)
                    if idx not in vertices_to_remove
                ]
                cleaned_part_as_array = arcpy.Array(
                    [arcpy.Point(*coords) for coords in vertices_to_keep])
                cleaned_parts.append(cleaned_part_as_array)

            if cleaned_parts:
                cleaned_shape = arcpy.Polyline(
                    arcpy.Array(cleaned_parts), in_sr)
                row[0] = cleaned_shape
                ucur.updateRow(row)

if __name__ == '__main__':
    fc = r'C:\GIS\Temp\ArcGISHomeFolder\Default.gdb\_SimpleRoads'
    #r'C:\GIS\Temp\ArcGISHomeFolder\empty.gdb\roads'
    clean_geometries(fc, densify_curves=False)

0 votos

Alex T. con respecto a su 3er punto, ¿cómo podríamos ampliar su solución para simplificar polígono vértices sabiendo que cuando una forma es limpiada y actualizada las formas contiguas a esa deben seguir esa simplificación para que la capa de polígonos de salida no tenga huecos? Generalizar y Simplificar herramientas (Arcgis) no son un buen ajuste a nuestro escenario.

0 votos

@AbreuFreire hace tiempo que no trabajo con arcpy y lamentablemente ya no lo uso y no podría ayudar más, así que lo siento. Creo que si usted podría publicar una nueva pregunta explicando en detalle lo que está tratando de lograr y el enlace al código en esta respuesta para la referencia, usted debe obtener ayuda de otros usuarios. Mucha suerte.

2voto

UnkwnTech Puntos 21942

Creo que tendrás que escribir un script que trabaje a lo largo de cada línea desde su nodo de inicio y tome tres coordenadas de vértice a la vez.

Si el ángulo entre el primer vértice y el vértice central es el mismo (dentro de la tolerancia que establezcas) que entre el vértice central y el tercero, cuando reescribas la línea omite el vértice central.

Si empiezas a escribir este tipo de código y te quedas atascado, preséntalo aquí y nuestros usuarios estarán a menudo dispuestos a ayudarte.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X