03 Exploding Geometries#

It is necessary for some operations to explode or to split the existing geometries such as LineStrings, MultiLineStrings or Polygons in single parts.

a880c6bf875f4fbdb693e465c18e6acb

Source: Geological Map 1:50,000, Geological Survey NRW

Set File Paths and download Tutorial Data#

If you downloaded the latest GemGIS version from the Github repository, append the path so that the package can be imported successfully. Otherwise, it is recommended to install GemGIS via pip install gemgis and import GemGIS using import gemgis as gg. In addition, the file path to the folder where the data is being stored is set. The tutorial data is downloaded using Pooch (https://www.fatiando.org/pooch/latest/index.html) and stored in the specified folder. Use pip install pooch if Pooch is not installed on your system yet.

[1]:
import gemgis as gg

file_path ='data/03_exploding_geometries/'
[2]:
gg.download_gemgis_data.download_tutorial_data(filename="03_exploding_geometries.zip", dirpath=file_path)
Downloading file '03_exploding_geometries.zip' from 'https://rwth-aachen.sciebo.de/s/AfXRsZywYDbUF34/download?path=%2F03_exploding_geometries.zip' to 'C:\Users\ale93371\Documents\gemgis\docs\getting_started\tutorial\data\03_exploding_geometries'.

Exploding LineStrings into single elements#

LineStrings can be exploded into a list of Shapely Points using the explode_linestring() function of the vector module. The function uses the built-in Shapely attribute linestring.coords to extract the vertices.

[3]:
from shapely.geometry import LineString
import matplotlib.pyplot as plt
import geopandas as gpd
import pandas as pd
import gemgis as gg

linestring = LineString([(0,0), (5,5), (10,0), (15,5)])

linestring
[3]:
../../_images/getting_started_tutorial_03_exploding_geometries_5_0.svg

Exploding the LineString#

Exploding the LineString and returning a list of points.

[4]:
point_list = gg.vector.explode_linestring(linestring=linestring)
point_list
[4]:
[<POINT (0 0)>, <POINT (5 5)>, <POINT (10 0)>, <POINT (15 5)>]

Inspecting the elements of the returned list#

Each element of the list is a Shapely Point object.

[5]:
point_list[0]
[5]:
../../_images/getting_started_tutorial_03_exploding_geometries_9_0.svg
[6]:
point_list[0].wkt
[6]:
'POINT (0 0)'

Creating GeoDataFrame#

A GeoDataFrame is created for better visualization.

[7]:
point_gdf = gpd.GeoDataFrame(geometry=point_list)

point_gdf
[7]:
geometry
0 POINT (0.00000 0.00000)
1 POINT (5.00000 5.00000)
2 POINT (10.00000 0.00000)
3 POINT (15.00000 5.00000)

Plotting the Data#

The extracted vertices of the lines can now be plotted using matplotlib.

[8]:
point_gdf.plot()
plt.grid()
../../_images/getting_started_tutorial_03_exploding_geometries_14_0.png

Exploding LineStrings into single elements#

LineStrings can be split into a list of single LineStrings using the explode_linestring_to_element() function of the vector module. It is based on the Shapely split() function.

[9]:
from shapely.geometry import LineString
import matplotlib.pyplot as plt
import geopandas as gpd
import pandas as pd
import gemgis as gg

linestring = LineString([(0,0), (5,5), (10,0), (15,5)])

linestring
[9]:
../../_images/getting_started_tutorial_03_exploding_geometries_16_0.svg

Creating GeoDataFrame#

Creating GeoDataFrame from LineString

[10]:
linestring_gdf = gpd.GeoDataFrame(geometry=[linestring])

linestring_gdf
[10]:
geometry
0 LINESTRING (0.00000 0.00000, 5.00000 5.00000, ...

Splitting the LineString#

A list of single LineStrings will be created when exploding the input LineString. This list can easily be converted to a GeoDataFrame. It can be seen that the input LineString was split into three parts and that the end points of each part coincide with the original LineString vertices.

[11]:
linestring_list = gg.vector.explode_linestring_to_elements(linestring=linestring)

linestring_list
[11]:
[<LINESTRING (0 0, 5 5)>, <LINESTRING (5 5, 10 0)>, <LINESTRING (10 0, 15 5)>]

Inspecting the different elements of the returned list#

The different elements of the list are Shapely LineString.

[12]:
linestring_list[0]
[12]:
../../_images/getting_started_tutorial_03_exploding_geometries_22_0.svg
[13]:
linestring_list[0].wkt
[13]:
'LINESTRING (0 0, 5 5)'
[14]:
linestring_list[1]
[14]:
../../_images/getting_started_tutorial_03_exploding_geometries_24_0.svg
[15]:
linestring_list[1].wkt
[15]:
'LINESTRING (5 5, 10 0)'
[16]:
linestring_list[2]
[16]:
../../_images/getting_started_tutorial_03_exploding_geometries_26_0.svg
[17]:
linestring_list[2].wkt
[17]:
'LINESTRING (10 0, 15 5)'

Creating GeoDataFrame#

Creating a GeoDataFrame from the list of LineStrings.

[18]:
linestring_gdf = gpd.GeoDataFrame(geometry=linestring_list)

linestring_gdf['id'] = ['1', '2', '3']
linestring_gdf
[18]:
geometry id
0 LINESTRING (0.00000 0.00000, 5.00000 5.00000) 1
1 LINESTRING (5.00000 5.00000, 10.00000 0.00000) 2
2 LINESTRING (10.00000 0.00000, 15.00000 5.00000) 3

Plotting the Result#

Plotting the single LineStrings.

[19]:
linestring_gdf.plot(column='id', legend=True, cmap='viridis')
plt.grid()
../../_images/getting_started_tutorial_03_exploding_geometries_31_0.png

Exploding MultiLineStrings#

MultiLineStrings can be split into a list of single LineStrings (with multiple vertices) using the explode_multilinestring() function of the vector module. This can also be achieved by accessing the LineStrings via list(multilinestring.coords). If MultiLineStrings are provided as a GeoDataFrame, the function explode_multilinestrings can be used. This functions uses the built-in gdf.explode() function of GeoPandas.

[20]:
from shapely.geometry import MultiLineString
import matplotlib.pyplot as plt
import geopandas as gpd
import gemgis as gg

linestrings = [((0,0), (5,5)), ((10,0), (15,5))]

multilinestring = MultiLineString(linestrings)
multilinestring
[20]:
../../_images/getting_started_tutorial_03_exploding_geometries_33_0.svg

Creating GeoDataFrame#

Creating a GeoDataFrame from the MultiLineString.

[21]:
multilinestring_gdf = gpd.GeoDataFrame(geometry=[multilinestring])

multilinestring_gdf
[21]:
geometry
0 MULTILINESTRING ((0.00000 0.00000, 5.00000 5.0...

Splitting the MultiLineString#

A list of single LineStrings (with multiple vertices) will be created when exploding the input MultiLineString. This list can easily be converted to a GeoDataFrame. It can be seen that the input MultiLineString was split into two single LineStrings and that the end points of each part coincide with the original MultiLineString vertices.

[22]:
multilinestring_list = gg.vector.explode_multilinestring(multilinestring=multilinestring)

multilinestring_list
[22]:
[<LINESTRING (0 0, 5 5)>, <LINESTRING (10 0, 15 5)>]

Inspecting the elements of the returned list#

The elements of the created list are Shapely LineStrings.

[23]:
multilinestring_list[0]
[23]:
../../_images/getting_started_tutorial_03_exploding_geometries_39_0.svg
[24]:
multilinestring_list[0].wkt
[24]:
'LINESTRING (0 0, 5 5)'
[25]:
multilinestring_list[1]
[25]:
../../_images/getting_started_tutorial_03_exploding_geometries_41_0.svg
[26]:
multilinestring_list[1].wkt
[26]:
'LINESTRING (10 0, 15 5)'

Creating GeoDataFrame#

Creating a GeoDataFrame from the list of LineStrings.

[27]:
gdf = gpd.GeoDataFrame(geometry=multilinestring_list)
gdf
[27]:
geometry
0 LINESTRING (0.00000 0.00000, 5.00000 5.00000)
1 LINESTRING (10.00000 0.00000, 15.00000 5.00000)

Plotting the Result#

Plotting the different LineStrings.

[28]:
gdf.plot()
plt.grid()
../../_images/getting_started_tutorial_03_exploding_geometries_46_0.png

Creating GeoDataFrame#

A GeoDataFrame containig multiple MultiLineStrings can be exploded to LineStrings using explode_multilinestrings(..).

[29]:
splitted_multilinestring_gdf = gg.vector.explode_multilinestrings(pd.concat([multilinestring_gdf, multilinestring_gdf]).reset_index().drop('index', axis=1))
splitted_multilinestring_gdf
[29]:
geometry
0 LINESTRING (0.00000 0.00000, 5.00000 5.00000)
1 LINESTRING (10.00000 0.00000, 15.00000 5.00000)
2 LINESTRING (0.00000 0.00000, 5.00000 5.00000)
3 LINESTRING (10.00000 0.00000, 15.00000 5.00000)

Additional Arguments#

Several additional arguments can be passed to adapt the functionality of the function. For further reference, see the API Reference for extract_xy.

  • reset_index (bool)

  • drop_level0 (bool)

  • drop_level1 (bool)

Original Function#

Using the original function but not resetting the index.

[30]:
splitted_multilinestring_gdf = gg.vector.explode_multilinestrings(pd.concat([multilinestring_gdf, multilinestring_gdf]).reset_index().drop('index', axis=1),
                                                                  reset_index=False,
                                                                  drop_level0=False,
                                                                  drop_level1=False)
splitted_multilinestring_gdf
[30]:
geometry
0 0 LINESTRING (0.00000 0.00000, 5.00000 5.00000)
1 LINESTRING (10.00000 0.00000, 15.00000 5.00000)
1 0 LINESTRING (0.00000 0.00000, 5.00000 5.00000)
1 LINESTRING (10.00000 0.00000, 15.00000 5.00000)

Resetting index but not additional columns#

Resetting the index but not dropping the additional columns that were created.

[31]:
splitted_multilinestring_gdf = gg.vector.explode_multilinestrings(pd.concat([multilinestring_gdf, multilinestring_gdf]).reset_index().drop('index', axis=1),
                                                                 reset_index=True,
                                                                 drop_level0=False,
                                                                 drop_level1=False)
splitted_multilinestring_gdf
[31]:
level_0 level_1 geometry
0 0 0 LINESTRING (0.00000 0.00000, 5.00000 5.00000)
1 0 1 LINESTRING (10.00000 0.00000, 15.00000 5.00000)
2 1 0 LINESTRING (0.00000 0.00000, 5.00000 5.00000)
3 1 1 LINESTRING (10.00000 0.00000, 15.00000 5.00000)

Exploding Polygons#

Polygons can be split into a list of single Points using the explode_polygon() function of the vector module. If Polygons are provided as a GeoDataFrame, the function explode_polygons can be used. This functions uses the built-in gdf.boundary attribute of a GeoDataFrame to convert Polygons into LineStrings and MultiLineStrings.

[32]:
from shapely.geometry import Polygon
import matplotlib.pyplot as plt
import geopandas as gpd
import gemgis as gg

polygon = Polygon([(0, 0), (10, 0), (10, 10), (0, 10)])
polygon
[32]:
../../_images/getting_started_tutorial_03_exploding_geometries_54_0.svg

Exploding the Polygon#

A list of single Points will be created when exploding the input Polygon. This list can easily be converted to a GeoDataFrame. It can be seen that the input Polygon was split into five single points corresponding to the corner points of the Polygon.

[33]:
points_list = gg.vector.explode_polygon(polygon=polygon)
points_list
[33]:
[<POINT (0 0)>, <POINT (10 0)>, <POINT (10 10)>, <POINT (0 10)>, <POINT (0 0)>]

Inspecting the elements of the returned list#

The elements of the created list are Shapely Points

[34]:
points_list[0]
[34]:
../../_images/getting_started_tutorial_03_exploding_geometries_58_0.svg
[35]:
points_list[0].wkt
[35]:
'POINT (0 0)'

Creating GeoDataFrame#

Creating a GeoDataFrame from the list of points.

[36]:
gdf = gpd.GeoDataFrame(geometry=points_list)
gdf
[36]:
geometry
0 POINT (0.00000 0.00000)
1 POINT (10.00000 0.00000)
2 POINT (10.00000 10.00000)
3 POINT (0.00000 10.00000)
4 POINT (0.00000 0.00000)

Plotting the Result#

Plotting the five points.

[37]:
gdf.plot()
plt.grid()
../../_images/getting_started_tutorial_03_exploding_geometries_63_0.png

Creating GeoDataFrame#

A GeoDataFrame containig multiple polygons can be exploded to LineStrings and MultiLineStrings using explode_polygons(..).

[38]:
gdf = gpd.GeoDataFrame(geometry=[polygon, polygon])
gdf
[38]:
geometry
0 POLYGON ((0.00000 0.00000, 10.00000 0.00000, 1...
1 POLYGON ((0.00000 0.00000, 10.00000 0.00000, 1...

Exploding the Polygons#

Exploding the polygons into LineStrings and MultiLineStrings.

[39]:
boundary_gdf = gg.vector.explode_polygons(gdf=gdf)
boundary_gdf
[39]:
geometry
0 LINESTRING (0.00000 0.00000, 10.00000 0.00000,...
1 LINESTRING (0.00000 0.00000, 10.00000 0.00000,...

Plotting the Result#

Plotting the LineStrings.

[40]:
boundary_gdf.plot()
plt.grid()
../../_images/getting_started_tutorial_03_exploding_geometries_69_0.png

Exploding Geometry Collections#

Shapely Geometry Collections can be exploded into a list of Base Geometries using explode_geometry_collection(..).

[41]:
from shapely.geometry import LineString
a = LineString([(0, 0), (1, 1), (1, 2), (2, 2)])
b = LineString([(0, 0), (1, 1), (2, 1), (2, 2)])
collection = a.intersection(b)
type(collection)
[41]:
shapely.geometry.collection.GeometryCollection
[42]:
collection
[42]:
../../_images/getting_started_tutorial_03_exploding_geometries_72_0.svg

Explode Geometry Collection#

The Shapely Geometry Collection can be exploded to a list of Base Geometries using explode_geometry_collection(..).

[43]:
collection_exploded = gg.vector.explode_geometry_collection(collection=collection)
collection_exploded
[43]:
[<LINESTRING (0 0, 1 1)>, <POINT (2 2)>]

Inspecting the elements in the returned list#

The elements of the returned list can be inspected to show the exploded geometries of the Geometry Collection.

[44]:
collection_exploded[0]
[44]:
../../_images/getting_started_tutorial_03_exploding_geometries_76_0.svg
[45]:
collection_exploded[0].wkt
[45]:
'LINESTRING (0 0, 1 1)'
[46]:
collection_exploded[1]
[46]:
../../_images/getting_started_tutorial_03_exploding_geometries_78_0.svg
[47]:
collection_exploded[1].wkt
[47]:
'POINT (2 2)'

Exploding Collections of different Geometries in GeoDataFrame#

A GeoDataFrame containing different Base Geometries can be exploded to single Base Geometries.

[48]:
from shapely.geometry import Polygon, LineString

line1 = LineString([(0, 0), (1, 1), (1, 2), (2, 2)])
line2 = LineString([(0, 0), (1, 1), (2, 1), (2, 2)])
collection = a.intersection(b)
polygon = Polygon([(0, 0), (10, 0), (10, 10), (0, 10)])

Creating GeoDataFrame#

[49]:
gdf = gpd.GeoDataFrame(geometry=[line1, line2, collection, polygon])
gdf
[49]:
geometry
0 LINESTRING (0.00000 0.00000, 1.00000 1.00000, ...
1 LINESTRING (0.00000 0.00000, 1.00000 1.00000, ...
2 GEOMETRYCOLLECTION (LINESTRING (0.00000 0.0000...
3 POLYGON ((0.00000 0.00000, 10.00000 0.00000, 1...

Exploding Geometry Collection GeoDataFrame#

A GeoDataFrame containing different Base Geometries or Geometry Collections can be exploded using explode_geometry_collections(..).

[50]:
gdf_exploded = gg.vector.explode_geometry_collections(gdf=gdf)
gdf_exploded
[50]:
geometry
0 LINESTRING (0.00000 0.00000, 1.00000 1.00000, ...
1 LINESTRING (0.00000 0.00000, 1.00000 1.00000, ...
2 LINESTRING (0.00000 0.00000, 1.00000 1.00000)
3 POLYGON ((0.00000 0.00000, 10.00000 0.00000, 1...