Learn how to find an address or place with a search bar and the Geocoding service.
Geocoding is the process of converting address or place text into a location. The geocoding service can search for an address or a place and perform reverse geocoding.
In this tutorial, you use a search bar in the user interface to access the geocoding service and search for addresses and places.
To learn how to use the geocoding service to reverse geocode, visit the Reverse geocode tutorial.
Prerequisites
Before starting this tutorial:
-
You need an ArcGIS Location Platform or ArcGIS Online account.
-
Your system meets the system requirements.
-
The ArcGIS Runtime API for Qt is installed.
Steps
Get an access token
You need an access token to use the location services used in this tutorial.
-
Go to the Create an API key tutorial to obtain an access token using your ArcGIS Location Platform or ArcGIS Online account.
-
Ensure that the following privileges are enabled: Location services > Basemaps > Basemap styles service and Location services > Geocoding.
-
Copy the access token as it will be used in the next step.
To learn more about other ways to get an access token, go to Types of authentication.
Open the project in Qt Creator
-
To start this tutorial, complete the Display a map tutorial or download and unzip the solution.
-
Open the display_a_map project in Qt Creator.
-
In the Projects window, in the Sources folder, open the main.cpp file.
-
Modify the code to set the API key to the access token. Save and close the file.
main.cppUse dark colors for code blocks 43 44 45 46Change line // 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("");
Declare classes, member variables, functions, and signals
-
Double click on Sources > Display_a_map.h to open the file. Include the six header files below.
Display_a_map.hUse dark colors for code blocks 22 23 24Add line. Add line. Add line. Add line. Add line. Add line. class Map; class MapQuickView; class GraphicsOverlay; class Graphic; class LocatorTask; class GeocodeResult; class SuggestResult; class TextSymbol;
-
Add the following two include statements.
Display_a_map.hUse dark colors for code blocks 32 33 34 35Add line. Add line. } } #include <QObject> #include <QAbstractListModel> #include "GeocodeParameters.h"
-
Add a
Q
for the member variable_PROPERTY suggestions
.Display_a_map.hUse dark colors for code blocks 39 40 41 42 43Add line. class Display_a_map : public QObject { Q_OBJECT Q_PROPERTY(Esri::ArcGISRuntime::MapQuickView* mapView READ mapView WRITE setMapView NOTIFY mapViewChanged) Q_PROPERTY(QAbstractListModel* suggestions READ suggestions NOTIFY suggestionsChanged)
-
Add the following public member functions with the
Q
macro to allow these to be invokable from the GUI._INVOKABLE Display_a_map.hUse dark colors for code blocks 46 47 48 49Add line. Add line. Add line. public: explicit Display_a_map(QObject* parent = nullptr); ~Display_a_map() override; Q_INVOKABLE void geocode(const QString& query); Q_INVOKABLE void clearGraphics(); Q_INVOKABLE void setSuggestions(const QString& text);
-
Add two new signal declarations.
Display_a_map.hUse dark colors for code blocks 54 55 56Add line. Add line. signals: void mapViewChanged(); void suggestionsChanged(); void hideSuggestionView();
-
Declare the
setup
private method.Locator Task Display_a_map.hUse dark colors for code blocks 60 61 62 63 64Add line. private: Esri::ArcGISRuntime::MapQuickView* mapView() const; void setMapView(Esri::ArcGISRuntime::MapQuickView* mapView); void setupViewpoint(); void setupLocatorTask();
-
Add the following six private member functions and variables. Then save and close the header file.
Display_a_map.hUse dark colors for code blocks 65 66 67 68 69Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. void setupLocatorTask(); Esri::ArcGISRuntime::Map* m_map = nullptr; Esri::ArcGISRuntime::MapQuickView* m_mapView = nullptr; void configureGraphic(); QAbstractListModel* suggestions() const; Esri::ArcGISRuntime::GraphicsOverlay* m_graphicsOverlay = nullptr; Esri::ArcGISRuntime::LocatorTask* m_locatorTask = nullptr; Esri::ArcGISRuntime::Graphic* m_graphicResultLocation = nullptr; Esri::ArcGISRuntime::Graphic* m_graphicResultText = nullptr; Esri::ArcGISRuntime::TextSymbol* m_textSymbol = nullptr; QAbstractListModel* m_suggestListModel = nullptr; Esri::ArcGISRuntime::GeocodeParameters m_geocodeParams;
Include header files to access needed classes
-
In Projects, double click on Sources > Display_a_map.cpp to open the file and add the following header file declarations.
Display_a_map.cppUse dark colors for code blocks 15 16 17 18 19Add line. Add line. Add line. Add line. Add line. Add line. #include "Display_a_map.h" #include "ArcGISRuntimeEnvironment.h" #include "Map.h" #include "MapQuickView.h" #include "SimpleRenderer.h" #include "SimpleMarkerSymbol.h" #include "TextSymbol.h" #include "LocatorTask.h" #include "SuggestResult.h" #include "SuggestListModel.h"
-
Include the following Qt classes.
Display_a_map.cppUse dark colors for code blocks 27 28Add line. Add line. #include <QUrl> #include <QAbstractListModel> #include <QGeoPositionInfoSource>
Create a locator task with geocode parameters
Geocoding is implemented with a locator, typically created by referencing a service such as the Geocoding service or, for offline geocoding, by referencing locator data contained in a mobile package. Geocoding parameters can be used to fine-tune the results, such as setting the maximum number of results or requesting additional attributes in the results.
-
Add the call to
setup
. This method will be implemented next.Locator Task Display_a_map.cppUse dark colors for code blocks 34 35 36 37 38Add line. Display_a_map::Display_a_map(QObject* parent /* = nullptr */): QObject(parent), m_map(new Map(BasemapStyle::ArcGISTopographic, this)) { setupLocatorTask();
-
Add code to begin implementing the
setup
method and initialize the auto-suggestion list. Within the method body, create a newLocator Task Locator
based on the Geocoding service, and set it to theTask m
member variable._locator Task A locator task is used to convert an address to a point (geocode) or vice-versa (reverse geocode). An address includes any type of information that distinguishes a place. A locator involves finding matching locations for a given address. Reverse-geocoding is the opposite and finds the closest address for a given location.
-
Create a
Suggest
, instance and initialize it with three categories as shown. Then set max results to limit for the number of returned suggestion results to 5.Parameters -
Configure
Geocode
, (m_geocodeParams). Add code to set the minimum match score and the attribute names for the results to be returned. CallParams suggestions
onm
and assign to_locator Task m
._suggest List Model Display_a_map.cppUse dark colors for code blocks 39 40 41 42 43 44 45Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. setupLocatorTask(); } Display_a_map::~Display_a_map() { } void Display_a_map::setupLocatorTask() { const QUrl geocode_service("https://geocode-api.arcgis.com/arcgis/rest/services/World/GeocodeServer"); m_locatorTask = new LocatorTask(geocode_service, this); SuggestParameters suggestParams; const QStringList categories{"Address", "POI", "Populated Place"}; suggestParams.setCategories(categories); suggestParams.setMaxResults(5); m_locatorTask->suggestions()->setSuggestParameters(suggestParams); m_geocodeParams.setMinScore(75); m_geocodeParams.setResultAttributeNames(QStringList {"Place_addr", "Match_addr"}); m_suggestListModel = m_locatorTask->suggestions(); emit suggestionsChanged();
-
Add code to the
setup
to connect to the geocode complete signal on theLocator Task Locator
. Within the lambda bodyTask if
statement, the code checks for geocoding results and verifies that the graphic exists. If both conditions are met, the result location is set as the graphic’s geometry and the attributes provided by the result are copied to the graphic. The map view display is centered on the graphic before making it visible. -
The second code block in the
if
statement sets text symbol, sets the text graphic geometry for the geocoding result display location, sets attributes for the text graphic, and displays the graphic.Display_a_map.cppUse dark colors for code blocks 57 58 59 60 61Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. m_geocodeParams.setMinScore(75); m_geocodeParams.setResultAttributeNames(QStringList {"Place_addr", "Match_addr"}); m_suggestListModel = m_locatorTask->suggestions(); emit suggestionsChanged(); // connect to geocode complete signal on the LocatorTask connect(m_locatorTask, &LocatorTask::geocodeCompleted, this, [this](QUuid, const QList<GeocodeResult>& geocodeResults) { if (!geocodeResults.isEmpty() && m_graphicResultLocation) { // display geocode result label and position const GeocodeResult geocodeResult = geocodeResults.at(0); m_graphicResultLocation->setGeometry(geocodeResult.displayLocation()); m_graphicResultLocation->attributes()->setAttributesMap(geocodeResult.attributes()); constexpr double scale = 8000.0; m_mapView->setViewpointCenter(geocodeResult.extent().center(), scale); m_graphicResultLocation->setVisible(true); m_textSymbol->setText(geocodeResult.label()); m_graphicResultText->setGeometry(geocodeResult.displayLocation()); m_graphicResultText->attributes()->setAttributesMap(geocodeResult.attributes()); m_graphicResultLocation->setVisible(true); } }); }
Create the auto-suggestion feature
-
Add a new
set
method to implement the auto-suggestion feature. This generates a list of suggested addresses based on the user's input in the GUI text field.Suggestions Display_a_map.cppUse dark colors for code blocks 110 111 112 113Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. setupViewpoint(); emit mapViewChanged(); } void Display_a_map::setSuggestions(const QString& text) { if (!m_suggestListModel) return; SuggestListModel* suggestListModel = dynamic_cast<SuggestListModel*>(m_suggestListModel); if (!suggestListModel) return; suggestListModel->setSearchText(text); }
-
Revise the
setup
method to respond to the user's mouse selection of an address from the list of suggested addresses.Viewpoint Display_a_map.cppUse dark colors for code blocks 90 91 92Add line. Add line. Add line. Add line. void Display_a_map::setupViewpoint() { connect(m_mapView, &MapQuickView::mousePressed, this, [this](QMouseEvent& /* event */) { emit hideSuggestionView(); });
Add text and marker graphics to identify location on map
-
Add the call to
configure
, which will be implemented in the next step.Graphic Display_a_map.cppUse dark colors for code blocks 98 99 100 101Add line. const Point center(-118.80543, 34.02700, SpatialReference::wgs84()); const Viewpoint viewpoint(center, 100000.0); m_mapView->setViewpoint(viewpoint); configureGraphic();
-
Implement the
configure
public method. Create aGraphic Simple
(blue square), initialize aMarker Symbol Graphic
and add that to aGraphics
. Then createOverlay Text
, initialize aSymbol Graphic
with that, and add it to theGraphics
. Then add theOverlay Graphics
toOverlay Map
.View Display_a_map.cppUse dark colors for code blocks 128 129 130 131 132 133Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. if (!suggestListModel) return; suggestListModel->setSearchText(text); } void Display_a_map::configureGraphic() { if (m_graphicResultLocation) return; // create graphics overlay and add to map view m_graphicsOverlay = new GraphicsOverlay(this); // set a renderer on the graphics overlay SimpleRenderer* simpleRenderer = new SimpleRenderer(this); // Create a graphic and symbol to display the result location. SimpleMarkerSymbol* simpleMarkerSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbolStyle::Square, QColor("blue"), 12.0, this); simpleRenderer->setSymbol(simpleMarkerSymbol); m_graphicResultLocation = new Graphic(this); m_graphicResultLocation->setSymbol(simpleMarkerSymbol); m_graphicsOverlay->graphics()->append(m_graphicResultLocation); // Create a graphic and symbol to display a label next to the result location m_textSymbol = new TextSymbol("", QColor("red"), 18.0, HorizontalAlignment::Center, VerticalAlignment::Bottom, this); m_graphicResultText = new Graphic(this); m_graphicResultText->setSymbol(m_textSymbol); m_graphicsOverlay->graphics()->append(m_graphicResultText); m_mapView->graphicsOverlays()->append(m_graphicsOverlay); }
Add the Geocode method
An asynchronous geocode operation is required to find and return the location candidates for a given address and geocode parameters.
-
Add the
geocode
public method to geocode an address when the user clicks on that address in the auto-suggestion list.Display_a_map.cppUse dark colors for code blocks 157 158 159 160 161Add line. Add line. Add line. Add line. m_graphicsOverlay->graphics()->append(m_graphicResultText); m_mapView->graphicsOverlays()->append(m_graphicsOverlay); } void Display_a_map::geocode(const QString& query) { m_locatorTask->geocodeWithParameters(query, m_geocodeParams); }
-
Add the
suggestions
method to register the value ofm
as the value of the QML property_suggest List Model suggestions
.Display_a_map.cppUse dark colors for code blocks Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. void Display_a_map::geocode(const QString& query) { m_locatorTask->geocodeWithParameters(query, m_geocodeParams); } QAbstractListModel* Display_a_map::suggestions() const { return m_suggestListModel; }
-
Add the
clear
method. Then save and close the file.Graphics Display_a_map.cppUse dark colors for code blocks 167 168 169 170 171Add line. Add line. Add line. Add line. Add line. QAbstractListModel* Display_a_map::suggestions() const { return m_suggestListModel; } void Display_a_map::clearGraphics() { m_graphicResultLocation->setGeometry(Point()); m_graphicResultText->setGeometry(Point()); }
Create the application GUI
The GUI will let you enter partial or full addresses into a field, see a list of matching addresses, click an address and zoom to that location, and clear the address field.
-
In Projects, click on Resources > qml\qml.qrc > /qml. Then open the file Display_a_mapForm.qml
-
Add the following import statement.
Display_a_mapForm.qmlUse dark colors for code blocks 15 16 17 18Add line. import QtQuick 2.6 import QtQuick.Controls 2.2 import Esri.Display_a_map 1.0 import QtQuick.Layouts 1.3
-
Change the
Map
componentView id
tosearch
.Display_a_mapForm.qmlUse dark colors for code blocks 31 32 33Change line // Declare the C++ instance that creates the map etc. and supply the view Display_a_map { id: search
-
Add the following Qml code to implement the app gui.
Display_a_mapForm.qmlUse dark colors for code blocks 31 32 33 34 35 36 37 38Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. Add line. // Declare the C++ instance that creates the map etc. and supply the view Display_a_map { id: search mapView: view } Rectangle { // add rectangle for gui code id: searchRect width: parent.width height: childrenRect.height property int cellHeight: 40; Column { anchors { fill: parent margins: 10 } Rectangle { color: "#f7f8fa" border { color: "#7B7C7D" } radius: 2 width: parent.width height: childrenRect.height GridLayout { width: parent.width columns: 4 TextField { id: textField Layout.margins: 5 Layout.fillWidth: true font.pixelSize: 14 placeholderText: "Type in an address" selectByMouse: true onTextChanged: { if (text.length > 0 && suggestView) suggestView.visible = true; search.setSuggestions(text); } onAccepted: { suggestView.visible = false; search.geocode(textField.text); Qt.inputMethod.hide(); } } Rectangle { Layout.margins: 5 width: height height: textField.height color: "#f7f8fa" visible: textField.length === 0 enabled: visible Button { anchors.fill: parent text: "X" font.pixelSize: 16 MouseArea { anchors.fill: parent onClicked: { textField.focus = true; suggestView.visible = !suggestView.visible; } } } } Rectangle { Layout.margins: 5 width: height color: "transparent" height: textField.height visible: textField.length !== 0 enabled: visible Button { anchors.fill: parent text: "X" font.pixelSize: 16 MouseArea { anchors.fill: parent onClicked: { textField.text = ""; search.clearGraphics(); } } } } } } //Tutorial add ListView to display suggested location results and bind it to the locator task list model. ListView { id: suggestView height: 20 * searchRect.cellHeight width: textField.width model: search.suggestions visible: false clip: true delegate: Component { Rectangle { id: rect width: textField.width height: searchRect.cellHeight color: "#f7f8fa" Text { anchors { verticalCenter: parent.verticalCenter leftMargin: 5 rightMargin: 5 } font { weight: Font.Black pixelSize: 16 } width: textField.width text: label elide: Text.ElideRight leftPadding: 5 color: "black" } MouseArea { anchors.fill: parent onClicked: { textField.text = label; suggestView.visible = false; search.geocode(label); Qt.inputMethod.hide(); } } } } } } }
Press Ctrl + R to run the app.
You should see a map centered on the Santa Monica Mountains in California, with an address search bar at the top. Input an address in the search bar and the app will present a list of suggested addresses (not limited to the displayed map area). Click an address to zoom to that address location.
What's next?
Learn how to use additional API features, ArcGIS location services, and ArcGIS tools in these tutorials: