Commit ed302711 authored by Eric Duminil's avatar Eric Duminil
Browse files

Split to metalink lib

parent 7346cda5
......@@ -9,11 +9,8 @@
# Datenmenge: ca. 150 GB
# Weitere Informationen: https://geodaten.bayern.de/odd/m/3/pdf/hinweise_daten_lod2_download.pdf
import random
import xml.etree.ElementTree as ET
from pathlib import Path
from citygml_download import TMP_DIR, Bundesland, CityGMLWithHash, download_all_files, download_file
from citygml_download import Bundesland, download_all_files
from metalink_download import download_metalink, parse_metalink
BAYERN = Bundesland(
"Bayern",
......@@ -22,55 +19,6 @@ BAYERN = Bundesland(
)
def download_metalink(metalink_url: str, tmp_path: Path = TMP_DIR) -> Path:
"""Download metalink file to temporary directory."""
print(f"Downloading {metalink_url}")
basename = metalink_url.split("/")[-1] or "metalink.xml"
metalink_path = tmp_path / basename
download_file(metalink_url, metalink_path)
return metalink_path
def parse_metalink(metalink_path: Path, bundesland: Bundesland) -> list[CityGMLWithHash]:
"""Parse metalink XML file and return CityGMLWithHash objects."""
print(f"Parsing metalink file: {metalink_path}")
tree = ET.parse(metalink_path)
root = tree.getroot()
# Handle namespace
ns = {"ml": "urn:ietf:params:xml:ns:metalink"}
files = []
for file_elem in root.findall("ml:file", ns):
filename = file_elem.get("name")
if filename is None:
raise ValueError(f"Not enough information from {file_elem}")
hash_node = file_elem.find('ml:hash[@type="sha-256"]', ns)
if hash_node is None or hash_node.text is None:
raise ValueError(f"{filename} has no sha256")
urls = [url.text for url in file_elem.findall("ml:url", ns) if url.text]
if len(urls) == 0:
raise ValueError(f"No URL for {file_elem}")
else:
# Randomize URL order to distribute load across servers
random.shuffle(urls)
url = urls[0]
files.append(
CityGMLWithHash(
url=url,
coordinate_reference_system="EPSG:25832",
bundesland=bundesland,
expected_sha256=hash_node.text,
)
)
return files
if __name__ == "__main__":
metalink_path = download_metalink(BAYERN.source)
......
import random
import xml.etree.ElementTree as ET
from pathlib import Path
from citygml_download import TMP_DIR, Bundesland, CityGMLWithHash, download_file
def download_metalink(metalink_url: str, tmp_path: Path = TMP_DIR) -> Path:
"""Download metalink file to temporary directory."""
print(f"Downloading {metalink_url}")
basename = metalink_url.split("/")[-1] or "metalink.xml"
metalink_path = tmp_path / basename
download_file(metalink_url, metalink_path)
return metalink_path
def parse_metalink(metalink_path: Path, bundesland: Bundesland) -> list[CityGMLWithHash]:
"""Parse metalink XML file and return CityGMLWithHash objects."""
print(f"Parsing metalink file: {metalink_path}")
tree = ET.parse(metalink_path)
root = tree.getroot()
# Handle namespace
ns = {"ml": "urn:ietf:params:xml:ns:metalink"}
files = []
for file_elem in root.findall("ml:file", ns):
filename = file_elem.get("name")
if filename is None:
raise ValueError(f"Not enough information from {file_elem}")
hash_node = file_elem.find('ml:hash[@type="sha-256"]', ns)
if hash_node is None or hash_node.text is None:
raise ValueError(f"{filename} has no sha256")
urls = [url.text for url in file_elem.findall("ml:url", ns) if url.text]
if len(urls) == 0:
raise ValueError(f"No URL for {file_elem}")
else:
# Randomize URL order to distribute load across servers
random.shuffle(urls)
url = urls[0]
files.append(
CityGMLWithHash(
url=url,
coordinate_reference_system="EPSG:25832",
bundesland=bundesland,
expected_sha256=hash_node.text,
)
)
return files
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment