Обчисліть площу в скрипті Python в ArcMap


14

Я намагаюся обчислити площу багатокутника в рамках мого сценарію Python. Я створюю новий багатокутник з об'єднання двох разом, і я хотів би додати область отриманого многокутника до поля у вихідному файлі. Полігон зберігається у звичайному форматному файлі та проектується. Площа переважно в одиницях карт.

Я вважав би це досить розповсюдженим і простим завданням, але, незважаючи на багато Googleing, я досі не зміг знайти робочі рішення.

Я планував використовувати arcpy.updateCursorдля вставки значення, коли воно обчислюється (на цьому етапі є лише одна особливість у ФК), тому найпростіше, якщо його можна повернути як змінну. Будь-яке альтернативне рішення, яке виконує те саме завдання (отримання значення області у правильне поле), також буде працювати.

Я також спробував калькулятор поля від Python. Змінено на довідкових сторінках, я думав, що наступне буде працювати, але поки що не пощастило.

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

Запуск ArcGIS Basic 10.1 SP1 з Python 2.7 у Windows 7.

Відповідні частини мого поточного коду виглядають так:

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

Який тип виходу? Shapefile, базу даних геоданих, ще щось? Ваш вихідний файл спроектований чи непроектований?
blord-castillo

Також ви можете опублікувати трохи більше зразка коду, зокрема курсору, який ви використовуєте для оновлення? Швидше за все, ви можете досягти того, що хочете, використовуючи SHAPE@AREAяк частину курсору для читання області; але структура коду залежить від того, чи знаходиться ваша область в тих же одиницях, що і те, що ви хочете виписати.
blord-castillo

Відповіді:


29

Існує три різні способи пошуку та зберігання області багатокутника в клас функції з дугою: 1) полевий калькулятор, 2) "класичні" дуги-дуги та 3) arcpy.daкурсори. Дещо з цього запозичено з моєї попередньої відповіді про використання SearchCursor .


1. Польовий калькулятор

  • При використанні калькулятора поля є три різні типи виразів, які використовують різні аналізатори вираження. Це вказано в третьому параметрі інструменту для геообробки поля обчислення . Отримуючи доступ до властивостей об’єкта Geometry, використовуючи, як in !shape.area!, ви повинні використовувати аналізатор Python 9.3.

  • Вираз, який ви мали раніше, виконував split()команду на результат !SHAPE.AREA!. Це повертає об'єкт Python list, який не можна передавати в floatоб'єкт.

  • У своєму вираженні ви можете вказати одиницю повернутої області, використовуючи @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. Дуга 10.0 - курсори "Класика"

  • При використанні класичних курсорів (тобто arcpy.UpdateCursor) об'єкт курсору - це ітерабельний вміст rowоб'єктів. Вам потрібно скористатися методами getValueта setValueметодами, щоб отримати геометрію з рядка (як об’єкт геометрії та встановити значення площі rowяк поплавок.

  • Ваш вихідний рядок зберігається у тимчасовому просторі подряпин, поки ви не викликаєте 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. Дуга 10.1 - курсори arcpy.da

  • Під час використання нових курсорів у модулі доступу до даних (тобто arcpy.da.UpdateCursor) вам потрібно передати список імен полів як другий параметр конструктора курсору. Для цього потрібна ще деяка робота, але отримані rowоб'єкти - це списки Python, що полегшує читання та запис даних під час ітерації через рядки курсору. arcpy.da.UpdateCursorтакож має кращі показники, ніж arcpy.UpdateCursorчастково, тому що пропускає неважливі поля, особливо геометрію.

  • При читанні геометрії, ви можете вибрати один з декількох геометричних лексем, наприклад SHAPE@TRUECENTROID, SHAPE@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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.