Escribir geometrías

Al utilizar los cursores insertar y actualizar, los scripts pueden crear entidades en una clase de entidad o actualizar las existentes. Un script puede definir una entidad al crear un objeto de Point, completar sus propiedades y colocarlo en un Array. Después, esa matriz puede utilizarse para establecer la geometría de una entidad utilizando las clases de geometría Polygon, Polyline, PointGeometry o Multipoint.

import arcpy
fc = "c:/data/gdb.gdb/roads"
cursor = arcpy.da.InsertCursor(fc, ["SHAPE@"])
array = arcpy.Array([arcpy.Point(-77.4349451, 37.5408265),
                     arcpy.Point(-78.6384349, 35.7780943)])
spatial_reference = arcpy.SpatialReference(4326)
polyline = arcpy.Polyline(array, spatial_reference)

cursor.insertRow([polyline])

Según se mostró anteriormente, una sola parte de la geometría se define mediante un conjunto de puntos. De igual manera, se puede crear una entidad multiparte a partir de un conjunto de conjuntos de puntos según se muestra más adelante utilizando el mismo cursor.

first_part = arcpy.Array([arcpy.Point(-77.4349451, 37.5408265),
                          arcpy.Point(-78.6384349, 35.7780943)])
second_part = arcpy.Array([arcpy.Point(-79.7910143, 36.0786785),
                           arcpy.Point(-80.8546435, 35.2315402)])

array = arcpy.Array([first_part, second_part])
spatial_reference = arcpy.SpatialReference(4326)
multipart_feature = arcpy.Polyline(array, spatial_reference)

cursor.insertRow([multipart_feature])

Al escribir entidades de punto, se utiliza solamente un solo objeto de punto para establecer la geometría de una entidad de puntos. Los puntos también se pueden crear más fácilmente (y eficientemente) utilizando el token SHAPE@XY (y los tokens SHAPE@M y SHAPE@Z, según sea necesario).

import arcpy

# fc is a point feature class
fc = "c:/data/gdb.gdb/stops"
cursor = arcpy.da.InsertCursor(fc, ["SHAPE@XY"])
xy = (5997594.4753, 2069901.75682)

cursor.insertRow([xy])

Todas las geometrías se validan antes de que se escriban en una clase de entidad. Determinados problemas, tales como una incorrecta orientación del anillo y polígonos que se intersecan a sí mismos, entre otros, se corrigen cuando se simplifica la geometría antes de su inserción.

El siguiente ejemplo muestra cómo leer un conjunto de coordenadas (definido por coords_list) que contiene una serie de coordenadas lineales y utilizarlo para crear una clase de entidad:

# Create a new line feature class using a text file of coordinates.
#   Each coordinate entry is semicolon delimited in the format of ID;X;Y
import arcpy
import os

# List of coordinates (ID, X, Y)
coords_list = [[1, -61845879.0968, 45047635.4861], 
               [1, -3976119.96791, 46073695.0451],
               [1, 1154177.8272, -25134838.3511],
               [1, -62051091.0086, -26160897.9101],
               [2, 17365918.8598, 44431999.7507],
               [2, 39939229.1582, 45252847.3979],
               [2, 41170500.6291, 27194199.1591],
               [2, 17981554.5952, 27809834.8945],
               [3, 15519011.6535, 11598093.8619],
               [3, 52046731.9547, 13034577.2446],
               [3, 52867579.6019, -16105514.2317],
               [3, 17160706.948, -16515938.0553]]

# The output feature class to be created
outFC = arcpy.GetParameterAsText(0)

# Get the template feature class
template = arcpy.GetParameterAsText(1)

cur = None
try:
    # Create the output feature class
    arcpy.CreateFeatureclass_management(os.path.dirname(outFC),
                                        os.path.basename(outFC), 
                                        "POLYLINE", template)

    # Access spatial reference of template to define spatial
    # reference of geometries
    spatial_reference = arcpy.Describe(template).spatialReference

    # Open an insert cursor for the new feature class
    cur = arcpy.da.InsertCursor(outFC, ["SHAPE@"])

    # Create an array object needed to create features
    array = arcpy.Array()

    # Initialize a variable for keeping track of a feature's ID.
    ID = -1
    for coords in coords_list: 
        if ID == -1:
            ID = coords[0]

        # Add the point to the feature's array of points
        #   If the ID has changed, create a new feature
        if ID != coords[0]:
            cur.insertRow([arcpy.Polyline(array)])
            array.removeAll()
        array.add(arcpy.Point(coords[1], coords[2], ID=coords[0]))
        ID = coords[0]

    # Add the last feature
    polyline = arcpy.Polyline(array, spatial_reference)
    cur.insertRow([polyline])


except Exception as e:
    print(e)
finally:
    # Clean up the cursor if necessary
    if cur:
        del cur

Para crear entidades poligonales y de polilínea multiparte y entidades poligonales con anillos interiores, cree primero una matriz de matrices. A continuación, entréguelo a las clases Polygon y Polyline.

Creación de geometría a partir de listas de coordenadas

También es posible crear una geometría a partir de una lista de coordenadas. Este planteamiento puede ofrecer mejoras de rendimiento, ya que evita la sobrecarga de creación de objetos de geometría. Sin embargo, está limitada solamente a entidades que sean de parte simple y, en el caso de los polígonos, sin anillos interiores. Todas las coordenadas deben estar en las unidades de la referencia espacial de la clase de entidad.

En el siguiente ejemplo, se crea una sola entidad de polilínea a partir de una lista de pares x,y.

import arcpy

coordinates = [(-117.2000424, 34.0555514), 
               (-117.2000788, 34.0592066), 
               (-117.1957315, 34.0592309), 
               (-117.1956951, 34.0556001)]

# Create a feature class with a spatial reference of GCS WGS 1984
result = arcpy.management.CreateFeatureclass(
    arcpy.env.scratchGDB, "esri_square", "POLYLINE", spatial_reference=4326)
feature_class = result[0]

# Write feature to new feature class
with arcpy.da.InsertCursor(feature_class, ['SHAPE@']) as cursor:
    cursor.insertRow([coordinates])

De modo parecido, en el siguiente ejemplo, se crea una sola entidad de polilínea 3D a partir de una lista de coordenadas x, y, z.

import arcpy

coordinates = [(-117.2000424, 34.0555514, 1), 
               (-117.2000788, 34.0592066, 2), 
               (-117.1957315, 34.0592309, 5), 
               (-117.1956951, 34.0556001, 2)]

# Create a feature class with a spatial reference of GCS WGS 1984
result = arcpy.management.CreateFeatureclass(
    arcpy.env.scratchGDB, "esri_square_z", "POLYLINE", has_z="ENABLED", 
    spatial_reference=4326)
feature_class = result[0]

# Write feature to new feature class
with arcpy.da.InsertCursor(feature_class, ['SHAPE@']) as cursor:
    cursor.insertRow([coordinates])