Visionneuse GeoJSON (QML)
L'exemple de visualiseur GeoJson montre comment manipuler des MapItems, gérer les entrées utilisateur et les opérations d'E/S vers et depuis un fichier GeoJson.

L'exemple affiche une carte comportant divers MapItems. Ces MapItems sont soit importés depuis un fichier GeoJson à l'aide de l'API GeoJsonData de QtLocation, soit dessinés par l'utilisateur à l'aide de TapHandlers.
Vous trouverez des exemples de fichiers GeoJSON dans le répertoire « data » du répertoire d’exemples.
Pour tracer un élément de carte (MapItem), cliquez avec le bouton droit de la souris sur une partie vide de la carte et sélectionnez le type d’élément de votre choix dans le menu qui s’affiche. Les clics suivants permettront de définir l’élément choisi. L’exemple permet de tracer des MapCircles, MapRectangles, MapPolygons et MapPolylines. Les éléments entièrement définis par deux points, c’est-à-dire les cercles et les rectangles, sont tracé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 avec le bouton gauche et finalisés à l’aide du bouton droit de la souris. Les éléments dessinés de cette manière sont enregistrés sous forme de points, de polygones et de polylignes conformément à la spécification GeoJSON, voir https://geojson.org/.
Exécution de l'exemple
Vous pouvez exécuter l’exemple à partir de :
- Qt Creator
Ouvrez le mode « Welcome » et sélectionnez l’exemple à l’adresse Examples. Pour plus d’informations, consultez Qt Creator: Tutoriel : Créer et exécuter.
- Qt Extension for Visual Studio Code
Exécutez la commande « Qt: Open Qt examples » à partir de Command Palette, puis sélectionnez l'exemple dans la liste. Pour plus d'informations, consultez Qt Extension for Visual Studio Code: Tutoriel : Compiler et exécuter.
Création d'une MapView
Nous commençons par créer une carte de base sur laquelle tous les éléments peuvent être placés. Nous utilisons un élément MapView qui combine une carte de base Map avec la gestion des entrées (molette de souris, glisser-déposer, etc.). La carte sous-jacente Map est accessible via la propriété map. Si une propriété vous manque dans MapView, vous pourrez très probablement y accéder via 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 MapItems
Afin d’afficher le contenu du fichier sur la carte, nous utiliserons un modèle de conception appelé « programmation modèle-vue ». Nous devons tout d’abord configurer une vue adaptée, dans cet exemple un élément MapItemView. Son parent doit être défini sur la carte sous-jacente de l’ 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 adapté, représentant un document GeoJSON. À cette fin, QtLocation propose l’élément GeoJsonData, capable de lire et d’écrire des fichiers GeoJSON. Il peut être facilement instancié
GeoJsonData {
id: geoDatabase
sourceUrl: ":/data/11-full.json"
}et attribué à l’objet ` MapItemView`.
model: geoDatabase.modelLe fichier ` 11-full.json ` est chargé au démarrage à titre d’exemple.
Enfin, nous avons besoin d’un ` delegate`, qui convertit les données du modèle en une représentation d’éléments et remplit le fichier ` MapItemView`.
delegate: GeoJsonDelegate {}L’élément ` GeoJsonDelegate ` est déclaré dans le fichier ` GeoJsonDelegate.qml`. Il s’agit d’un élément de type ` DelegateChooser `, afin de prendre 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 « DelegateChoice » pour chaque type de géométrie pouvant figurer dans un fichier GeoJSON. La propriété « role » sera mise en correspondance avec « DelegateChoice.roleValue » afin de déterminer le délégué approprié.
À titre d’exemple, un point, décrit par "type":"Point" dans GeoJson, est représenté par MapCircle dans la propriété 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
}
}Le système tente de lire les propriétés de l’ MapCircle, telles que color ou radius, à partir du fichier GeoJSON disponible sous la forme de la propriété modelData. Cependant, cela ne constitue pas une norme stricte de GeoJSON et des valeurs de secours sont définies pour toutes les propriétés.
Écriture de MapItems dans un fichier GeoJSON
Pour écrire des MapItems dans un fichier GeoJson, il suffit d’appeler la fonction ` GeoJsonData::saveAs ` en lui passant le nom de fichier souhaité. Cela permet d’écrire tous les éléments du modèle actuel dans le fichier spécifié. Tout autre élément devant être écrit dans le fichier doit d’abord être ajouté 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 de l'utilisateur, nous utiliserons les ` PointHandlers`. Ces derniers sont particulièrement bien adaptés à cette tâche, car ils épousent exactement la forme de l'élément sous-jacent, contrairement aux ` MouseArea`, qui couvrent toujours une forme carrée. Les `MapItems` importés depuis un fichier GeoJSON disposent de 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
}La propriété TapHandler sert à afficher des informations sur l’élément dans la console lorsque l’utilisateur appuie dessus. La propriété HoverHandler permet de mettre en surbrillance les éléments situés sous le pointeur de la souris. Cette fonctionnalité est mise en œuvre en définissant la propriété border.color en fonction de la propriété / de l’état hovered de l’ HoverHandler.
Ajout de nouveaux éléments
La combinaison des signaux « HoverHandler » et « TapHandler » pour la propriété « MapView » nous permet de réagir aux mouvements de souris et aux clics de l’utilisateur.
Si l’ TapHandler émet un signal singleTapped, nous créerons ou modifierons un nouvel élément MapItem sur LeftButton et finaliserons cet élément sur RightButton. S’il n’y a aucun élément à finaliser, RightButton ouvrira alors 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 sert à mettre à jour temporairement un MapItem, offrant ainsi 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 MapItems 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 pour permettre à l’utilisateur de le manipuler ultérieurement.
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.")
}
}Il suffit d'ajouter l'élément à la ` Map ` pour l'afficher. Cependant, pour pouvoir l'utiliser ultérieurement (par exemple, pour l'enregistrer dans un fichier), il doit être ajouté 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 reset 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.