Fix nodata results.
[philipp/winterrodeln/wrpylib.git] / wrpylib / wrdem.py
1 import math
2 from typing import Optional
3
4 import fiona.crs
5 import fiona.transform
6 import rasterio
7 import rasterio.sample
8
9 from wrpylib.wrvalidators import LonLat
10
11 LON_LAT_CRS = fiona.crs.from_epsg(4326)
12
13
14 def get_ele_from_raster(filename: str, lon_lat: LonLat, band: int = 1) -> Optional[float]:
15     """
16     Examples of filenames:
17     * '/path/to/file.tif'
18     * 'file:///path/to/file.tif'
19     * 'zip:///path/to/file.zip!/folder/file.tif'
20     * 'zip+file:///path/to/file.zip!/folder/file.tif'
21     """
22     with rasterio.open(filename) as dataset:
23         xs, ys = fiona.transform.transform(LON_LAT_CRS, dataset.crs.to_proj4(), [lon_lat.lon], [lon_lat.lat])
24         xy_list = [(x, y) for x, y in zip(xs, ys)]
25         ele = list(rasterio.sample.sample_gen(dataset, xy_list, band))[0]
26         return None if ele == dataset.nodata else float(ele)
27
28
29 class DemBase:
30     def get_ele(self, lon_lat: LonLat) -> float:
31         return math.nan
32
33     def get_name(self) -> str:
34         return self.__class__.__name__
35
36
37 class DemBasemap(DemBase):
38     def __init__(self):
39         self.filename = '/home/philipp/daten/GeoData/dem/oesterreich_10m/dhm_lamb_10m.tif'
40         # self.filename = 'zip:///home/philipp/daten/GeoData/dem/oesterreich_10m/ogd-10m-at.zip!dhm_lamb_10m.tif'
41
42     def get_ele(self, lon_lat: LonLat) -> float:
43         return get_ele_from_raster(self.filename, lon_lat)