Search code examples
qtdictionarypluginsqmlhost

Dynamically change custom host URL of osm Plugin in a QML Map


I have a custom chart host with several tiled maps in a directory structure:

http://host/New_York/
http://host/Washington/
http://host/Montreal/

The QML application has a ComboBox component that allows the user to select which chart he wants to display.

The Map component uses the osm Plugin with a PluginParameter pointing to the URL to use for the chart. I thought I could simply dynamically assign a value to this PluginParameter, but it does not work, the value remains unchanged even after assigning it. I also tried destroying the Plugin object, recreating it and assigning it to the Map object, but I get an error saying that the plugin property is ReadOnly.

What is the proper way to dynamically change the custom host URL of a Plugin object used by a Map component?

    Plugin {
        id: mapPlugin
        name: "osm"

        PluginParameter { id: charturl; name: "osm.mapping.custom.host"; }
    }

    Map {
        id: mapview
        plugin: mapPlugin
        activeMapType: supportedMapTypes[supportedMapTypes.length - 1]
...

    ComboBox {
...
        onCurrentIndexChanged: {
            charturl.value = cbItems.get(currentIndex).url
...

Solution

  • The Plugin can only be written once, so you cannot change it later, so in this you will have to create a new map using Loader:

    main.qml

    import QtQuick 2.14
    import QtQuick.Window 2.14
    import QtQuick.Layouts 1.14
    import QtQuick.Controls 2.14
    
    import QtLocation 5.14
    import QtPositioning 5.14
    
    Window {
        visible: true
        width: 640
        height: 480
        ColumnLayout {
            anchors.fill: parent
            ComboBox {
                id: combobox
                model: [
                    "http://host/New_York/",
                    "http://host/Washington/",
                    "http://host/Montreal/"
                ]
                Layout.fillWidth: true
                onActivated: changeHost()
            }
            Loader{
                id: loader
                Layout.fillWidth: true
                Layout.fillHeight: true
                onStatusChanged: if (loader.status === Loader.Ready) console.log('Loaded')
            }
            Component.onCompleted: changeHost()
        }
        function changeHost(){
            var item = loader.item
            var zoomLevel = item ? item.zoomLevel: 14
            var center = item ? item.center: QtPositioning.coordinate(59.91, 10.75)
    
            loader.setSource("MapComponent.qml", {
                                 "host": combobox.currentValue,
                                 "center": center,
                                 "zoomLevel": zoomLevel}
                             )
        }
    }
    

    MapComponent.qml

    import QtLocation 5.14
    
    Map {
        id: map
        property string host: ""
        plugin: Plugin {
            name: "osm"
            PluginParameter {
                name: "osm.mapping.custom.host"
                value: map.host
            }
        }
        activeMapType: supportedMapTypes[supportedMapTypes.length - 1]
    }