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
The following are required for this tutorial:
- An ArcGIS account to access API keys. If you don't have an account, sign up for free.
- Your system meets the system requirements.
- The ArcGIS Runtime API for Qt is installed.
Steps
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.
-
If you downloaded the Display a map solution, set your API key.
An API Key enables access to services, web maps, and web scenes hosted in ArcGIS Online.
-
Go to your developer dashboard to get your API key. For these tutorials, use your default API key. It is scoped to include all of the services demonstrated in the tutorials.
-
In the Projects window, in the Sources folder, open the main.cpp file.
-
Modify the code to set the API key. Paste the API key, acquired from your dashboard, between the quotes. Then save and close the file.
main.cppUse dark colors for code blocks Change line // 2. API key: A permanent key that gives your application access to Esri // location services. Create a new API key or access existing API keys from // your ArcGIS for Developers dashboard (https://links.esri.com/arcgis-api-keys). const QString apiKey = 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 Add 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 Add line. Add line. } } #include <QObject> #include <QAbstractListModel> #include "GeocodeParameters.h"
-
Add a
Q_
for the member variablePROPERTY suggestions
.Display_a_map.hUse dark colors for code blocks Add 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 Add 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 Add 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 Add 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 Add 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 Add 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 Add 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 Add 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
with the Geocoding service URL, 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 tolocator Task m_
.suggest List Model 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. 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 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. 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 Add 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 Add 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 Add 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 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. 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 Add 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 propertysuggest 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 Add 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 Add 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 Change 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 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. 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: