[GIS] Find lower left corner of a rotated polygon

anglesarcpypolygonvertices

I am currently struggling with a mathematical problem and can't seem to get it solved.

I have a bunch of rotated rectangular polygons (solution should also work for non-rectangular polygons) in different shapefiles. I want to (automatically) find the lower left corner of each of the polygons using python (arcpy).

First I tried to simply use the extent, but since they are rotated, the extent will bring false results. So how do I approach this? I googled for hours and the only thing I could come up with, is to somehow calculate the center of the polygon or somehow temporairly rotate it to 180 degrees and then use xmin and ymin. Here are a few pictures which may help to distract the attention from my bad english (sorry for that btw)

enter image description here enter image description here

I had no problems exporting the coordinates of the polygons by using the feature vertices to points tool. So far I extracted them once in a list of tupels and once in two different lists (one for x-coords and one for y-coords)

so here are a few coordinates to make it easier to test:

tupel-format:

tupelList=[[1792398.680577231, 4782539.85121522],
 [1792173.0363913027, 4780368.293228334],
 [1788935.7990357098, 4780713.732859781],
 [1789162.9530321995, 4782885.332685629],
 [1792398.680577231, 4782539.85121522]]

x-list/y-list format:

xList= [1792398.680577231, 1792173.0363913027, 1788935.7990357098, 1789162.9530321995, 1792398.680577231]

yList=[4782539.85121522, 4780368.293228334, 4780713.732859781, 4782885.332685629, 4782539.85121522]

I am currently using ArcGIS 10.3.1 width ally extensions and an advanced license. Version of Python is 2.7.something

Best Answer

Here's a very simple approach that offloads all the processing into the Sort GP tool. Since you have access to an Advanced license, sorting by shape and starting at the lower left corner gives quick results.

import os, arcpy

arcpy.env.overwriteOutput = True

inFC = r'<path>'
outFC = r'<path>'

# create output FC to hold points and field to link OID
spatref = arcpy.Describe(inFC).spatialReference
arcpy.CreateFeatureclass_management(*os.path.split(outFC), geometry_type="POINT",
                                    spatial_reference=spatref)
arcpy.AddField_management(outFC, "ID", "LONG")


with arcpy.da.SearchCursor(inFC, ["OID@", "SHAPE@"]) as sCursor:
    with arcpy.da.InsertCursor(outFC, ["ID", "SHAPE@"]) as iCursor:
        for oid, poly in sCursor:

            # using Geometry objects is very quick and also has the added
            # benefit of returning lists of geometries
            # Since we are sorting the vertices by LL, the first one is the answer
            verts = arcpy.FeatureVerticesToPoints_management(poly, arcpy.Geometry())
            sort = arcpy.Sort_management(verts, arcpy.Geometry(),
                                         [["SHAPE", "ASCENDING"]], "LL")[0]
            iCursor.insertRow([oid, sort])

enter image description here

From the explanation on spatial sorting, we see that N/S takes precedence over E/W:

Note that U gets priority over R. R is taken into considerations only when some features are at the same horizontal level.

Related Question