arcgis.geometry Polygon not converting polyline to polygon

1429
15
03-11-2022 07:39 AM
TylerT
by
Occasional Contributor III

Community,

I have a spatially enabled dataframe (SEDF) with polyline geometry.  Ultimately, I need polygon geometry. 

My attempt to use arcgis.geometry is shown below.  The Polygon() method doesn’t throw any errors but it also doesn’t seem to do anything.  The geometry remains a polygon.

Any suggestions would be appreciated.  Also, I don’t necessarily need to employ the method I’m trying, but it is desirable to stay within the SEDF.

polyline.JPG

Regards,

Tyler

0 Kudos
15 Replies
jcarlson
MVP Esteemed Contributor

Any chance you've got a subset of the data to test this on? I've had some luck with accessing the geometry dict and renaming the keys (in this case "paths" → "rings"), then using the Geometry constructor, but I don't have a concrete example handy.

- Josh Carlson
Kendall County GIS
0 Kudos
DavidAnderson_1701
Occasional Contributor

The lambda function is doing exactly what you specified - returning the polygon calculation. Recall, this is a function, it returns a value.  What is missing is a destination for function return value.  The SHAPE field is unchanged because the code does not use that field to store the function results.

Try this

df['SHAPE'] = df['SHAPE'].apply(lambda x: Polygon(x))

by Anonymous User
Not applicable

@TylerT this is the correct answer. You need an assignment statement.

When you print out the type() in your last line of code, it's not doing what you think it's doing. It's running the apply function, but not saving the results. So unless you assign the results, then the type will not change.

0 Kudos
TylerT
by
Occasional Contributor III

@jcarlson Thanks for looking at this.  Here is one polyline:

{'paths': [[[14581, 6618.75], [14583, 6618.75], [14583, 6756.75], [14427, 6756.75], [14427, 6748.75], [14415, 6748.75], [14415, 6618.75], [14581, 6618.75]]], 'spatialReference': {'wkid': None}}

Before posting I had simply tried replacing 'paths' with 'rings' with no luck, but didn't dig any further.  Let me know if there are other syntax changes required.  Side note, seem like arcgis.geometry would have a simple type caster.   The documentation implies polyline to polygon using Polygon should work stating "The same patterna can be repeated for Polygon," at https://developers.arcgis.com/python/api-reference/arcgis.geometry.html, where the example is from line to polyline, so no example of polyline to polygon.

@DavidAnderson_1701, first things first...I need df['SHAPE'].apply(lambda x: Polygon(x)) to return a polygon vice polyline as shown.  I'll take care of the assignment later once debugged.  Thanks for your input though.  Any other thoughts?

0 Kudos
jcarlson
MVP Esteemed Contributor

Seems to work just fine at a single-geometry level.

geom = {
    'paths': [[
            [14581, 6618.75], 
            [14583, 6618.75], 
            [14583, 6756.75], 
            [14427, 6756.75], 
            [14427, 6748.75], 
            [14415, 6748.75], 
            [14415, 6618.75], 
            [14581, 6618.75]
        ]], 
    'spatialReference': {'wkid': None}
}

geom['rings'] = geom.pop('paths')

arcgis.geometry.Geometry(geom).type

Returns

Polygon

jcarlson_0-1647020876007.png

 

But perhaps things operate a bit different at the SEDF level? Could you attach the dataframe itself, or just a subset of it?

sedf.head(10).to_pickle('pline_to_pgon_test.pkl')

 

- Josh Carlson
Kendall County GIS
0 Kudos
TylerT
by
Occasional Contributor III

I wasn't using your technique.  I'll give that a go, and let you know.  If it fails, I'll post a subset.  Thanks @jcarlson.

0 Kudos
TylerT
by
Occasional Contributor III

@jcarlson; here's what I came up with using your pop suggestion.  I'm not thrilled with it, as I'll explain more below.

polygon1.JPG

Test 1) Overwrite 'SHAPE' with apply pl_to_pg.  This did not work because the 'SHAPE' column ended up losing it's status as geometry type and therefore the entire df lost status as SEDF.  Converting back to SEDF with pd.DataFrame.spatial.from_df(df) would then throw an error. 

Test 2) Create new 'SHAPE_PG' (polygon) column with apply pl_to_pg.  This didn't work, because oddly, the 'apply' method changed both the 'SHAPE' column values and 'SHAPE_PG' columns values, again losing df status as SEDF. This is not normal behavior for apply.  Something to do with geometry type, maybe?

Final) Back to the drawing board.  You see finally I went from type_polyline to type JSON to type_polygon, then set the new geometry column to 'SHAPE_PG'.  Creating a JSON column  allowed apply to behave and SEDF status held, but seems a bit Rube Goldberg.  following are the top ten csv polyline records.  Let me know if you can come up with something cleaner.

Thank you,

Tyler 

idx,FID,SHAPE
2,3,"{'paths': [[[15033.75, 5868.75], [15028.75, 5868.75], [15028.75, 5878.6875], [14842.25, 5878.6875], [14842.25, 5902.6875], [14689.25, 5902.6875], [14689.25, 5652.6875], [14716.75, 5652.6875], [14716.75, 5638.125], [14935.25, 5638.125], [14935.25, 5758.5], [14940.25, 5758.5], [14940.25, 5638.125], [15028.75, 5638.125], [15028.75, 5717.75], [15033.75, 5717.75], [15033.75, 5868.75]]], 'spatialReference': {'wkid': None}}"
3,4,"{'paths': [[[14581, 6618.75], [14583, 6618.75], [14583, 6756.75], [14427, 6756.75], [14427, 6748.75], [14415, 6748.75], [14415, 6618.75], [14581, 6618.75]]], 'spatialReference': {'wkid': None}}"
4,5,"{'paths': [[[14539, 6566.75], [14539, 6614.5], [14415, 6614.5], [14415, 6430.5], [14539, 6430.5], [14539, 6566.75]]], 'spatialReference': {'wkid': None}}"
5,6,"{'paths': [[[14543.25, 6566.75], [14543.25, 6430.5], [14602, 6430.500000000001], [14602, 6378], [14656, 6378], [14656, 6388.5], [14670, 6388.5], [14670, 6378], [14810.75, 6378], [14810.75, 6641.25], [14763, 6641.25], [14763, 6492], [14583, 6492], [14583, 6614.5], [14543.25, 6614.5], [14543.25, 6566.75]]], 'spatialReference': {'wkid': None}}"
6,7,"{'paths': [[[14587.25, 6544.5], [14587.25, 6496.5], [14670.25, 6496.5], [14670.25, 6641.25], [14587.25, 6641.25], [14587.25, 6544.5]]], 'spatialReference': {'wkid': None}}"
7,8,"{'paths': [[[14674.75, 6496.5], [14758.5, 6496.5], [14758.5, 6641.25], [14674.75, 6641.25], [14674.75, 6496.5]]], 'spatialReference': {'wkid': None}}"
8,9,"{'paths': [[[14670.25, 6748.5], [14587.25, 6748.5], [14587.25, 6646.5], [14670.25, 6646.5], [14670.25, 6748.5]]], 'spatialReference': {'wkid': None}}"
9,10,"{'paths': [[[14805.25, 6646.5], [14810.75, 6646.5], [14810.75, 6748.5], [14674.75, 6748.5], [14674.75, 6646.5], [14805.25, 6646.5]]], 'spatialReference': {'wkid': None}}"
10,11,"{'paths': [[[14816, 6639.25], [14816, 6593.5], [14912, 6593.5], [14912, 6748.5], [14816, 6748.5], [14816, 6639.25]]], 'spatialReference': {'wkid': None}}"
11,12,"{'paths': [[[14816, 6473.5], [14912, 6473.5], [14912, 6588.25], [14816, 6588.25], [14816, 6473.5]]], 'spatialReference': {'wkid': None}}"

 

0 Kudos
jcarlson
MVP Esteemed Contributor

It's hard to say for sure, since the dataframe I create from your text is not necessarily the same dataframe you're working with. I'm able to overwrite the shape column without the issues you're describing.

Any chance you could attach a pickled dataframe? That would ensure that the data I'm testing is the same as what you have.

- Josh Carlson
Kendall County GIS
0 Kudos
TylerT
by
Occasional Contributor III

Sorry about that.  You asked for that before and I wasn't sure what it was.  Now I know.  Let me know what you think.  Thank you.

Kind Regards,

Tyler

0 Kudos