Чи є в ArcMap інструмент ArcPy для зміни розміру полігону, як масштабний інструмент панелі інструментів розширеного редагування?


17

Я пишу сценарій пітона для ArcGIS 10.3. Я знаю про Scale toolінтерфейс ArcGIS, але я не можу знайти таку команду arcpy. Він існує?

Як ви бачите на малюнку, Scale toolтвори відрізняються від того, що Buffer toolвони змінюють форму оригінального багатокутника. Отже, питання:

Чи можу я використовувати Scale tool(доступний через інтерфейс ArcGIS) за допомогою arcpy?

введіть тут опис зображення


2
Як щодо буферизації та видалення старого багатокутника !? буфер можна використовувати з позитивними та негативними значеннями!
Фарид Черагі

Питання стосується наявного інструменту arcpy, а не про те, як змінити розмір багатокутника.
Містер Че

Здається, ваша назва, запитання та коментар суперечать один одному. Якщо надані повторювані запитання не відповідають на ваше запитання, чи можете ви відредагувати своє запитання, щоб уточнити, що ви хочете?
Аарон

1
@ Буфер інструмент Mr.Che можна використовувати в сценаріях пітона через arcpy.Buffer_analysis (...)
Farid Cheraghi

Це супер! Як я можу оновлювати кожен клас функцій на число в таблиці, а не масштабувати, наприклад, всі функції на 0,5? Дякую
користувач1655130

Відповіді:


27

Мені нічого не відомо в API arcpy, що зробить масштабування для вас, але написання функції зробити це було б відносно просто.

Нижче наведений код виконує масштабування для двовимірних функцій і не враховує значення M або Z:

import arcpy
import math

def scale_geom(geom, scale, reference=None):
    """Returns geom scaled to scale %"""
    if geom is None: return None
    if reference is None:
        # we'll use the centroid if no reference point is given
        reference = geom.centroid

    refgeom = arcpy.PointGeometry(reference)
    newparts = []
    for pind in range(geom.partCount):
        part = geom.getPart(pind)
        newpart = []
        for ptind in range(part.count):
            apnt = part.getObject(ptind)
            if apnt is None:
                # polygon boundaries and holes are all returned in the same part.
                # A null point separates each ring, so just pass it on to
                # preserve the holes.
                newpart.append(apnt)
                continue
            bdist = refgeom.distanceTo(apnt)

            bpnt = arcpy.Point(reference.X + bdist, reference.Y)
            adist = refgeom.distanceTo(bpnt)
            cdist = arcpy.PointGeometry(apnt).distanceTo(bpnt)

            # Law of Cosines, angle of C given lengths of a, b and c
            angle = math.acos((adist**2 + bdist**2 - cdist**2) / (2 * adist * bdist))

            scaledist = bdist * scale

            # If the point is below the reference point then our angle
            # is actually negative
            if apnt.Y < reference.Y: angle = angle * -1

            # Create a new point that is scaledist from the origin 
            # along the x axis. Rotate that point the same amount 
            # as the original then translate it to the reference point
            scalex = scaledist * math.cos(angle) + reference.X
            scaley = scaledist * math.sin(angle) + reference.Y

            newpart.append(arcpy.Point(scalex, scaley))
        newparts.append(newpart)

    return arcpy.Geometry(geom.type, arcpy.Array(newparts), geom.spatialReference)

Ви можете назвати його об’єктом геометрії, коефіцієнтом масштабу (1 = однаковий розмір, 0,5 = розмір половини, 5 = 5 разів більший і т. Д.) Та необов'язковою опорною точкою:

scale_geom(some_geom, 1.5)

Використовуйте це спільно з курсорами для масштабування цілого класу функцій, припускаючи, що цільовий клас функцій вже існує:

incur = arcpy.da.SearchCursor('some_folder/a_fgdb.gdb/orig_fc', ['OID@','SHAPE@'])
outcur = arcpy.da.InsertCursor('some_folder/a_fgdb.gdb/dest_fc', ['SHAPE@'])

for row in incur:
    # Scale each feature by 0.5 and insert into dest_fc
    outcur.insertRow([scale_geom(row[1], 0.5)])
del incur
del outcur

редагувати: ось приклад використання апроксимації вашої тестової геометрії для 0,5 та 5 разів: введіть тут опис зображення

Тестували також багатокільцеві багатокутники (отвори)! введіть тут опис зображення

Потрібне пояснення:

scale_geomприймає по одному многокутнику і петлі через кожну вершину, вимірюючи відстань від нього до опорної точки (за замовчуванням - центроїд багатокутника).
Ця відстань потім масштабується шкалою, заданою для створення нової «масштабованої» вершини.

Масштабування здійснюється, по суті, нанесенням лінії на масштабній довжині від опорної точки через початкову вершину, при цьому кінець рядка стає масштабованою вершиною.
Кут і обертання є там, оскільки більш прямим вперед є обчислити положення кінця лінії вздовж однієї осі, а потім повернути її "на місце".


1
Я перевірив цей сценарій, і він прекрасно працює. Ти проклятий геній! =) Thx багато. Я залишу це питання без уваги, тому більше людей побачать його у "завтрашньому питанні".
Містер Че

1
Я виявив, що коли я намагаюся обробити багатокутник з отвором - це призводить до краху сценарію в черзі bdist = refgeom.distanceTo(apnt). Чи можете ви протестувати і виправити це?
Містер Че

@ Mr.Che На жаль, я забув, що ArcPy повертає всі кільця частини багатокутника в одному масиві. Кільця розділені нульовими точками. Це легко виправити, будь ласка, дивіться редагування.
Злий геній

Привіт. Чи можливо це отримати невелике пояснення того, як працює сценарій, я погано кодую і не отримую всі рядки, таким чином, це не працює для мене, будь ласка?
пітер

@peter Звичайно, я додав коротке пояснення того, що відбувається. Це не призначено бути самостійним сценарієм, а щось інтегрувати у власний сценарій. Нижній фрагмент коду показує приклад того, як його можна було використовувати.
Злий геній
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.