Visor GeoJson (QML)
El ejemplo del visor GeoJson demuestra cómo manipular MapItems, manejar la entrada del usuario y la E/S hacia y desde un archivo GeoJson.

El ejemplo muestra un mapa con varios MapItems. Los MapItems son importados desde un archivo GeoJson, utilizando la API GeoJsonData de QtLocation o dibujados por el usuario utilizando TapHandlers.
Puede encontrar ejemplos de archivos GeoJson en el directorio data dentro del directorio example.
Para dibujar un MapItem, haga clic con el botón derecho del ratón en una parte vacía del mapa y seleccione un tipo de elemento de su elección en el menú que aparece. Los siguientes clics definirán el elemento elegido. El ejemplo permite dibujar MapCircles, MapRectangles, MapPolygons y MapPolylines. Los elementos totalmente definidos por dos puntos, es decir, círculos y rectángulos, se dibujan con dos clics del botón izquierdo del ratón. Los elementos definidos por varios puntos, es decir, polígonos y polilíneas, se crean con una cantidad arbitraria de clics del botón izquierdo y se completan con el botón derecho del ratón. Los elementos dibujados de esta forma se guardan como puntos, polígonos y polilíneas para ajustarse a la especificación GeoJson, véase https://geojson.org/.
Ejecutar el ejemplo
Para ejecutar el ejemplo desde Qt Creatorabra el modo Welcome y seleccione el ejemplo de Examples. Para más información, consulte Qt Creator: Tutorial: Construir y ejecutar.
Creación de un MapView
Primero creamos un mapa base sobre el que se pueden colocar todos los elementos. Aprovechamos un elemento de MapView que combina un Map básico con manejo de entradas (rueda del ratón, arrastrar, etc.). Se puede acceder al Map subyacente con la propiedad map. Si echa en falta una propiedad en MapView, lo más probable es que se pueda acceder a ella con MapView.map.
MapView { id: view anchors.fill: parent map.plugin: Plugin { name: "osm" } map.zoomLevel: 4 map.center: QtPositioning.coordinate(3, 8) }
Configuración del modelo GeoJson / Visualización de MapItems
Para mostrar el contenido de los archivos en el mapa utilizaremos un patrón de diseño conocido como Programación Modelo/Vista. Primero tenemos que configurar una vista adecuada, en este ejemplo un elemento MapItemView. Su padre debe ser el mapa subyacente de MapView para mostrar correctamente todos los elementos colocados en él.
MapItemView { id: miv parent: view.map }
A continuación necesitamos un modelo adecuado, que represente un documento GeoJSON. Para ello, QtLocation ofrece el elemento GeoJsonData que puede leer y escribir archivos GeoJSON. Puede instanciarse fácilmente
GeoJsonData { id: geoDatabase sourceUrl: ":/data/11-full.json" }
y asignarlo a MapItemView.
model: geoDatabase.model
El archivo 11-full.json se carga al iniciarse como ejemplo.
Finalmente necesitamos un delegate, que traduzca los datos del modelo en una representación de elementos, llenando el MapItemView.
delegate: GeoJsonDelegate {}
El elemento GeoJsonDelegate se declara en el archivo GeoJsonDelegate.qml. Se trata de un elemento DelegateChooser, para tener en cuenta las propiedades variables de los distintos tipos de geometría.
DelegateChooser { id: dc role: "type" }
El DelegateChooser contiene un DelegateChoice para cada tipo de geometría que se puede encontrar en un archivo GeoJson. La propiedad role se cotejará con DelegateChoice.roleValue para determinar el delegado correcto.
Como ejemplo, un punto, descrito con "type":"Point" en GeoJson, está representado por un MapCircle en el 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 } }
Las propiedades de MapCircle, como color o radius se intentan leer del archivo GeoJson que está disponible en forma de la propiedad modelData. Sin embargo, éste no es un estándar estricto de GeoJson y se establecen valores de reserva para todas las propiedades.
Escribir MapItems en GeoJson
Para escribir MapItems en un archivo GeoJson podemos simplemente llamar a la función GeoJsonData::saveAs con el nombre de archivo designado. Esto escribe todos los elementos del modelo actual en el archivo designado. Cualquier otro elemento que deba escribirse en el archivo tiene que añadirse primero al modelo utilizando la función GeoJsonData::addItem o GeoJsonData::setModelToMapContents.
geoDatabase.saveAs(fileWriteDialog.selectedFile)
Interacción del usuario con MapItems
Para manejar las interacciones del usuario utilizaremos PointHandlers. Son especialmente adecuados para la tarea, ya que se ajustan a la forma exacta del elemento subyacente, en contraste con MouseArea, que siempre cubre una forma cuadrada. Los MapItems que se importan desde un archivo GeoJson obtienen sus propios HoverHandler y TapHandler directamente en el delegado:
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 }
TapHandler se utiliza para escribir información sobre el elemento en la consola cuando se pulsa sobre él. El HoverHandler se utiliza para resaltar los elementos que se encuentran bajo el puntero del ratón. Esto se implementa describiendo la propiedad border.color dependiendo de la propiedad / estado hovered del HoverHandler.
Añadir nuevos elementos
Una combinación de HoverHandler y TapHandler para el MapView nos permite reaccionar a los movimientos y clics del ratón por parte del usuario.
Si el TapHandler emite una señal singleTapped, crearemos o modificaremos un nuevo MapItem en LeftButton y finalizaremos el MapItem en RightButton. Si no hay ningún elemento que terminar, RightButton abrirá un menú.
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() } } } }
La señal pointChanged se utiliza para actualizar temporalmente un MapItem, dando al usuario una vista previa.
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) } }
Los Mapitems se generan a partir de prototipos que se definen en archivos qml independientes. Se crean con la función createComponent y se añaden al mapa con addMapItem. Se almacena una referencia al nuevo elemento para que el usuario pueda manipularlo posteriormente.
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.") } }
Añadir el elemento a Map es suficiente para visualizarlo. Sin embargo, para poder seguir utilizando el elemento (por ejemplo, guardarlo en un archivo), hay que añadirlo al modelo. Esto se hace una vez finalizada la edición:
function finishGeoItem() { unfinishedItem.finishAddGeometry() geoDatabase.addItem(unfinishedItem) map.removeMapItem(unfinishedItem) unfinishedItem = undefined }
Eliminar elementos
Para eliminar todos los elementos del mapa, basta con llamar a la función reset del objeto 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.