Change Basemap with button

446
5
Jump to solution
08-16-2019 06:43 AM
jaykapalczynski
Frequent Contributor

Simply trying to change the basemap with a click of a button any it does not seem to be working....any thoughts?

import ArcGIS.AppFramework 1.0
import ArcGIS.AppFramework.Controls 1.0
import QtQuick 2.9
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import Esri.ArcGISRuntime 100.5
import QtQuick.Layouts 1.1

Item {

    signal previous(string message)
    property string basemapId: "http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer"

    MapView {
        id:mapView
        Layout.fillHeight: true
        Layout.alignment: Qt.AlignTop
        width: parent.width
        height: parent.height
        property real initialMapRotation: 0

        Map {
            id: map
            Basemap {
                id: basemaplocation
                ArcGISTiledLayer {
                    id: baseMap
                    url: basemapId 
                    visible: true
                }
            }
        }
    }


    Row {
        anchors {
            bottom: parent.bottom
            left: parent.left
            right: parent.right
            margins: 5 * scaleFactor
            bottomMargin: 50 * scaleFactor
        }
        spacing: 5
        Button {
            text: "Switch Basemap"
            onClicked: {
                console.log("changing basemamp");
                basemapId = "http://services.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer"
                baseMap.load(basemapId);
            }
        }
    }

}
0 Kudos
1 Solution

Accepted Solutions
jaykapalczynski
Frequent Contributor

I changed my code to this and everything works fine....

Thanks Harsh from ESRI 

It was in reference to this example: https://github.com/Esri/arcgis-runtime-samples-qt/tree/master/ArcGISRuntimeSDKQt_QMLSamples/Maps/Cha...

that used a combobox and its index to find the correct map to load....As I was using a button I had to create that index and decided to do so with an If then statement and an index number I created to loop through the maps. 

Anyone know a better way to do this?

import ArcGIS.AppFramework 1.0
import ArcGIS.AppFramework.Controls 1.0
import QtQuick 2.9
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import Esri.ArcGISRuntime 100.5
import QtQuick.Layouts 1.1

Item {

    signal previous(string message)
    property string basemapId: ""
    property int basemapindex: 1
    MapView {
        id:mapView
        Layout.fillHeight: true
        Layout.alignment: Qt.AlignTop
        width: parent.width
        height: parent.height
        property real initialMapRotation: 0

        Map {
            id: map
            initialViewpoint: viewPoint
            // Set the initial basemap to Topographic
            BasemapTopographic {}
        } // END OF MAP

    } // END OF MAPVIEW

    ListModel {
        id: cbItems

        ListElement { text: "Topographic"; map: "BasemapTopographic" }
        ListElement { text: "Streets (Vector)"; map: "BasemapStreetsVector" }
        ListElement { text: "Streets - Night (Vector)"; map: "BasemapStreetsNightVector" }
        ListElement { text: "Imagery with Labels (Vector)"; map: "BasemapImageryWithLabelsVector" }
        ListElement { text: "Navigation (Vector)"; map: "BasemapNavigationVector" }
        //ListElement { text: "Streets"; map: "BasemapStreets" }
        //ListElement { text: "Imagery (Raster)"; map: "BasemapImagery" }
        //ListElement { text: "Imagery with Labels (Raster)"; map: "BasemapImageryWithLabels" }
        //ListElement { text: "Dark Gray Canvas (Vector)"; map: "BasemapDarkGrayCanvasVector" }
        //ListElement { text: "Light Gray Canvas (Raster)"; map: "BasemapLightGrayCanvas" }
        //ListElement { text: "Light Gray Canvas (Vector)"; map: "BasemapLightGrayCanvasVector" }
        //ListElement { text: "OpenStreetMap (Raster)"; map: "BasemapOpenStreetMap" }
        //ListElement { text: "Oceans"; map: "BasemapOceans" }
    }

    Row {
        anchors {
            bottom: parent.bottom
            left: parent.left
            right: parent.right
            margins: 5 * scaleFactor
            bottomMargin: 50 * scaleFactor
        }
        spacing: 5

        Button {
            id: buttontext
            text: "Topo"
            onClicked: {
                if (basemapindex == 1) {
                    changeBasemap(cbItems.get(1).map);
                    basemapindex = 2
                    buttontext.text = "Streets"
                } else if (basemapindex == 2){
                    changeBasemap(cbItems.get(2).map);
                    basemapindex = 3
                    buttontext.text = "Street Night"
                } else if (basemapindex == 3){
                    changeBasemap(cbItems.get(3).map);
                    basemapindex = 4
                    buttontext.text = "Imagery Labels"
                } else if (basemapindex == 4){
                    changeBasemap(cbItems.get(4).map);
                    basemapindex = 0
                    buttontext.text = "Navigation"
                } else if (basemapindex == 0){
                    basemapindex = 1
                    changeBasemap(cbItems.get(0).map);
                    buttontext.text = "Topo"
                }
                function changeBasemap(type) {
                    map.basemap = ArcGISRuntimeEnvironment.createObject(type);
                }
            } // End of OnClicked
        } // End of Button
    } // End of Row

    ViewpointCenter {
        id: viewPoint
        center: Point {
            //x: -13630484
            //y: 4545415
            x: -8622115
            y: 4513608
            spatialReference: SpatialReference {
                wkid: 102100
            }
        }
        targetScale: 3000000
    }
}
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

View solution in original post

0 Kudos
5 Replies
jaykapalczynski
Frequent Contributor

I found a way and did it like this....if anyone knows a smoother way please chime in...

import ArcGIS.AppFramework 1.0
import ArcGIS.AppFramework.Controls 1.0
import QtQuick 2.9
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import Esri.ArcGISRuntime 100.5
import QtQuick.Layouts 1.1


Item {

    signal previous(string message)
    property string basemapId: ""
    property int basemapindex: 1


    MapView {
        id:mapView
        Layout.fillHeight: true
        Layout.alignment: Qt.AlignTop
        width: parent.width
        height: parent.height
        property real initialMapRotation: 0

        Map {
            id: map
            initialViewpoint: viewPoint

        } // END OF MAP

    } // END OF MAPVIEW

    Component.onCompleted: {
         loadWebMap(cbItems2.get(0).item)
    }


    // Javascript Functions
    // Function to load webmap
    function loadWebMap(webmapitemid){
        var organizationPortalUrl = "http://arcgis.com/sharing/rest/content/items/";
        var webmapUrl = organizationPortalUrl + webmapitemid;
        var newMap = ArcGISRuntimeEnvironment.createObject("Map", {initUrl: webmapUrl, autoFetchLegendInfos:true});
        mapView.map = newMap;
    }


    ListModel {
        id: cbItems2
        ListElement { name: "Imagery hybrid w Labels"; item: "86265e5a4bbb4187a59719cf134e0018" }
        ListElement { name: "Topo"; item: "d5e02a0c1f2b4ec399823fdd3c2fdebd" }
        ListElement { name: "Topographic"; item: "931d892ac7a843d7ba29d085e0433465" }
        ListElement { name: "Streets"; item: "8bf7167d20924cbf8e25e7b11c7c502c" }
        ListElement { name: "Streets Nights"; item: "7e2b9be8a9c94e45b7f87857d8d168d6" }
    }


    Row {
        anchors {
            bottom: parent.bottom
            left: parent.left
            right: parent.right
            margins: 5 * scaleFactor
            bottomMargin: 50 * scaleFactor
        }
        spacing: 5
        Button {
            id: buttontext
            text: "Imagery"
            onClicked: {

                if (basemapindex == 1) {
                   loadWebMap(cbItems2.get(1).item)
                   basemapindex = 2
                    buttontext.text = "Topo"
                } else if (basemapindex == 2){
                   loadWebMap(cbItems2.get(2).item)
                   basemapindex = 3
                    buttontext.text = "Topographic"
                } else if (basemapindex == 3){
                   loadWebMap(cbItems2.get(3).item)
                   basemapindex = 4
                    buttontext.text = "Streets"
                } else if (basemapindex == 4){
                   loadWebMap(cbItems2.get(4).item)
                   basemapindex = 0
                    buttontext.text = "Streets Night"
                } else if (basemapindex == 0){
                   basemapindex = 1
                    loadWebMap(cbItems2.get(0).item)
                    buttontext.text = "Imagery"
                }
            }
        }
    }

    ViewpointCenter {
        id: viewPoint
        center: Point {
            //x: -13630484
            //y: 4545415
            x: -8622115
            y: 4513608
            spatialReference: SpatialReference {
                wkid: 102100
            }
        }
        targetScale: 3000000
    }



}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos
jaykapalczynski
Frequent Contributor

My only problem now is that when I switch between them it zooms me way out ....I want to keep the user at the spot they were last zoomed to.....I guess I need to capture the current extent and put that in....not sure how to do that.  Thoughts?

0 Kudos
jaykapalczynski
Frequent Contributor

I changed my code to this and everything works fine....

Thanks Harsh from ESRI 

It was in reference to this example: https://github.com/Esri/arcgis-runtime-samples-qt/tree/master/ArcGISRuntimeSDKQt_QMLSamples/Maps/Cha...

that used a combobox and its index to find the correct map to load....As I was using a button I had to create that index and decided to do so with an If then statement and an index number I created to loop through the maps. 

Anyone know a better way to do this?

import ArcGIS.AppFramework 1.0
import ArcGIS.AppFramework.Controls 1.0
import QtQuick 2.9
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import Esri.ArcGISRuntime 100.5
import QtQuick.Layouts 1.1

Item {

    signal previous(string message)
    property string basemapId: ""
    property int basemapindex: 1
    MapView {
        id:mapView
        Layout.fillHeight: true
        Layout.alignment: Qt.AlignTop
        width: parent.width
        height: parent.height
        property real initialMapRotation: 0

        Map {
            id: map
            initialViewpoint: viewPoint
            // Set the initial basemap to Topographic
            BasemapTopographic {}
        } // END OF MAP

    } // END OF MAPVIEW

    ListModel {
        id: cbItems

        ListElement { text: "Topographic"; map: "BasemapTopographic" }
        ListElement { text: "Streets (Vector)"; map: "BasemapStreetsVector" }
        ListElement { text: "Streets - Night (Vector)"; map: "BasemapStreetsNightVector" }
        ListElement { text: "Imagery with Labels (Vector)"; map: "BasemapImageryWithLabelsVector" }
        ListElement { text: "Navigation (Vector)"; map: "BasemapNavigationVector" }
        //ListElement { text: "Streets"; map: "BasemapStreets" }
        //ListElement { text: "Imagery (Raster)"; map: "BasemapImagery" }
        //ListElement { text: "Imagery with Labels (Raster)"; map: "BasemapImageryWithLabels" }
        //ListElement { text: "Dark Gray Canvas (Vector)"; map: "BasemapDarkGrayCanvasVector" }
        //ListElement { text: "Light Gray Canvas (Raster)"; map: "BasemapLightGrayCanvas" }
        //ListElement { text: "Light Gray Canvas (Vector)"; map: "BasemapLightGrayCanvasVector" }
        //ListElement { text: "OpenStreetMap (Raster)"; map: "BasemapOpenStreetMap" }
        //ListElement { text: "Oceans"; map: "BasemapOceans" }
    }

    Row {
        anchors {
            bottom: parent.bottom
            left: parent.left
            right: parent.right
            margins: 5 * scaleFactor
            bottomMargin: 50 * scaleFactor
        }
        spacing: 5

        Button {
            id: buttontext
            text: "Topo"
            onClicked: {
                if (basemapindex == 1) {
                    changeBasemap(cbItems.get(1).map);
                    basemapindex = 2
                    buttontext.text = "Streets"
                } else if (basemapindex == 2){
                    changeBasemap(cbItems.get(2).map);
                    basemapindex = 3
                    buttontext.text = "Street Night"
                } else if (basemapindex == 3){
                    changeBasemap(cbItems.get(3).map);
                    basemapindex = 4
                    buttontext.text = "Imagery Labels"
                } else if (basemapindex == 4){
                    changeBasemap(cbItems.get(4).map);
                    basemapindex = 0
                    buttontext.text = "Navigation"
                } else if (basemapindex == 0){
                    basemapindex = 1
                    changeBasemap(cbItems.get(0).map);
                    buttontext.text = "Topo"
                }
                function changeBasemap(type) {
                    map.basemap = ArcGISRuntimeEnvironment.createObject(type);
                }
            } // End of OnClicked
        } // End of Button
    } // End of Row

    ViewpointCenter {
        id: viewPoint
        center: Point {
            //x: -13630484
            //y: 4545415
            x: -8622115
            y: 4513608
            spatialReference: SpatialReference {
                wkid: 102100
            }
        }
        targetScale: 3000000
    }
}
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos
KeithLarson1
MVP

Hey,

I think you could do away with the if statements in the onClicked function completely. You could change it to a switch case block, or you could just use the index to get the basemap and text from the ListModel. You could either reuse the "text" field in the ListElements as the button text, or you could create a separate shorter "buttonText" field to associate the index with the button text. Then, when you click the button, you just have to grab the basemap at that index, increment the index or reset to 0 depending on the ListModel count, and set the button's text to the buttonText at that index.

import ArcGIS.AppFramework 1.0
import ArcGIS.AppFramework.Controls 1.0
import QtQuick 2.9
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import Esri.ArcGISRuntime 100.5
import QtQuick.Layouts 1.1

Item {

    signal previous(string message)
    property string basemapId: ""
    property int basemapindex: 1
    MapView {
        id:mapView
        Layout.fillHeight: true
        Layout.alignment: Qt.AlignTop
        width: parent.width
        height: parent.height
        property real initialMapRotation: 0

        Map {
            id: map
            initialViewpoint: viewPoint
            // Set the initial basemap to Topographic
            BasemapTopographic {}
        } // END OF MAP

    } // END OF MAPVIEW

    ListModel {
        id: cbItems

        ListElement { text: "Topographic"; map: "BasemapTopographic", buttonText: "Topo" }
        ListElement { text: "Streets (Vector)"; map: "BasemapStreetsVector", buttonText: "Streets" }
        ListElement { text: "Streets - Night (Vector)"; map: "BasemapStreetsNightVector", buttonText: "Street Night" }
        ListElement { text: "Imagery with Labels (Vector)"; map: "BasemapImageryWithLabelsVector", buttonText: "Imagery Labels" }
        ListElement { text: "Navigation (Vector)"; map: "BasemapNavigationVector", buttonText: "Navigation" }
    }

    Row {
        anchors {
            bottom: parent.bottom
            left: parent.left
            right: parent.right
            margins: 5 * scaleFactor
            bottomMargin: 50 * scaleFactor
        }
        spacing: 5

        Button {
            id: buttontext
            text: "Topo"
            onClicked: {
				changeBasemap(cbItems.get(basemapindex).map);
				if (basemapindex < cbItems.count - 1) {
					basemapindex++;
				}
				else {
					basemapindex = 0;
				}
				buttontext.text = cbItems.get(basemapIndex).buttonText;

                function changeBasemap(type) {
                    map.basemap = ArcGISRuntimeEnvironment.createObject(type);
                }
            } // End of OnClicked
        } // End of Button
    } // End of Row

    ViewpointCenter {
        id: viewPoint
        center: Point {
            //x: -13630484
            //y: 4545415
            x: -8622115
            y: 4513608
            spatialReference: SpatialReference {
                wkid: 102100
            }
        }
        targetScale: 3000000
    }
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

I hope this helps!

-Keith

jaykapalczynski
Frequent Contributor

Awesome Keith....thanks...

0 Kudos