Створення інструменту скрипту, який створить копію класу функцій та компенсує її за заданою відстані за допомогою ArcPy?


9

Я хочу скопіювати клас функцій багатокутника і змістити всі полігони приблизно на 10 футів в обох напрямках x і y. Я запитав, чи є спосіб зробити це на минулому тижні, і мені повідомили, що, швидше за все, мені потрібно буде зробити свій власний скрипт python, використовуючи arcpy. Я створив власний сценарій за допомогою arcpy, але він не працює:

import arcpy
from arcpy import env
import os

env.overwriteOutput = True

# Get arguments: 
#   Input polygon feature class
#   Output polygon feature class
#
inputFeatureClass = arcpy.GetParameterAsText(0)
outputFeatureClass = arcpy.GetParameterAsText(1)
xShift = arcpy.GetParameterAsText(2)
yShift = arcpy.GetParameterAsText(3)

shapeName = arcpy.Describe(inputFeatureClass).shapeFieldName

# Create the output feature class with the same fields and spatial reference as the input feature class
arcpy.CreateFeatureclass_management(os.path.dirname(outputFeatureClass), os.path.basename(outputFeatureClass), "POLYGON", inputFeatureClass, "", "", inputFeatureClass)

# Create a search cursor to iterate through each row of the input feature class
inrows = arcpy.SearchCursor(inputFeatureClass)
# Create an insert cursor to insert rows into the output feature class
outrows = arcpy.InsertCursor(outputFeatureClass)

# Create empty Point and Array objects
pntArray = arcpy.Array()
partArray = arcpy.Array()

# Loop through each row/feature
for row in inrows:
    # Create the geometry object
    feature = row.getValue(shapeName)

    partnum = 0

    # Count the total number of points in the current multipart feature
    partcount = feature.partCount


    while partnum < partcount:
        part = feature.getPart(partnum)
        pnt = part.next()
        pntcount = 0

        # Enter while loop for each vertex
        #
        while pnt:

            pnt = part.next()
            shiftedPoint = arcpy.Point()
            try:
                shiftedPoint.ID = pnt.ID
                shiftedPoint.X = pnt.X + float(xShift)
                shiftedPoint.Y = pnt.Y + float(yShift)
            except AttributeError:
                continue
            #shiftedPoint = arcpy.Point(float(pnt.X) + float(xShift), float(pnt.Y) + float(yShift))
            pntArray.add(shiftedPoint)
            pntcount += 1

            # If pnt is null, either the part is finished or there is an 
            #   interior ring
            #
            if not pnt: 
                pnt = part.next()
                if pnt:
                    arcpy.AddMessage("Interior Ring:")
        # Create a polygon using the array of points
        polygon = arcpy.Polygon(pntArray)

        # Empty the array for the next run through the loop
        pntArray.removeAll()

        # Add the polygons (or 'parts') to an array. This is necessary for multipart features, or those with holes cut in them
        partArray.add(polygon)
        arcpy.AddMessage("Added a polygon to the partArray!")
        partnum += 1

    # Create a new row object that will be inserted into the ouput feature class. Set newRow = row so that it has the same attributes
    # Set newRow.shape = partArray so that the only thing different about this new feature is that its geometry is different (shifted)
    newRow = row
    newRow.shape = partArray

    outrows.insertRow(newRow)

    # Empy the array for the next run through the loop
    partArray.removeAll()

del inrows, outrows

Я продовжую отримувати цю помилку за рядком 70

<type 'exceptions.ValueError'>: Array: Add input not point nor array object

Я не можу зрозуміти, чому це дає мені цю помилку, оскільки я визначив вхід як масив.

Хтось знає, чому я отримую цю помилку?

Відповіді:


14

Замість того, щоб створювати та намагатися додати багатокутник до масиву, додайте масив точок до масиву частин. Змініть це:

polygon = arcpy.Polygon(pntArray)
pntArray.removeAll()
partArray.add(polygon)

До цього:

partArray.add(pntArray)
pntArray.removeAll()

Також існує проблема з вашим кодом, який намагається вставити рядок. Щоб створити новий рядок і вставити його, потрібно використовувати курсор вставки. Починаючи з рядка 77 в оригінальному зразку коду:

newRow = outrows.newRow()
newRow.shape = partArray
outrows.insertRow(newRow)

Редагувати : Ви також повинні перемістити "pnt = part.next ()" у своєму внутрішньому циклі під час циклу внизу вашого блоку спробу / крім, щоб ви не пропускали жодних точок, і щоб блок if, який перевіряється на внутрішні кільця, запускався. Так як код у вашій посаді не підбере внутрішні кільця. Ось вся справа після всіх описаних нами модифікацій:

import arcpy
from arcpy import env
import os

env.overwriteOutput = True

# Get arguments: 
#   Input polygon feature class
#   Output polygon feature class
#
inputFeatureClass = arcpy.GetParameterAsText(0)
outputFeatureClass = arcpy.GetParameterAsText(1)
xShift = arcpy.GetParameterAsText(2)
yShift = arcpy.GetParameterAsText(3)
print '\nparams: ', inputFeatureClass, outputFeatureClass, xShift, yShift, '\n'

shapeName = arcpy.Describe(inputFeatureClass).shapeFieldName

# Create the output feature class with the same fields and spatial reference as the input feature class
if arcpy.Exists(outputFeatureClass):
    arcpy.Delete_management(outputFeatureClass)
arcpy.CreateFeatureclass_management(os.path.dirname(outputFeatureClass), os.path.basename(outputFeatureClass), "POLYGON", inputFeatureClass, "", "", inputFeatureClass)

# Create a search cursor to iterate through each row of the input feature class
inrows = arcpy.SearchCursor(inputFeatureClass)
# Create an insert cursor to insert rows into the output feature class
outrows = arcpy.InsertCursor(outputFeatureClass)

# Create empty Point and Array objects
pntArray = arcpy.Array()
partArray = arcpy.Array()

# Loop through each row/feature
for row in inrows:
    # Create the geometry object
    feature = row.getValue(shapeName)
    partnum = 0
    # Count the total number of points in the current multipart feature
    partcount = feature.partCount
    print 'num parts: ', partcount
    while partnum < partcount:
        part = feature.getPart(partnum)
        pnt = part.next()
        print 'outer while'
        pntcount = 0
        # Enter while loop for each vertex
        #
        while pnt:
            shiftedPoint = arcpy.Point()
            try:
                shiftedPoint.ID = pnt.ID
                shiftedPoint.X = pnt.X + float(xShift)
                shiftedPoint.Y = pnt.Y + float(yShift)
            except AttributeError:
                continue
            pntArray.add(shiftedPoint)
            pntcount += 1
            pnt = part.next()
            print 'pntcount: ', pntcount
            # If pnt is null, either the part is finished or there is an 
            #   interior ring
            if pnt is None: 
                pnt = part.next()
                if pnt:
                    arcpy.AddMessage("Interior Ring:")
        partArray.add(pntArray)
        pntArray.removeAll()
        arcpy.AddMessage("Added a polygon to the partArray!")
        partnum += 1
    # Create a new row object that will be inserted into the ouput feature class. Set newRow = row so that it has the same attributes
    # Set newRow.shape = partArray so that the only thing different about this new feature is that its geometry is different (shifted)
    newRow = outrows.newRow()
    newRow.shape = partArray
    outrows.insertRow(newRow)
    # Empy the array for the next run through the loop
    partArray.removeAll()
del inrows, outrows

Я щойно виявив, що сценарій зміщує все ідеально, за винятком функцій, які мають 2 і більше внутрішніх кілець. Це залишить лінії з'єднаними та спотворить багатокутник. Чи знаєте ви, як це врахувати?
Таннер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.