Visualisateur GeoJson (QML)
L'exemple du visualisateur GeoJson montre comment manipuler les MapItems, gérer les entrées utilisateur et les E/S vers et depuis un fichier GeoJson.

L'exemple affiche une carte avec différents MapItems. Les MapItems sont soit importés à partir d'un fichier GeoJson, en utilisant l'API GeoJsonData de QtLocation, soit dessinés par l'utilisateur à l'aide de TapHandlers.
Des exemples de fichiers GeoJson peuvent être trouvés dans le répertoire data du répertoire example.
Pour dessiner un MapItem, faites un clic droit sur une partie vide de la carte et sélectionnez un type d'élément de votre choix dans le menu qui apparaît. Les prochains clics définiront l'élément choisi. L'exemple permet de dessiner MapCircles, MapRectangles, MapPolygons et MapPolylines. Les éléments entièrement définis par deux points, c'est-à-dire les cercles et les rectangles, sont dessinés en deux clics du bouton gauche de la souris. Les éléments définis par plusieurs points, c'est-à-dire les polygones et les polylignes, sont créés par un nombre arbitraire de clics sur le bouton gauche de la souris et complétés par le bouton droit de la souris. Les éléments dessinés de cette manière sont enregistrés en tant que points, polygones et polylignes pour correspondre à la spécification GeoJson, voir https://geojson.org/.
Exécution de l'exemple
Pour exécuter l'exemple à partir de Qt CreatorOuvrez le mode Welcome et sélectionnez l'exemple à partir de Examples. Pour plus d'informations, voir Qt Creator: Tutorial : Construire et exécuter.
Création d'une vue de carte
Nous commençons par créer une carte de base sur laquelle tous les éléments peuvent être placés. Nous tirons parti d'un élément MapView qui combine une Map de base avec la gestion des entrées (molette de la souris, glisser, etc.). La propriété map permet d'accéder à l'élément Map sous-jacent. Si vous manquez une propriété dans MapView, il est très probable que vous puissiez y accéder avec MapView.map.
MapView { id: view anchors.fill: parent map.plugin: Plugin { name: "osm" } map.zoomLevel: 4 map.center: QtPositioning.coordinate(3, 8) }
Configuration du modèle GeoJson / Affichage des éléments de la carte
Afin d'afficher le contenu des fichiers sur la carte, nous utiliserons un modèle de conception connu sous le nom de Programmation Modèle/Vue. Tout d'abord, nous devons mettre en place une vue appropriée, dans cet exemple un élément MapItemView. Son parent doit être défini sur la carte sous-jacente du site MapView afin d'afficher correctement tous les éléments qui y sont placés.
MapItemView { id: miv parent: view.map }
Ensuite, nous avons besoin d'un modèle approprié, représentant un document GeoJSON. À cette fin, QtLocation propose l'élément GeoJsonData qui peut lire et écrire des fichiers GeoJSON. Il peut être facilement instancié
GeoJsonData { id: geoDatabase sourceUrl: ":/data/11-full.json" }
et assigné à l'élément MapItemView.
model: geoDatabase.model
Le fichier 11-full.json est chargé au démarrage à titre d'exemple.
Enfin, nous avons besoin d'un élément delegate, qui traduit les données du modèle en une représentation des éléments, et qui remplit l'élément MapItemView.
delegate: GeoJsonDelegate {}
L'élément GeoJsonDelegate est déclaré dans le fichier GeoJsonDelegate.qml. Il s'agit d'un élément DelegateChooser, qui prend en compte les propriétés variables des différents types de géométrie.
DelegateChooser { id: dc role: "type" }
Le fichier DelegateChooser contient un élément DelegateChoice pour chaque type de géométrie qui peut être trouvé dans un fichier GeoJson. La propriété role sera mise en correspondance avec DelegateChoice.roleValue pour déterminer le délégué correct.
Par exemple, un point, décrit par "type":"Point" dans GeoJson, est représenté par MapCircle sur MapItemView:
DelegateChoice { roleValue: "Point" delegate: MapCircle { property string geojsonType: "Point" property var props: modelData.properties geoShape: modelData.data radius: (props && props.radius) || 20*1000 border.width: 2 border.color: hh.hovered ? "magenta" : Qt.darker(color) opacity: dc.defaultOpacity color: (props && props.color) || (parent && parent.props && parent.props.color) || dc.defaultColor } }
Les propriétés de MapCircle, telles que color ou radius, tentent d'être lues à partir du fichier GeoJson disponible sous la forme de la propriété modelData. Toutefois, il ne s'agit pas d'une norme stricte de GeoJson et des valeurs de repli sont définies pour toutes les propriétés.
Ecrire des MapItems dans GeoJson
Pour écrire des MapItems dans un fichier GeoJson, nous pouvons simplement appeler la fonction GeoJsonData::saveAs avec le nom de fichier désigné. Cela permet d'écrire tous les éléments du modèle actuel dans le fichier désigné. Tous les autres éléments qui doivent être écrits dans le fichier doivent d'abord être ajoutés au modèle à l'aide de la fonction GeoJsonData::addItem ou GeoJsonData::setModelToMapContents.
geoDatabase.saveAs(fileWriteDialog.selectedFile)
Interaction de l'utilisateur avec les MapItems
Pour gérer les interactions avec l'utilisateur, nous utiliserons PointHandlers. Les MapItems sont particulièrement bien adaptés à cette tâche car ils se conforment à la forme exacte de l'élément sous-jacent, contrairement à MouseArea, qui couvre toujours une forme carrée. Les MapItems importés d'un fichier GeoJson reçoivent leurs propres HoverHandler et TapHandler directement dans le délégué :
TapHandler { onTapped: { if (props !== undefined) console.log(props.name) else if (parent.parent.geojsonType == "MultiPoint") console.log(parent.parent.props.name) else console.log("NO NAME!", props) } } HoverHandler { id: hh }
Le TapHandler est utilisé pour écrire des informations sur l'élément dans la console lorsque l'on touche l'élément. Le HoverHandler est utilisé pour mettre en évidence les éléments qui se trouvent sous le pointeur de la souris. Cette fonction est mise en œuvre en décrivant la propriété border.color en fonction de la propriété / de l'état hovered du délégué HoverHandler.
Ajout de nouveaux éléments
Une combinaison de HoverHandler et TapHandler pour MapView nous permet de réagir aux mouvements de la souris et aux clics de l'utilisateur.
Si TapHandler émet un signal singleTapped, nous créons ou modifions un nouveau MapItem sur LeftButton et terminons le MapItem sur RightButton. S'il n'y a pas d'élément à terminer, RightButton ouvrira un menu.
onSingleTapped: (eventPoint, button) => { lastCoordinate = view.map.toCoordinate(tapHandler.point.position) if (button === Qt.RightButton) { if (view.unfinishedItem !== undefined) { view.finishGeoItem() } else mapPopupMenu.show(lastCoordinate) } else if (button === Qt.LeftButton) { if (view.unfinishedItem !== undefined) { if (view.unfinishedItem.addGeometry(view.map.toCoordinate(tapHandler.point.position), false)) { view.finishGeoItem() } } } }
Le signal pointChanged est utilisé pour mettre à jour temporairement un MapItem, en donnant un aperçu à l'utilisateur.
HoverHandler { id: hoverHandler property variant currentCoordinate grabPermissions: PointerHandler.CanTakeOverFromItems | PointerHandler.CanTakeOverFromHandlersOfDifferentType onPointChanged: { currentCoordinate = view.map.toCoordinate(hoverHandler.point.position) if (view.unfinishedItem !== undefined) view.unfinishedItem.addGeometry(view.map.toCoordinate(hoverHandler.point.position), true) } }
Les MapItem sont générés à partir de prototypes définis dans des fichiers qml distincts. Ils sont créés à l'aide de la fonction createComponent et ajoutés à la carte avec addMapItem. Une référence au nouvel élément est stockée en vue d'une manipulation ultérieure par l'utilisateur.
function addGeoItem(item) { var co = Qt.createComponent('mapitems/'+item+'.qml') if (co.status === Component.Ready) { unfinishedItem = co.createObject(map) unfinishedItem.setGeometry(tapHandler.lastCoordinate) unfinishedItem.addGeometry(hoverHandler.currentCoordinate, false) view.map.addMapItem(unfinishedItem) } else { console.log(item + " is not supported right now, please call us later.") } }
L'ajout de l'élément à Map suffit à l'afficher. Toutefois, pour pouvoir utiliser l'élément ultérieurement (par exemple en l'enregistrant dans un fichier), il faut l'ajouter au modèle. Cette opération s'effectue une fois l'édition terminée :
function finishGeoItem() { unfinishedItem.finishAddGeometry() geoDatabase.addItem(unfinishedItem) map.removeMapItem(unfinishedItem) unfinishedItem = undefined }
Suppression d'éléments
Pour supprimer tous les éléments de la carte, il suffit d'appeler la fonction de réinitialisation de l'objet GeoJsonData.
function clearAllItems() { geoDatabase.clear(); }
© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.