1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
// [WriteFile Name=FindAddress, Category=Search]
// [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
#include "FindAddress.h"
#include "Map.h"
#include "MapQuickView.h"
#include "Basemap.h"
#include "GraphicsOverlay.h"
#include "PictureMarkerSymbol.h"
#include "SimpleRenderer.h"
#include "LocatorTask.h"
#include "GeocodeParameters.h"
#include "Graphic.h"
#include "MapTypes.h"
#include "TaskWatcher.h"
#include "GraphicsOverlayListModel.h"
#include "GraphicListModel.h"
#include "AttributeListModel.h"
#include "GeocodeResult.h"
#include "CalloutData.h"
#include "IdentifyGraphicsOverlayResult.h"
#include "Point.h"
#include "Envelope.h"
#include <QUrl>
#include <memory>
#include <QUuid>
using namespace Esri::ArcGISRuntime;
FindAddress::FindAddress(QQuickItem* parent) :
QQuickItem(parent)
{
}
FindAddress::~FindAddress() = default;
void FindAddress::init()
{
qmlRegisterType<MapQuickView>("Esri.Samples", 1, 0, "MapView");
qmlRegisterType<FindAddress>("Esri.Samples", 1, 0, "FindAddressSample");
qmlRegisterUncreatableType<CalloutData>("Esri.Samples", 1, 0, "CalloutData", "CalloutData is an uncreatable type");
}
void FindAddress::componentComplete()
{
QQuickItem::componentComplete();
// find QML MapView component
m_mapView = findChild<MapQuickView*>("mapView");
// create a new basemap instance
Basemap* basemap = new Basemap(BasemapStyle::ArcGISImagery, this);
// create a new map instance
m_map = new Map(basemap, this);
// set map on the map view
m_mapView->setMap(m_map);
// create graphics overlay and add to map view
m_graphicsOverlay = new GraphicsOverlay(this);
m_mapView->graphicsOverlays()->append(m_graphicsOverlay);
// set a renderer on the graphics overlay
SimpleRenderer* simpleRenderer = new SimpleRenderer(this);
PictureMarkerSymbol* pictureMarkerSymbol = new PictureMarkerSymbol(QUrl("qrc:/Samples/Search/FindAddress/pin_circle_red.png"), this);
pictureMarkerSymbol->setWidth(35);
pictureMarkerSymbol->setHeight(35);
pictureMarkerSymbol->setOffsetY(pictureMarkerSymbol->height() / 2);
simpleRenderer->setSymbol(pictureMarkerSymbol);
m_graphicsOverlay->setRenderer(simpleRenderer);
m_graphic = new Graphic(this);
m_graphicsOverlay->graphics()->append(m_graphic);
// create locator task and parameters
//! [FindAddress create LocatorTask]
// An ArcGIS Developer API key is required to utilize this world geocoding service
m_locatorTask = new LocatorTask(QUrl("https://geocode-api.arcgis.com/arcgis/rest/services/World/GeocodeServer"), this);
//! [FindAddress create LocatorTask]
m_geocodeParameters.setMinScore(75);
m_geocodeParameters.setResultAttributeNames(QStringList { "Place_addr", "Match_addr" });
connectSignals();
}
void FindAddress::connectSignals()
{
// connect to geocode complete signal on the LocatorTask
//! [FindAddress geocodeCompleted handler]
connect(m_locatorTask, &LocatorTask::geocodeCompleted, this, [this](const QUuid&, const QList<GeocodeResult>& geocodeResults)
{
if (geocodeResults.length() > 0)
{
m_graphic->setGeometry(geocodeResults.at(0).displayLocation());
m_graphic->attributes()->setAttributesMap(geocodeResults.at(0).attributes());
constexpr double scale = 8000.0;
m_mapView->setViewpointCenter(geocodeResults.at(0).extent().center(), scale);
}
});
//! [FindAddress geocodeCompleted handler]
// connect to the mouse click signal on the MapQuickView
connect(m_mapView, &MapQuickView::mouseClicked, this, [this](QMouseEvent& mouseEvent)
{
// set the properties for qml
m_mapView->calloutData()->setLocation(m_mapView->screenToLocation(mouseEvent.position().x(), mouseEvent.position().y()));
emit hideCallout();
// call identify on the map view
m_mapView->identifyGraphicsOverlay(m_graphicsOverlay, mouseEvent.position().x(), mouseEvent.position().y(), 5, false, 1);
});
// connect to the identifyGraphicsOverlayCompleted signal on the map view
connect(m_mapView, &MapQuickView::identifyGraphicsOverlayCompleted, this, [this](const QUuid&, IdentifyGraphicsOverlayResult* rawIdentifyResult)
{
// Delete rawIdentifyResult on leaving scope.
auto identifyResult = std::unique_ptr<IdentifyGraphicsOverlayResult>(rawIdentifyResult);
if (!identifyResult)
return;
const QList<Graphic*> graphics = identifyResult->graphics();
if (graphics.length() > 0)
{
const AttributeListModel* attributes = graphics.at(0)->attributes();
const QString calloutText = attributes->attributeValue("Match_addr").toString();
m_mapView->calloutData()->setTitle(calloutText);
emit showCallout();
}
});
}
void FindAddress::geocodeAddress(const QString& address)
{
//! [FindAddress geocodeWithParameters]
m_locatorTask->geocodeWithParameters(address, m_geocodeParameters);
//! [FindAddress geocodeWithParameters]
}
void FindAddress::clearGraphics()
{
m_graphic->setGeometry(Point());
}