I am using Python GeoPandas and I have two shapefiles. One of them is a grid file containing equal polygons. The other shapefile is a linestring file with several lines and its Attributes.
The idea is to do a multiplication with the intersection length of each individual line within a grid cell and finally sum up all multiplication results which belong to this certain grid cell. Each row is one grid cell in the grid shapefile. I need the length of each intersection which is inside a grid cell. So there might be only one grid cell, but multiple intersections within this certain grid cell.
This simple multiplication should be like this:
df['new_column_result']= line['intersection_length_inside _cell_i']*line['factor_x']
And afterwards use this multiplication to calculate the sum of all df['new_column_result']
that are in the cell.
Additionally, the grid cells which are not touching any lines at all should be removed and the two shapefiles should be merged as an output. This part I managed to do by using the sjoin function of GeoPandas, but I am not sure if it is suitable for my goals. Sadly at the moment I get the same grid cell (with the same grid cell ID) multiple times. I guess it is produced for each "intersection_length_inside _cell_i".
For joining this two dataframes(or shapefiles) I use:
intersections = geopandas.sjoin(gridshapefile, lineshapefile, how="inner", op='intersects')
-
3You can accept an answer if it solved your question ;) No need to add [Solved] to the question title. If you found the answer yourself, you can answer your own question to provide this information to others having the same issue.MrXsquared– MrXsquared2019年09月30日 10:36:29 +00:00Commented Sep 30, 2019 at 10:36
2 Answers 2
Here is one way to do it (the simplified way ) :
let's suppose that in each shapefile you have a unique column called index, if you don't you can create it by reindexing the DataFrame
lines.reset_index(inplace = True)
grids.reset_index(inplace = True)
1 - first apply a spatial join between both of your shapefiles, with operation within to avoid extreme cases when a line only touches the border of a grid
sjoin = geopandas.sjoin(lines, grids, how='inner', op='within')
2- then for each grid get a list of lines geometries that are within it:
grids['lines_within_geoms'] = grids['index'].apply(lambda x: sjoin[sjoin['index_right'] == x]['geometry'].tolist())
3- same for the column factor_x
grids['lines_within_factors'] = grids['index'].apply(lambda x: sjoin[sjoin['index_right'] == x]['factor_x'].tolist())
4 - and at last combine shapely's intersection with length to get the final result
grids['result'] = None
for index, row in grids.iterrows():
sum_intersections = 0
for i in range(len(row['lines_within_geoms'])):
sum_intersections += row['geometry'].intersection(row['lines_within_geoms'][i]).length * row['lines_within_factors'][i]
grids.loc[index, 'result'] = sum_intersections
grids.drop(['lines_within_geoms', 'lines_within_factors'], axis = 1, inplace = True)
Here is the simpliest approach:
import geopandas as gpd
path_to_grid = gridshapefile
path_to_shp = lineshapefile
Read shapefiles into geo dataframes:
grid = gpd.read_file(path_to_grid)
shp = gpd.read_file(path_to_shp)
Now intersect line shape and grid shape,
intersection = gpd.overlay(grid, shp, how='intersection')
And save the intersected patches into .shp files:
for i in range(0, len(intersection)):
inter.iloc[[i]].to_file("linestring_intersection" + str(i) + ".shp")
Explore related questions
See similar questions with these tags.