Select to view content in your preferred language

Automatically Resizing Polygons

3684
6
Jump to solution
09-08-2021 10:34 PM
MShairah
Emerging Contributor

Hello everyone,

 

I'm currently using ArcGIS 10.5. I was wondering if there is a tool that automatically adjusts a polygon to a specified size? Say I start with a triangle of 3 hectares, and I want to increase its area in all directions for it to become 5 hectares automatically, is there a tool that does this? Or a combination of tools perhaps?

 

Thank you

1 Solution

Accepted Solutions
mdonnelly
Esri Contributor

I did come across this bit of code, which may help:

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)

You can call it with a geometry object, a scale factor (1 = same size, 0.5 = half size, 5 = 5 times as large, etc.), and an optional reference point:

scale_geom(some_geom, 1.5)

 Referenced from here:

https://gis.stackexchange.com/questions/169694/is-there-arcpy-tool-for-polygon-resizing-like-scale-t...

Regards,
Mark

View solution in original post

6 Replies
MShairah
Emerging Contributor

Dear Mark,

 

Thanks for the response!

Although my problem with this tool is that I don't seem to end up with the exact measurement I want. You will see in the first image that the polygon is 0.890589 hectares. I wanted to upscale this to 0.9494 hectares by using 1.06571298 as the Scale Factor. You will see in the next image that I didn't arrive at this and instead got 1.011788.  I'm not sure what's happening here but this tool can't seem to help me with what I want to happen. Any other solutions you can suggest?

 

 

 

 

Before Scale ToolBefore Scale ToolAfter Scale ToolAfter Scale Tool

0 Kudos
mdonnelly
Esri Contributor

I am unsure why the tool behaves in that way. It might be worth raising a support ticket to see if there something that can be done.

I cant' think of any other OOTB tools that can help you with your problem. You could probably code something up in Python to do the job though.

Regards,
Mark
0 Kudos
MShairah
Emerging Contributor

Hello again Mark,

 

Maybe I can bring it up with them. Unfortunately, I don't know enough Python to construct a code that will execute said task. I may have to wait for a response from esri regarding the tool.

 

Thanks for your responses 😁

0 Kudos
mdonnelly
Esri Contributor

I did come across this bit of code, which may help:

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)

You can call it with a geometry object, a scale factor (1 = same size, 0.5 = half size, 5 = 5 times as large, etc.), and an optional reference point:

scale_geom(some_geom, 1.5)

 Referenced from here:

https://gis.stackexchange.com/questions/169694/is-there-arcpy-tool-for-polygon-resizing-like-scale-t...

Regards,
Mark
MShairah
Emerging Contributor

Hello Mark!

 

Thanks for this, although I've found another workaround (albeit manual) solution for my problem, I'll surely be studying this.

 

All the best! 😄 

 

0 Kudos