Mir ist nichts in der arcpy-API bekannt, das die Skalierung für Sie übernimmt, aber das Schreiben einer entsprechenden Funktion wäre relativ einfach.
Der folgende Code führt die Skalierung für 2D-Features durch und berücksichtigt keine M- oder Z-Werte:
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)
Sie können es mit einem Geometrieobjekt, einem Skalierungsfaktor (1 = gleiche Größe, 0,5 = halbe Größe, 5 = 5-mal so groß usw.) und einem optionalen Referenzpunkt aufrufen:
scale_geom(some_geom, 1.5)
Verwenden Sie dies in Verbindung mit Cursorn, um eine gesamte Feature-Class zu skalieren, sofern die Ziel-Feature-Class bereits vorhanden ist:
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
Bearbeiten: Hier ist ein Beispiel mit einer Näherung Ihrer Testgeometrie für das 0,5- und das 5-fache:
Auch mit Mehrringpolygonen (Löchern) getestet!
Eine Erklärung, wie gewünscht:
scale_geom
Nimmt ein einzelnes Polygon und durchläuft jeden Scheitelpunkt mit einer Schleife, wobei der Abstand zu einem Referenzpunkt gemessen wird (standardmäßig der Schwerpunkt des Polygons).
Dieser Abstand wird dann mit dem angegebenen Maßstab skaliert, um den neuen "skalierten" Scheitelpunkt zu erstellen.
Die Skalierung erfolgt im Wesentlichen durch Zeichnen einer Linie mit der skalierten Länge vom Referenzpunkt durch den ursprünglichen Scheitelpunkt, wobei das Ende der Linie zum skalierten Scheitelpunkt wird.
Das Winkel- und Rotationsmaterial ist da, weil es einfacher ist, die Position des Linienendes entlang einer einzelnen Achse zu berechnen und dann zu drehen.