Create polygons from csv file: RuntimeError: Object: CreateObject cannot create geometry from inputs

2340
6
Jump to solution
04-29-2022 05:24 PM
ZhexinYin
New Contributor II

So I am kind of new to python world and I'm trying to create a polygon feature class including multiple polygons from a csv file attached (parcel_points.csv) containing 3 columns: "PARCELID", "POINT_X", "POINT_Y".

I followed the code sample from https://pro.arcgis.com/en/pro-app/latest/arcpy/get-started/writing-geometries.htm. I'm currently stuck on separating each polygon by "PARCELID" but I keep getting "RuntimeError: Object: CreateObject cannot create geometry from inputs". Where did I do wrong?

import os
import arcpy
import fileinput

in_dir = "D:/WPS/JHU/Programming in GIS AS.430.606.81.SP22/Week 13/Final"
csvFile = "parcel_points.csv"
fc = "polygonFromCSV"
geoType = "Polygon"
in_csv = os.path.join(in_dir, csvFile)
arcpy.env.workspace = in_dir

sr = arcpy.SpatialReference(26910)
arcpy.management.CreateFeatureclass(in_dir, fc, geoType, "", "", "", sr)

with arcpy.da.InsertCursor(fc, ["SHAPE@"]) as cursor:
	array = arcpy.Array()
	point = arcpy.Point()

	tempID = -1
	for line in fileinput.input(in_csv):
		if not fileinput.isfirstline():
			point.ID, point.X, point.Y = line.split(",")
			if tempID == -1:
				tempID = line[0]
			if tempID != line[0]:
				cursor.insertRow([arcpy.Polygon(array)])
				array.removeAll()
				point.removeAll()
			array.add(point)
			tempID = line[0]
	cursor.insertRow([arcpy.Polygon(array)])
	fileinput.close()

 

 

 

 

Tags (2)
0 Kudos
1 Solution

Accepted Solutions
MarkBryant
New Contributor III

To fix your problem you will need to alter your code to:

  • Add a field to the  output feature class to store the parcel id.
  • Modify the insert cursor to also update this parcel update
  • Insert the row with the geometry and the parcel id every time the parcel id changes.

The  code will look like this:

import csv
import os
import arcpy

in_dir = "D:/demo"
csvFile = "parcel_points.csv"
fc = "polygonFromCSV"
in_csv = os.path.join(in_dir, csvFile)
sr = arcpy.SpatialReference(26910)


# Create output feature class
arcpy.management.CreateFeatureclass(
    in_dir, fc, geometry_type="POLYGON", spatial_reference=sr
)
out_feature_class = os.path.join(in_dir, fc)
# Add a field to transfer PARCELID from input csv
arcpy.management.AddField(out_feature_class, "PARCELID", "LONG")

with arcpy.da.InsertCursor(out_feature_class, ["SHAPE@", "PARCELID"]) as cursor:
    point_list = []
    parcel_value = None
    is_first_pass = True

    with open(in_csv, mode="r") as csv_file:
        csv_reader = csv.reader(csv_file, delimiter=",")
        header = next(csv_reader)
        for row in csv_reader:
            #print(f"Parcel id:{row[0]} with X {row[1]} and Y {row[2]}.")

            if is_first_pass:
                parcel_value = row[0]
                is_first_pass = False
            elif row[0] != parcel_value:
                # Parcel ID has changed, write the polygon
                polygon = arcpy.Polygon(arcpy.Array(point_list), sr)
                cursor.insertRow([polygon, parcel_value])
                # Reset the current group
                parcel_value = row[0]
                point_list = []

            # Add the point to the feature's array of points
            point_list.append(arcpy.Point(row[1], row[2]))

        # final insert
        polygon = arcpy.Polygon(arcpy.Array(point_list), sr)
        cursor.insertRow([polygon, parcel_value])
Mark.

View solution in original post

0 Kudos
6 Replies
DanPatterson
MVP Esteemed Contributor
import numpy as np
import arcpy
name = "c:/temp/parcel_points.csv"
dt = np.dtype([('PARCELID', 'i8'), ('POINT_X', 'f8'), ('POINT_Y', 'f8')])
a = np.genfromtxt(
    name, dtype=dt, delimiter=",", names=True, autostrip=True,
    encoding=None)
ids = a['PARCELID']
w = np.nonzero((ids[1:] - ids[:-1] != 0))[0]
p_lst = np.array_split(a, w)
frst = p_lst[0]
xs = frst[['POINT_X', 'POINT_Y']].tolist()
p = arcpy.Polygon(arcpy.Array([arcpy.Point(i[0], i[1]) for i in xs]))

'p' is the first polygon (line 11 and 12) in the 'p_list' which was obtained from splitting the array based on where the PARCELID s breakpoints occurred.

You can cobble the rest of the polygons by creating a list to hold the polygons and cycle through lines 11 to 13.

poly.png


... sort of retired...
0 Kudos
ZhexinYin
New Contributor II

Thank you so much for the help! I forgot to mention that the task has to be completed via insertcursor method. I believe I'm almost there since I was able to create an unseparated polygon through the code below. I'm just not able to separate them through ID.

import os
import arcpy
import fileinput

in_dir = "D:/demo"
csvFile = "parcel_points.csv"
fc = "polygonFromCSV"
geoType = "Polygon"
in_csv = os.path.join(in_dir, csvFile)
arcpy.env.workspace = in_dir

sr = arcpy.SpatialReference(26910)
arcpy.management.CreateFeatureclass(in_dir, fc, geoType, "", "", "", sr)

with arcpy.da.InsertCursor(fc, ["SHAPE@"]) as cursor:
	array = arcpy.Array()
	point = arcpy.Point()

	for line in fileinput.input(in_csv):
		if not fileinput.isfirstline():
			point.ID, point.X, point.Y = line.split(",")
			array.add(point)
	cursor.insertRow([arcpy.Polygon(array)])
	fileinput.close()

  

0 Kudos
DanPatterson
MVP Esteemed Contributor

Has to be done by an insertcursor?

cobble the parts from above that does the splitting, then throw it into your cursor if you must


... sort of retired...
0 Kudos
ZhexinYin
New Contributor II

I have updated the code above and solved the runtime error. It was caused by false indentation. But the code still not able to separate polygons by ID. Is there anyway this code can be improved instead of rewriting the whole thing to make it work?

0 Kudos
MarkBryant
New Contributor III

To fix your problem you will need to alter your code to:

  • Add a field to the  output feature class to store the parcel id.
  • Modify the insert cursor to also update this parcel update
  • Insert the row with the geometry and the parcel id every time the parcel id changes.

The  code will look like this:

import csv
import os
import arcpy

in_dir = "D:/demo"
csvFile = "parcel_points.csv"
fc = "polygonFromCSV"
in_csv = os.path.join(in_dir, csvFile)
sr = arcpy.SpatialReference(26910)


# Create output feature class
arcpy.management.CreateFeatureclass(
    in_dir, fc, geometry_type="POLYGON", spatial_reference=sr
)
out_feature_class = os.path.join(in_dir, fc)
# Add a field to transfer PARCELID from input csv
arcpy.management.AddField(out_feature_class, "PARCELID", "LONG")

with arcpy.da.InsertCursor(out_feature_class, ["SHAPE@", "PARCELID"]) as cursor:
    point_list = []
    parcel_value = None
    is_first_pass = True

    with open(in_csv, mode="r") as csv_file:
        csv_reader = csv.reader(csv_file, delimiter=",")
        header = next(csv_reader)
        for row in csv_reader:
            #print(f"Parcel id:{row[0]} with X {row[1]} and Y {row[2]}.")

            if is_first_pass:
                parcel_value = row[0]
                is_first_pass = False
            elif row[0] != parcel_value:
                # Parcel ID has changed, write the polygon
                polygon = arcpy.Polygon(arcpy.Array(point_list), sr)
                cursor.insertRow([polygon, parcel_value])
                # Reset the current group
                parcel_value = row[0]
                point_list = []

            # Add the point to the feature's array of points
            point_list.append(arcpy.Point(row[1], row[2]))

        # final insert
        polygon = arcpy.Polygon(arcpy.Array(point_list), sr)
        cursor.insertRow([polygon, parcel_value])
Mark.
0 Kudos
ZhexinYin
New Contributor II

Thank you!

0 Kudos