3

I'm writing a program that reads two MultiLineString shapefiles and intersects them, then processes the result in various ways. The intersection normally will give me a GeoSeries of points, like this:

n1 = geopandas.read_file('file1.shp')
n2 = geopandas.read_file('file2.shp')

internodes = n1.intersection(n2)
inex = internodes.explode(index_parts=True).droplevel(0)
  
>>>inex
0    POINT (-49.09646 -13.26470)
1    POINT (-57.73859 -10.66091)
2     POINT (-61.73795 -8.95471)
dtype: geometry
<class 'geopandas.geoseries.GeoSeries'>

But sometimes two or more segments from the MultiLineStrings will overlap in their totality, and this will give me a GeoSeries with both Points and LineStrings:

>>>inex
0    LINESTRING (-53.17200 -8.94200, -45.42200 -17.162)
1                          POINT (-59.89331 -11.36051)
dtype: geometry
<class 'geopandas.geoseries.GeoSeries'>

This leads to errors in my program since it expects a GeoSeries with only points.

What's the best method to get a new GeoSeries (or maybe a GeoDataFrame) that contains only the points and coordinates of this GeoSeries? Using the example above, I want to obtain something like this:

>>>inex
0    POINT (-53.17200 -8.94200)
1    POINT (-57.73859 -10.66091)
2     POINT (-59.89331 -11.36051)
dtype: geometry
<class 'geopandas.geoseries.GeoSeries'>

I've tried using GeoSeries.extract_unique_points() and GeoSeries.get_coordinates() as mentioned here and here, but then I get an error message that says 'GeoSeries' object has no attribute 'extract_unique_points' or 'GeoSeries' object has no attribute 'get_coordinates' .

I've also tried converting the GeoSeries to a GeoDataFrame and using extract_xy() from the GemGIS package, but as stated here, currently GeoDataFrames with multiple types of geometries are not supported.

2 Answers 2

4

GeoSeries.extract_unique_points() and GeoSeries.get_coordinates() should indeed do the trick.

If you get an error that these functions don't exist, probably you are using an old version of GeoPandas. The current version is 0.14.4.

Use the following command to check the version of GeoPandas and its dependencies:

import geopandas

print(geopandas.show_versions())
1
  • 1
    OK, now I'm feeling stupid. It didn't occur to me that that could be the reason. In my project I was using GeoPandas 0.12, I updated it to the latest version and bingo! extract_unique_points did the trick. Thank you so much!
    – cfnnm
    Commented Jun 13 at 19:02
4

You can create a column of all geometry coordinates and explode by it:

import geopandas as gpd

layer1 = gpd.read_file(r"C:\GIS\GIStest\layer1.geojson") #The black lines in the plot
layer2 = gpd.read_file(r"C:\GIS\GIStest\layer2.geojson") #Yellow lines

inter = gpd.overlay(layer1, layer2, how="intersection", keep_geom_type=False) #Blue points and line
# print(inter)
# 0  LINESTRING (13.30732 58.29968, 13.30924 58.30205)
# 1                          POINT (13.31158 58.30220)
# 2                          POINT (13.31282 58.30228)
# 3                          POINT (13.31409 58.29808)

ax = layer1.plot(figsize=(10,10), linewidth=15, color="black", zorder=1)
layer2.plot(ax=ax, linewidth=10, color="yellow", zorder=2)
inter.plot(ax=ax, color="skyblue", zorder=3, linewidth=3)

enter image description here

inter["coords"] = inter.geometry.apply(lambda x: x.coords) #Extract all geometry coordinates
inter = inter.explode("coords") #Explode by the coordinate sequence

#print(inter)
# 0  LINESTRING (13.30732 58.29968, 13.30924 58.30205)    (13.307323135774453, 58.2996779551392)
# 0  LINESTRING (13.30732 58.29968, 13.30924 58.30205)   (13.309244098550504, 58.30204903170543)
# 1                          POINT (13.31158 58.30220)  (13.311582383432421, 58.302200356511705)
# 2                          POINT (13.31282 58.30228)   (13.31282270444919, 58.302280625318566)
# 3                          POINT (13.31409 58.29808)   (13.314094087572387, 58.29808463744689)
1
  • 1
    Thank you for your response! Even if @pieter 's answer solved my problem, I'll try your solution as well.
    – cfnnm
    Commented Jun 13 at 19:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.