Find webmap portal items by using a search term.

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. For more results, click the “More Results” button at the bottom.
How it works
- Create a new
Portaland load it. - Create new
PortalQueryParametersForItems. Set the type toPortalItemType::WebMapand add the text you want to search for. - Use
portal::findItemsAsync(params)to get the first set of matching items (10 by default). - Get more results with
portal::findItemsAsync(PortalQueryResultSetForItems.nextQueryParameters()).
Relevant API
- Portal
- PortalItem
- PortalQueryParameters
- PortalQueryResultSet
Tags
keyword, query, search, webmap
Sample Code
// [WriteFile Name=SearchForWebmap, Category=CloudAndPortal]// [Legal]// Copyright 2016 Esri.//// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at// http://www.apache.org/licenses/LICENSE-2.0//// Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.// [Legal]
#ifdef PCH_BUILD#include "pch.hpp"#endif // PCH_BUILD
// sample headers#include "SearchForWebmap.h"
// ArcGIS Maps SDK headers#include "Error.h"#include "Map.h"#include "MapQuickView.h"#include "MapTypes.h"#include "MapViewTypes.h"#include "Portal.h"#include "PortalItem.h"#include "PortalItemListModel.h"#include "PortalQueryParametersForItems.h"#include "PortalQueryResultSetForItems.h"#include "PortalTypes.h"
// Qt headers#include <QDate>#include <QDateTime>#include <QFuture>
using namespace Esri::ArcGISRuntime;
SearchForWebmap::SearchForWebmap(QQuickItem* parent /* = nullptr */) : QQuickItem(parent), m_portal(new Portal(this)){}
SearchForWebmap::~SearchForWebmap() = default;
void SearchForWebmap::init(){ qmlRegisterType<MapQuickView>("Esri.Samples", 1, 0, "MapView"); qmlRegisterType<SearchForWebmap>("Esri.Samples", 1, 0, "SearchForWebmapSample");}
void SearchForWebmap::componentComplete(){ QQuickItem::componentComplete();
if (m_portal) { connect(m_portal, &Portal::loadStatusChanged, this, [this]() { m_portalLoaded = m_portal->loadStatus() == LoadStatus::Loaded; emit portalLoadedChanged(); });
m_portal->load(); }
// find QML MapView component m_mapView = findChild<MapQuickView*>("mapView"); if (m_mapView) { m_mapView->setWrapAroundMode(WrapAroundMode::Disabled); }}
bool SearchForWebmap::portalLoaded() const{ return m_portalLoaded;}
QAbstractListModel* SearchForWebmap::webmaps() const{ return m_webmaps;}
bool SearchForWebmap::hasMoreResults() const{ return m_webmapResults && m_webmapResults->nextQueryParameters().startIndex() > -1;}
QString SearchForWebmap::mapLoadError() const{ return m_mapLoadeError;}
void SearchForWebmap::search(const QString& keyword){ if (!m_portal) { return; }
//! [SearchForWebmap CPP Portal find items async] // webmaps authored prior to July 2nd, 2014 are not supported // so search only from that date to the current time (in milliseconds) QString fromDate = QString("000000%1").arg(QDateTime::fromString(QDate(2014, 7, 2).toString()).toMSecsSinceEpoch()); QString toDate = QString("000000%1").arg(QDateTime::currentDateTime().toMSecsSinceEpoch());
PortalQueryParametersForItems query; query.setSearchString(QString("tags:\"%1\" AND +uploaded:[%2 TO %3]").arg(keyword, fromDate, toDate)); query.setTypes(QList<PortalItemType>() << PortalItemType::WebMap);
m_portal->findItemsAsync(query).then(this, [this](PortalQueryResultSetForItems* webmapResults) { onFindItemsCompleted(webmapResults); }); //! [SearchForWebmap CPP Portal find items async]
if (m_mapView) { m_mapView->setVisible(false); }}
void SearchForWebmap::searchNext(){ if (!m_webmapResults || !m_portal) { return; }
//! [Portal find with nextQueryParameters] PortalQueryParametersForItems nextQuery = m_webmapResults->nextQueryParameters(); // check whether the startIndex of the new query is valid if (!nextQuery.isEmpty()) { m_portal->findItemsAsync(nextQuery).then(this, [this](PortalQueryResultSetForItems* webmapResults) { onFindItemsCompleted(webmapResults); }); } //! [Portal find with nextQueryParameters]}
void SearchForWebmap::loadSelectedWebmap(int index){ if (!m_webmaps) { return; }
if (m_map) { delete m_map; }
// create map from portal item m_map = new Map(m_webmaps->at(index), this);
connect(m_map, &Map::errorOccurred, this, [this]() { m_mapLoadeError = m_map->loadError().message(); emit mapLoadErrorChanged(); });
// set map on mapview m_mapView->setMap(m_map); m_mapView->setVisible(true);}
void SearchForWebmap::errorAccepted(){ m_mapLoadeError.clear(); emit mapLoadErrorChanged();}
void SearchForWebmap::onFindItemsCompleted(PortalQueryResultSetForItems* webmapResults){ m_webmapResults = webmapResults; m_webmaps = m_webmapResults->itemResults(); emit webmapsChanged(); emit hasMoreResultsChanged();}// [WriteFile Name=SearchForWebmap, Category=CloudAndPortal]// [Legal]// Copyright 2016 Esri.//// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at// http://www.apache.org/licenses/LICENSE-2.0//// Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.// [Legal]
#ifndef SEARCHFORWEBMAP_H#define SEARCHFORWEBMAP_H
// Qt headers#include <QAbstractListModel>#include <QQuickItem>
namespace Esri::ArcGISRuntime{ class Map; class MapQuickView; class Portal; class PortalItem; class PortalItemListModel; class PortalQueryResultSetForItems;} // namespace Esri::ArcGISRuntime
class SearchForWebmap : public QQuickItem{ Q_OBJECT
Q_PROPERTY(bool portalLoaded READ portalLoaded NOTIFY portalLoadedChanged) Q_PROPERTY(QAbstractListModel* webmaps READ webmaps NOTIFY webmapsChanged) Q_PROPERTY(bool hasMoreResults READ hasMoreResults NOTIFY hasMoreResultsChanged) Q_PROPERTY(QString mapLoadError READ mapLoadError NOTIFY mapLoadErrorChanged)
public: explicit SearchForWebmap(QQuickItem* parent = nullptr); ~SearchForWebmap() override;
void componentComplete() override; static void init();
bool portalLoaded() const; QAbstractListModel* webmaps() const; bool hasMoreResults() const; QString mapLoadError() const;
Q_INVOKABLE void search(const QString& keyword); Q_INVOKABLE void searchNext(); Q_INVOKABLE void loadSelectedWebmap(int index); Q_INVOKABLE void errorAccepted();
signals: void portalLoadedChanged(); void webmapsChanged(); void hasMoreResultsChanged(); void mapLoadErrorChanged();
private: void onFindItemsCompleted(Esri::ArcGISRuntime::PortalQueryResultSetForItems* webmapResults);
Esri::ArcGISRuntime::Map* m_map = nullptr; Esri::ArcGISRuntime::MapQuickView* m_mapView = nullptr; Esri::ArcGISRuntime::Portal* m_portal = nullptr; Esri::ArcGISRuntime::PortalQueryResultSetForItems* m_webmapResults = nullptr; Esri::ArcGISRuntime::PortalItemListModel* m_webmaps = nullptr; Esri::ArcGISRuntime::PortalItem* m_selectedItem = nullptr; bool m_portalLoaded = false; QString m_mapLoadeError;};
#endif // SEARCHFORWEBMAP_H// [WriteFile Name=SearchForWebmap, Category=CloudAndPortal]// [Legal]// Copyright 2016 ESRI//// All rights reserved under the copyright laws of the United States// and applicable international laws, treaties, and conventions.//// You may freely redistribute and use this sample code, with or// without modification, provided you include the original copyright// notice and use restrictions.//// See the Sample code usage restrictions document for further information.// [Legal]
import QtQuickimport QtQuick.Controlsimport QtQuick.Layoutsimport Esri.Samplesimport Esri.ArcGISRuntime.Toolkit
SearchForWebmapSample { id: root width: 800 height: 600 clip: true
property string selItem
// Create MapQuickView here, and create its Map etc. in C++ code MapView { id: mapView objectName: "mapView" anchors { top: searchBox.bottom bottom: parent.bottom left: parent.left right: parent.right margins: 10 } visible: false
Component.onCompleted: { // Set the focus on MapView to initially enable keyboard navigation forceActiveFocus(); } }
Component { id: webmapDelegate
Rectangle { anchors.margins: 25 width: webmapsList.width height: 32 border.color: "white" border.width: 2 color: index === webmapsList.currentIndex ? palette.highlight : palette.mid radius: 10
//! [PortalItemListModel example QML delegate] Label { anchors { fill: parent margins: 10 } text: title // access the title role of the model elide: Text.ElideRight wrapMode: Text.Wrap horizontalAlignment: Text.AlignHCenter } //! [PortalItemListModel example QML delegate]
MouseArea { anchors.fill: parent onClicked: webmapsList.currentIndex = index; onDoubleClicked: loadSelectedWebmap(index); } } }
BusyIndicator { anchors.centerIn: parent running: !portalLoaded visible: !portalLoaded }
Rectangle { id: resultsBox anchors { top: searchBox.bottom bottom: parent.bottom left: parent.left right: parent.right margins: 10 } visible: webmaps && !mapView.visible border.color: "grey" border.width: 2 radius: 5 color: palette.base
Label { id: resultsTitle anchors { margins: 10 top: parent.top left: parent.left right: parent.right } text: qsTr("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 model: webmaps }
Button { id: moreResultsButton anchors { margins: 20 bottom: parent.bottom horizontalCenter: resultsBox.horizontalCenter } visible: hasMoreResults text: qsTr("More Results") onClicked: searchNext(); } }
Column { id: searchBox anchors { top: parent.top; horizontalCenter: parent.horizontalCenter margins: 10 } visible: portalLoaded spacing: 5
Label { id: instruction text: qsTr("Search for webmaps:") font.bold: true }
Row { spacing: 5
TextField { id: keyWordField placeholderText: qsTr("Enter keyword") selectByMouse: true
Keys.onReturnPressed: { if (text.length > 0) search(text); } }
ToolButton { width: height height: keyWordField.height enabled: keyWordField.text.length > 0 flat: true icon { source: "qrc:/Samples/CloudAndPortal/SearchForWebmap/search-24.svg" width: 24 height: 24 color: palette.text } onClicked: search(keyWordField.text)
background: Rectangle { color: "transparent" radius: 4 } }
SequentialAnimation on x { id: noResultsAnimation loops: 10 running: false PropertyAnimation { to: 50; duration: 20 } PropertyAnimation { to: 0; duration: 20 } }
} }
// Declare Authenticator to handle any authentication challenges Authenticator { anchors.fill: parent }
Dialog { id: webMapMsg modal: true x: Math.round(parent.width - width) / 2 y: Math.round(parent.height - height) / 2 standardButtons: Dialog.Ok title: qsTr("Could not load web map!") visible: mapLoadError.length > 0 property alias text : textLabel.text property alias informativeText : detailsLabel.text ColumnLayout { Label { id: textLabel text: mapLoadError } Label { id: detailsLabel } } onAccepted: errorAccepted() }}// [WriteFile Name=SearchForWebmap, Category=CloudAndPortal]// [Legal]// Copyright 2015 Esri.//// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at// http://www.apache.org/licenses/LICENSE-2.0//// Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.// [Legal]
// Qt headers#include <QCommandLineParser>#include <QDir>#include <QGuiApplication>#include <QQmlEngine>#include <QQuickView>
#ifdef QT_WEBVIEW_WEBENGINE_BACKEND#include <QtWebEngineQuick>#endif // QT_WEBVIEW_WEBENGINE_BACKEND
#ifdef Q_OS_WIN#include <Windows.h>#endif
#include "Esri/ArcGISRuntime/Toolkit/register.h"#include "ArcGISRuntimeEnvironment.h"
#include "SearchForWebmap.h"
#define STRINGIZE(x) #x#define QUOTE(x) STRINGIZE(x)
int main(int argc, char* argv[]){#ifdef QT_WEBVIEW_WEBENGINE_BACKEND QtWebEngineQuick::initialize();#endif // QT_WEBVIEW_WEBENGINE_BACKEND
QGuiApplication app(argc, argv); app.setApplicationName(QString("Search for Webmap"));
// Use of ArcGIS location services, such as basemap styles, geocoding, and routing services, // requires an access token. For more information see // https://links.esri.com/arcgis-runtime-security-auth.
// The following methods grant an access token:
// 1. User authentication: Grants a temporary access token associated with a user's ArcGIS account. // To generate a token, a user logs in to the app with an ArcGIS account that is part of an // organization in ArcGIS Online or ArcGIS Enterprise.
// 2. API key authentication: Get a long-lived access token that gives your application access to // ArcGIS location services. Go to the tutorial at https://links.esri.com/create-an-api-key. // Copy the API Key access token.
const QString accessToken = QString("");
if (accessToken.isEmpty()) { qWarning() << "Use of ArcGIS location services, such as the basemap styles service, requires" << "you to authenticate with an ArcGIS account or set the API Key property."; } else { Esri::ArcGISRuntime::ArcGISRuntimeEnvironment::setApiKey(accessToken); }
// Initialize the sample SearchForWebmap::init();
// Initialize application view QQuickView view; view.setResizeMode(QQuickView::SizeRootObjectToView);
// Add the import Path view.engine()->addImportPath(QDir(QCoreApplication::applicationDirPath()).filePath("qml"));
QString arcGISRuntimeImportPath = QUOTE(ARCGIS_RUNTIME_IMPORT_PATH);
#if defined(LINUX_PLATFORM_REPLACEMENT) // on some linux platforms the string 'linux' is replaced with 1 // fix the replacement paths which were created QString replaceString = QUOTE(LINUX_PLATFORM_REPLACEMENT); arcGISRuntimeImportPath = arcGISRuntimeImportPath.replace(replaceString, "linux", Qt::CaseSensitive);#endif
// Add the Runtime and Extras path view.engine()->addImportPath(arcGISRuntimeImportPath);
Esri::ArcGISRuntime::Toolkit::registerComponents(*(view.engine()));
// Set the source view.setSource(QUrl("qrc:/Samples/CloudAndPortal/SearchForWebmap/SearchForWebmap.qml"));
view.show();
return app.exec();}