main.qml:
import QtQuick 2.14
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
import QtLocation 5.12
import QtPositioning 5.12
import OsmDataParser 1.0
ApplicationWindow {
visible: true
width: 800
height: 600
OsmDataParser {
id: osmParser
onOsmDataLoaded: {
// Use the parsed coordinates to create map elements (e.g., markers)
for (var i = 0; i < coordinates.length; i++) {
var coordinate = coordinates[i];
// Create MapQuickItem and assign it to a variable
var marker = MapQuickItem {
coordinate: QtPositioning.coordinate(coordinate.latitude, coordinate.longitude)
sourceItem: Item {
width: 32
height: 32
Image {
source: "marker.png" // Your custom marker image
}
}
};
// Add the MapQuickItem to the map
map.addMapItem(marker);
}
}
}
// Create a Map with OpenStreetMap as the map provider
Map {
id: map
anchors.fill: parent
plugin: Plugin { name: "osm" }
}
PositionSource {
active: true
onPositionChanged: {
// Center the map on the user's location (optional)
map.center = position.coordinate;
}
}
Component.onCompleted: {
// Load and parse the OSM XML data file
osmParser.parseOsmXml("india_osm.xml"); // Replace with your XML file path
}
}
main.cpp:
#include <QtQml>
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "qosmdataparser.h"
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
qmlRegisterType<OsmDataParser>("OsmDataParser", 1, 0, "OsmDataParser");
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
qosmdataparser.h:
#ifndef OSMDATAPARSER_H
#define OSMDATAPARSER_H
#include <QObject>
#include <QQmlApplicationEngine>
#include <QFile>
#include <QXmlStreamReader>
#include <QGeoCoordinate>
#include <QList>
class OsmDataParser : public QObject
{
Q_OBJECT
public:
explicit OsmDataParser(QObject* parent = nullptr);
Q_INVOKABLE void parseOsmXml(const QString& xmlFilePath);
signals:
void osmDataLoaded(const QList<QGeoCoordinate>& coordinates);
private:
QList<QGeoCoordinate> coordinateList;
};
#endif // OSMDATAPARSER_H
qosmdataparser.cpp:
#include "qosmdataparser.h"
OsmDataParser::OsmDataParser(QObject* parent)
: QObject(parent)
{
}
void OsmDataParser::parseOsmXml(const QString& xmlFilePath)
{
QFile file(xmlFilePath);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
{
// Handle file open error
return;
}
QXmlStreamReader xmlReader(&file);
while (!xmlReader.atEnd())
{
xmlReader.readNext();
if (xmlReader.isStartElement() && xmlReader.name() == "node")
{
double lat = xmlReader.attributes().value("lat").toDouble();
double lon = xmlReader.attributes().value("lon").toDouble();
QGeoCoordinate coordinate(lat, lon);
coordinateList.append(coordinate);
}
}
if (xmlReader.hasError())
{
// Handle XML parsing error
return;
}
emit osmDataLoaded(coordinateList);
}
Error:
/home/babloo/Qt_workspace/MapDemo/main.qml:21: error: Expected token `;'
How do I solve this issue?
I think the error is misleading here. It looks like you're trying to create an instance of a QML object (MapQuickItem) dynamically within javascript code. But you're doing it the wrong way. See Qt Docs: Dynamic QML Object Creation from JavaScript.
My recommendation is to create a Component, and then use
createObject
to generate the instance, like this:UPDATE:
You may find MapItemView to be a simpler way of populating your map though. I'm not an expert with this, but it might look something like this: