ArcMapのPythonスクリプト内の面積を計算する


14

Pythonスクリプト内でポリゴンの面積を計算しようとしています。2つのポリゴンをマージして新しいポリゴンを作成し、結果のポリゴンの領域を出力ファイルのフィールドに追加します。ポリゴンは通常のシェープファイルに保存され、投影されます。できればマップ単位の面積。

これは非常に一般的で簡単な作業だと思っていましたが、Googleの多くにもかかわらず、今のところ有効なソリューションを見つけることができませんでした。

arcpy.updateCursor値を計算したら挿入することを計画していました(この段階ではFCに機能は1つしかありません)ので、変数として返すことができるのが最も簡単です。同じタスクを実行する(面積値を正しいフィールドに取得する)代替ソリューションも機能します。

Pythonのフィールド計算機も試しました。ヘルプページから変更したものは、次のように動作すると思いましたが、これまでのところ運はありません。

arcpy.AddField_management(tempPgs, "Shape_area", 'DOUBLE')
exp = "float(!SHAPE.AREA!.split())"
arcpy.CalculateField_management(tempPgs, "Shape_area", exp)

Windows 7でPython 2.7を使用してArcGIS Basic 10.1 SP1を実行する。

現在のコードの関連部分は次のようになります。

#/.../
arcpy.Copy_management(inpgs, outpgs)
arcpy.AddField_management(outpgs, 'Shape_area', 'LONG')
fields = AM.FieldLst(outpgs)

#/.../

# Identify and search for shapes smaller than minimum area
where1 = '"' + 'Shape_Area' + '" < ' + str(msz)
polyrows = arcpy.SearchCursor(inpgs, where1)

for prow in polyrows:
    grd1 = prow.GridID   # GridID on the current polygon
    grd2 = nDD.get(grd1) # GridID on the polygon downstream

    # Update features
    if grd2
        geometry1 = prow.Shape
        geometry2 = geometryDictionary[grd2]

        # Update temporary features
        arcpy.Merge_management([geometry1, geometry2], tempMerged)
        arcpy.Dissolve_management(tempMerged, tempPgs)

        fds = AM.FieldLst(tempPgs)

        for field in fields[2:]:
            arcpy.AddField_management(tempPgs, field, 'DOUBLE')

        for fd in fds[2:]:
            arcpy.DeleteField_management(tempPgs, fd)

        exp = "float(!SHAPE.AREA!.split())"
        arcpy.CalculateField_management(tempPgs, "Shape_area", exp)

        # Append them to output FC
        try:
            arcpy.Append_management(tempPgs, outpgs, "TEST")
        except arcgisscripting.ExecuteError:
            arcpy.Append_management(tempPgs, outpgs, "NO_TEST")

    elif ...

    else ...

出力タイプは何ですか?シェープファイル、ファイルジオデータベース、他に何か?出力ファイルは投影されていますか?
blord-castillo

また、コードサンプル、特に更新を行うために使用しているカーソルをもう少し投稿できますか?ほとんどの場合SHAPE@AREA、カーソルの一部としてを使用して領域を読み取ることで、目的を達成できます。ただし、コードの構造は、エリアが書き出すものと同じユニットにあるかどうかによって異なります。
blord-castillo

回答:


29

arcpyを使用してポリゴンエリアを検索してフィーチャクラスに格納するには、1)フィールド計算機、2)「クラシック」アークピーカーソル、3)arcpy.daカーソルの3つの異なる方法があります。これのいくつかは、SearchCursorの使用に関する前回の回答から借用しています


1.フィールド計算機

  • フィールド計算機を使用する場合、異なる式パーサーを使用する3つの異なる式タイプがあります。これは、[ フィールド計算]ジオプロセシングツールの 3番目のパラメーターで指定されます。like inを使用してGeometryオブジェクトのプロパティにアクセスするとき!shape.area!は、Python 9.3パーサーを使用する必要があります。

  • 以前に持っていた式split()は、の結果に対してコマンドを実行しました!SHAPE.AREA!。これlistにより、floatオブジェクトにキャストできないPython オブジェクトが返されます。

  • 式では、@SQUAREKILOMETERSフラグを使用して、返される領域の単位を指定できます。これは、フィールドSQUAREKILOMETERS計算ヘルプページの単位に置き換えます

このメソッドに使用するPythonコードは次のとおりです。

tempPgs = "LayerName"
arcpy.AddField_management(tempPgs, "Shape_area", "DOUBLE")
exp = "!SHAPE.AREA@SQUAREKILOMETERS!"
arcpy.CalculateField_management(tempPgs, "Shape_area", exp, "PYTHON_9.3")

2. Arc 10.0-「クラシック」カーソル

  • クラシックカーソル(つまりarcpy.UpdateCursor)を使用する場合、カーソルオブジェクトはオブジェクトを含む反復可能rowオブジェクトです。getValueおよびsetValueメソッドを使用して、行からジオメトリを取得する必要があります(ジオメトリオブジェクトとして、面積値をrowfloatとして設定します)。

  • 出力行はupdateRow、カーソルでメソッドを呼び出すまで一時的なスクラッチスペースに保存されます。これにより、新しいデータが実際のデータセットに保存されます。

このメソッドに使用するPythonコードは次のとおりです。

tempPgs = "LayerName"
arcpy.AddField_management(tempPgs, "Shape_area", "DOUBLE")
geometryField = arcpy.Describe(tempPgs).shapeFieldName #Get name of geometry field
cursor = arcpy.UpdateCursor(tempPgs)
for row in cursor:
    AreaValue = row.getValue(geometryField).area #Read area value as double
    row.setValue("Shape_area",AreaValue) #Write area value to field
    cursor.updateRow(row)
del row, cursor #Clean up cursor objects

3. Arc 10.1-arcpy.daカーソル

  • データアクセスモジュールで新しいカーソルを使用する場合(つまりarcpy.da.UpdateCursor)、カーソルコンストラクターの2番目のパラメーターとしてフィールド名のリストを渡す必要があります。これには事前にいくつかの作業が必要rowですが、結果のオブジェクトはPythonリストであるため、カーソル行を反復処理するときにデータの読み取りと書き込みが簡単になります。arcpy.da.UpdateCursorまたarcpy.UpdateCursor、重要ではないフィールド、特にジオメトリをスキップするため、パフォーマンスが向上しています。

  • ジオメトリを読むとき、あなたはジオメトリトークンの数の1つ、例えばを選択することができSHAPE@TRUECENTROIDSHAPE@AREAまたはSHAPE@。「シンプルな」トークンを使用するとSHAPE@、すべてのジオメトリ情報を含むに比べてパフォーマンスが大幅に向上します。トークンの完全なリストはarcpy.da.UpdateCursorヘルプページにあります。

  • 前と同様に、出力行はupdateRow、カーソルでメソッドを呼び出すまで一時的なスクラッチスペースに格納されます。これにより、新しいデータが実際のデータセットに保存されます。

このメソッドに使用するPythonコードは次のとおりです。

tempPgs = "LayerName"
arcpy.AddField_management(tempPgs, "Shape_area", "DOUBLE")
CursorFieldNames = ["SHAPE@AREA","Shape_area"]
cursor = arcpy.da.UpdateCursor(tempPgs,CursorFieldNames)
for row in cursor:
    AreaValue = row[0].area #Read area value as double
    row[1] = AreaValue #Write area value to field
    cursor.updateRow(row)
del row, cursor #Clean up cursor objects

5
素晴らしい答え。10.2のrow[1] = row[0]時点では、area属性がなくなったのでそれを行うと言いたいだけです。また、カーソルをwithステートメント内のコンテキストマネージャーとして使用することもでき、何も削除する必要はありません。
ポールH
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.