Writing geometries |
|
Release 9.3
Last modified June 3, 2010 |
Print all topics in : "Data properties and access when scripting" |
Note:
This topic was updated for 9.3.1.
Using insert and update cursors, scripts can create new features in a feature class or update existing ones. A script can define a feature by creating a point object, populating its properties, and placing it in an array. That array can then be used to set a feature's geometry. A single geometry part is defined by an array of points, so a multipart feature can be created from multiple arrays of points.
Below is an example of a file that may be processed by the script below:
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
# 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 native arcgisscripting module and other required modules # import arcgisscripting import fileinput import os import string # Create the geoprocessor object # gp = arcgisscripting.create(9.3) gp.OverWriteOutput = 1 # Get the coordinate ascii file # infile = gp.GetParameterAsText(0) # Get the output feature class # fcname = gp.GetParameterAsText(1) # Get the template feature class # template = gp.GetParameterAsText(2) try: # Create the output feature class # gp.CreateFeatureClass(os.path.dirname(fcname),os.path.basename(fcname), "Polyline", template) # Open an insert cursor for the new feature class # cur = gp.InsertCursor(fcname) # Create an array and point object needed to create features # lineArray = gp.CreateObject("Array") pnt = gp.CreateObject("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: print gp.GetMessages(2)
In some cases, it is desirable to create new geometries based on the features of another feature class. This can be achieved by using SearchCursor and InsertCursor simultaneously.
In the following example, InputCursor is used to identify x,y coordinates of an input point feature class. These point coordinates are used to calculate the corner locations for square buffer polygons that are entered into the output using InsertCursor.
Using only geoprocessing tools, a square buffer can also be calculated using the Buffer and FeatureEnvelopeToPolygon tools in succession.
# Import native arcgisscripting module # import arcgisscripting import os # Create the geoprocessor object # gp = arcgisscripting.create(9.3) gp.OverWriteOutput = 1 # Input point feature class # inPoints = gp.GetParameterAsText(0) # Output polygon feature class # outPolys = gp.GetParameterAsText(1) #Buffer distance # bufDist = gp.GetParameterAsText(2) # Boolean type: Maintain fields and field values of the input in the output # keepFields = gp.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 # gp.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 = gp.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 = gp.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 # gp.CreateFeatureClass(os.path.dirname(outPolys), os.path.basename(outPolys), "POLYGON", "", "", "", inPoints) # Open searchcursor # inRows = gp.SearchCursor(inPoints) inRow = inRows.Next() # Open insertcursor # outRows = gp.InsertCursor(outPolys) # Create point and array objects # pntObj = gp.CreateObject("Point") arrayObj = gp.CreateObject("Array") while inRow: # 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: 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() # Get next feature in searchcursor # inRow = inRows.Next() # Delete inputcursor # del outRows