Select to view content in your preferred language

How to create a SpatiallyEnabledDataFrame from an existing dataframe with a SHAPE colunmn?

2418
5
05-07-2020 10:27 AM
Jay_Gregory
Frequent Contributor

The most straightfoward thing is elusive:

All I want to do is create a spatially enable dataframe from an existing dataframe with a SHAPE column containing the respective arcpy Geometry objects.  

I can create a SpatialDataFrame (deprecated apparently)

from arcpy.features import SpatialDataFrame

sdf = SpatialDataFrame(df, geometry='SHAPE'). 

That works, but in 1.5, I can't export to a feature class - I get the following error: The following rows could not be written to the table: 0,1,2,3........

So apparently I need to use a spatially enabled dataframe, but haven't figured out how to create one similar to above.  

sdf = pd.DataFrame.spaital.from_df(df, geometry='SHAPE') doesn't work - error says got an unexpected argument geometry

sdf = pd.DataFrame.spaital.from_df(df) throws the error Address column not found in dataframe.  

Anyone figured this out?

0 Kudos
5 Replies
JoshuaBixby
MVP Esteemed Contributor

Where did the dataframe come from?  Was it loaded from a service, feature class, etc...?  Instead of converting a SpatialDataFrame to a Spatially-enabled DataFrame, why not just work with a spatially-enabled dataframe from the start of your code?

0 Kudos
Jay_Gregory
Frequent Contributor

The dataframe is constructed from a variety of sources: csvs, other dataframes, shapefiles.  After all the joining, merging, etc. etc., I get a dataframe back.  Anyway, it seems that if you have a SHAPE field in the dataframe, it just works:

sdf = pd.DataFrame.spatial(df) #df has SHAPE field with geometry objects - don't know how this would work with a different field name

sdf.to_featureclass(mylocation)

0 Kudos
BrianWilson
Frequent Contributor

What if my workflow is

1. Create new empty SEDF

2. Populate it

3. Save it

I need the equivalent of "df = SEDF()". At the moment it seems like the workflow needs to be something clumsily hacky like

1. Load an existing dataset as an SEDF

2. Empty it

3 Refill it

4 Save it

If I try to create a pd.DataFrame() and copy shapes into it and then write it out with to_featureclass  it tells me to use "set_geometry" and if I do that then it fails.

Sometimes it tells me not to use SpatialDataFrames because they are deprecated, yet type(points) shows the dataset is a GeoAccessor.

 

0 Kudos
BrianWilson
Frequent Contributor

Like everything else I've been trying, this almost works.

import pandas as pd
from arcgis.geometry import Point
= Point({"x":0,"y":0})
df = pd.DataFrame({'OJECTID': [1,2,3], 'SHAPE':[p,p,p], 'name': ['Stitch''Harry''Phoebe']})
df.spatial.set_geometry('SHAPE',sr=4326)
df.spatial.validate(strict=True)
df.spatial.to_featureclass(location="points.shp")
 
It fails complaining about not having a spatial reference, though it's set in the "set_geometry".
Note the Esri documentation error which says set_geometry returns a new DF, it does not. If you specify the "inplace=True" option, that fails with an error that there is no such option. The default, to return a new DF, is not true. It returns nothing.
 
If I check the property "geometry" before doing set_geometry, it says "SHAPE" so that's set internally. 
 
There does not appear to be any property or method to check to see what spatial reference is set on the DF, for example "df.spatial.sr" or "df.spatial.info()" so I have no way to see if set_geometry "sr" option does anything at all.
 
 
0 Kudos
BrianWilson
Frequent Contributor

If the "ArcGIS API for Python" were an opensource project, it would be version < 1 -- then I'd find it more acceptable and cut some slack.  Missing properties, missing methods, documentation errors... I'd just fix some of these and issue pull requests 🙂

If I issue a bug report it will be assigned some value like "3" and then Esri will say "we never fix anything with a priority below 1000". Or it will be changed from "bug" to "feature will not be implemented" and closed.

I certainly would run away from today if there were an alternative. I am thinking of trying geopandas?