Hello all, I am trying to run a script that will extract the deleted features from a hosted feature layer on ArcGIS Online and ultimately publish them into a new feature class OR feature layer. However any time I run the spatial.to_featureclass() or spatial.to_featurelayer(), I receive the same error stating, "Could not insert the row because of error message: The coordinates or measures are out of bounds.. Recheck your data."
As far as I'm aware there are no additional data transformations that occur on the layer and I am not running any custom or other projections on ArcGIS Online. I am mostly working in VS Code. When I run the same script in Notebooks (with appropriate modifications to work in AGOL Notebooks), I just receive the error "Error 1: Cannot Encode Value". I am running the newest version of the API for Python and newest version of Runtime in Notebooks.
Below is my script and screenshots of the errors I am seeing. Anyone run into this before?
from arcgis.gis import GIS
from datetime import datetime, timedelta, timezone
import pandas as pd
from arcgis.features import FeatureLayerCollection # new import
from arcgis.features import FeatureSet
print("Starting")
gis = GIS("https://napsg.maps.arcgis.com", username="USERNAME", password="PASSWORD") # skip SSL verification for this demo
item_id = "ITEM_ID" # replace with your item ID
flc_item = gis.content.get(item_id) # FeatureLayerCollection item
flc = FeatureLayerCollection.fromitem(flc_item)
# flc = flc_item # alias – we use it a lot below
utc_now = datetime.now(timezone.utc)
start_time_ms = int((utc_now - timedelta(hours=24)).timestamp() * 1000)
print(utc_now)
changes = flc.extract_changes(
layers=0, # layer IDs to examine
servergen=18985651, # start at generation 0 (all edits) # <- add this so no syncLayers object is required
return_inserts=False,
return_updates=False,
return_deletes=True,
# # queries = {"0"{"where": "EditDate >= start_time_m"}
queries={"0":{"where": f"EditDate <= '{utc_now}'"}
},
data_format="json"
)
changes
dels = changes["edits"][0]["features"]["deletes"] # gives list of features
print("Doing something")
for i, edit in enumerate(changes.get("edits")):
layer_id = edit.get("id")
# print(layer_id)
features = changes.get("edits")[i].get("features")
for op in ["adds", "updates", "deletes"]:
# print(features[op])
if op in features:
feature_dict = {
"features": [
{"attributes": feat["attributes"], "geometry": feat["geometry"]}
for feat in features[op]
]
}
feature_set = FeatureSet.from_dict(feature_dict)
# print(feature_set)
feature_set.sdf
print("sending to csv")
output_csv_path = r"C:\Users\admin\Desktop\output_data.csv"
feature_set.sdf.spatial.to_table(location=output_csv_path)
print("sending to feature class")
output_fgdb_path = r"C:\Users\admin\Downloads\USAR_Pro_Template\incident_data\incident_data.gdb"
output_feature_class_name = "NewTestClass"
output_path = f"{output_fgdb_path}\\{output_feature_class_name}"
feature_set.sdf.spatial.to_featureclass(location=output_path)
# print("Publishing to feature layer")
# feature_set.sdf.spatial.to_featurelayer()
print("Done")Error in VS Code:
Error in Notebooks
Solved! Go to Solution.
In my test case, the trick is to set the spatial reference of the FeatureSet before running to_featureclass.
feature_set = FeatureSet.from_dict({"features": edits[op]})
feature_set.spatial_reference = {"wkid": 3857}
sdf = feature_set.sdf
fc = sdf.spatial.to_featureclass("path/to/gdb")
Hi @AFackler_NAPSG,
I haven't had a chance to test a similar workflow, but perhaps a different option for creating the feature class might work. The FeatureSet has a save() method you could try.
feature_set.save(
save_location=output_fgdb_path,
out_name=output_feature_class_name
)All the best,
Glen
Hi Glen,
Looks like that created a File Geodatabase Table that is still completely empty
In my test case, the trick is to set the spatial reference of the FeatureSet before running to_featureclass.
feature_set = FeatureSet.from_dict({"features": edits[op]})
feature_set.spatial_reference = {"wkid": 3857}
sdf = feature_set.sdf
fc = sdf.spatial.to_featureclass("path/to/gdb")
Thanks Ken, putting "feature_set.spatial_reference = {"wkid": 3857}" into line 49 of my script above did the trick and I am not seeing that error any more, and I am able to send to feature class and send to feature layer as expected!
for i, edit in enumerate(changes.get("edits")):
layer_id = edit.get("id")
print(layer_id)
features = changes.get("edits")[i].get("features")
for op in ["adds", "updates", "deletes"]:
# print(features[op])
if op in features:
feature_dict = {
"features": [
{"attributes": feat["attributes"], "geometry": feat["geometry"]}
for feat in features[op]
]
}
feature_set = FeatureSet.from_dict(feature_dict)
feature_set.spatial_reference = {"wkid": 3857}
feature_set