File size: 4,384 Bytes
4bb7968
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
"""
Downloads BD Charm-50 (BRGM's harmonized 1:50,000 geological maps) for
the departments covering the Eure/Risle study area.

CONFIRMED (via data.gouv.fr / InfoTerre): free, open (Licence Ouverte),
no authentication -- direct per-department ZIP download from InfoTerre.
This is a genuinely different access pattern than the WFS sources
elsewhere in this project (BD TOPO, BDCavités): no bbox query, no axis-
order ambiguity, just a fixed URL per department. Real, working URL
pattern (found directly, not guessed):
    http://infoterre.brgm.fr/telechargements/BDCharm50/GEO050K_HARM_XXX.zip
where XXX is the 3-digit department code (e.g. 027 for Eure).

NOTE: a separate, DIFFERENT distribution of this same underlying dataset
exists that requires CIGAL network membership (seen for at least Alsace
regional data) -- that is NOT what this script uses. This script only
uses the free InfoTerre download confirmed via data.gouv.fr.

DEPARTMENTS: 27 (Eure), 61 (Orne), 28 (Eure-et-Loir) -- 27 and 61
confirmed directly from real INSEE codes seen in this project's own
station_list.csv (61342, 27040, 27116, 27468); 28 included because the
Eure's own southern tributaries (Voise, Drouette) run through Chartres/
Dreux, unambiguously in Eure-et-Loir. Add more department codes via
--departments if the real geographic extent turns out to need them.

Usage:
    python -m scripts.download_bdcharm50
"""
import argparse
import zipfile
from pathlib import Path

import requests

DEFAULT_DEPARTMENTS = ["027", "028", "061"]
BASE_URL = "http://infoterre.brgm.fr/telechargements/BDCharm50"


def download_department(dept: str, output_dir: Path) -> bool:
    url = f"{BASE_URL}/GEO050K_HARM_{dept}.zip"
    zip_path = output_dir / f"GEO050K_HARM_{dept}.zip"

    print(f"  department {dept}: {url}")
    try:
        resp = requests.get(url, timeout=120, stream=True)
    except requests.RequestException as e:
        print(f"    FAILED: {e}")
        return False

    if resp.status_code != 200:
        print(f"    FAILED: HTTP {resp.status_code}")
        return False

    content_type = resp.headers.get("Content-Type", "")
    if "zip" not in content_type and "octet-stream" not in content_type:
        # A 200 status with an HTML content-type here usually means an
        # error page or a "department not available" page was returned
        # instead of the real ZIP -- catching this explicitly rather
        # than silently saving an HTML file with a .zip extension.
        print(f"    WARNING: Content-Type is {content_type!r}, not zip -- "
              f"this department's file may not exist at this URL. Saving "
              f"anyway for inspection, but verify before trusting it.")

    zip_path.write_bytes(resp.content)
    size_kb = zip_path.stat().st_size / 1024
    print(f"    saved {zip_path} ({size_kb:.0f} KB)")

    extract_dir = output_dir / f"dept_{dept}"
    try:
        with zipfile.ZipFile(zip_path) as zf:
            zf.extractall(extract_dir)
        shp_files = list(extract_dir.rglob("*.shp"))
        print(f"    extracted to {extract_dir} ({len(shp_files)} .shp file(s) found)")
        return True
    except zipfile.BadZipFile:
        print(f"    FAILED: downloaded file is not a valid zip -- likely an error page, "
              f"not real data. Check {zip_path} directly.")
        return False


def main() -> None:
    parser = argparse.ArgumentParser(description="Download BD Charm-50 geological maps")
    parser.add_argument("--departments", nargs="+", default=DEFAULT_DEPARTMENTS,
                         help="3-digit department codes, e.g. 027 028 061")
    parser.add_argument("--output-dir", type=Path, default=Path("datasets/bdcharm50"))
    args = parser.parse_args()

    args.output_dir.mkdir(parents=True, exist_ok=True)
    print(f"Downloading BD Charm-50 for departments: {args.departments}")
    print()

    results = {}
    for dept in args.departments:
        results[dept] = download_department(dept, args.output_dir)
        print()

    print("=" * 60)
    ok = [d for d, r in results.items() if r]
    failed = [d for d, r in results.items() if not r]
    print(f"Succeeded: {ok}")
    if failed:
        print(f"Failed: {failed} -- check the URL pattern still matches by visiting "
              f"https://infoterre.brgm.fr/page/telechargement-cartes-geologiques directly")


if __name__ == "__main__":
    main()