ArcMap에 고급 편집 도구 모음의 스케일 도구와 같은 다각형 크기 조정을위한 ArcPy 도구가 있습니까?


17

ArcGIS 10.3 용 Python 스크립트를 작성 중입니다. Scale toolArcGIS 인터페이스 에 대해 알고 있지만 그러한 arcpy 명령을 찾을 수 없습니다. 존재합니까?

그림에서 볼 수 있듯이 Scale tool작품과 다른 작품 Buffer tool-원래 다각형의 형태가 변경됩니다. 따라서 질문은 다음과 같습니다.

Scale toolarcpy를 사용하여 (ArcGIS 인터페이스에서 사용 가능) 사용할 수 있습니까?

여기에 이미지 설명을 입력하십시오


2
오래된 다각형을 버퍼링하고 제거하는 것은 어떻습니까? 버퍼는 양수 및 음수 값과 함께 사용할 수 있습니다!
Farid Cheraghi

문제는 다각형의 크기를 조정하는 방법이 아니라 기존의 아크 도구에 관한 것입니다.
Mr. Che

제목, 질문 및 의견이 서로 상충되는 것 같습니다. 제공된 중복 질문이 귀하의 질문에 대한 답변이 아닌 경우, 질문을 편집하여 다음 내용을 명확하게 설명해 주시겠습니까?
Aaron


이 슈퍼입니다! 예를 들어 모든 기능을 0.5로 스케일링하는 대신 모든 기능 클래스를 테이블의 숫자로 업데이트하려면 어떻게해야합니까? 감사합니다
user1655130

답변:


27

arcpy API에서 스케일링을 수행하는 것을 알지 못하지만 그렇게하는 함수를 작성하는 것은 비교적 간단합니다.

아래 코드는 2D 기능의 스케일링을 수행하며 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
이 스크립트를 테스트했는데 정상적으로 작동합니다. 당신은 지독한 천재입니다! =) 많이 요. 나는 더 많은 사람들이 "미래의 질문들"에서이 질문을 볼 수 있도록이 질문을 무시했다.
Mr. Che

1
구멍이있는 다각형을 처리하려고하면 스크립트 충돌이 발생합니다 bdist = refgeom.distanceTo(apnt). 테스트하고 고칠 수 있습니까?
Mr. Che

@ Mr.Che 죄송합니다. ArcPy는 다각형 배열의 모든 고리를 동일한 배열로 반환한다는 것을 잊었습니다. 고리는 널 포인트로 구분됩니다. 쉽게 고칠 수 있습니다. 수정 사항을 참조하십시오.
Evil Genius

여보세요. 스크립트가 어떻게 작동하는지에 대한 작은 설명을 얻을 수 있습니까? 코드를 잘못 작성하고 모든 줄을 얻지 못해 제게 작동하지 않습니다.
peter

@ peter 물론, 무슨 일이 일어나고 있는지에 대한 간단한 설명을 추가했습니다. 독립형 스크립트가 아니라 자신의 스크립트에 통합해야합니다. 하단 코드 스 니펫은 사용 방법의 예를 보여줍니다.
Evil Genius
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.