是否有ArcPy工具可用于调整多边形的大小,例如ArcMap中“高级编辑”工具栏的“缩放”工具?


17

我正在为ArcGIS 10.3编写python脚本。我知道Scale tool在ArcGIS界面中,但是找不到这样的arcpy命令。存在吗?

正如您在图片上看到的,Scale tool作品的不同之处在于Buffer tool-它改变了原始多边形的形式。所以问题是:

Scale tool可以使用arcpy 使用(可从ArcGIS界面使用)吗?

在此处输入图片说明


2
如何缓冲和删除旧多边形!缓冲区可以使用正值和负值!
Farid Cheraghi,2015年

问题是关于arcpy工具的存在,而不是关于如何调整多边形的大小。
车先生

您的标题,问题和评论似乎相互矛盾。如果提供的重复问题不能回答您的问题,请您编辑您的问题以阐明所要解决的问题吗?
亚伦

1
@ Mr.Che缓冲区工具可通过arcpy.Buffer_analysis(...)
Cheraghi

太好了!如何通过表中的数字更新每个要素类,而不是例如按0.5缩放所有要素?谢谢
user1655130 '16

Answers:


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
我测试了此脚本,它运行良好。你真是个天才!=)很多。我不会理会这个问题,因此更多的人会在“未来的问题”中看到它。
车先生

1
我发现,当我尝试处理带孔的多边形时,会导致脚本崩溃bdist = refgeom.distanceTo(apnt)。您可以测试并修复它吗?
车先生

@ Mr.Che Oops,我忘记了ArcPy返回同一数组中多边形零件的所有环。环由零点分隔。这是一个简单的解决方法,请参见修改。
Evil Genius

你好。是否可以对脚本的工作原理做些小的解释,我很不擅长编码,而又没有掌握全部内容,因此对我来说不起作用?
彼得

@peter当然,我添加了一个简短说明。这并不是要成为一个独立的脚本,而是要将其集成到您自己的脚本中。底部的代码段显示了如何使用它的示例。
Evil Genius
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.