diff --git a/.pylintrc b/.pylintrc index e1580699..badff796 100644 --- a/.pylintrc +++ b/.pylintrc @@ -21,5 +21,6 @@ disable=raw-checker-failed, too-many-locals, redefined-builtin, too-many-instance-attributes, + duplicate-code, too-many-statements, - attribute-defined-outside-init \ No newline at end of file + attribute-defined-outside-init diff --git a/.vscode/launch.json b/.vscode/launch.json index 729720ed..04aed0f2 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,42 +1,42 @@ { - "version": "0.2.0", - "configurations": [ - { - "name": "Streamlit: webui", - "type": "debugpy", - "request": "launch", - "module": "streamlit", - "args": ["run", "./webui/webui.py"], - "presentation": { - "reveal": "always", - "panel": "new" - }, - "env": { - "PYTHONPATH": "${workspaceFolder}:${PYTHONPATH}", - "LOG_LEVEL": "DEBUG", - } - }, - { - "name": "demo.py", - "type": "debugpy", - "request": "launch", - "program": "${workspaceFolder}/demo.py", - "console": "integratedTerminal", - "justMyCode": true, - "env": { - "PYTHONPATH": "${workspaceFolder}" - } - }, - { - "name": "Current File", - "type": "debugpy", - "request": "launch", - "program": "${file}", - "console": "integratedTerminal", - "justMyCode": true, - "env": { - "PYTHONPATH": "${workspaceFolder}" - } - } - ] -} \ No newline at end of file + "version": "0.2.0", + "configurations": [ + { + "name": "Streamlit: webui", + "type": "debugpy", + "request": "launch", + "module": "streamlit", + "args": ["run", "./webui/webui.py"], + "presentation": { + "reveal": "always", + "panel": "new" + }, + "env": { + "PYTHONPATH": "${workspaceFolder}:${PYTHONPATH}", + "LOG_LEVEL": "DEBUG" + } + }, + { + "name": "demo.py", + "type": "debugpy", + "request": "launch", + "program": "${workspaceFolder}/demo.py", + "console": "integratedTerminal", + "justMyCode": true, + "env": { + "PYTHONPATH": "${workspaceFolder}" + } + }, + { + "name": "Current File", + "type": "debugpy", + "request": "launch", + "program": "${file}", + "console": "integratedTerminal", + "justMyCode": true, + "env": { + "PYTHONPATH": "${workspaceFolder}" + } + } + ] +} diff --git a/docs/dtm_providers.md b/docs/dtm_providers.md index 83b5df23..0b3eb311 100644 --- a/docs/dtm_providers.md +++ b/docs/dtm_providers.md @@ -122,7 +122,7 @@ Then, it determines which tiles are needed, downloads them all to a temporary fo Finally, it returns a list of file paths to the downloaded tiles. As you can see, it's pretty simple to implement a DTM provider. You can use any source of elevation data, as long as it's free and open. -NOTE: DTM Providers which require API keys, paid subscriptions, or any other form of payment will not be considered for implementation in the generator. +NOTE: If a DTM Provider requires an API key, paid subscription, or any other form of payment, you will be fully responsible for setting up your own access to the provider. The provider in the app will expose the settings needed to provide your authentication key or other required information. ### How DTM Provider can interact with the generator? diff --git a/maps4fs/__init__.py b/maps4fs/__init__.py index a1885e12..14313fc5 100644 --- a/maps4fs/__init__.py +++ b/maps4fs/__init__.py @@ -8,6 +8,13 @@ from maps4fs.generator.dtm.hessen import HessenProvider from maps4fs.generator.dtm.england import England1MProvider from maps4fs.generator.dtm.canada import CanadaProvider +from maps4fs.generator.dtm.scotland import ScotlandProvider +from maps4fs.generator.dtm.finland import FinlandProvider +from maps4fs.generator.dtm.italy import ItalyProvider +from maps4fs.generator.dtm.flanders import FlandersProvider +from maps4fs.generator.dtm.spain import SpainProvider +from maps4fs.generator.dtm.france import FranceProvider +from maps4fs.generator.dtm.norway import NorwayProvider from maps4fs.generator.game import Game from maps4fs.generator.map import Map from maps4fs.generator.settings import ( diff --git a/maps4fs/generator/dtm/base/wcs.py b/maps4fs/generator/dtm/base/wcs.py index ff88f56b..9e2fc565 100644 --- a/maps4fs/generator/dtm/base/wcs.py +++ b/maps4fs/generator/dtm/base/wcs.py @@ -30,6 +30,18 @@ def get_wcs_parameters(self, tile: tuple[float, float, float, float]) -> dict: dict: The parameters for the WCS request. """ + def get_wcs_instance_parameters(self) -> dict: + """Get the parameters for the WCS instance. + + Returns: + dict: The parameters for the WCS instance. + """ + return { + "url": self._url, + "version": self._wcs_version, + "timeout": 120, + } + def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.shared_tiff_path = os.path.join(self._tile_directory, "shared") @@ -53,12 +65,9 @@ def download_all_tiles(self, tiles: list[tuple[float, float, float, float]]) -> list: List of paths to the downloaded GeoTIFF files. """ all_tif_files = [] - wcs = WebCoverageService( - self._url, - version=self._wcs_version, - # auth=Authentication(verify=False), - timeout=600, - ) + params = self.get_wcs_instance_parameters() + wcs = WebCoverageService(**params) + for tile in tqdm(tiles, desc="Downloading tiles", unit="tile"): file_name = "_".join(map(str, tile)) + ".tif" file_path = os.path.join(self.shared_tiff_path, file_name) diff --git a/maps4fs/generator/dtm/base/wms.py b/maps4fs/generator/dtm/base/wms.py index 7f1f7ec0..5503095c 100644 --- a/maps4fs/generator/dtm/base/wms.py +++ b/maps4fs/generator/dtm/base/wms.py @@ -4,6 +4,7 @@ import os from owslib.wms import WebMapService +from tqdm import tqdm from maps4fs.generator.dtm import utils from maps4fs.generator.dtm.dtm import DTMProvider @@ -58,7 +59,7 @@ def download_all_tiles(self, tiles: list[tuple[float, float, float, float]]) -> # auth=Authentication(verify=False), timeout=600, ) - for tile in tiles: + for tile in tqdm(tiles, desc="Downloading tiles", unit="tile"): file_name = "_".join(map(str, tile)) + ".tif" file_path = os.path.join(self.shared_tiff_path, file_name) if not os.path.exists(file_path): diff --git a/maps4fs/generator/dtm/dtm.py b/maps4fs/generator/dtm/dtm.py index 7a25a99e..28578a14 100644 --- a/maps4fs/generator/dtm/dtm.py +++ b/maps4fs/generator/dtm/dtm.py @@ -12,13 +12,14 @@ import numpy as np import osmnx as ox # type: ignore import rasterio # type: ignore -import requests from pydantic import BaseModel from rasterio.enums import Resampling from rasterio.merge import merge from rasterio.warp import calculate_default_transform, reproject +import requests from tqdm import tqdm + from maps4fs.logger import Logger if TYPE_CHECKING: @@ -395,28 +396,47 @@ def download_tif_files(self, urls: list[str], output_path: str) -> list[str]: list: List of paths to the downloaded GeoTIFF files. """ tif_files: list[str] = [] - for url in tqdm(urls, desc="Downloading tiles", unit="tile"): + + existing_file_urls = [ + f for f in urls if os.path.exists(os.path.join(output_path, os.path.basename(f))) + ] + + for url in existing_file_urls: + self.logger.debug("File already exists: %s", os.path.basename(url)) file_name = os.path.basename(url) - self.logger.debug("Retrieving TIFF: %s", file_name) file_path = os.path.join(output_path, file_name) - if not os.path.exists(file_path): - try: - # Send a GET request to the file URL - response = requests.get(url, stream=True, timeout=60) - response.raise_for_status() # Raise an error for HTTP status codes 4xx/5xx - - # Write the content of the response to the file - with open(file_path, "wb") as file: - for chunk in response.iter_content(chunk_size=8192): # Download in chunks - file.write(chunk) - self.logger.debug("File downloaded successfully: %s", file_path) - except requests.exceptions.RequestException as e: - self.logger.error("Failed to download file: %s", e) - else: - self.logger.debug("File already exists: %s", file_name) if file_name.endswith(".zip"): file_path = self.unzip_img_from_tif(file_name, output_path) tif_files.append(file_path) + + for url in tqdm( + (u for u in urls if u not in existing_file_urls), + desc="Downloading tiles", + unit="tile", + initial=len(tif_files), + ): + try: + file_name = os.path.basename(url) + file_path = os.path.join(output_path, file_name) + self.logger.debug("Retrieving TIFF: %s", file_name) + + # Send a GET request to the file URL + response = requests.get(url, stream=True, timeout=60) + response.raise_for_status() # Raise an error for HTTP status codes 4xx/5xx + + # Write the content of the response to the file + with open(file_path, "wb") as file: + for chunk in response.iter_content(chunk_size=8192): + file.write(chunk) + + self.logger.debug("File downloaded successfully: %s", file_path) + + if file_name.endswith(".zip"): + file_path = self.unzip_img_from_tif(file_name, output_path) + + tif_files.append(file_path) + except requests.exceptions.RequestException as e: + self.logger.error("Failed to download file: %s", e) return tif_files def unzip_img_from_tif(self, file_name: str, output_path: str) -> str: @@ -585,7 +605,7 @@ def normalize_dem(self, data: np.ndarray) -> np.ndarray: "Applying power factor: %s to the DEM data.", power_factor, ) - data = np.power(data, power_factor).astype(np.uint16) + data = np.power(data, power_factor) normalized_data = np.round(data * scaling_factor).astype(np.uint16) self.logger.debug( diff --git a/maps4fs/generator/dtm/finland.py b/maps4fs/generator/dtm/finland.py new file mode 100644 index 00000000..b2b9476e --- /dev/null +++ b/maps4fs/generator/dtm/finland.py @@ -0,0 +1,53 @@ +"""This module contains provider of Finland data.""" + +from owslib.util import Authentication + +from maps4fs.generator.dtm.base.wcs import WCSProvider +from maps4fs.generator.dtm.dtm import DTMProvider, DTMProviderSettings + + +class FinlandProviderSettings(DTMProviderSettings): + """Settings for the Finland provider.""" + + api_key: str = "" + + +class FinlandProvider(WCSProvider, DTMProvider): + """Provider of Finland data.""" + + _code = "finland" + _name = "Finland" + _region = "FI" + _icon = "🇫🇮" + _resolution = 2 + _settings = FinlandProviderSettings + _author = "[kbrandwijk](https://github.com/kbrandwijk)" + _is_community = True + _is_base = False + _extents = (70.09, 59.45, 31.59, 19.08) + + _url = "https://avoin-karttakuva.maanmittauslaitos.fi/ortokuvat-ja-korkeusmallit/wcs/v2" + _wcs_version = "2.0.1" + _source_crs = "EPSG:3067" + _tile_size = 1000 + + _instructions = ( + "ℹ️ This provider requires an API Key. See [here](https://www.maanmittausl" + "aitos.fi/rajapinnat/api-avaimen-ohje) for more information on how to create one, then " + "enter it below in the settings field for API Key." + ) + + def get_wcs_instance_parameters(self): + settings = super().get_wcs_instance_parameters() + settings["auth"] = Authentication( + username=self.user_settings.api_key, password=self.user_settings.api_key + ) + return settings + + def get_wcs_parameters(self, tile: tuple[float, float, float, float]) -> dict: + return { + "identifier": ["korkeusmalli_2m"], + "subsets": [("N", str(tile[0]), str(tile[2])), ("E", str(tile[1]), str(tile[3]))], + "format": "image/tiff", + "timeout": 600, + } diff --git a/maps4fs/generator/dtm/flanders.py b/maps4fs/generator/dtm/flanders.py new file mode 100644 index 00000000..97fe6161 --- /dev/null +++ b/maps4fs/generator/dtm/flanders.py @@ -0,0 +1,34 @@ +"""This module contains provider of Flanders data.""" + +from maps4fs.generator.dtm.base.wcs import WCSProvider +from maps4fs.generator.dtm.dtm import DTMProvider + + +class FlandersProvider(WCSProvider, DTMProvider): + """Provider of Flanders data.""" + + _code = "flanders" + _name = "Flanders DHM II" + _region = "BE" + _icon = "🇧🇪" + _resolution = 1 + _author = "[kbrandwijk](https://github.com/kbrandwijk)" + _is_community = True + _is_base = False + _extents = (51.5150730375579684, 50.6694992827160817, 5.9444417082210812, 2.5170092434134252) + + _url = "https://geo.api.vlaanderen.be/el-dtm/wcs" + _wcs_version = "1.0.0" + _source_crs = "EPSG:4258" + _tile_size = 0.02 + + def get_wcs_parameters(self, tile: tuple[float, float, float, float]) -> dict: + return { + "identifier": "EL.GridCoverage.DTM", + "bbox": tile, + "format": "GeoTIFF", + "crs": "EPSG:4258", + "width": 1000, + "height": 1000, + "timeout": 600, + } diff --git a/maps4fs/generator/dtm/france.py b/maps4fs/generator/dtm/france.py new file mode 100644 index 00000000..54fa9609 --- /dev/null +++ b/maps4fs/generator/dtm/france.py @@ -0,0 +1,59 @@ +"""This module contains provider of France data.""" + +import os +import rasterio +from maps4fs.generator.dtm import utils +from maps4fs.generator.dtm.dtm import DTMProvider + + +class FranceProvider(DTMProvider): + """Provider of France data.""" + + _code = "france" + _name = "France RGE Alti 2.0" + _region = "FR" + _icon = "🇫🇷" + _resolution = 1 + _author = "[kbrandwijk](https://github.com/kbrandwijk)" + _is_community = True + + _url = "https://data.cquest.org/ign/rgealti/repack/cog/RGEALTI_2-0_1M_COG_LAMB93-IGN69_FXX.vrt" + _is_base = False + # no extents, because it also has a few colonies throughout the world + # _extents = (54.148101, 51.153098, 11.754046, 6.505772) + + def download_tiles(self) -> list[str]: + with rasterio.open( + self.url, + crs="EPSG:2154", + ) as vrt_src: + # Get bbox in EPSG:2154 in the right order + bbox = self.get_bbox() + bbox = utils.transform_bbox(bbox, "EPSG:2154") + bbox = (bbox[0], bbox[3], bbox[1], bbox[2]) + + # read the window of data from the vrt + dst_window = vrt_src.window(*bbox) + data = vrt_src.read(1, window=dst_window) + width, height = data.shape[0], data.shape[1] + + # define the transform for the new raster telling where it is in the world + transform = rasterio.transform.from_bounds(*bbox, width=width, height=height) + + # write it to a temporary file following the standard DTMProvider interface + file_name = "_".join(map(str, bbox)) + ".tif" + file_path = os.path.join(self._tile_directory, file_name) + with rasterio.open( + file_path, + "w", + driver="GTiff", + crs="EPSG:2154", + width=width, + height=height, + transform=transform, + count=1, + dtype=data.dtype, + ) as dst: + dst.write(data, indexes=1) + + return [file_path] diff --git a/maps4fs/generator/dtm/italy.py b/maps4fs/generator/dtm/italy.py new file mode 100644 index 00000000..8064e8a5 --- /dev/null +++ b/maps4fs/generator/dtm/italy.py @@ -0,0 +1,40 @@ +"""This module contains provider of Italy data.""" + +from owslib.util import Authentication + +from maps4fs.generator.dtm.base.wcs import WCSProvider +from maps4fs.generator.dtm.dtm import DTMProvider + + +class ItalyProvider(WCSProvider, DTMProvider): + """Provider of Italy data.""" + + _code = "italy" + _name = "Italy Tinitaly/1.1" + _region = "IT" + _icon = "🇮🇹" + _resolution = 10 + _author = "[kbrandwijk](https://github.com/kbrandwijk)" + _is_community = True + _instructions = None + _is_base = False + _extents = (47.15570815704503, 35.177652867276855, 19.720144130809693, 6.527697471770745) + + _url = "http://tinitaly.pi.ingv.it/TINItaly_1_1/wcs" + _wcs_version = "2.0.1" + _source_crs = "EPSG:32632" + _tile_size = 10000 + + def get_wcs_instance_parameters(self): + settings = super().get_wcs_instance_parameters() + settings["auth"] = Authentication( + verify=False, + ) + return settings + + def get_wcs_parameters(self, tile): + return { + "identifier": ["TINItaly_1_1__tinitaly_dem"], + "subsets": [("E", str(tile[1]), str(tile[3])), ("N", str(tile[0]), str(tile[2]))], + "format": "image/tiff", + } diff --git a/maps4fs/generator/dtm/niedersachsen.py b/maps4fs/generator/dtm/niedersachsen.py index 38a0638e..1cce9199 100644 --- a/maps4fs/generator/dtm/niedersachsen.py +++ b/maps4fs/generator/dtm/niedersachsen.py @@ -4,7 +4,6 @@ from maps4fs.generator.dtm.dtm import DTMProvider -# pylint: disable=R0801 class NiedersachsenProvider(WMSProvider, DTMProvider): """Provider of Niedersachsen data.""" diff --git a/maps4fs/generator/dtm/norway.py b/maps4fs/generator/dtm/norway.py new file mode 100644 index 00000000..df9628fb --- /dev/null +++ b/maps4fs/generator/dtm/norway.py @@ -0,0 +1,39 @@ +"""This module contains provider of Norway data.""" + +from maps4fs.generator.dtm.base.wcs import WCSProvider +from maps4fs.generator.dtm.dtm import DTMProvider + + +class NorwayProvider(WCSProvider, DTMProvider): + """Provider of Norway data.""" + + _code = "norway" + _name = "Norway Topobathy" + _region = "NO" + _icon = "🇳🇴" + _resolution = 1 + _author = "[kbrandwijk](https://github.com/kbrandwijk)" + _is_community = True + _instructions = None + _is_base = False + _extents = (72.1016879476356962, 57.2738836442695103, 33.3365910058243742, -2.0075617181675725) + + _instructions = ( + "This is a topobathy dataset which means it includes water depth information as well. " + "You do not have to manually set a water depth to get realistic water depths in your map." + ) + + _url = "https://wms.geonorge.no/skwms1/wcs.hoyde-dtm-nhm-topobathy-25833" + _wcs_version = "1.0.0" + _source_crs = "EPSG:25833" + _tile_size = 1000 + + def get_wcs_parameters(self, tile): + return { + "identifier": "nhm_dtm_topobathy_25833", + "bbox": (tile[1], tile[0], tile[3], tile[2]), + "crs": "EPSG:25833", + "width": 1000, + "height": 1000, + "format": "tiff", + } diff --git a/maps4fs/generator/dtm/scotland.py b/maps4fs/generator/dtm/scotland.py new file mode 100644 index 00000000..e2c63746 --- /dev/null +++ b/maps4fs/generator/dtm/scotland.py @@ -0,0 +1,116 @@ +"""This module contains provider of Scotland data.""" + +import os + +import requests + +from maps4fs.generator.dtm.dtm import DTMProvider, DTMProviderSettings + + +class ScotlandProviderSettings(DTMProviderSettings): + """Settings for the Scotland provider.""" + + dataset: dict | str = { + "scotland-gov/lidar/phase-1/dtm": "LiDAR for Scotland Phase I DTM", + "scotland-gov/lidar/phase-2/dtm": "LiDAR for Scotland Phase II DTM", + "scotland-gov/lidar/phase-3/dtm": "LiDAR for Scotland Phase III DTM", + "scotland-gov/lidar/phase-4/dtm": "LiDAR for Scotland Phase IV DTM", + "scotland-gov/lidar/phase-5/dtm": "LiDAR for Scotland Phase V DTM", + "scotland-gov/lidar/phase-6/dtm": "LiDAR for Scotland Phase VI DTM", + "scotland-gov/lidar/hes/hes-2010/dtm": ( + "HES LiDAR Data Stirling City and surrounding area (2010) DTM" + ), + "scotland-gov/lidar/hes/hes-2010s10/dtm": ( + "LiDAR for Historic Environment Scotland Scottish Ten Project (2010) DTM" + ), + "scotland-gov/lidar/hes/hes-2016-2017/dtm": ( + "LiDAR for Historic Environment Scotland Projects (2016-2017 sub project 4) DTM" + ), + "scotland-gov/lidar/hes/hes-2016/dtm": ( + "LiDAR for Historic Environment Scotland Projects (2016) DTM" + ), + "scotland-gov/lidar/hes/hes-2017/dtm": ( + "LiDAR for Historic Environment Scotland Projects (2017) DTM" + ), + "scotland-gov/lidar/hes/hes-2017sp3/dtm": ( + "LiDAR for Historic Environment Scotland Project (2017 Sub Project 3) DTM" + ), + "scotland-gov/lidar/hes/hes-luing/dtm": ( + "LiDAR for Historic Environment Scotland Projects Isle of Luing DTM" + ), + "scotland-gov/lidar/outerheb-2019/dtm/25cm": "LiDAR for Outer Hebrides 2019 - 25cm DTM", + "scotland-gov/lidar/outerheb-2019/dtm/50cm": "LiDAR for Outer Hebrides 2019 - 50cm DTM", + } + + +class ScotlandProvider(DTMProvider): + """Provider of Scotland.""" + + _code = "scotland" + _name = "Scotland LiDAR" + _region = "UK" + _icon = "🏴󠁧󠁢󠁳󠁣󠁴󠁿" + _resolution = "variable" + _settings = ScotlandProviderSettings + _author = "[kbrandwijk](https://github.com/kbrandwijk)" + _is_community = True + _instructions = ( + "Coverage for Scotland is very limited. " + "Make sure to check the [coverage map](https://remotesensingdata.gov.scot/data#/map)." + ) + _extents = (60.2151105070992756, 54.5525982243521881, -1.1045617513147328, -6.7070796770431951) + + _url = "https://srsp-catalog.jncc.gov.uk/search/product" + + def download_tiles(self): + download_urls = self.get_download_urls() + all_tif_files = self.download_tif_files(download_urls, self.shared_tiff_path) + return all_tif_files + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.shared_tiff_path = os.path.join(self._tile_directory, "shared") + os.makedirs(self.shared_tiff_path, exist_ok=True) + + def get_download_urls(self) -> list[str]: + """Get download URLs of the GeoTIFF files from the USGS API. + + Returns: + list: List of download URLs. + """ + urls = [] + try: + # Make the GET request + (north, south, east, west) = self.get_bbox() + response = requests.post( # pylint: disable=W3101 + self.url, # type: ignore + json={ + "collections": ( + [self.user_settings.dataset] if self.user_settings else [] # type: ignore + ), + "footprint": ( + f"POLYGON(({west} {south}, {west} {north}, " + f"{east} {north}, {east} {south}, {west} {south}))" + ), + "offset": 0, + "limit": 100, + "spatialop": "intersects", + }, + timeout=60, + ) + self.logger.debug("Getting file locations from JNCC...") + + # Check if the request was successful (HTTP status code 200) + if response.status_code == 200: + # Parse the JSON response + json_data = response.json() + items = json_data["result"] + for item in items: + urls.append(item["data"]["product"]["http"]["url"]) + # self.download_tif_files(urls) + else: + self.logger.error("Failed to get data. HTTP Status Code: %s", response.status_code) + except requests.exceptions.RequestException as e: + self.logger.error("Failed to get data. Error: %s", e) + self.logger.debug("Received %s urls", len(urls)) + return urls diff --git a/maps4fs/generator/dtm/spain.py b/maps4fs/generator/dtm/spain.py new file mode 100644 index 00000000..e81bb7df --- /dev/null +++ b/maps4fs/generator/dtm/spain.py @@ -0,0 +1,31 @@ +"""This module contains provider of Spain data.""" + +from maps4fs.generator.dtm.base.wcs import WCSProvider +from maps4fs.generator.dtm.dtm import DTMProvider + + +class SpainProvider(WCSProvider, DTMProvider): + """Provider of Spain data.""" + + _code = "spain" + _name = "Spain" + _region = "ES" + _icon = "🇪🇸" + _resolution = 5 + _author = "[kbrandwijk](https://github.com/kbrandwijk)" + _is_community = True + _is_base = False + _extents = (43.9299999999999997, 27.6299999999999990, 4.9400000000000004, -18.2100000000000009) + + _url = "https://servicios.idee.es/wcs-inspire/mdt" + _wcs_version = "2.0.1" + _source_crs = "EPSG:25830" + _tile_size = 1000 + + def get_wcs_parameters(self, tile: tuple[float, float, float, float]) -> dict: + return { + "identifier": ["Elevacion25830_5"], + "subsets": [("y", str(tile[0]), str(tile[2])), ("x", str(tile[1]), str(tile[3]))], + "format": "GEOTIFFINT16", + "timeout": 600, + } diff --git a/maps4fs/generator/dtm/usgs.py b/maps4fs/generator/dtm/usgs.py index 7b37b052..f21152fb 100644 --- a/maps4fs/generator/dtm/usgs.py +++ b/maps4fs/generator/dtm/usgs.py @@ -60,14 +60,17 @@ def get_download_urls(self) -> list[str]: Returns: list: List of download URLs. """ + assert self.url is not None + urls = [] try: # Make the GET request (north, south, east, west) = self.get_bbox() - response = requests.get( # pylint: disable=W3101 - self.url # type: ignore + response = requests.get( + self.url + f"&datasets={self.user_settings.dataset}" # type: ignore - + f"&bbox={west},{north},{east},{south}" + + f"&bbox={west},{north},{east},{south}", + timeout=60, ) self.logger.debug("Getting file locations from USGS...") diff --git a/maps4fs/toolbox/background.py b/maps4fs/toolbox/background.py index 740fec98..235cf067 100644 --- a/maps4fs/toolbox/background.py +++ b/maps4fs/toolbox/background.py @@ -5,7 +5,7 @@ import trimesh # type: ignore -# pylint: disable=R0801, R0914 +# pylint: disable=R0914 def plane_from_np( dem_data: np.ndarray, resize_factor: float, diff --git a/webui/generator.py b/webui/generator.py index 43b99b64..948ddf60 100644 --- a/webui/generator.py +++ b/webui/generator.py @@ -206,6 +206,8 @@ def _create_widget( key = f"{prefix}_{raw_field_name}" if disabled: st.warning(Messages.SETTING_DISABLED_ON_PUBLIC.format(setting=field_name)) + if type(value) is str: + return st.text_input(label=field_name, value=value, key=key, disabled=disabled) if type(value) is int: return st.number_input( label=field_name, value=value, min_value=0, key=key, disabled=disabled