From 9daf8e0fa5db84988679606c9b4c8f26ef463db1 Mon Sep 17 00:00:00 2001 From: gdamms Date: Fri, 24 Jul 2026 13:25:21 +0200 Subject: clean the repo --- src/rn.py | 173 +++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 97 insertions(+), 76 deletions(-) (limited to 'src/rn.py') diff --git a/src/rn.py b/src/rn.py index 0c6589c..c78f1c2 100644 --- a/src/rn.py +++ b/src/rn.py @@ -1,81 +1,102 @@ -import requests +import argparse +import json import re +import xml.etree.ElementTree as ET + +import requests + +from kml_utils import add_placemark, add_polygon, new_document, write_kml +LIST_URL = "https://reserves-naturelles.org/reserves-naturelles/" -def get_coordinates_from_url(url): + +def get_coordinates_from_url(url: str) -> list[tuple[float, float]] | None: + """Fetch a reserve page and extract its outer polygon ring. + + Args: + url (str): URL of the reserve page. + Returns: + list[tuple[float, float]] | None: (longitude, latitude) points, or None if no + coordinates could be found on the page. + """ response = requests.get(url) - regex = r"\[\[-?\d+\.\d+,-?\d+\.\d+\](?:,\[-?\d+\.\d+,-?\d+\.\d+\])+\]" - matche = re.search(regex, response.text) - if not matche: + match = re.search( + r"\[\[-?\d+\.\d+,-?\d+\.\d+\](?:,\[-?\d+\.\d+,-?\d+\.\d+\])+\]", response.text + ) + if not match: return None - coordinates = eval(matche.group(0)) - return coordinates - - -response = requests.get("https://reserves-naturelles.org/reserves-naturelles/") -regex = r"
  • " -matches = re.findall(regex, response.text) - -kml_file = open("reserves_naturelles.kml", "w", encoding="utf-8") -kml_file.write(""" - - - RN -""") - - -for i, match in enumerate(matches): - - regex = r"title=\"([^\"]+)\"" - full_name = re.search(regex, match) - if not full_name: - print(f"Full name not found in the match: {match}") - continue - full_name = full_name.group(1) - - regex = r"class=\"rsv_nom\">([^<]+)<" - name = re.search(regex, match) - if not name: - print(f"Name not found in the match: {match}") - continue - name = name.group(1) - - regex = r"href=\"([^\"]+)\"" - url = re.search(regex, match) - if not url: - print(f"URL not found in the match: {match}") - continue - url = url.group(1) - - coordinates = get_coordinates_from_url(url) - if not coordinates: - print(f"Coordinates not found for URL: {url}") - continue - - kml_file.write(f""" - - {name} - - {full_name}
    {url} -
    - - - - -""") - for coordinate in coordinates: - kml_file.write(f" {coordinate[0]},{coordinate[1]},0\n") - kml_file.write(""" - - - - -
    -""") - - print(f"Processed: {name} ({i+1: 3d}/{len(matches)})") - - -kml_file.write(""" -
    -
    """) + return [tuple(point) for point in json.loads(match.group(0))] + + +def get_reserves(list_url: str = LIST_URL) -> list[dict]: + """Fetch the reserves list page and extract each reserve's name and URL. + + Args: + list_url (str, optional): URL of the reserves list page. Defaults to LIST_URL. + Returns: + list[dict]: One {"full_name", "name", "url"} entry per reserve found on the page. + """ + response = requests.get(list_url) + items = re.findall(r"
  • ", response.text) + + reserves = [] + for item in items: + full_name_match = re.search(r"title=\"([^\"]+)\"", item) + name_match = re.search(r"class=\"rsv_nom\">([^<]+)<", item) + url_match = re.search(r"href=\"([^\"]+)\"", item) + + if not full_name_match or not name_match or not url_match: + print(f"Skipping incomplete list entry: {item}") + continue + + reserves.append( + { + "full_name": full_name_match.group(1), + "name": name_match.group(1), + "url": url_match.group(1), + } + ) + + return reserves + + +def scrape_reserves(list_url: str = LIST_URL) -> ET.Element: + """Scrape reserves-naturelles.org and build a KML tree with one Placemark per reserve. + + Args: + list_url (str, optional): URL of the reserves list page. Defaults to LIST_URL. + Returns: + ET.Element: The root element. + """ + root, document = new_document("RN") + + reserves = get_reserves(list_url) + for i, reserve in enumerate(reserves): + coordinates = get_coordinates_from_url(reserve["url"]) + if not coordinates: + print(f"No coordinates found for URL: {reserve['url']}") + continue + + placemark = add_placemark( + document, + name=reserve["name"], + description=f"{reserve['full_name']}
    {reserve['url']}", + ) + add_polygon(placemark, coordinates) + + print(f"Processed: {reserve['name']} ({i + 1:3d}/{len(reserves)})") + + return root + + +def main(): + parser = argparse.ArgumentParser(description="Scrape reserves-naturelles.org and export reserves to KML") + parser.add_argument("-o", "--output", default="reserves_naturelles.kml", help="Path to the output KML file") + args = parser.parse_args() + + root = scrape_reserves() + write_kml(root, args.output) + + +if __name__ == "__main__": + main() -- cgit v1.3.1