Commit 732d5f11 authored by Eric Duminil's avatar Eric Duminil
Browse files

Working example?

parent c43d9971
...@@ -6,6 +6,7 @@ import json ...@@ -6,6 +6,7 @@ import json
import os import os
import sys import sys
from concurrent.futures import ThreadPoolExecutor, as_completed from concurrent.futures import ThreadPoolExecutor, as_completed
from datetime import datetime
from pathlib import Path from pathlib import Path
from download_metalink import SCRIPT_DIR, download_file from download_metalink import SCRIPT_DIR, download_file
...@@ -13,17 +14,7 @@ from download_metalink import SCRIPT_DIR, download_file ...@@ -13,17 +14,7 @@ from download_metalink import SCRIPT_DIR, download_file
NIEDERSACHSEN_GEOJSON_URL = ( NIEDERSACHSEN_GEOJSON_URL = (
"https://arcgis-geojson.s3.eu-de.cloud-object-storage.appdomain.cloud/lod2/lgln-opengeodata-lod2.geojson" "https://arcgis-geojson.s3.eu-de.cloud-object-storage.appdomain.cloud/lod2/lgln-opengeodata-lod2.geojson"
) )
NIEDERSACHSEN_JSON = SCRIPT_DIR / "tmp" / "niedersachsen_lod2.geojson"
tmp_path = SCRIPT_DIR / "tmp"
tmp_path.mkdir(parents=True, exist_ok=True)
if not NIEDERSACHSEN_JSON.exists():
download_file(NIEDERSACHSEN_GEOJSON_URL, NIEDERSACHSEN_JSON)
with open(NIEDERSACHSEN_JSON) as json_file:
data = json.load(json_file)
features = data["features"]
# { # {
# 'type': 'Feature', # 'type': 'Feature',
...@@ -50,19 +41,23 @@ features = data["features"] ...@@ -50,19 +41,23 @@ features = data["features"]
# TODO: Dry with 02_bayern.py and 10_nordrhein_westfalen.py, and move some functions to utils.py? # TODO: Dry with 02_bayern.py and 10_nordrhein_westfalen.py, and move some functions to utils.py?
# NOTE: Could define a CityGML class: URL, Path, Size, SHA, Date, UTM, Source, Bundesland. And "Check" method, as well as "Download". "Select", "Compress" too? # NOTE: Could define a CityGML class: URL, Path, Size, SHA, Date, UTM, Source, Bundesland. And "Up to date?", "Check" method, as well as "Download". "Select", "Compress" too?
def download_and_verify(file_info: dict, tmp_dir: Path, download_dir: Path, max_retries=3) -> bool: def download_and_verify(file_info: dict, tmp_dir: Path, download_dir: Path, max_retries=3) -> bool:
"""Download a file, verify its size, and move to final location.""" """Download a file, verify its size, and move to final location."""
filename = file_info["name"] url = file_info["xml"]
expected_size = int(file_info["size"]) filename = url.split("/")[-1]
urls = [NRW_SERVER + filename] last_updated_server = datetime.strptime(file_info["Aktualitaet"], "%Y-%m-%d %H:%M:%S")
urls = [url]
final_path = download_dir / filename final_path = download_dir / filename
# Check if file already exists and is valid # Check if file already exists and is valid
if final_path.exists(): if final_path.exists():
print(f"Checking existing file: {filename}") print(f"Checking existing file: {filename}")
if os.path.getsize(final_path) == expected_size: if (
os.path.getsize(final_path) > 0
and datetime.fromtimestamp(os.path.getmtime(final_path)) > last_updated_server
):
print(f"✓ {filename} already downloaded and verified") print(f"✓ {filename} already downloaded and verified")
return True return True
else: else:
...@@ -91,16 +86,14 @@ def download_and_verify(file_info: dict, tmp_dir: Path, download_dir: Path, max_ ...@@ -91,16 +86,14 @@ def download_and_verify(file_info: dict, tmp_dir: Path, download_dir: Path, max_
print(f" Verifying size for {filename}") print(f" Verifying size for {filename}")
actual_size = os.path.getsize(tmp_path) actual_size = os.path.getsize(tmp_path)
if actual_size == expected_size: if actual_size > 0:
# Move to final location # Move to final location
final_path.parent.mkdir(parents=True, exist_ok=True) final_path.parent.mkdir(parents=True, exist_ok=True)
tmp_path.rename(final_path) tmp_path.rename(final_path)
print(f"✓ {filename} downloaded and verified successfully") print(f"✓ {filename} downloaded and verified successfully")
return True return True
else: else:
print(f" Hash mismatch for {filename}") print("Empty GML")
print(f" Expected: {expected_size}")
print(f" Got: {actual_size}")
tmp_path.unlink() tmp_path.unlink()
print(f"✗ Failed to download {filename} after {max_retries} attempts") print(f"✗ Failed to download {filename} after {max_retries} attempts")
...@@ -108,20 +101,25 @@ def download_and_verify(file_info: dict, tmp_dir: Path, download_dir: Path, max_ ...@@ -108,20 +101,25 @@ def download_and_verify(file_info: dict, tmp_dir: Path, download_dir: Path, max_
def download_all_files( def download_all_files(
json_filename: str, download_path: Path, tmp_path: Path = SCRIPT_DIR / "tmp", jobs: int = 4, retries: int = 3 json_url: str,
local_json: str,
download_path: Path,
tmp_path: Path = SCRIPT_DIR / "tmp",
jobs: int = 4,
retries: int = 3,
): ):
# Create directories # Create directories
tmp_path.mkdir(parents=True, exist_ok=True) tmp_path.mkdir(parents=True, exist_ok=True)
download_file( local_json_path = tmp_path / local_json
json_filename, if not local_json_path.exists():
NRW_JSON, download_file(json_url, local_json_path)
)
with open(NRW_JSON) as json_file: with open(local_json_path) as json_file:
data = json.load(json_file) data = json.load(json_file)
# Parse metalink file features = data["features"][:20]
files = [file for sets in data["datasets"] for file in sets["files"]]
files = [feature["properties"] for feature in features]
print(f"Found {len(files)} files to download\n") print(f"Found {len(files)} files to download\n")
...@@ -133,7 +131,7 @@ def download_all_files( ...@@ -133,7 +131,7 @@ def download_all_files(
with ThreadPoolExecutor(max_workers=jobs) as executor: with ThreadPoolExecutor(max_workers=jobs) as executor:
futures = { futures = {
executor.submit(download_and_verify, file_info, tmp_path, download_path, retries): file_info["name"] executor.submit(download_and_verify, file_info, tmp_path, download_path, retries): file_info["xml"]
for file_info in files for file_info in files
} }
...@@ -158,4 +156,8 @@ def download_all_files( ...@@ -158,4 +156,8 @@ def download_all_files(
if __name__ == "__main__": if __name__ == "__main__":
download_all_files(NRW_SERVER + "index.json", SCRIPT_DIR / "citygml" / "nordrhein_westfalen") download_all_files(
NIEDERSACHSEN_GEOJSON_URL,
"niedersachsen_lod2.geojson",
SCRIPT_DIR / "citygml" / "niedersachsen",
)
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