05 Processing Data Type 2 - Vector Lines
Contents
© Alexander Jüstel, Fraunhofer IEG, Institution for Energy Infrastructures and Geothermal Systems, RWTH Aachen University, GNU Lesser General Public License v3.0
05 Processing Data Type 2 - Vector Lines#
This notebook illustrates how to process data of Data Type 2 - Vector Lines. The input data is provided as street lines including the heat demand.
Importing Libraries#
[1]:
import rasterio
from rasterio.plot import show
import geopandas as gpd
from shapely.geometry import box
import matplotlib.pyplot as plt
from pyheatdemand import processing
C:\Users\ale93371\Anaconda3\envs\pygeomechanical\lib\site-packages\numpy\_distributor_init.py:30: UserWarning: loaded more than 1 DLL from .libs:
C:\Users\ale93371\Anaconda3\envs\pygeomechanical\lib\site-packages\numpy\.libs\libopenblas.FB5AE2TYXYH2IJRDKGDGQ3XBKLKTF43H.gfortran-win_amd64.dll
C:\Users\ale93371\Anaconda3\envs\pygeomechanical\lib\site-packages\numpy\.libs\libopenblas64__v0.3.23-246-g3d31191b-gcc_10_3_0.dll
warnings.warn("loaded more than 1 DLL from .libs:"
Loading Sample Data#
The sample data is loaded using GeoPandas
.
[2]:
data = gpd.read_file('../../../test/data/Data_Type_II_Vector_lines.shp')
data.head()
[2]:
WLD_ID | RW_WW_WBED | RW_WW_WLD | gn | kn | Shape_Leng | geometry | |
---|---|---|---|---|---|---|---|
0 | 97788 | 0.000000 | 0.000000 | Aachen | 05334002 | 333.796658 | LINESTRING (295503.878 5623817.124, 295488.811... |
1 | 97949 | 99663.765041 | 151.003176 | Aachen | 05334002 | 660.011053 | LINESTRING (299141.912 5623848.623, 299133.223... |
2 | 97963 | 49128.731927 | 71.262682 | Aachen | 05334002 | 689.403354 | LINESTRING (299162.867 5623851.481, 299167.851... |
3 | 98153 | 0.000000 | 0.000000 | Aachen | 05334002 | 579.963937 | LINESTRING (292516.371 5623891.800, 292632.748... |
4 | 98190 | 0.000000 | 0.000000 | Aachen | 05334002 | 406.229754 | LINESTRING (294896.970 5623900.105, 294904.346... |
[3]:
fig, ax = plt.subplots(figsize=(10,10))
data.plot(column='RW_WW_WBED', ax=ax, vmax=800000, legend=True, legend_kwds={'shrink':0.51, 'label': 'Heat Demand [MWh]'})
plt.xlabel('X [m]')
plt.ylabel('Y [m]')
[3]:
Text(70.09722222222221, 0.5, 'Y [m]')
Inspect CRS#
We are inspecting the CRS and see that is does not match with the desired CRS EPSG:3034
.
[4]:
data.crs
[4]:
<Projected CRS: EPSG:25832>
Name: ETRS89 / UTM zone 32N
Axis Info [cartesian]:
- E[east]: Easting (metre)
- N[north]: Northing (metre)
Area of Use:
- name: Europe between 6°E and 12°E: Austria; Belgium; Denmark - onshore and offshore; Germany - onshore and offshore; Norway including - onshore and offshore; Spain - offshore.
- bounds: (6.0, 38.76, 12.01, 84.33)
Coordinate Operation:
- name: UTM zone 32N
- method: Transverse Mercator
Datum: European Terrestrial Reference System 1989 ensemble
- Ellipsoid: GRS 1980
- Prime Meridian: Greenwich
Reprojecting CRS#
The CRS of the data is reprojected to the desired CRS EPSG:3034
.
[5]:
data = data.to_crs('EPSG:3034')
Creating GeoDataFrame Outline from vectorized Raster#
For further processing, we are creating an outline GeoDataFrame
from the total_bounds
of the vectorized raster.
[6]:
gdf = processing.create_outline(data)
gdf
[6]:
geometry | |
---|---|
0 | POLYGON ((3741177.414 2670239.306, 3741177.414... |
Loading Interreg Mask#
We are loading the previously created 10 km mask.
[7]:
mask_10km = gpd.read_file('../../../test/data/Interreg_NWE_mask_10km_3034.shp')
mask_10km
[7]:
FID | geometry | |
---|---|---|
0 | 0 | POLYGON ((2651470.877 2955999.353, 2651470.877... |
1 | 1 | POLYGON ((2651470.877 2965999.353, 2651470.877... |
2 | 2 | POLYGON ((2651470.877 2975999.353, 2651470.877... |
3 | 3 | POLYGON ((2651470.877 2985999.353, 2651470.877... |
4 | 4 | POLYGON ((2651470.877 2995999.353, 2651470.877... |
... | ... | ... |
9225 | 9225 | POLYGON ((4141470.877 2605999.353, 4141470.877... |
9226 | 9226 | POLYGON ((4141470.877 2615999.353, 4141470.877... |
9227 | 9227 | POLYGON ((4151470.877 2585999.353, 4151470.877... |
9228 | 9228 | POLYGON ((4151470.877 2595999.353, 4151470.877... |
9229 | 9229 | POLYGON ((4151470.877 2605999.353, 4151470.877... |
9230 rows × 2 columns
[8]:
mask_10km.crs
[8]:
<Projected CRS: EPSG:3034>
Name: ETRS89-extended / LCC Europe
Axis Info [cartesian]:
- N[north]: Northing (metre)
- E[east]: Easting (metre)
Area of Use:
- name: Europe - European Union (EU) countries and candidates. Europe - onshore and offshore: Albania; Andorra; Austria; Belgium; Bosnia and Herzegovina; Bulgaria; Croatia; Cyprus; Czechia; Denmark; Estonia; Faroe Islands; Finland; France; Germany; Gibraltar; Greece; Hungary; Iceland; Ireland; Italy; Kosovo; Latvia; Liechtenstein; Lithuania; Luxembourg; Malta; Monaco; Montenegro; Netherlands; North Macedonia; Norway including Svalbard and Jan Mayen; Poland; Portugal including Madeira and Azores; Romania; San Marino; Serbia; Slovakia; Slovenia; Spain including Canary Islands; Sweden; Switzerland; Türkiye (Turkey); United Kingdom (UK) including Channel Islands and Isle of Man; Vatican City State.
- bounds: (-35.58, 24.6, 44.83, 84.73)
Coordinate Operation:
- name: Europe Conformal 2001
- method: Lambert Conic Conformal (2SP)
Datum: European Terrestrial Reference System 1989 ensemble
- Ellipsoid: GRS 1980
- Prime Meridian: Greenwich
[9]:
fig, ax = plt.subplots(figsize=(10,10))
mask_10km.boundary.plot(ax=ax, linewidth=1, color='green')
plt.xlabel('X [m]')
plt.ylabel('Y [m]')
plt.grid()
plt.tight_layout()
Crop Mask to Data Limits#
The 10 km cells that intersect with the data outline are selected.
[10]:
mask_10km_cropped = mask_10km.sjoin(gdf).reset_index()[['geometry']]
mask_10km_cropped
[10]:
geometry | |
---|---|
0 | POLYGON ((3721470.877 2665999.353, 3721470.877... |
1 | POLYGON ((3731470.877 2665999.353, 3731470.877... |
2 | POLYGON ((3721470.877 2665999.353, 3721470.877... |
3 | POLYGON ((3721470.877 2675999.353, 3721470.877... |
4 | POLYGON ((3731470.877 2675999.353, 3731470.877... |
5 | POLYGON ((3721470.877 2665999.353, 3721470.877... |
6 | POLYGON ((3721470.877 2675999.353, 3721470.877... |
7 | POLYGON ((3731470.877 2665999.353, 3731470.877... |
8 | POLYGON ((3731470.877 2675999.353, 3731470.877... |
Plotting the Cropped Mask#
The cropped mask and the data outline are plotted using matplotlib
.
[11]:
fig, ax = plt.subplots(figsize=(10,10))
mask_10km_cropped.boundary.plot(ax=ax, linewidth=3, color='green')
gdf.to_crs('EPSG:3034').boundary.plot(ax=ax, linewidth=3)
plt.xlabel('X [m]')
plt.ylabel('Y [m]')
plt.grid()
plt.tight_layout()
Creating mask from cropped mask#
Here, the final mask with a width and height of 100 m is created.
[12]:
mask_100m_cropped = processing.create_polygon_mask(gdf=mask_10km_cropped,
step_size=100,
crop_gdf=True)
mask_100m_cropped
[12]:
geometry | |
---|---|
0 | POLYGON ((3721470.877 2665999.353, 3721570.877... |
1 | POLYGON ((3721470.877 2666099.353, 3721570.877... |
2 | POLYGON ((3721470.877 2666199.353, 3721570.877... |
3 | POLYGON ((3721470.877 2666299.353, 3721570.877... |
4 | POLYGON ((3721470.877 2666399.353, 3721570.877... |
... | ... |
91804 | POLYGON ((3741370.877 2685499.353, 3741470.877... |
91805 | POLYGON ((3741370.877 2685599.353, 3741470.877... |
91806 | POLYGON ((3741370.877 2685699.353, 3741470.877... |
91807 | POLYGON ((3741370.877 2685799.353, 3741470.877... |
91808 | POLYGON ((3741370.877 2685899.353, 3741470.877... |
91809 rows × 1 columns
Cropping Mask to outline#
[13]:
fig, ax = plt.subplots(figsize=(10,10))
mask_10km_cropped.boundary.plot(ax=ax, linewidth=3, color='green')
gdf.to_crs('EPSG:3034').boundary.plot(ax=ax, linewidth=3)
mask_100m_cropped.boundary.plot(ax=ax, linewidth=0.5, color='green')
plt.xlabel('X [m]')
plt.ylabel('Y [m]')
plt.grid()
plt.tight_layout()
#plt.savefig('../images/Data_Type_1_Outline.png', dpi=300)
[14]:
fig, ax = plt.subplots(figsize=(15,9))
# mask_10km_cropped.boundary.plot(ax=ax, linewidth=3, color='green')
# gdf.to_crs('EPSG:3034').boundary.plot(ax=ax, linewidth=3)
mask_100m_cropped.boundary.plot(ax=ax, linewidth=0.5, color='green')
data.plot(ax=ax, column='RW_WW_WBED', vmax=1500000, legend=True, legend_kwds={'shrink':0.81, 'label': 'Heat Demand [MWh]'})
plt.xlabel('X [m]')
plt.ylabel('Y [m]')
plt.grid()
plt.tight_layout()
Calculate Heat Demand#
With the vectorized raster and the 100 m mask, we can now directly calculate the heat demand using calculate_hd
.
[15]:
hd_gdf = data
mask_gdf = mask_100m_cropped
[16]:
gdf_hd = processing.calculate_hd(hd_gdf,
mask_gdf,
'RW_WW_WBED')
gdf_hd
[16]:
HD | geometry | |
---|---|---|
0 | 0.000000 | POLYGON ((3728870.877 2673699.353, 3728970.877... |
1 | 0.000000 | POLYGON ((3728870.877 2674199.353, 3728970.877... |
2 | 0.000000 | POLYGON ((3728870.877 2674399.353, 3728970.877... |
3 | 0.000000 | POLYGON ((3728870.877 2674499.353, 3728970.877... |
4 | 55461.301266 | POLYGON ((3728870.877 2675999.353, 3728970.877... |
... | ... | ... |
6979 | 0.000000 | POLYGON ((3740770.877 2677499.353, 3740870.877... |
6980 | 0.000000 | POLYGON ((3740770.877 2677599.353, 3740870.877... |
6981 | 0.000000 | POLYGON ((3740770.877 2678199.353, 3740870.877... |
6982 | 0.000000 | POLYGON ((3740770.877 2678299.353, 3740870.877... |
6983 | 0.000000 | POLYGON ((3740770.877 2678399.353, 3740870.877... |
6984 rows × 2 columns
[17]:
fig, ax = plt.subplots(figsize=(10,10))
gdf_hd.plot(column='HD', vmax=2000000, ax=ax, legend=True, legend_kwds={'shrink':0.51, 'label': 'Heat Demand [MWh]'})
plt.xlabel('X [m]')
plt.ylabel('Y [m]')
[17]:
Text(70.09722222222221, 0.5, 'Y [m]')
Rasterizing Vector Data#
The vector data will be rasterized and saved to file.
[18]:
processing.rasterize_gdf_hd(gdf_hd,
path_out='../../../test/data/Data_Type_II_Vector_Lines.tif',
crs = 'EPSG:3034',
xsize = 100,
ysize = 100)
Opening and plotting raster#
The final raster can now be opened and plotted.
[19]:
raster = rasterio.open('../../../test/data/Data_Type_II_Vector_Lines.tif')
[20]:
show(raster)
[20]:
<Axes: >