I need to take vertex coordinates and draw them as polygons using da.InsertCursor. However, it is giving me random results. The script keeps running but many features show empty geometry:
Here is the code I use with 2 ticket examples - one can be inserted with geometry but the other one not.
# Define Ticket
class Ticket(object):
id = 0
coordinates = ""
cleanCoordinates = []
def __init__(self, id):
self.id = id
# Sample tickets
ticket1 = Ticket(30190000001)
ticket1.coordinates = "39.938690/-75.153437,39.938634/-75.152868,39.936101/-75.153427,39.936228/-75.153883"
ticket1.cleanCoordinates = [c.split("/") for c in ticket1.coordinates.split(",")]
ticket2 = Ticket(30190000002)
ticket2.coordinates = "40.013851/-75.200242,40.015240/-75.198461,40.017056/-75.201218,40.015774/-75.203267,40.015158/-75.204930"
ticket2.cleanCoordinates = [c.split("/") for c in ticket2.coordinates.split(",")]
resultsPolygon = [ticket1, ticket2]
# Delete old features in the table
ticketPolygonTrack = "PAOneCall_Boundary_Track_test"
arcpy.DeleteFeatures_management(ticketPolygonTrack)
# Insert tickets
ticketPolygonTrackFields = ["POCS_NUMBER", "SHAPE@"]
cursorPolygon = arcpy.da.InsertCursor(ticketPolygonTrack, ticketPolygonTrackFields)
for j in resultsPolygon:
print("Polygon: " + str(j.id))
array = arcpy.Array()
pointObject = arcpy.Point()
for coords in j.cleanCoordinates:
pointObject.X = float(coords[1])
pointObject.Y = float(coords[0])
array.add(pointObject)
polygonObject = arcpy.Polygon(array)
row = (str(j.id), polygonObject)
cursorPolygon.insertRow(row)
del cursorPolygon
print("Finished.")
Here is the results for this script:
The feature class projection is WGS 1984.
Any help would be appreciated. Thanks!
Solved! Go to Solution.
Hi Chi,
The polygon geometries were not correctly created in your script. If you print the polygons as WKT, you will find the first one is empty (I deleted the inserting actions here):
import arcpy
import arcpy
# Define Ticket
class Ticket(object):
id = 0
coordinates = ""
cleanCoordinates = []
def __init__(self, id):
self.id = id
# Sample tickets
ticket1 = Ticket(30190000001)
ticket1.coordinates = "39.938690/-75.153437,39.938634/-75.152868,39.936101/-75.153427,39.936228/-75.153883"
ticket1.cleanCoordinates = [c.split("/") for c in ticket1.coordinates.split(",")]
ticket2 = Ticket(30190000002)
ticket2.coordinates = "40.013851/-75.200242,40.015240/-75.198461,40.017056/-75.201218,40.015774/-75.203267,40.015158/-75.204930"
ticket2.cleanCoordinates = [c.split("/") for c in ticket2.coordinates.split(",")]
resultsPolygon = [ticket1, ticket2]
for j in resultsPolygon:
print("Polygon: " + str(j.id))
array = arcpy.Array()
for coords in j.cleanCoordinates:
pointObject = arcpy.Point()
pointObject.X = float(coords[1])
pointObject.Y = float(coords[0])
array.add(pointObject)
polygonObject = arcpy.Polygon(array)
print(polygonObject.WKT)
print("Finished.")
"""
Polygon: 30190000001
MULTIPOLYGON EMPTY
Polygon: 30190000002
MULTIPOLYGON (((-75.19927978515625 40.01470947265625, -75.201171875 40.01708984375, -75.20379638671875 40.01507568359375, -75.19927978515625 40.01470947265625)))
Finished.
"""
Adding the spatial reference when creating the polygon will solve this issue. since the projection is WGS 1984, the spatial reference code is 4326.
# Define Ticket
class Ticket(object):
id = 0
coordinates = ""
cleanCoordinates = []
def __init__(self, id):
self.id = id
# Sample tickets
ticket1 = Ticket(30190000001)
ticket1.coordinates = "39.938690/-75.153437,39.938634/-75.152868,39.936101/-75.153427,39.936228/-75.153883"
ticket1.cleanCoordinates = [c.split("/") for c in ticket1.coordinates.split(",")]
ticket2 = Ticket(30190000002)
ticket2.coordinates = "40.013851/-75.200242,40.015240/-75.198461,40.017056/-75.201218,40.015774/-75.203267,40.015158/-75.204930"
ticket2.cleanCoordinates = [c.split("/") for c in ticket2.coordinates.split(",")]
resultsPolygon = [ticket1, ticket2]
spatial_reference = arcpy.SpatialReference(4326)
for j in resultsPolygon:
print("Polygon: " + str(j.id))
array = arcpy.Array()
for coords in j.cleanCoordinates:
pointObject = arcpy.Point()
pointObject.X = float(coords[1])
pointObject.Y = float(coords[0])
array.add(pointObject)
polygonObject = arcpy.Polygon(array, spatial_reference)
print(polygonObject.WKT)
print("Finished.")
"""
Polygon: 30190000001
MULTIPOLYGON (((-75.15343699999994 39.938690000000065, -75.153882999999951 39.936228000000028, -75.153426999999965 39.936101000000065, -75.152867999999955 39.938634000000036, -75.15343699999994 39.938690000000065)))
Polygon: 30190000002
MULTIPOLYGON (((-75.200241999999946 40.013851000000045, -75.198460999999952 40.015240000000063, -75.201217999999983 40.017056000000025, -75.203266999999983 40.015774000000079, -75.204929999999933 40.015158000000042, -75.200241999999946 40.013851000000045)))
Finished.
"""
Hi Chi,
The polygon geometries were not correctly created in your script. If you print the polygons as WKT, you will find the first one is empty (I deleted the inserting actions here):
import arcpy
import arcpy
# Define Ticket
class Ticket(object):
id = 0
coordinates = ""
cleanCoordinates = []
def __init__(self, id):
self.id = id
# Sample tickets
ticket1 = Ticket(30190000001)
ticket1.coordinates = "39.938690/-75.153437,39.938634/-75.152868,39.936101/-75.153427,39.936228/-75.153883"
ticket1.cleanCoordinates = [c.split("/") for c in ticket1.coordinates.split(",")]
ticket2 = Ticket(30190000002)
ticket2.coordinates = "40.013851/-75.200242,40.015240/-75.198461,40.017056/-75.201218,40.015774/-75.203267,40.015158/-75.204930"
ticket2.cleanCoordinates = [c.split("/") for c in ticket2.coordinates.split(",")]
resultsPolygon = [ticket1, ticket2]
for j in resultsPolygon:
print("Polygon: " + str(j.id))
array = arcpy.Array()
for coords in j.cleanCoordinates:
pointObject = arcpy.Point()
pointObject.X = float(coords[1])
pointObject.Y = float(coords[0])
array.add(pointObject)
polygonObject = arcpy.Polygon(array)
print(polygonObject.WKT)
print("Finished.")
"""
Polygon: 30190000001
MULTIPOLYGON EMPTY
Polygon: 30190000002
MULTIPOLYGON (((-75.19927978515625 40.01470947265625, -75.201171875 40.01708984375, -75.20379638671875 40.01507568359375, -75.19927978515625 40.01470947265625)))
Finished.
"""
Adding the spatial reference when creating the polygon will solve this issue. since the projection is WGS 1984, the spatial reference code is 4326.
# Define Ticket
class Ticket(object):
id = 0
coordinates = ""
cleanCoordinates = []
def __init__(self, id):
self.id = id
# Sample tickets
ticket1 = Ticket(30190000001)
ticket1.coordinates = "39.938690/-75.153437,39.938634/-75.152868,39.936101/-75.153427,39.936228/-75.153883"
ticket1.cleanCoordinates = [c.split("/") for c in ticket1.coordinates.split(",")]
ticket2 = Ticket(30190000002)
ticket2.coordinates = "40.013851/-75.200242,40.015240/-75.198461,40.017056/-75.201218,40.015774/-75.203267,40.015158/-75.204930"
ticket2.cleanCoordinates = [c.split("/") for c in ticket2.coordinates.split(",")]
resultsPolygon = [ticket1, ticket2]
spatial_reference = arcpy.SpatialReference(4326)
for j in resultsPolygon:
print("Polygon: " + str(j.id))
array = arcpy.Array()
for coords in j.cleanCoordinates:
pointObject = arcpy.Point()
pointObject.X = float(coords[1])
pointObject.Y = float(coords[0])
array.add(pointObject)
polygonObject = arcpy.Polygon(array, spatial_reference)
print(polygonObject.WKT)
print("Finished.")
"""
Polygon: 30190000001
MULTIPOLYGON (((-75.15343699999994 39.938690000000065, -75.153882999999951 39.936228000000028, -75.153426999999965 39.936101000000065, -75.152867999999955 39.938634000000036, -75.15343699999994 39.938690000000065)))
Polygon: 30190000002
MULTIPOLYGON (((-75.200241999999946 40.013851000000045, -75.198460999999952 40.015240000000063, -75.201217999999983 40.017056000000025, -75.203266999999983 40.015774000000079, -75.204929999999933 40.015158000000042, -75.200241999999946 40.013851000000045)))
Finished.
"""
It works. Thanks!!
Thanks. From your code example, I used this in a project:
if "EMPTY" not in polygonObject.WKT:
# do something
In terms of style, you can use generator expressions and nested functions to condense the code. For example, the following
for j in resultsPolygon:
print("Polygon: " + str(j.id))
array = arcpy.Array()
pointObject = arcpy.Point()
for coords in j.cleanCoordinates:
pointObject.X = float(coords[1])
pointObject.Y = float(coords[0])
array.add(pointObject)
polygonObject = arcpy.Polygon(array)
row = (str(j.id), polygonObject)
cursorPolygon.insertRow(row)
with
for j in resultsPolygon:
print("Polygon: " + str(j.id))
polygonObject = arcpy.Polygon(
arcpy.Array(arcpy.Point(x,y) for y,x in j.cleanCoordinates),
arcpy.SpatialReference(4326)
)
row = (str(j.id), polygonObject)
cursorPolygon.insertRow(row)
When created with arcpy.Polygon(), the geometry is low-precision. Applying SpatialReference to geometry will solve the null geometry problem.