Skip to content

Chatbot web : itérer ​

Une fois le script testé et fonctionnel, nous allons demander quelques modifications :

  • utiliser une icone pour représenter les bureaux de Camptocamp sur la carte.

TIP

Utilisez la fonctionnalité Canvas de votre Chatbot, cela lui permet de modifier à la volée le code généré.

Demander des modifications ​

Je voudrais mettre une icone pour les bureaux, au lieu des points. Je l'ai téléchargée, elle s'appelle favicon.png.

Voici la réponse du chatbot :

📁 1. Assure-toi que : favicon.png est accessible localement (ex. : /home/ton_nom/favicon.png)

Le chemin est absolu (pas relatif)

🧑‍💻 2. Ajoute ce code après l’ajout de la couche dans le projet

python
icon_path = "/chemin/vers/favicon.png"  # <-- à adapter !

# Crée un symbole basé sur l'image
symbol = QgsMarkerSymbol.createSimple({
    'name': 'image',
    'image': icon_path,
    'size': '10'  # taille de l’icône en mm
})

# Appliquer le symbole à la couche
vl.renderer().setSymbol(symbol)
vl.triggerRepaint()

Cela permet de voir au premier abord ce que le chatbot comprend et ce qu'il est capable de générer.

Tester et corriger ​

Malheureusement, le code généré ne fonctionne pas tel quel.

> l'icone ne s'affiche pas

✅ Solution fonctionnelle : utiliser QgsRasterMarkerSymbolLayer

Voici le code corrigé à insérer pour que ton favicon.png s’affiche :

python
from qgis.core import QgsRasterMarkerSymbolLayer, QgsMarkerSymbol

# Appliquer une icône PNG avec RasterMarkerSymbolLayer
symbol_layer = QgsRasterMarkerSymbolLayer(icon_path)
symbol_layer.setSize(10)  # en mm

# Créer un symbole vide et y ajouter la couche raster
symbol = QgsMarkerSymbol()
symbol.changeSymbolLayer(0, symbol_layer)

# Appliquer à la couche
vl.renderer().setSymbol(symbol)
vl.triggerRepaint()

Résultat final ​

Le script complet qui fonctionne !

python
from qgis.core import *
from qgis.utils import iface
from PyQt5.QtCore import QVariant
from qgis.core import QgsRasterMarkerSymbolLayer, QgsMarkerSymbol

import requests

# Dictionnaire des bureaux
bureaux = {
    "Le Bourget-du-Lac": "Le Bourget-du-Lac, France",
    "Chambéry": "Chambéry, France",
    "Lausanne": "Lausanne, Switzerland",
    "Olten": "Olten, Switzerland",
    "Basel": "Basel, Switzerland",
    "Munich": "Munich, Germany"
}

# Fonction de géocodage avec Nominatim
def geocode(adresse):
    url = "https://nominatim.openstreetmap.org/search"
    params = {
        'q': adresse,
        'format': 'json',
        'limit': 1
    }
    try:
        r = requests.get(url, params=params, headers={'User-Agent': 'QGIS Script'})
        r.raise_for_status()
        results = r.json()
        if results:
            lon = float(results[0]['lon'])
            lat = float(results[0]['lat'])
            return lon, lat
    except Exception as e:
        print(f"Erreur pour {adresse} : {e}")
    return None

# Créer une couche mémoire
vl = QgsVectorLayer("Point?crs=EPSG:4326", "Bureaux Camptocamp", "memory")
pr = vl.dataProvider()
pr.addAttributes([QgsField("Nom", QVariant.String)])
vl.updateFields()

# Ajouter les points des bureaux
for nom, adresse in bureaux.items():
    coords = geocode(adresse)
    if coords:
        feat = QgsFeature()
        point = QgsPointXY(coords[0], coords[1])
        feat.setGeometry(QgsGeometry.fromPointXY(point))
        feat.setAttributes([nom])
        pr.addFeature(feat)

vl.updateExtents()
QgsProject.instance().addMapLayer(vl)

# Appliquer une icône personnalisée
icon_path = "/votre-chemin/public/favicon.png"  # Remplace par ton chemin local

symbol_layer = QgsRasterMarkerSymbolLayer(icon_path)
symbol_layer.setSize(10)  # en mm

# Créer un symbole vide et y ajouter la couche raster
symbol = QgsMarkerSymbol()
symbol.changeSymbolLayer(0, symbol_layer)

vl.renderer().setSymbol(symbol)

# Activer l'infobulle au survol
vl.setDisplayExpression('"Nom"')
vl.setMapTipTemplate('<b>Bureau :</b> [% "Nom" %]')
vl.triggerRepaint()

# Ajouter fond OSM si absent
tile_url = "type=xyz&url=https://tile.openstreetmap.org/{z}/{x}/{y}.png"
osm_exists = any(layer.name() == "OSM" for layer in QgsProject.instance().mapLayers().values())
if not osm_exists:
    osm_layer = QgsRasterLayer(tile_url, "OSM", "wms")
    if osm_layer.isValid():
        QgsProject.instance().addMapLayer(osm_layer)
    else:
        print("Erreur : couche OSM invalide")

# Zoom sur les bureaux
iface.mapCanvas().setExtent(vl.extent())
iface.mapCanvas().refresh()