Tính diện tích trong tập lệnh Python trong ArcMap


14

Tôi đang cố gắng tính diện tích của một đa giác trong tập lệnh Python của tôi. Tôi tạo một đa giác mới từ việc hợp nhất hai lại với nhau và tôi muốn thêm diện tích của đa giác kết quả vào một trường trong tệp đầu ra. Đa giác được lưu trữ trong một shapefile thông thường, và được chiếu. Diện tích tốt nhất là trong các đơn vị bản đồ.

Tôi đã có thể nghĩ rằng đây là một nhiệm vụ khá phổ biến và đơn giản, nhưng mặc dù có rất nhiều Google, tôi đã không thể tìm thấy một giải pháp làm việc cho đến nay.

Tôi đã lên kế hoạch sử dụng arcpy.updateCursorđể chèn giá trị khi nó được tính toán (chỉ có một tính năng trong FC ở giai đoạn này), vì vậy dễ nhất là nếu nó có thể được trả về dưới dạng một biến. Bất kỳ giải pháp thay thế nào thực hiện cùng một nhiệm vụ (nhận giá trị khu vực vào trường chính xác) cũng sẽ hoạt động.

Tôi cũng đã thử máy tính Field từ Python. Được sửa đổi từ các trang trợ giúp tôi nghĩ rằng những điều sau đây sẽ hoạt động, nhưng cho đến nay không có may mắn.

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

Chạy ArcGIS Basic 10.1 SP1 với Python 2.7 trên Windows 7.

Các phần có liên quan của mã hiện tại của tôi trông như thế này:

#/.../
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 ...

Loại đầu ra của bạn là gì? Shapefile, tập tin geodatabase, cái gì khác? Là tập tin đầu ra của bạn được chiếu hoặc không được cung cấp?
blord-castillo

Ngoài ra, bạn có thể đăng thêm một chút mẫu mã, đặc biệt là con trỏ mà bạn đang sử dụng để thực hiện cập nhật không? Nhiều khả năng bạn có thể đạt được những gì bạn muốn bằng cách sử dụng SHAPE@AREAnhư một phần của con trỏ để đọc khu vực; nhưng cấu trúc của mã phụ thuộc vào việc khu vực của bạn có cùng đơn vị với những gì bạn muốn viết ra không.
blord-castillo

Câu trả lời:


29

Có ba cách khác nhau để tìm và lưu trữ khu vực đa giác vào một lớp tính năng với Arcpy: 1) máy tính trường, 2) con trỏ arcpy "cổ điển" và 3) arcpy.dacon trỏ. Một số điều này được mượn từ câu trả lời trước đây của tôi về việc sử dụng SearchC tiền .


1. Máy tính hiện trường

  • Khi sử dụng máy tính trường, có ba loại biểu thức khác nhau sử dụng các trình phân tích cú pháp biểu thức khác nhau. Điều này được chỉ định trong tham số thứ ba của công cụ xử lý địa lý trường tính toán . Khi truy cập các thuộc tính của đối tượng Geometry bằng like in !shape.area!, bạn nên sử dụng trình phân tích cú pháp Python 9.3.

  • Biểu thức bạn có trước khi thực hiện một split()lệnh về kết quả của !SHAPE.AREA!. Điều này trả về một listđối tượng Python , không thể truyền vào floatđối tượng.

  • Trong biểu thức của bạn, bạn có thể chỉ định đơn vị của khu vực được trả về bằng cách sử dụng @SQUAREKILOMETERScờ, thay thế SQUAREKILOMETERSbằng các đơn vị trên trang trợ giúp Trường tính toán .

Đây là mã Python tôi sẽ sử dụng cho phương thức này:

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 - con trỏ "cổ điển"

  • Khi sử dụng các con trỏ cổ điển (tức là arcpy.UpdateCursor) đối tượng con trỏ là một rowđối tượng có thể lặp lại . Bạn cần sử dụng các phương thức getValuesetValueđể lấy hình học từ hàng (dưới dạng đối tượng hình học và đặt giá trị diện tích thành hình rownổi.

  • Hàng đầu ra của bạn được lưu trữ trong một không gian đầu tạm thời cho đến khi bạn gọi updateRowphương thức trên con trỏ. Điều này lưu dữ liệu mới vào bộ dữ liệu thực tế.

Đây là mã Python tôi sẽ sử dụng cho phương thức này:

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 - con trỏ arcpy.da

  • Khi sử dụng các con trỏ mới trong mô-đun truy cập dữ liệu (nghĩa là arcpy.da.UpdateCursor) bạn cần chuyển vào một danh sách các tên trường làm tham số thứ hai trong hàm tạo con trỏ. Điều này đòi hỏi một số công việc trước mắt, nhưng các rowđối tượng kết quả là danh sách Python, giúp đọc và ghi dữ liệu dễ dàng hơn khi lặp qua các hàng con trỏ. arcpy.da.UpdateCursorcũng có hiệu suất tốt hơn arcpy.UpdateCursor, một phần vì nó bỏ qua các trường không quan trọng, đặc biệt là hình học.

  • Khi đọc hình học, bạn có thể chọn một trong số các thẻ hình học, ví dụ SHAPE@TRUECENTROID, SHAPE@AREAhoặc SHAPE@. Sử dụng mã thông báo "đơn giản hơn" sẽ cải thiện đáng kể hiệu suất so với SHAPE@, trong đó có tất cả thông tin hình học. Danh sách đầy đủ các mã thông báo có tại arcpy.da.UpdateCursortrang trợ giúp.

  • Như trước, hàng đầu ra của bạn được lưu trữ trong một không gian đầu tạm thời cho đến khi bạn gọi updateRowphương thức trên con trỏ. Điều này lưu dữ liệu mới vào bộ dữ liệu thực tế.

Đây là mã Python tôi sẽ sử dụng cho phương thức này:

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
Câu trả lời tuyệt vời. Chỉ muốn nói rằng vào ngày 10.2, bạn sẽ làm row[1] = row[0]như không còn areathuộc tính. Bạn cũng có thể sử dụng con trỏ làm trình quản lý bối cảnh trong withcâu lệnh và không phải lo lắng về việc xóa bất cứ điều gì.
Paul H
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.