© 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]')
../_images/notebooks_05_Processing_Data_Type_II_Vector_Lines_5_1.png

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()
../_images/notebooks_05_Processing_Data_Type_II_Vector_Lines_15_0.png

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()
../_images/notebooks_05_Processing_Data_Type_II_Vector_Lines_19_0.png

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

mask_100m.to_file('../data/Interreg_NWE_mask_500m_EPSG3034.shp')

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)
../_images/notebooks_05_Processing_Data_Type_II_Vector_Lines_24_0.png
[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()
../_images/notebooks_05_Processing_Data_Type_II_Vector_Lines_25_0.png

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]')
../_images/notebooks_05_Processing_Data_Type_II_Vector_Lines_29_1.png

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)
../_images/notebooks_05_Processing_Data_Type_II_Vector_Lines_34_0.png
[20]:
<Axes: >