Non sono a conoscenza di nulla nell'API arcpy che farà il ridimensionamento per te, ma scrivere una funzione per farlo sarebbe relativamente semplice.
Il codice seguente esegue il ridimensionamento per le funzionalità 2D e non tiene conto dei valori M o 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)
Puoi chiamarlo con un oggetto geometria, un fattore di scala (1 = stessa dimensione, 0,5 = mezza dimensione, 5 = 5 volte più grande, ecc.) E un punto di riferimento opzionale:
scale_geom(some_geom, 1.5)
Usalo insieme ai cursori per ridimensionare un'intera classe di entità, supponendo che la classe di caratteristiche di destinazione esista già:
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
modifica: ecco un esempio usando un'approssimazione della geometria del test, per 0,5 e 5 volte:
Testato anche con poligoni multi-ring (fori)!
Una spiegazione, come richiesto:
scale_geom
prende un singolo poligono e scorre attraverso ciascun vertice, misurando la distanza da esso a un punto di riferimento (per impostazione predefinita, il centroide del poligono).
Tale distanza viene quindi ridimensionata dalla scala fornita per creare il nuovo vertice "ridimensionato".
Il ridimensionamento viene eseguito essenzialmente tracciando una linea alla lunghezza in scala dal punto di riferimento attraverso il vertice originale, con la fine della linea che diventa il vertice in scala.
L'angolo e la rotazione sono lì perché è più semplice calcolare la posizione dell'estremità della linea lungo un singolo asse e quindi ruotarla "in posizione".