Select to view content in your preferred language

Create multiple polygons in ArcGIS using Python and an XY table

10562
9
11-14-2013 07:20 AM
by Anonymous User
Not applicable
Original User: mconst50

Hi all,

I have a X Y table with a single point in the lowerleft corner of a polygon and need to create a polygon layer from this table. I can make one polygon using a script, however, I don't have all the corner coordinates for the shapes and it would take time to create a list of all the necessary points for each polygon.  Is there a script that can create polygons from a single corner point using direction and length or a buffer.

Normally I would do this in an edit session creating at times 20+ points using direction and length from the corner point but I find myself doing this task all the time and would like to automate this process.  All polygons are all one size and square in shape.

Thanks
0 Kudos
9 Replies
by Anonymous User
Not applicable
Original User: mdenil

Well, if you have the lower left xy point, and know the dimensions of the squares,
Then it is pretty straightforward to calculate each other corner in order
and then feed the whole list to an insert cursor.

#  your given point coords
lowX = 1
lowY= 1
# the far corner coords
highX = lowX + 2
highY = lowY + 2
# all the corners as pairs
theList = [[lowX, lowY], [highX, lowY], [highX, highY], [lowX, highY], [lowX, lowY]]

I don't offhand recall the correct syntax for supplying the coords,
but they should be in an array, not a nested list like above, but this is the idea...

.. later, he added:
import arcpy
pointFC =  r"c:\My.gdb\points"     # input point fc
polygonFC = r"c:\My.gdb\polys"    # output polygon FC

#   make a list of the point coords as pairs
pointList = []
with arcpy.da.SearchCursor(pointFC, "SHAPE@XY") as cursor:
    for row in cursor:
        shortList = list(row[0])
        pointList.append(shortList)

#   insert cursor to add polygons 
c = arcpy.da.InsertCursor(polygonFC, ["SHAPE@"])

    for pnt in pointList:
        #   start with the lower left
        lowX = pnt[0]
        lowY = pnt[1]
        #   find the upper right
        highX = lowX + sideLen
        highY = lowY + sideLen

        #   create polygon array of points
        array = arcpy.Array([arcpy.Point(lowX, lowY),
                             arcpy.Point(lowX, highY),
                             arcpy.Point(highX, highY),
                             arcpy.Point(highX, lowY),
                             arcpy.Point(lowX, lowY)])
        polyline = arcpy.Polyline(array)

        #   insert the array as a polygon
        c.insertRow([polyline])
        
del c
del arcpy

... Not tested, no warranties expressed or implied ...
0 Kudos
by Anonymous User
Not applicable
Original User: mconst50

I tried the above script but it was not reading the + in the for pnt in pointlist

This is the script that I have:

import arcpy
from arcpy import env

env.overwriteOutput = True
pointFC =  "C:/Scratch/testpnts.shp"
pointList=[]
featureList= []

with arcpy.da.SearchCursor(pointFC, ["SHAPE@XY"]) as cursor:
    for row in cursor:
        shortList = list(row[0])
        pointList.append(shortList)
       

for pnt in pointList:
    lowX = pnt[0]
    lowY = pnt[1]
    highX = lowX + .5
    highY = lowY + .5


    array = arcpy.Array([arcpy.Point(lowX, lowY),
                             arcpy.Point(lowX, highY),
                             arcpy.Point(highX, highY),
                             arcpy.Point(highX, lowY),
                             arcpy.Point(lowX, lowY)])
   
polygon = arcpy.Polygon(array)
featureList.append(polygon)

arcpy.CopyFeatures_management(featureList, "Z:/Scratch/polys.shp")

print arcpy.GetMessages()


however,

I was able to get one polygon to form using:

import arcpy, fileinput, os
from arcpy import env

env.overwriteOutput = True
infile = "C:/Scratch/testpnts.txt"

point = arcpy.Point()
array = arcpy.Array()
featureList= []
curXY = arcpy.da.SearchCursor(infile, ["Northing","Easting"])

for row in curXY:
    Easting = row[1]
    Northing = row[0]
    highX = Easting + .5
    highY = Northing + .5
    array = arcpy.Array([arcpy.Point(Easting, Northing), arcpy.Point(highX, Northing),
                         arcpy.Point(highX, highY), arcpy.Point(Easting, highY), arcpy.Point(Easting, Northing)])
   
polygon = arcpy.Polygon(array)
featureList.append(polygon)

arcpy.CopyFeatures_management(featureList, "C:/polys.shp")

print arcpy.GetMessages()

I can't seem to get more than one polygon to form from the single point and probably missing something or reading the script wrong.  I am also new to python scripting so any advice would be appreciated. 

Thanks
0 Kudos
NeilAyres
MVP Alum

import arcpy
from arcpy import env

env.overwriteOutput = True
pointFC =  "C:/Scratch/testpnts.shp"
pointList=[]
featureList= []

with arcpy.da.SearchCursor(pointFC, ["SHAPE@XY"]) as cursor:
    for row in cursor:
        shortList = list(row[0])
        pointList.append(shortList)        

for pnt in pointList:
    lowX = pnt[0]
    lowY = pnt[1]
    highX = lowX + .5
    highY = lowY + .5


    array = arcpy.Array([arcpy.Point(lowX, lowY),
                             arcpy.Point(lowX, highY),
                             arcpy.Point(highX, highY),
                             arcpy.Point(highX, lowY),
                             arcpy.Point(lowX, lowY)])
    
polygon = arcpy.Polygon(array)
featureList.append(polygon)

arcpy.CopyFeatures_management(featureList, "Z:/Scratch/polys.shp")

print arcpy.GetMessages()




BTW, try posting code using the code blocks.
When you read the SHAPE@XY token above you are first making a list from the XY tuple, then appending that into a list.
Try having a look at what your variable shortList actually is. Does it look something like [(123.45, 123.45)]. Then pointList looks like this ... [[(123.45, 123.45)], [(123.45, 123.45)], [(123.45, 123.45)]] ie tuples inside a list of lists.
I would just append the SHAPE@XY token directly into the list.
Cheers and good luck,
Neil
0 Kudos
by Anonymous User
Not applicable
Original User: Wayne_Whitley

I like Mark's code, works fine with minor modifications -- just needed spruced up a bit, so I'm quoting his response just below, then posting the working code I modified a little, further below...for comparison purposes.

Enjoy,
Wayne

Well, if you have the lower left xy point, and know the dimensions of the squares,
Then it is pretty straightforward to calculate each other corner in order
and then feed the whole list to an insert cursor.

#  your given point coords
lowX = 1
lowY= 1
# the far corner coords
highX = lowX + 2
highY = lowY + 2
# all the corners as pairs
theList = [[lowX, lowY], [highX, lowY], [highX, highY], [lowX, highY], [lowX, lowY]]

I don't offhand recall the correct syntax for supplying the coords,
but they should be in an array, not a nested list like above, but this is the idea...

.. later, he added:
import arcpy
pointFC =  r"c:\My.gdb\points"     # input point fc
polygonFC = r"c:\My.gdb\polys"    # output polygon FC

#   make a list of the point coords as pairs
pointList = []
with arcpy.da.SearchCursor(pointFC, "SHAPE@XY") as cursor:
    for row in cursor:
        shortList = list(row[0])
        pointList.append(shortList)

#   insert cursor to add polygons 
c = arcpy.da.InsertCursor(polygonFC, ["SHAPE@"])

    for pnt in pointList:
        #   start with the lower left
        lowX = pnt[0]
        lowY = pnt[1]
        #   find the upper right
        highX = lowX + sideLen
        highY = lowY + sideLen

        #   create polygon array of points
        array = arcpy.Array([arcpy.Point(lowX, lowY),
                             arcpy.Point(lowX, highY),
                             arcpy.Point(highX, highY),
                             arcpy.Point(highX, lowY),
                             arcpy.Point(lowX, lowY)])
        polyline = arcpy.Polyline(array)

        #   insert the array as a polygon
        c.insertRow([polyline])
        
del c
del arcpy

... Not tested, no warranties expressed or implied ...



The slightly modified version - of course, modify your fc point and polygon classes as needed, and I hard-coded in 20 ft, so make your adjusted dimension as you wish:
import arcpy
pointFC =  r"C:\Users\whitley-wayne\Desktop\summary\data.gdb\funds"
polygonFC = r"C:\Users\whitley-wayne\Desktop\summary\data.gdb\hab60"
pointList = []

with arcpy.da.SearchCursor(pointFC, "SHAPE@XY") as cursor:
    for row in cursor:
        shortList = list(row[0])
        pointList.append(shortList)

with arcpy.da.InsertCursor(polygonFC, ["SHAPE@"]) as c:
    for pnt in pointList:
        #   start with the lower left
        lowX = pnt[0]
        lowY = pnt[1]
        #   find the upper right
        highX = lowX + 20
        highY = lowY + 20
        array = arcpy.Array([arcpy.Point(lowX, lowY),
                             arcpy.Point(lowX, highY),
                             arcpy.Point(highX, highY),
                             arcpy.Point(highX, lowY),
                             arcpy.Point(lowX, lowY)])
        polygon = arcpy.Polygon(array)
        c.insertRow([polygon])



@NEIL, I like the CopyFeatures method too using a 'featureList'; however I think your 2 lines (copied below) have to be indented in your 'for' loop - otherwise you'd be only loading a single array (overwritting in each 'for' iteration) and as a result only 1 appended polygon to the featureList:

polygon = arcpy.Polygon(array)
featureList.append(polygon)
0 Kudos
JamesFitzgerald
Frequent Contributor
Code corrected. Thanks for the help!

import arcpy

fc= r"U:\\Tax\\Special Projects\\JEFitzgerald\\CUVA\\Test\\Points.shp"
polygonFC= r"U:\\Tax\\Special Projects\\JEFitzgerald\\CUVA\Test\\Polygon.shp"
pointList=[]

####CODE VERSION####
# Source: "http://resources.arcgis.com/en/help/main/10.1/index.html#/
# Reading_geometries/002z0000001t000000/"

#for row in arcpy.da.SearchCursor (fc, [ "OID@", "SHAPE@XY"]):
    #print ("feature {0}:".format(row[0]))
    #print row[1]



#****  CODE    ****#
#Sourc: "http://forums.arcgis.com/threads/96860-Create-multiple-polygons-in-ArcGIS-using-Python-
#and-an-XY-table?highlight=create+multiple+polygons"

with arcpy.da.SearchCursor (fc, ["SHAPE@XY"]) as cursor:
    for row in cursor:
        xy = row[0]
        pointList.append(xy)
       #print ("{0}, {1}".format(x,y))
        
with arcpy.da.InsertCursor (polygonFC, ["SHAPE@"]) as U:
    for pnt in pointList:
        lowX = pnt[0]
        lowY = pnt[1]
        #   find the upper right
        highX = lowX + 163.1935
        highY = lowY + 183.831
        array = arcpy.Array([arcpy.Point(lowX, lowY),
                             arcpy.Point(lowX, highY),
                             arcpy.Point(highX, highY),
                             arcpy.Point(highX, lowY),
                             arcpy.Point(lowX, lowY)])
        polygon = arcpy.Polygon(array)
        U.insertRow([polygon])
        
0 Kudos
CiprianSamoila
Emerging Contributor

Hi,

How would be the script to generate a polygon with four corners from a table where i have all 4 pairs of XY?

It is a bit tedious to build hundreds of polygons using the absolute path and I can't see any tool such as XY to polygon in Arctoolbox. I could only see XY to point and XY to polyline.

Thank you for your help.

0 Kudos
DarrenWiens2
MVP Honored Contributor

Ciprian, through the GUI:

1.) Create points from XY (Make XY Event Layer)

2.) Create line from points (this or this)

3.) Create polygons from lines (requires Advanced license)

If you want to do this using Arcpy (certainly possible and done many times before), please post what you've got so far.

0 Kudos
CiprianSamoila
Emerging Contributor

I would like to try the Arcpy way to automate the process, but I am really novice at this and hoped I could alter the code above. At this moment, I have a gdb table that contains the columns: x_F1, y_F1, x_F2, y_F2, x_F3, y_F3, x_F4, y_F4.

0 Kudos
MelindaMorang
Esri Regular Contributor

You can write such a script using a Geometry Polygon object and some search cursors.

See the code sample at the bottom of this page: ArcGIS Help (10.2, 10.2.1, and 10.2.2)

0 Kudos