フィーチャクラスのコピーを作成し、ArcPyを使用して特定の距離だけオフセットするスクリプトツールを作成していますか?


9

ポリゴンフィーチャクラスを複製し、すべてのポリゴンをx方向とy方向の両方に約10フィートオフセットします。先週、これを行う方法はあるかと尋ねたところ、arcpyを使用して独自のpythonスクリプトを作成する必要がある可能性が最も高いという通知を受けました。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)

編集:内部のwhileループの「pnt = part.next()」をtry / exceptブロックの下に移動して、ポイントをスキップしないようにし、内部リングをテストする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つ以上の内部リングを持つフィーチャーを除いて、スクリプトがすべてを完全にシフトすることを発見しました。ラインを接続したままにして、ポリゴンを歪めます。これを説明する方法を知っていますか?
Tanner
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.