Escribir geometrías

Al utilizar los cursores insertar y actualizar, las secuencias de comandos pueden crear nuevas entidades en una clase de entidad o actualizar las existentes. Una secuencia de comandos puede definir una entidad al crear un objeto de punto, completar sus propiedades y colocarlo en un conjunto. Después ese conjunto puede utilizarse para establecer la geometría de una entidad. Una sola parte de la geometría está definida por un conjunto de puntos; por lo tanto, una entidad multiparte se puede crear a partir de varios conjuntos de puntos.

A continuación hay un ejemplo de un archivo que va a ser procesado por la secuencia de comandos que sigue. Contiene un Id. de punto y una coordenada x e y.

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

El siguiente ejemplo muestra cómo leer un archivo de texto que contiene una serie de coordenadas lineales (como el anterior) y utilizarlo para crear una nueva 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 and other required modules
#
import arcpy
from arcpy import env
import fileinput
import string
import os

env.overwriteOutput = True

# Get the coordinate ASCII file
#
infile = arcpy.GetParameterAsText(0)

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

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

try:
   # Create the output feature class
   #
   arcpy.CreateFeatureclass_management(os.path.dirname(fcname),
                                       os.path.basename(fcname), 
                                       "Polyline", template)

   # Open an insert cursor for the new feature class
   #
   cur = arcpy.InsertCursor(fcname)

   # Create an array and point object needed to create features
   #
   lineArray = arcpy.Array()
   pnt = arcpy.Point()

   # Initialize a variable for keeping track of a feature's ID.
   #
   ID = -1 
   for line in fileinput.input(infile): # Open the input file
      # set the point's ID, X and Y properties
      #
      pnt.ID, pnt.X, pnt.Y = string.split(line,";")
      print pnt.ID, pnt.X, pnt.Y
      if ID == -1:
         ID = pnt.ID

      # Add the point to the feature's array of points
      #   If the ID has changed, create a new feature
      #
      if ID != pnt.ID:
         # Create a new row or feature, in the feature class
         #
         feat = cur.newRow()

         # Set the geometry of the new feature to the array of points
         #
         feat.shape = lineArray

         # Insert the feature
         #
         cur.insertRow(feat)
         lineArray.removeAll()
      lineArray.add(pnt)
      ID = pnt.ID

   # Add the last feature
   #
   feat = cur.newRow()
   feat.shape = lineArray
   cur.insertRow(feat)
      
   lineArray.removeAll()
   fileinput.close()
   del cur
except Exception as e:
   print e.message

No se necesita un conjunto de puntos cuando se escriben entidades de punto. Se utiliza un solo objeto de punto para establecer la geometría de una entidad de puntos.

Todas las geometrías se validan antes de que se escriban en una clase de entidad. Problemas 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.

Ejemplo: utilizar SearchCursor e InsertCursor para crear áreas de influencia cuadradas

En algunos casos, se recomienda crear nuevas geometrías basadas en las entidades de otra clase de entidad. Esto se puede lograr al utilizar SearchCursor e InsertCursor simultáneamente.

En el siguiente ejemplo, se utiliza InsertCursor para identificar las coordenadas x, y de una clase de entidad de puntos de entrada. Estas coordenadas de punto se utilizan para calcular las ubicaciones de las esquinas para los polígonos de zonas de influencia cuadradas que se introducen en la salida con InsertCursor.

import arcpy
from arcpy import env
import os

env.overwriteOutput = True

# Get arguments: 
#   Input point feature class
#   Output polygon feature class
#   Buffer distance
#   Boolean type: Maintain fields and field values of the input in the output 
#
inPoints   = arcpy.GetParameterAsText(0)
outPolys   = arcpy.GetParameterAsText(1)
bufDist    = arcpy.GetParameterAsText(2)
keepFields = arcpy.GetParameterAsText(3)

# Prepare the output based on whether field and field values are desired in the output
#
if keepFields:
    # Create empty output polygon feature class that includes fields of the input
    #
    arcpy.CreateFeatureClass(os.path.dirname(outPolys), os.path.basename(outPolys), "POLYGON",
                             inPoints, "", "", inPoints)

    # Create a short list of fields to ignore when moving fields values from 
    #  input to output
    #
    ignoreFields = []

    # Use Describe properties to identify the shapeFieldName and OIDFieldName
    #
    desc = arcpy.Describe(inPoints)
    ignoreFields.append(desc.shapeFieldName)
    ignoreFields.append(desc.OIDFieldName)

    # Create a list of fields to use when moving field values from input to output
    #
    fields = arcpy.ListFields(inPoints)
    fieldList = []
    for field in fields:
        if field.name not in ignoreFields:
            fieldList.append(field.name)
else:
    # Create empty output polygon feature class without fields of the input
    #
    arcpy.CreateFeatureclass(os.path.dirname(outPolys), os.path.basename(outPolys), "POLYGON",
                             "", "", "", inPoints)

# Open searchcursor
#
inRows = arcpy.SearchCursor(inPoints)

# Open insertcursor
#
outRows = arcpy.InsertCursor(outPolys)

# Create point and array objects
#
pntObj = arcpy.Point()
arrayObj = arcpy.Array()

for inRow in inRows: # One output feature for each input point feature
    inShape = inRow.shape
    pnt = inShape.getPart(0)

    # Need 5 vertices for square buffer: upper right, upper left, lower left,
    #   lower right, upper right. Add and subtract distance from coordinates of
    #   input point as appropriate.
    for vertex in [0,1,2,3,4]:
        pntObj.ID = vertex
        if vertex in [0,3,4]:
            pntObj.X = pnt.X + bufDist
        else:
            pntObj.X = pnt.X - bufDist
        if vertex in [0,1,5]:
            pntObj.Y = pnt.Y + bufDist
        else:
            pntObj.Y = pnt.Y - bufDist
        arrayObj.add(pntObj)

    # Create new row for output feature
    #
    feat = outRows.newRow()

    # Shift attributes from input to output
    #
    if keepFields == "true":
        for fieldName in fieldList:
            feat.setValue(fieldName, inRow.getValue(fieldName))
    
    # Assign array of points to output feature
    #
    feat.shape = arrayObj

    # Insert the feature
    #
    outRows.insertRow(feat)

    # Clear array of points
    #
    arrayObj.removeAll()

# Delete inputcursor
#
del outRows
NotaNota:

Solamente con las herramientas de geoprocesamiento, también se puede calcular una zona de influencia cuadrada con las herramientas Zona de influencia y FeatureEnvelopeToPolygon de forma consecutiva.

Temas relacionados


7/11/2012