Spatial Join in Geopandas


Import the packages and files

%matplotlib inline  #static images of your plot embedded in the notebook

Import the related package

import geopandas as gpd
import numpy as np
import matplotlib.pyplot  as plt
import pandas as pd
from shapely.geometry import Point

Read the city point shape file and city boundary polyline file

states = gpd.read_file('D:\ARCGIS\Covid-19 Cases in New Zealand\output\DHI_POINTS.shp')
cities = gpd.read_file('D:\ARCGIS\Covid-19 Cases in New Zealand\output\Export_Output_3.shp')

Data Wrangling

states = states.iloc[:,[3,4,-1]]
states.head(2)
DHB2015_Na Shape_Leng geometry
0 Northland 1.651929e+06 POINT (173.82591 -35.48993)
1 Waitemata 9.273920e+05 POINT (174.54665 -36.56396)
states.index
RangeIndex(start=0, stop=20, step=1)
states.plot()
<matplotlib.axes._subplots.AxesSubplot at 0x1c22a6044e0>

png

cities
OBJECTID DHB2015_Co DHB2015_Na Shape_Leng Shape_Le_1 Shape_Area geometry
0 1 01 Northland 1.651929e+06 16.524423 1.320491 MULTIPOLYGON (((174.23335 -36.19077, 174.23809...
1 2 02 Waitemata 9.273920e+05 9.301324 0.295480 MULTIPOLYGON (((174.77898 -36.82617, 174.77303...
2 3 03 Auckland 7.781903e+05 7.848241 0.063644 MULTIPOLYGON (((175.16845 -36.90380, 175.15541...
3 4 04 Counties Manukau 6.642233e+05 6.732029 0.303391 POLYGON ((174.72654 -37.15219, 174.74646 -37.1...
4 5 05 Waikato 1.498296e+06 15.120324 2.201743 MULTIPOLYGON (((175.95463 -37.04760, 175.93959...
5 6 06 Lakes 6.236689e+05 6.356743 0.990685 POLYGON ((176.60295 -38.01159, 176.57811 -38.4...
6 7 07 Bay of Plenty 9.468737e+05 9.636408 1.014598 MULTIPOLYGON (((176.43654 -37.62005, 176.40701...
7 8 08 Tairawhiti 6.895486e+05 7.001250 0.860188 MULTIPOLYGON (((178.35631 -38.17577, 178.36485...
8 9 09 Taranaki 5.657958e+05 5.886723 0.830015 POLYGON ((174.98759 -39.66387, 174.78429 -39.8...
9 10 10 Hawke's Bay 9.454397e+05 9.687377 1.335790 MULTIPOLYGON (((177.87052 -39.27876, 177.86687...
10 11 11 Whanganui 6.694279e+05 6.927098 1.003196 POLYGON ((176.29008 -39.24717, 176.26502 -39.3...
11 12 12 MidCentral 6.167762e+05 6.345139 0.937664 POLYGON ((176.49213 -40.53208, 176.26669 -40.7...
12 13 13 Hutt Valley 2.106983e+05 2.184028 0.098310 MULTIPOLYGON (((174.86764 -41.25918, 174.86522...
13 14 14 Capital and Coast 2.923868e+05 3.012962 0.080068 MULTIPOLYGON (((174.78879 -41.09057, 174.77354...
14 15 15 Wairarapa 4.554528e+05 4.751018 0.636207 POLYGON ((176.27048 -40.74387, 176.26669 -40.7...
15 16 16 Nelson Marlborough 1.188104e+06 12.372261 2.986687 POLYGON ((173.36103 -40.80538, 173.20652 -41.2...
16 17 17 West Coast 1.602904e+06 17.070329 2.569502 POLYGON ((172.31080 -41.01154, 172.32531 -41.0...
17 19 19 South Canterbury 5.492453e+05 5.835052 1.547516 POLYGON ((170.61509 -43.43343, 170.59805 -43.4...
18 20 22 Southern 2.725169e+06 30.268153 7.932661 MULTIPOLYGON (((167.39897 -47.26532, 167.39639...
cities.drop(axis=0,  columns=['DHB2015_Co'],inplace=True)
cities.head(2)
OBJECTID DHB2015_Na Shape_Leng Shape_Le_1 Shape_Area geometry
0 1 Northland 1.651929e+06 16.524423 1.320491 MULTIPOLYGON (((174.23335 -36.19077, 174.23809...
1 2 Waitemata 9.273920e+05 9.301324 0.295480 MULTIPOLYGON (((174.77898 -36.82617, 174.77303...
cities.index
RangeIndex(start=0, stop=19, step=1)
cities.plot()
<matplotlib.axes._subplots.AxesSubplot at 0x1c22a63b5f8>

png

Spatial Join

Column join in Pandas-- take dataset A+ B based on a common column

Spatial Join -take dataset A+B = Dataset AB,based on space/geographic relationship

same as the spatial join in ArcGis, but it much more convient to use than Arcpy

Check the coordinate systems of the to two taget file, if they are not in the same coordinate system, then project them into the same coordinate system

print(states.crs, cities.crs)
epsg:4326 epsg:4326
states.to_crs(cities.crs, inplace =True)
len(states)
20
states_with_cities = gpd.sjoin(states, cities, how = 'inner', op = 'within')
states_with_cities.head(2)
DHB2015_Na_left Shape_Leng_left geometry index_right OBJECTID DHB2015_Na_right Shape_Leng_right Shape_Le_1 Shape_Area
0 Northland 1.651929e+06 POINT (173.82591 -35.48993) 0 1 Northland 1.651929e+06 16.524423 1.320491
1 Waitemata 9.273920e+05 POINT (174.54665 -36.56396) 1 2 Waitemata 9.273920e+05 9.301324 0.295480
states_with_cities.shape
(18, 9)
states.shape
(20, 3)
The order here is very important, similar as the join in pandas.

The geometry of the first file(cities here) is will be kept.

how:

  • ‘Left’ means to keep all the information in the first file even they do not have matching state
  • ‘inner’ means to drop the information in the first file if they do not have matching state
cities_with_states = gpd.sjoin(cities, states, how = 'inner', op = 'contains')
cities_with_states.head(2)
OBJECTID DHB2015_Na_left Shape_Leng_left Shape_Le_1 Shape_Area geometry index_right DHB2015_Na_right Shape_Leng_right
0 1 Northland 1.651929e+06 16.524423 1.320491 MULTIPOLYGON (((174.23335 -36.19077, 174.23809... 0 Northland 1.651929e+06
1 2 Waitemata 9.273920e+05 9.301324 0.295480 MULTIPOLYGON (((174.77898 -36.82617, 174.77303... 1 Waitemata 9.273920e+05
cities_with_states.shape
(18, 9)
gpd.sjoin(cities, states, how = 'inner', op = 'contains').plot()
<matplotlib.axes._subplots.AxesSubplot at 0x1c22a6cdbe0>

png

gpd.sjoin(cities, states, how = 'left', op = 'contains').plot()
<matplotlib.axes._subplots.AxesSubplot at 0x1c22a3f0710>

png

gpd.sjoin(cities, states, how = 'left', op = 'contains').shape
(19, 9)
Another way
states_with_cities = gpd.sjoin(states, cities, how = 'inner', op = 'within')
states_with_cities.head()
DHB2015_Na_left Shape_Leng_left geometry index_right OBJECTID DHB2015_Na_right Shape_Leng_right Shape_Le_1 Shape_Area
0 Northland 1.651929e+06 POINT (173.82591 -35.48993) 0 1 Northland 1.651929e+06 16.524423 1.320491
1 Waitemata 9.273920e+05 POINT (174.54665 -36.56396) 1 2 Waitemata 9.273920e+05 9.301324 0.295480
2 Auckland 7.781903e+05 POINT (175.15511 -36.78522) 2 3 Auckland 7.781903e+05 7.848241 0.063644
3 Counties Manukau 6.642233e+05 POINT (174.93239 -37.18770) 3 4 Counties Manukau 6.642233e+05 6.732029 0.303391
4 Waikato 1.498296e+06 POINT (175.35693 -38.04867) 4 5 Waikato 1.498296e+06 15.120324 2.201743
states_with_cities.shape
(18, 9)
states_with_cities.plot()
<matplotlib.axes._subplots.AxesSubplot at 0x1c22a7317f0>

png

gpd.sjoin(states, cities, how = 'left', op = 'within').shape
(20, 9)
Here, the shape is different from the previous one(19,9), since the data of all the states is kept, then final joined result is same as the source data(states).

Reference

https://geopandas.org/install.html#dependencies
https://www.youtube.com/watch?v=mV8bqV2j46M&list=PLewNEVDy7gq3DjrPDxGFLbHE4G2QWe8Qh&index=12


Author: Fan Yang
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint polocy. If reproduced, please indicate source Fan Yang !
  TOC