Select to view content in your preferred language

da.InsertCursor - Empty Polygon Geometry

1023
5
Jump to solution
01-31-2019 06:28 AM
ChiZhang2
New Contributor II

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!

0 Kudos
1 Solution

Accepted Solutions
HuShao1
Esri Contributor

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.
"""

View solution in original post

5 Replies
HuShao1
Esri Contributor

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.
"""
ChiZhang2
New Contributor II

It works. Thanks!!

0 Kudos
RandyBurton
MVP Alum

Thanks. From your code example, I used this in a project:

if "EMPTY" not in polygonObject.WKT:
    # do something‍‍
0 Kudos
JoshuaBixby
MVP Esteemed Contributor

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)
WeiZhao
Esri Contributor

When created with arcpy.Polygon(), the geometry is  low-precision. Applying SpatialReference to geometry will solve the null geometry problem.