Search code examples
c++qtqmlqtpositioning

It's possible to draw MapPolygon with a hole on Map in QML?


In C++ I can use QPainterPath::subtracted for drawing polygon with hole, but I don't know, how it's possible in QML Map.


Solution

  • Since Qt 5.13 is possible with the Mapbox GL Plugin, for example using a QGeoPolygon, you could also use GeoJSON. For example:

    main.cpp

    #include <QGeoPolygon>
    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    #include <QQmlContext>
    
    int main(int argc, char *argv[])
    {
        QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    
        QGuiApplication app(argc, argv);
    
        QGeoPolygon polygon;
        polygon.setPath({{51.11, 17.13},
                         {50.42, 30.54},
                         {58.36, 26.70},
                         {51.11, 17.13}});
        polygon.addHole({{54.36, 23.46},
                         {51.91, 20.52},
                         {51.50, 28.25},
                         {54.36, 26.80},
                         {54.36, 23.46}});
    
        QQmlApplicationEngine engine;
        engine.rootContext()->setContextProperty("poly", QVariant::fromValue(polygon));
        const QUrl url(QStringLiteral("qrc:/main.qml"));
        QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                         &app, [url](QObject *obj, const QUrl &objUrl) {
            if (!obj && url == objUrl)
                QCoreApplication::exit(-1);
        }, Qt::QueuedConnection);
        engine.load(url);
    
        return app.exec();
    }
    

    main.qml

    import QtQuick 2.12
    import QtQuick.Window 2.12
    import QtLocation 5.13
    import QtPositioning 5.13
    
    Window {
        visible: true
        width: 640
        height: 480
        Map {
            anchors.fill: parent
            center: QtPositioning.coordinate(52, 22)
            plugin: Plugin {
                name: "mapboxgl"
            }
            zoomLevel: 4
            MapPolygon {
                color: "red"
                border.color: "green"
                border.width: 2
                smooth: true
                opacity: 0.25
                geoShape: poly
            }
        }
    }
    

    enter image description here