5 min read

Convertir une carte Google MyMaps en JSON, facilement.

Et si on faisait un peu de Python pour transformer une carte Google en fichier utilisable partout ?
Convertir une carte Google MyMaps en JSON, facilement.

J'ai eu besoin de transformer une carte Google MyMaps en fichier JSON, pas de souci, il y a Python pour ça : il suffit de créer un script dédié. Même si j'adore Google Maps, parfois j'ai besoin de sortir l'information et de l'utiliser à la volée sur d'autres sites ou d'autres outils.


Donc bon, petit rappel : j'avais besoin de convertir un fichier Google MyMaps KML en JSON. Le format KML, utilisé pour représenter les données géospatiales, n'est pas directement lisible par les scripts de cartographie courants, qui préfèrent souvent le JSON.

L'objectif était donc de développer un script Python capable de :

  1. Télécharger un fichier KML ou KMZ à partir d'un lien de partage Google MyMaps (comme ça, on récupère de n'importe où, oui je vous vois les pirates).
  2. Convertir ce fichier en JSON, parce que c'est cool.
  3. Enregistrer le JSON avec un nom de fichier pertinent (nom de la carte ou nom du fichier KML/KMZ).

Après plusieurs itérations et ajustements, j'ai fini par développer un script Python robuste qui :

  • Télécharge le fichier KML ou KMZ.
  • Gère la décompression des fichiers KMZ.
  • Convertit le contenu KML en JSON.
  • Nomme le fichier JSON de manière appropriée.

Le script, il fait quoi en fait ?

1 - On télécharge.

Pour commencer, on télécharge le fichier KML ou KMZ à partir de l'URL de partage. On utilise la bibliothèque requests pour effectuer cette opération et on vérifie le type de contenu pour différencier les fichiers KML et KMZ.

def download_kml_or_kmz(url):
    response = requests.get(url)
    response.raise_for_status()  # Ensure we notice bad responses
    content_type = response.headers.get('Content-Type')
    
    if 'xml' in content_type ou 'kml' in content_type:
        return response.content, 'map'
    elif 'kmz' in content_type:
        with zipfile.ZipFile(io.BytesIO(response.content)) as kmz:
            for file_name in kmz.namelist():
                if file_name.endswith('.kml'):
                    with kmz.open(file_name) as kml_file:
                        return kml_file.read(), os.path.splitext(file_name)[0]
        raise ValueError("KMZ file does not contain a KML file")
    else:
        raise ValueError("URL does not point to a KML or KMZ file")

2 - On extrait.

Une fois le fichier KML téléchargé, on extrait les Points of Interest (POIs) et le nom de la carte. La bibliothèque xmltodict est utilisée pour convertir le contenu XML en dictionnaire Python.

def extract_pois(kml_dict):
    pois = []
    document = kml_dict.get('kml', {}).get('Document', {})
    
    folders = document.get('Folder', [])
    if isinstance(folders, dict):  # Ensure folders is a list
        folders = [folders]

    for folder in folders:
        placemarks = folder.get('Placemark', [])
        if isinstance(placemarks, dict):  # Ensure placemarks is a list
            placemarks = [placemarks]
        
        for placemark in placemarks:
            poi = {}
            poi['name'] = placemark.get('name')
            poi['description'] = placemark.get('description')
            
            point = placemark.get('Point')
            if point:
                coordinates = point.get('coordinates')
                if coordinates:
                    lon, lat, _ = map(float, coordinates.split(','))
                    poi['location'] = {
                        'latitude': lat,
                        'longitude': lon
                    }
            
            pois.append(poi)
    
    return pois

def extract_name(kml_dict):
    document = kml_dict.get('kml', {}).get('Document', {})
    name = document.get('name')
    if name:
        return name
    return None

3 - On passe en JSON.

Ensuite, on convertit les données KML extraites en JSON et on enregistre le fichier avec un nom pertinent.

def kml_to_json(kml_content, json_file_path):
    kml_dict = xmltodict.parse(kml_content)
    map_name = extract_name(kml_dict)
    pois = extract_pois(kml_dict)
    json_content = json.dumps(pois, indent=4, ensure_ascii=False)
    
    if not map_name:
        map_name = os.path.splitext(os.path.basename(json_file_path))[0]
    json_file_path = f"{map_name}.json"
    
    with open(json_file_path, 'w', encoding='utf-8') as json_file:
        json_file.write(json_content)
    
    return json_file_path  # Return the actual file path used

4 - On met en forme.

Enfin, le script principal demande à l'utilisateur de fournir l'URL de partage, télécharge le fichier KML/KMZ, et convertit les données en JSON.

if __name__ == "__main__":
    share_url = input("Veuillez entrer l'URL de partage de votre carte Google MyMaps : ")
    try:
        unique_id = share_url.split("mid=")[-1]
        kml_url = f"https://www.google.com/maps/d/kml?mid={unique_id}"

        kml_content, default_name = download_kml_or_kmz(kml_url)
        json_file_path = kml_to_json(kml_content, f"{default_name}.json")
        print(f"Le fichier KML/KMZ a été téléchargé et converti en JSON avec succès sous le nom {json_file_path}.")
    except Exception as e:
        print(f"Une erreur s'est produite : {e}")

Pourquoi Python ?

Je suis un ancien dev. Pas un de la nouvelle génération. J'adore PHP et le Vanilla JavaScript.

Oui, ça étonne toujours.

Mais Python est un excellent choix pour ce type de tâche pour plusieurs raisons :

  • Facilité d'utilisation : Python a une syntaxe claire et lisible, ce qui le rend accessible même aux débutants (comme moi).
  • Richesse des bibliothèques : La vaste collection de bibliothèques Python, comme requests et xmltodict, simplifie considérablement le traitement des données et les opérations HTTP.
  • Communauté active : Une communauté active signifie que vous pouvez trouver de l'aide facilement et accéder à de nombreux tutoriels et ressources.

Méthodologie MVP.

Je fonctionne toujours en mode MVP (Minimum Viable Product). Cette méthode me permet de me focaliser sur l'essentiel et de livrer rapidement une première version fonctionnelle. Une fois cette version en place, je peux l'améliorer itérativement en fonction des retours et des nouveaux besoins.

Cela permet de valider les idées rapidement et d'ajuster le développement en fonction des réalités du terrain. Ce script a suivi cette approche, évoluant de manière itérative jusqu'à atteindre une solution robuste.

TL;DR.

Ok ok, voilà le script complet à copier / coller :

Ce script télécharge un fichier KML ou KMZ à partir d’un lien de partage Google MyMaps, extrait les Points of Interest (POIs), et convertit les données en JSON en enregistrant le fichier avec un nom pertinent.
Ce script télécharge un fichier KML ou KMZ à partir d’un lien de partage Google MyMaps, extrait les Points of Interest (POIs), et convertit les données en JSON en enregistrant le fichier avec un no…

Et après ?

N'oubliez pas que vous pouvez aussi découvrir mon service de cartographie qui permet de jouer avec vos POI, les afficher partout, ajouter du contenu dédié, avoir des interfaces exploitable sur n'importe quel device, avec du tracking ...

Le tout de façon un peu sexy et avec un nom rigolo :

LesGrossesCartes - La cartographie repensée
Renforcez votre notoriété, améliorez l’expérience utilisateur et performez sur le web avec nos cartes interactives.