Có công cụ ArcPy để thay đổi kích thước đa giác như công cụ Scale của thanh công cụ Chỉnh sửa nâng cao trong ArcMap không?


17

Tôi đang viết một kịch bản python cho ArcGIS 10.3. Tôi biết về Scale toolgiao diện ArcGIS nhưng tôi không thể tìm thấy lệnh Arcpy như vậy. Nó có tồn tại?

Như bạn có thể thấy trên hình, các Scale tooltác phẩm khác với Buffer tool- nó thay đổi hình dạng của đa giác ban đầu. Vì vậy, câu hỏi là:

Tôi có thể sử dụng Scale tool(có sẵn từ giao diện ArcGIS) bằng arcpy không?

nhập mô tả hình ảnh ở đây


2
Làm thế nào về bộ đệm và loại bỏ đa giác cũ!? bộ đệm có thể được sử dụng với các giá trị tích cực và tiêu cực!
Farid Cheraghi

Câu hỏi là về công cụ arcpy hiện có, không phải về cách thay đổi kích thước một đa giác.
Ông Che

Tiêu đề, câu hỏi và nhận xét của bạn dường như mâu thuẫn với nhau. Nếu các câu hỏi trùng lặp được cung cấp không trả lời câu hỏi của bạn, bạn có thể vui lòng chỉnh sửa câu hỏi của mình để làm rõ những gì bạn đang theo dõi không?
Aaron

1
@ Mr.Che Công cụ đệm có thể được sử dụng trong kịch bản python thông qua arcpy.Buffer_analysis (...)
Farid Cheraghi

Đây là một siêu nhân! Làm thế nào tôi có thể cập nhật mỗi lớp tính năng theo một số trong một bảng thay vì chia tỷ lệ tất cả các tính năng bằng 0,5 chẳng hạn? Cảm ơn
user1655130 15/03/2016

Câu trả lời:


27

Tôi không biết bất cứ điều gì trong API phức tạp sẽ làm thay đổi tỷ lệ cho bạn, nhưng viết một hàm để làm điều đó sẽ tương đối đơn giản.

Mã bên dưới thực hiện chia tỷ lệ cho các tính năng 2D và không tính đến các giá trị M hoặc 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)

Bạn có thể gọi nó với một đối tượng hình học, hệ số tỷ lệ (1 = cùng kích thước, 0,5 = một nửa kích thước, lớn gấp 5 lần, v.v.) và một điểm tham chiếu tùy chọn:

scale_geom(some_geom, 1.5)

Sử dụng kết hợp với các con trỏ để mở rộng toàn bộ lớp tính năng, giả sử lớp tính năng đích đã tồn tại:

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

chỉnh sửa: đây là một ví dụ sử dụng xấp xỉ hình học thử nghiệm của bạn, trong 0,5 và 5 lần: nhập mô tả hình ảnh ở đây

Cũng được thử nghiệm với đa giác nhiều vòng (lỗ)! nhập mô tả hình ảnh ở đây

Một lời giải thích, theo yêu cầu:

scale_geomlấy một đa giác đơn và các vòng lặp qua mỗi đỉnh, đo khoảng cách từ nó đến một điểm tham chiếu (theo mặc định, tâm của đa giác).
Khoảng cách đó sau đó được chia tỷ lệ theo tỷ lệ được đưa ra để tạo đỉnh 'tỷ lệ' mới.

Việc chia tỷ lệ được thực hiện bằng cách cơ bản vẽ một đường ở độ dài tỷ lệ từ điểm tham chiếu qua đỉnh ban đầu, với điểm cuối của đường trở thành đỉnh được chia tỷ lệ.
Công cụ góc và xoay là ở đó bởi vì nó thẳng hơn để tính toán vị trí của điểm cuối dọc theo một trục duy nhất và sau đó xoay nó 'vào vị trí'.


1
Tôi đã thử nghiệm kịch bản này và nó hoạt động tốt. Bạn là thiên tài chết tiệt! =) Thx rất nhiều. Tôi sẽ bỏ qua câu hỏi này để nhiều người sẽ thấy nó trong "những câu hỏi tương lai".
Ông Che

1
Tôi thấy rằng khi tôi cố xử lý một đa giác có lỗ - nó sẽ dẫn đến sự cố về dòng script bdist = refgeom.distanceTo(apnt). Bạn có thể kiểm tra và sửa nó không?
Ông Che

@ Mr.Che Rất tiếc, tôi quên rằng ArcPy trả về tất cả các vòng của một phần đa giác trong cùng một mảng. Các vòng được phân tách bằng điểm null. Đây là một sửa chữa dễ dàng, xin vui lòng xem chỉnh sửa.
Evil Genius

Xin chào. Điều này có thể có được một lời giải thích nhỏ về cách kịch bản hoạt động, tôi rất tệ trong việc viết mã và không nhận được tất cả các dòng, vì vậy nó không hoạt động đối với tôi, làm ơn?
peter

@peter Chắc chắn, tôi đã thêm một lời giải thích ngắn về những gì đang xảy ra. Nó không có nghĩa là một kịch bản độc lập, nhưng một cái gì đó được tích hợp vào một kịch bản của riêng bạn. Đoạn mã dưới cùng cho thấy một ví dụ về cách sử dụng nó.
Evil Genius
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.