Schreiben von Geometrien

Mit Einfüge- und Aktualisierungs-Cursorn können Skripte neue Features in einer Feature-Class erstellen oder vorhandene aktualisieren. Ein Skript kann ein Feature definieren, indem es ein Punktobjekt erstellt, dessen Eigenschaften festlegt und es in einem Array platziert. Mit diesem Array kann anschließend die Geometrie eines Features festgelegt werden. Eine Singlepart-Geometrie ist durch ein Array von Punkten definiert. Daher kann ein Multipart-Feature aus mehreren Arrays von Punkten erstellt werden.

Das folgende Beispiel zeigt eine Datei, die vom weiter unten dargestellten Skript verarbeitet werden soll. Sie enthält eine Punkt-ID und eine X- und Y-Koordinate.

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

Im folgenden Beispiel wird veranschaulicht, wie eine Textdatei mit mehreren linearen Koordinaten (wie oben) gelesen und anhand der Koordinaten eine neue Feature-Class erstellt wird.

# 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

Ein Array von Punkten ist beim Schreiben von Punkt-Features nicht erforderlich. Mit einem einzelnen Punktobjekt wird die Geometrie eines Punkt-Features festgelegt.

Sämtliche Geometrien werden validiert, bevor sie in eine Feature-Class geschrieben werden. Probleme wie eine fehlerhafte Ringausrichtung und sich selbst überschneidende Polygone werden beim Vereinfachen der Geometrie behoben, bevor diese eingefügt wird.

Beispiel: Erstellen von quadratischen Puffern mit "SearchCursor" und "InsertCursor"

In bestimmten Fällen empfiehlt es sich, neue Geometrien auf der Grundlage von Features einer anderen Feature-Class zu erstellen. Verwenden Sie hierzu "SearchCursor" und "InsertCursor".

Im folgenden Beispiel werden die XY-Koordinaten einer Eingabe-Point-Feature-Class mit "InsertCursor" identifiziert. Anhand der Punktkoordinaten werden die Eckpositionen der quadratischen Pufferpolygone berechnet, die dann mit InsertCursor in die Ausgabe eingegeben werden.

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
HinweisHinweis:

Wenn nur Geoverarbeitungswerkzeuge verwendet werden, kann ein quadratischer Puffer auch mit den nacheinander verwendeten Werkzeugen Buffer und FeatureEnvelopeToPolygon berechnet werden.

Verwandte Themen


7/10/2012