Why do I get "error: Expected token ';'"?

124 Views Asked by At

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?

1

There are 1 best solutions below

2
On

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:

Component {
    id: mapItem

    MapQuickItem {
        sourceItem: Item {
            width: 32
            height: 32
            Image {
                source: "marker.png" // Your custom marker image
            }
        }
    }
}

OsmDataParser {
    id: osmParser

    onOsmDataLoaded: {
        for (var i = 0; i < coordinates.length; i++) {
            var coordinate = coordinates[i];
            var marker = mapItem.createObject(map, { coordinate: QtPositioning.coordinate(coordinate.latitude, coordinate.longitude) }

            // Add the MapQuickItem to the map
            map.addMapItem(marker);
        }
    }
}

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:

MapItemView {
    model: coordinates
    delegate: MapQuickItem {
        sourceItem: Item {
            width: 32
            height: 32
            coordinate: modelData
            Image {
                source: "marker.png" // Your custom marker image
            }
        }
    }
}