0c36de9bf8
* Implemented which uses the overpass API to download power features for individual countries. * Extended rule by input. * Bug fixes and improvements to clean_osm_data.py. Added in retrieve_osm_data.py. * Updated clean_osm_data and retrieve_osm_data to create clean substations. * Finished clean_osm_data function. * Added check whether line is a circle. If so, drop it. * Extended build_electricity.smk by build_osm_network.py * Added build_osm_network * Working osm-network-fast * Bug fixes. * Finalised and cleaned including docstrings. * Added try catch to retrieve_osm_data. Allows for parallelisation of downloads. * Updated cleaning process. * Set maximum number of threads for retrieving to 4, wrt. fair usage policy and potential request errors. * Intermediate update on clean_osm_data.py. Added docstrings. * Bug fix. * Bug fix. * Bug fixes in data types out of clean_osm_data * Significant improvements to retrieve_osm_data, clean_osm_data. Cleaned code. Speed improvements * Cleaned config. * Fixes. * Bug fixes. * Updated default config * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Removed overpass from required packages. Not needed anymore. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Added links_relations (route = power, frequency = 0) to retrieval. This will change how HVDC links are extracted in the near future. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Work-in-progress clean_osm_data * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Added clean links output to clean_osm_data. Script uses OSM relations to retrieve clean HVDC links. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * New code for integrating HVDC links. Using relations. Base network implementation functioning. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * removed manual line dropping. * Updated clean script * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * reverted Snakefile to default: sync settings * added prebuilt functionality. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Updated build_electricity.smk to work with scenario management. * removed commented-out code. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * removed commented-out code. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Fixed bug in pdf export by substituting pdf export with svg. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Bug-fix Snakefile * dropped not needed columns from build_osm_network. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Updated build_shapes, config.default and clean_osm_data. * pre-commit changes. * test * Added initial prepare_osm_network_release.py script * Finalised prepare_osm_network_release script to build clean and stable OSM base_network input files. * Added new rules/development.smk * Updated clean_osm_data to add substation_centroid to linestrings * Updated clean_osm_data to add substation_centroid to linestrings * Updated clean_osm_data to add substation_centroid to linestrings * Updated clean_osm_data to add substation_centroid to linestrings * Added osm-prebuilt functionality and zenodo sandbox repository. * Updated clean_osm_data to geopandas v.1.01 * Made base_network and build_osm_network function more robust for empty links. * Made base_network and build_osm_network function more robust for empty links. * Bug fix in base_network. Voltage level null is now kept (relevant e.g. for Corsica) * Merge with hcanges in upstream PR 1146. Fixing UA and MD. * Updated Zenodo and fixed prepare_osm_network_release * Updated osm network release. * Updated prepare osm network release. * Updated MD, UA scripts. * Cleaned determine_availability_matrix_MD_UA.py, removed redundant code * Bug fixes. * Bug fixes for UA MD scripts. * Rename of build script. * Bug fix: only distribute load to buses with substation. * Updated zenodo sandbox repository. * Updated config.default * Cleaned config.default.yaml: Related settings grouped together and redundant voltage settings aggregated. * Cleaned config.default.yaml: Related settings grouped together and redundant voltage settings aggregated. Added release notes. * Updated Zenodo repositories for OSM-prebuilt to offcial publication. * Updated configtables * Updated links.csv: Under_construction lines to in commission. * Updated link 8394 and parameter_corrections: Continuation of North-Sea-Link. * Major update: fix simplify_network, fix Corsica, updated build_osm_network to include lines overpassing nodes. * remove config backup * Bug fix: Carrier type of all supernodes corrected to 'AC' * Bug fix: Carrier type of all supernodes corrected to 'AC' * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Updated rules and base_network for compatibility with TYNDP projects. * Updated Zenodo repository and prebuilt network to include 150 kV HVDC connections. * Removed outdated config backup. * Implemented all comments from PR #1079. Cleaned up OSM implementation. * Bug fix: Added all voltages, 200 kV-750 kV, to default config. * Cleaning and bugfixes. * Updated Zenodo repository to https://zenodo.org/records/13358976. Added converter voltages, 'underground' property for DC lines/cables, and included Konti-Skan HVDC (DK-SE). Added compatibility with https://github.com/PyPSA/pypsa-eur/pull/1079 and https://github.com/PyPSA/pypsa-eur/pull/1085 * Apply suggestions from code review * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * simplify_network: handle complicated transformer topologies * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * syntax fix --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Fabian Neumann <fabian.neumann@outlook.de>
153 lines
5.1 KiB
Python
153 lines
5.1 KiB
Python
# -*- coding: utf-8 -*-
|
|
# SPDX-FileCopyrightText: : 2020-2024 The PyPSA-Eur Authors
|
|
#
|
|
# SPDX-License-Identifier: MIT
|
|
"""
|
|
Retrieve OSM data for the specified country using the overpass API and save it
|
|
to the specified output files.
|
|
|
|
Note that overpass requests are based on a fair
|
|
use policy. `retrieve_osm_data` is meant to be used in a way that respects this
|
|
policy by fetching the needed data once, only.
|
|
"""
|
|
|
|
import json
|
|
import logging
|
|
import os
|
|
import time
|
|
|
|
import requests
|
|
from _helpers import ( # set_scenario_config,; update_config_from_wildcards,; update_config_from_wildcards,
|
|
configure_logging,
|
|
set_scenario_config,
|
|
)
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def retrieve_osm_data(
|
|
country,
|
|
output,
|
|
features=[
|
|
"cables_way",
|
|
"lines_way",
|
|
"links_relation",
|
|
"substations_way",
|
|
"substations_relation",
|
|
],
|
|
):
|
|
"""
|
|
Retrieve OSM data for the specified country and save it to the specified
|
|
output files.
|
|
|
|
Parameters
|
|
----------
|
|
country : str
|
|
The country code for which the OSM data should be retrieved.
|
|
output : dict
|
|
A dictionary mapping feature names to the corresponding output file
|
|
paths. Saving the OSM data to .json files.
|
|
features : list, optional
|
|
A list of OSM features to retrieve. The default is [
|
|
"cables_way",
|
|
"lines_way",
|
|
"substations_way",
|
|
"substations_relation",
|
|
].
|
|
"""
|
|
# Overpass API endpoint URL
|
|
overpass_url = "https://overpass-api.de/api/interpreter"
|
|
|
|
features_dict = {
|
|
"cables_way": 'way["power"="cable"]',
|
|
"lines_way": 'way["power"="line"]',
|
|
"links_relation": 'relation["route"="power"]["frequency"="0"]',
|
|
"substations_way": 'way["power"="substation"]',
|
|
"substations_relation": 'relation["power"="substation"]',
|
|
}
|
|
|
|
wait_time = 5
|
|
|
|
for f in features:
|
|
if f not in features_dict:
|
|
logger.info(
|
|
f"Invalid feature: {f}. Supported features: {list(features_dict.keys())}"
|
|
)
|
|
raise ValueError(
|
|
f"Invalid feature: {f}. Supported features: {list(features_dict.keys())}"
|
|
)
|
|
|
|
retries = 3
|
|
for attempt in range(retries):
|
|
logger.info(
|
|
f" - Fetching OSM data for feature '{f}' in {country} (Attempt {attempt+1})..."
|
|
)
|
|
|
|
# Build the overpass query
|
|
op_area = f'area["ISO3166-1"="{country}"]'
|
|
op_query = f"""
|
|
[out:json];
|
|
{op_area}->.searchArea;
|
|
(
|
|
{features_dict[f]}(area.searchArea);
|
|
);
|
|
out body geom;
|
|
"""
|
|
try:
|
|
# Send the request
|
|
response = requests.post(overpass_url, data=op_query)
|
|
response.raise_for_status() # Raise HTTPError for bad responses
|
|
data = response.json()
|
|
|
|
filepath = output[f]
|
|
parentfolder = os.path.dirname(filepath)
|
|
if not os.path.exists(parentfolder):
|
|
os.makedirs(parentfolder)
|
|
|
|
with open(filepath, mode="w") as f:
|
|
json.dump(response.json(), f, indent=2)
|
|
logger.info(" - Done.")
|
|
break # Exit the retry loop on success
|
|
except (json.JSONDecodeError, requests.exceptions.RequestException) as e:
|
|
logger.error(f"Error for feature '{f}' in country {country}: {e}")
|
|
logger.debug(
|
|
f"Response text: {response.text if response else 'No response'}"
|
|
)
|
|
if attempt < retries - 1:
|
|
wait_time += 15
|
|
logger.info(f"Waiting {wait_time} seconds before retrying...")
|
|
time.sleep(wait_time)
|
|
else:
|
|
logger.error(
|
|
f"Failed to retrieve data for feature '{f}' in country {country} after {retries} attempts."
|
|
)
|
|
except Exception as e:
|
|
# For now, catch any other exceptions and log them. Treat this
|
|
# the same as a RequestException and try to run again two times.
|
|
logger.error(
|
|
f"Unexpected error for feature '{f}' in country {country}: {e}"
|
|
)
|
|
if attempt < retries - 1:
|
|
wait_time += 10
|
|
logger.info(f"Waiting {wait_time} seconds before retrying...")
|
|
time.sleep(wait_time)
|
|
else:
|
|
logger.error(
|
|
f"Failed to retrieve data for feature '{f}' in country {country} after {retries} attempts."
|
|
)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
if "snakemake" not in globals():
|
|
from _helpers import mock_snakemake
|
|
|
|
snakemake = mock_snakemake("retrieve_osm_data", country="BE")
|
|
configure_logging(snakemake)
|
|
set_scenario_config(snakemake)
|
|
|
|
# Retrieve the OSM data
|
|
country = snakemake.wildcards.country
|
|
output = snakemake.output
|
|
|
|
retrieve_osm_data(country, output)
|