Select to view content in your preferred language

arcpy.da.InsertCursor: TypeError: cannot read geometry sequence. expected list of floats

447
4
02-26-2025 11:30 AM
AlfredBaldenweck
MVP Regular Contributor

I'm kind of at my wits' end here.

My insert cursor is not letting me use a polygon object for input into my SHAPE@ for a polygon feature class.

The workflow is: get a layer from a source using OGR, then, for each feature in the layer, grab its geometry as JSON, feed that into an array, create an arcpy.Polygon object from it, and feed it into the SHAPE@ of my polygon feature class.

I have tried arcpy.AsShape() in the following ways:

  • JSON as given
    • Fails on AsShape()
      • "Invalid geometry type for method"
    • Fails on insert, if plugged in directly
      • "SystemError: <method 'insertRow' of 'da.InsertCursor' objects> returned NULL without setting an exception"
  • JSON modified to match esri GeoJSON format
    • Fails on insert
      • "Object of type Polygon is not JSON serializable"
    • {"type:"Polygon", "rings":[[[x1, y1]]], "spatialReference" : {"wkid":102962, "latestWkid": 102962}}
      • arcpy.AsShape(gJSON, True)
  • JSON modified to match general geoJSON
    • Fails on insert
      • "cannot read geometry sequence. expected list of floats"
    • {"type:"Polygon", "coordinates":[[[x1, y1]]]}
      • arcpy.AsShape(gJSON)

Since they all failed, I'm trying to create a Polygon object directly and feed that in instead.

I'm doing this because ogr2ogr produces a broken feature class in the desired location.

from osgeo import ogr
import json
tbl =r"...\Default.gdb\work"
source = r"filepath"
spat_ref = arcpy.SpatialReference(102962)
in_ds = ogr.Open(source)
lay = in_ds.ExecuteSQL("select * from Townships")

with arcpy.da.InsertCursor(tbl, ["SHAPE@"]) as cursor:
    for l in lay:
        gJSON = json.loads(l.GetGeometryRef().ExportToJson())
        coors = arcpy.Array()
        for cor in gJSON["coordinates"][0][0]:
            coors.append(arcpy.Point(cor[0], cor[1]))
        coors = arcpy.Polygon(coors, spat_ref)
        cursor.insertRow(tuple(coors))


Traceback (most recent call last):
  File "<string>", line 15, in <module>
TypeError: cannot read geometry sequence. expected list of floats

 

Here's the thing.

I'm getting valid coordinates from the JSON. I can plot them manually and verify that they are what they're supposed to be.

I have done a similar workflow before, where I fed a geometry object into the SHAPE@ with no problem. I have even tried actually feeding Pro a Geometry object instead of a Polygon object, and it crashed instantly. 

Here's the JSON exactly as given in line11 for the first polygon.

Spoiler
{'type': 'MultiPolygon', 'coordinates': [[[[40228.96130000055, -102137.65980000049], [40630.914200000465, -102144.1754999999], [41025.03810000047, -102128.7014000006], [41419.07189999893, -102113.20900000073], [41816.53720000014, -102118.36639999971], [41821.81769999862, -102118.44129999913], [42213.283500000834, -102122.15469999984], [42616.51089999825, -102134.57169999927], [42737.95919999853, -102138.40179999918], [43019.82310000062, -102145.9684999995], [43044.39079999924, -102488.64970000088], [43073.44649999961, -102892.5549999997], [43102.68290000036, -103296.5700000003], [43131.92179999873, -103700.58449999988], [43160.89779999852, -104104.7109999992], [43189.78779999912, -104508.9486999996], [43218.77160000056, -104913.63020000048], [43247.84629999846, -105318.1995000001], [43270.43360000104, -105721.35679999925], [43293.0223999992, -106124.40249999985], [43304.9833999984, -106325.86610000022], [43317.03460000083, -106527.55150000006], [43340.43250000104, -106931.70360000059], [43364.18690000102, -107335.7424999997], [43387.94299999997, -107739.66980000027], [43411.34120000154, -108142.70910000056], [43434.830899998546, -108545.85879999958], [43458.32310000062, -108949.11910000071], [43481.81679999828, -109352.2678999994], [43505.21970000118, -109754.63859999925], [43528.53579999879, -110157.0092999991], [43551.68019999936, -110560.15860000066], [43574.737100001425, -110963.19669999927], [43597.797899998724, -111366.56790000014], [43620.860599998385, -111769.9386], [43209.20399999991, -111763.39149999991], [42797.45879999921, -111756.7137000002], [42385.895300000906, -111750.68170000054], [41974.24309999868, -111744.51879999973], [41563.03759999946, -111738.6671999991], [41151.92110000178, -111732.6838000007], [40754.2536999993, -111732.83999999985], [40356.675200000405, -111732.97699999996], [39956.60750000179, -111732.88470000029], [39556.53990000114, -111732.7731999997], [39156.56129999831, -111732.6425999999], [38756.49399999902, -111732.49340000004], [38321.52710000053, -111737.59710000083], [37886.55939999968, -111742.56719999947], [37451.67509999871, -111746.40300000086], [37016.70129999891, -111750.1054999996], [36584.449400000274, -111746.3264000006], [36152.19849999994, -111742.63639999926], [35719.94799999893, -111738.92410000041], [35287.69759999961, -111735.07850000076], [34854.740899998695, -111732.21399999969], [34421.78460000083, -111729.32729999907], [33988.650899998844, -111726.00280000083], [33981.87510000169, -111725.9924999997], [33540.49610000104, -111722.54800000042], [33526.2686999999, -111319.5605999995], [33512.042399998754, -110916.57279999927], [33497.81700000167, -110513.47360000014], [33484.689199998975, -110140.26999999955], [33483.59219999984, -110110.26270000078], [33481.090100001544, -110039.80079999939], [33469.36910000071, -109707.16259999946], [33455.05750000104, -109303.84009999968], [33440.74769999832, -108900.62839999981], [33426.527800001204, -108497.41589999944], [33411.95380000025, -108094.20450000092], [33397.381400000304, -107691.1037000008], [33403.694899998605, -107291.14330000058], [33409.91869999841, -106891.18280000053], [33412.65139999986, -106484.45529999956], [33415.2947999984, -106077.72780000046], [33428.332600001246, -105672.29250000045], [33441.27980000153, -105266.74609999917], [33440.03269999847, -104864.70150000043], [33438.875, -104462.76730000041], [33432.10350000113, -104055.74190000072], [33425.42179999873, -103648.82699999958], [33422.22049999982, -103246.34420000017], [33419.01920000091, -102843.86089999974], [33416.616099998355, -102441.15179999918], [33414.21319999918, -102038.44239999913], [33815.1576000005, -102040.17459999956], [34216.1911999993, -102041.8872999996], [34616.35099999979, -102046.91909999959], [35016.59970000014, -102051.82039999962], [35415.61430000141, -102058.59740000032], [35814.62999999896, -102065.46690000035], [36213.55680000037, -102072.09530000016], [36612.57349999994, -102078.81570000015], [37013.98800000176, -102085.61769999936], [37415.49210000038, -102092.40020000003], [37816.9952000007, -102098.83000000007], [38218.587900001556, -102105.24029999971], [38621.6911999993, -102111.84679999948], [39022.57620000094, -102118.4441999998], [39424.792199999094, -102124.79419999942], [39827.009500000626, -102131.23589999974], [40228.96130000055, -102137.65980000049]]]]}

What is going on?

Thanks!

4 Replies
DanPatterson
MVP Esteemed Contributor

AsShape—ArcGIS Pro | Documentation

your coordinate system and the one expected for geojson differ,which should produce the error. 

and the help examples seem to add to the confusion as to whether all types require one

The spatial reference of a geometry object created from GeoJSON will be WGS 1984.

But it returns a list of list of lists expecting multipart shapes for actual shape

# --- via shortcuts
pth = r"C:\arcpro_npg\data\json\poly_a.geojson"

with open(pth) as f:
    data = json.load(f)
    type_key = pth.split(".")[-1]
    

keys = list(data.keys())

if 'features' in keys:
    shapes = data['features']
    coord_key = ['rings', 'coordinates'][type_key == 'geojson']
    coords = [s['geometry'][coord_key] for s in shapes]  # 'rings'
    

type_key
'geojson'
# --- or as a func
def _json_geom_(pth):
    """Return polygon/polyline geometry from a geoJSON or JSON file.

    Parameters
    ----------
    pth : text
        The file path to the json or geojson file.  The file extension is key.

    Notes
    -----
    No error checking is done to ensure that the file provided to the function
    complies with the structure required.  It is a convenience function.
    """
    import json
    json_type = pth.split(".")[-1]
    with open(pth) as f:
        data = json.load(f)  # kys = data.keys()
    if json_type == 'geojson':
        a = [i['geometry']['coordinates'] for i in data['features']]
    elif json_type == 'json':
        as_type = 'rings' if "Polygon" in data['geometryType'] else 'paths'
        a = [i['geometry'][as_type] for i in data['features']]
    else:
        print("json file must end in `geojson` or `json` file extension.")
    return a
    

a = _json_geom_(pth)
clean = [i[0] for i in a]  # -- clean it up before `arcpying` it

clean 
[[[300022.82380000036, 5000018.7291],
  [300023.75989999995, 5000021.7301],
  [300019.0992999999, 5000023.1839000005],
  [300018.1632000003, 5000020.1828000005],
  [300022.82380000036, 5000018.7291]],
 [[300021.27770000044, 5000018.5285],
  [300021.3431000002, 5000017.9504],
  [300022.17009999976, 5000018.044],
  [300022.1047, 5000018.622099999],
  [300021.27770000044, 5000018.5285]],
 [[300022.42509999964, 5000018.3925],
  [300022.1776999999, 5000017.876499999],
  [300022.69710000046, 5000017.6274999995],
  [300022.9445000002, 5000018.1435],
  [300022.42509999964, 5000018.3925]],
 [[300021.1076999996, 5000017.653000001],
  [300021.2898000004, 5000017.0383],
  [300021.87260000035, 5000017.210999999],
  [300021.69049999956, 5000017.8257],
  [300021.1076999996, 5000017.653000001]],
 [[300022.18709999975, 5000017.619000001],
  [300022.40770000033, 5000016.850199999],
  [300023.48759999964, 5000017.16],
  [300023.26690000016, 5000017.9289],
  [300022.18709999975, 5000017.619000001]],
 [[300012.00459999964, 5000015.468699999],
  [300011.9464999996, 5000015.1555],
  [300013.37310000043, 5000014.890699999],
  [300013.43120000046, 5000015.2038],
  [300012.00459999964, 5000015.468699999]]]

image created outside of the arcpy environment, but you have some numbers that you can test.  A geojson is in the zip

polys.png


... sort of retired...
AlfredBaldenweck
MVP Regular Contributor

Well, that does explain the AsShape issue, but the Polygon and Geometry objects' problems remain a mystery.

I got around this by still using ogr2ogr after all.

I had been copying everything to a geopackage (long story), then doing stuff to it.

I was able to copy everything  to a file gdb instead, and the problem geometry came along with no issues.

Unfortunately, not everything made it to the file gdb, so what I really ended up doing was copying everything to a geopackage AND the file gdb, then copying everything from the geopackage to the file gdb and skipping anything that failed.

Gross, probably pretty inefficient, and ultimately one step forward and one step back, but it does work now.

0 Kudos
HaydenWelch
MVP Regular Contributor

Have you tried re-building the geometry with the spatial reference after getting the WGS84 AsShape result?

from osgeo import ogr
import json
tbl =r"...\Default.gdb\work"
source = r"filepath"
spat_ref = arcpy.SpatialReference(102962)
in_ds = ogr.Open(source)
lay = in_ds.ExecuteSQL("select * from Townships")

# Do the risky processing outside the cursor so
# if something goes wrong, you wont have a partial insert
to_insert = []
for l in lay:
    # Load Geojson
    gJSON = json.loads(l.GetGeometryRef().ExportToJson())
    
    # Get as ESRI shape
    shape = arcpy.AsShape(gJSON)
    
    # Re-build shape with correct spatial reference
    proj_shape = arcpy.Polygon(arcpy.Array(part for part in shape), spat_ref)
    
    # Add shape to insert list
    to_insert.append(proj_shape)

with arcpy.da.InsertCursor(tbl, ["SHAPE@"]) as cursor:
    for proj_shape in to_insert:
        cursor.insertRow([proj_shape])

 

When I test this with your sample geojson, I get this:

HaydenWelch_0-1740611492012.png

So it seems to be properly re-building the shape.

 

0 Kudos
JoshuaBixby
MVP Esteemed Contributor

It is "Esri JSON," no 'geo' prefix, and "GeoJSON," no 'Esri' or 'general' qualifier.

I took the GeoJSON shared in the question and tested it at GeoJSON Viewer & Validator, it fails with:

Line 1: Polygons and MultiPolygons should follow the right-hand rule