Ecriture des géométries

A l'aide des curseur d'insertion et de mise à jour, les scripts peuvent créer de nouvelles entités dans une classe d'entités ou mettre à jour des entités existantes. Un script permet de définir une entité en créant un objet point, en définissant ses propriétés et en la plaçant dans un tableau. Ce tableau permet ensuite de définir la géométrie d'une entité. Une partie de géométrie unique est définie par un tableau de points. Il est donc possible de créer une entité multi-parties à partir de plusieurs tableaux de points.

Voici un exemple de fichier à traiter par le script ci-dessous. Il contient un ID de point et une coordonnée X et 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

L'exemple ci-dessous montre comment lire un fichier texte contenant une série de coordonnées linéaires (comme ci-dessus), puis les utiliser pour créer une nouvelle classe d'entités.

# 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

Un tableau de points n'est pas nécessaire à l'affichage des entités ponctuelles. Un objet point unique sert à définir la géométrie d'une entité ponctuelle.

Toutes les géométries sont validées avant leur enregistrement dans une classe d'entités. Les problèmes de boucles mal orientées et de polygones qui s'entrecoupent, entre autres, sont corrigés lorsque la géométrie est simplifiée avant son insertion.

Exemple : utilisation des fonctions SearchCursor et InsertCursor pour créer des zones tampon carrées

Dans certains cas, il est souhaitable de créer de nouvelles géométries basées sur les entités d'une autre classe d'entités. Cela est possible en utilisant SearchCursor et InsertCursor simultanément.

Dans l'exemple ci-dessous, la fonction InsertCursor permet d'identifier les coordonnées XY d'une classe d'entités points en entrée. Ces coordonnées de points permettent de calculer les emplacements des angles des zones tampon carrées introduits dans la sortie, à l'aide de la fonction 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
RemarqueRemarque :

En utilisant seulement des outils de géotraitement, une zone tampon carrée peut également être calculée à l'aide des outils Zone tampon et FeatureEnvelopeToPolygon, utilisés l'un après l'autre.

Rubriques connexes


7/10/2012