Skip To Content ArcGIS for Developers Sign In Dashboard

ArcGIS Runtime SDK for Qt

Search for web map by keyword

Sample Viewer View Sample on GitHub

Find portal items by using a keyword, and limit the results to items of a certain type - in this case, web maps.

Use case

Portals can contain many portal items and at times you may wish to query the portal to find what you're looking for. In this example, we search for webmap portal items using a text search.

How to use the sample

Enter search terms into the search bar. Once the search is complete, a list is populated with the resultant webmaps. Tap on a webmap to set it to the map view. Scrolling to the bottom of the webmap recycler view will get more results.

How it works

  1. A Portal is created with no credential set, when the app starts, the portal is loaded.
  2. A search bar allows the user to enter a keyword (a tag) to search for * e.g. "usa".
  3. The search term is passed as the searchString for a PortalQueryParametersForItems which also has the itemType set to Enums.PortalItemTypeWebMap. NOTE if multiple item types are required these can be set via the types property. Since webmaps authored prior to July 2nd, 2014 are not supported, a date filter is also applied.
  4. The query parameters are passed to the portal's findItems method.
  5. Once the findItems task is complete, a PortalQueryResultSetForItems is obtained by calling findItemsResult on the portal.
  6. The PortalItemListModel from the items result is set on a ListView to display the set of web maps. If many web maps match the search criteria, the results will contain only the 1st set (to allow "paging" through the results in batches).
  7. If there are additional results, a subsequent query can be issued by clicking the "More Results" button. This passes the itemResult's nextQueryParameters object to a new findItems operation.
  8. When the user double-clicks on a web map in the list, the PortalItem is loaded and set as a Map on the MapView
  9. If the item is secured, the user may be prompted to login via the AuthenticationView

Relevant API

  • Portal
  • PortalQueryParametersForItems
  • PortalQueryResultSetForItems
  • PortalItemListModel
  • PortalItem

Tags

keyword, query, search, webmap

Sample Code

import QtQuick 2.6
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
import Esri.ArcGISRuntime 100.9
import Esri.ArcGISRuntime.Toolkit.Dialogs 100.9

Rectangle {
    id: rootRectangle
    clip: true

    width: 800
    height: 600

    
    property var portalItem

    function search() {
        mapView.visible = false;
        mapView.map = null;
        //! [Portal findItems webmaps part 2]
        portal.findItems(webmapQuery);
        //! [Portal findItems webmaps part 2]
    }

    function searchNext(){
        //! [Portal find with nextQueryParameters]
        const nextQuery = portal.findItemsResult.nextQueryParameters;
        // check whether the startIndex of the new query is valid
        if (nextQuery.startIndex !== -1)
            portal.findItems(nextQuery);
        //! [Portal find with nextQueryParameters]
    }

    function loadSelectedWebmap(selectedWebmap) {
        portalItem = selectedWebmap;

        portalItem.loadStatusChanged.connect(createMap);
        portalItem.loadErrorChanged.connect(()=> {
            webMapMsg.text = portalItem.loadError.message;
            webMapMsg.visible = true;
        });

        portalItem.load();
    }

    function createMap() {
        if (portalItem.loadStatus !== Enums.LoadStatusLoaded)
            return;

        mapView.map = ArcGISRuntimeEnvironment.createObject("Map", {"item": portalItem});

        mapView.map.loadStatusChanged.connect(assignWebmap);
        mapView.map.loadErrorChanged.connect(()=> {
            webMapMsg.text = mapView.map.loadError.message;
            webMapMsg.visible = true;
        });

        mapView.map.load();
    }

    function assignWebmap() {
        if (mapView.map.loadStatus !== Enums.LoadStatusLoaded)
            return;

        webmapsList.visible = false;
        mapView.visible = true;
    }

    //! [Portal findItems webmaps part 1]
    // webmaps authored prior to July 2nd, 2014 are not supported - so search only from that date to the current time
    property string fromDate: "000000" + new Date('Wed, 02 Jul 2014 00:00:00 GMT').getTime()
    property string toDate: "000000" + new Date().getTime()

    PortalQueryParametersForItems {
        id: webmapQuery
        types: [ Enums.PortalItemTypeWebMap ]

        searchString: 'tags:\"' + keyWordField.text + '\" AND + uploaded:[' + fromDate + ' TO ' + toDate +']';
    }
    //! [Portal findItems webmaps part 1]

    Portal {
        id: portal

        Component.onCompleted: load();

        onLoadStatusChanged: {
            if (loadStatus === Enums.LoadStatusFailedToLoad)
                retryLoad();

            if (loadStatus !== Enums.LoadStatusLoaded)
                return;

            searchBox.visible = true
            keyWordField.focus = true
        }

        //! [Portal findItems completed]
        onFindItemsResultChanged: {
            if (portal.findItemsStatus !== Enums.TaskStatusCompleted)
                return;

            // bind the item list model to the view
            webmapsList.model = portal.findItemsResult.itemResults
            webmapsList.visible = true;
            webmapsList.focus = true;
        }
        //! [Portal findItems completed]
    }

    Component {
        id: webmapDelegate
        Rectangle {
            anchors.margins: 25
            width: webmapsList.width
            height: 32
            border.color: "white"
            border.width: 2
            color: "lightgrey"
            radius: 10

            //! [PortalItemListModel example QML delegate]
            Text {
                anchors {
                    fill: parent
                    margins: 10
                }
                text: title
                color: "white"
                elide: Text.ElideRight
                wrapMode: Text.Wrap
                horizontalAlignment: Text.AlignHCenter
            }
            //! [PortalItemListModel example QML delegate]

            MouseArea {
                anchors.fill: parent
                onClicked: webmapsList.currentIndex = index;
                onDoubleClicked: loadSelectedWebmap(webmapsList.model.get(index));
            }
        }
    }

    Component {
        id: highlightDelegate

        Rectangle {
            z: 110
            anchors.margins: 25
            width: webmapsList.width
            height: 24
            color: "orange"
            radius: 4

            Text {
                anchors {
                    fill: parent
                    margins: 10
                }
                text: webmapsList.model.count > 0 ? webmapsList.model.get(webmapsList.currentIndex).title : ""
                font.bold: true
                elide: Text.ElideRight
                wrapMode: Text.Wrap
                color: "white"
                horizontalAlignment: Text.AlignHCenter
            }
        }
    }

    BusyIndicator {
        anchors.centerIn: parent
        running: portal.loadStatus !== Enums.LoadStatusLoaded
    }

    Rectangle {
        id: resultsBox
        visible: webmapsList.model && webmapsList.model.count > 0
        anchors {
            top: searchBox.bottom
            bottom: parent.bottom
            left: parent.left
            right: parent.right
            margins: 10
        }
        border.color: "grey"
        border.width: 2
        radius: 5

        Text {
            id: resultsTitle
            anchors {
                margins: 10
                top: parent.top
                left: parent.left
                right: parent.right
            }
            text: "web maps: " + keyWordField.text
            elide: Text.ElideRight
            wrapMode: Text.Wrap
            font.bold: true
            font.pointSize: 10
            horizontalAlignment: Text.AlignHCenter
        }

        ListView {
            id: webmapsList
            anchors {
                margins: 20
                top: resultsTitle.bottom
                bottom: moreResultsButton.top
                left: parent.left
                right: parent.right
            }
            clip: true
            delegate: webmapDelegate
            highlightFollowsCurrentItem: true
            highlight: highlightDelegate
            model: null
        }

        Button {
            id: moreResultsButton
            anchors {
                margins: 20
                bottom: parent.bottom
                horizontalCenter: resultsBox.horizontalCenter
            }
            text: "More Results"
            visible: portal.findItemsStatus === Enums.TaskStatusCompleted && portal.findItemsResult.nextQueryParameters !== null
            onClicked: searchNext();
        }
    }

    Column {
        visible: portal.loadStatus === Enums.LoadStatusLoaded
        id: searchBox
        anchors {
            top: parent.top
            horizontalCenter: parent.horizontalCenter
            margins: 10
        }
        spacing: 5

        Text {
            id: instruction
            text: qsTr("search for webmaps:")
            font.bold: true
        }

        Row {
            spacing: 5

            TextField {
                id: keyWordField
                placeholderText: "enter keyword"
                selectByMouse: true

                Keys.onReturnPressed: {
                    if (text.length > 0)
                        search(text);
                }
            }

            Image {
                source: "qrc:/Samples/CloudAndPortal/SearchForWebmap/searchIcon.png"
                width: height
                height: keyWordField.height

                MouseArea {
                    anchors.fill: parent
                    enabled: keyWordField.text.length > 0
                    onClicked : search(keyWordField.text);
                }
            }

            SequentialAnimation on x {
                id: noResultsAnimation
                loops: 10
                running: false
                PropertyAnimation { to: 50; duration: 20 }
                PropertyAnimation { to: 0; duration: 20 }
            }

        }
    }

    MapView {
        id: mapView
        visible: false
        anchors {top: searchBox.bottom; bottom: parent.bottom; left: parent.left; right: parent.right; margins: 10}
    }

    // Uncomment this section when running as standalone application
    /*
    AuthenticationView {
        authenticationManager: AuthenticationManager
    }
    */

    Dialog {
        id: webMapMsg
        modal: true
        x: Math.round(parent.width - width) / 2
        y: Math.round(parent.height - height) / 2
        standardButtons: Dialog.Ok
        title: "Could not load web map!"
        property alias text : textLabel.text
        Text {
            id: textLabel
        }
        onAccepted: visible = false;
    }
}