10#include <KOSMIndoorMap/HitDetector>
11#include <KOSMIndoorMap/MapCSSLoader>
12#include <KOSMIndoorMap/MapCSSParser>
13#include <KOSMIndoorMap/OverlaySource>
16#include <QGuiApplication>
19#include <QQuickWindow>
27 , m_view(new
View(this))
30 connect(m_loader, &MapLoader::isLoadingChanged,
this, &MapItem::clear);
33 m_view->setScreenSize({100, 100});
34 m_controller.setView(m_view);
35 connect(m_view, &View::floorLevelChanged,
this, [
this]() {
update(); });
36 connect(m_view, &View::transformationChanged,
this, [
this]() {
update(); });
38 setStylesheetName({});
43MapItem::~MapItem() =
default;
45void MapItem::paint(
QPainter *painter)
47 m_controller.updateScene(m_sg);
48 m_renderer.setPainter(painter);
49 m_renderer.render(m_sg, m_view);
57View* MapItem::view()
const
62QString MapItem::styleSheetName()
const
64 return m_styleSheetUrl.toString();
67void MapItem::setStylesheetName(
const QString &styleSheet)
70 if (m_styleSheetUrl == styleFile) {
73 m_styleSheetUrl = styleFile;
74 m_style = MapCSSStyle();
77 disconnect(m_styleLoader,
nullptr,
this,
nullptr);
79 m_styleLoader =
nullptr;
84 if (m_styleLoader->hasError()) {
85 m_errorMessage = m_styleLoader->errorMessage();
87 m_style = m_styleLoader->takeStyle();
88 m_errorMessage.clear();
90 m_style.compile(m_data.dataSet());
91 m_controller.setStyleSheet(&m_style);
95 m_styleLoader->deleteLater();
96 m_styleLoader =
nullptr;
98 m_styleLoader->start();
100 Q_EMIT styleSheetChanged();
105 return m_floorLevelModel;
108void MapItem::geometryChange(
const QRectF &newGeometry,
const QRectF &oldGeometry)
111 m_view->setScreenSize(newGeometry.
size().
toSize());
119void MapItem::loaderDone()
121 m_floorLevelModel->setMapData(
nullptr);
124 if (!m_loader->hasError()) {
125 auto data = m_loader->takeData();
126 if (data.regionCode().isEmpty()) {
127 data.setRegionCode(m_data.regionCode());
129 data.setTimeZone(m_data.timeZone());
130 m_data = std::move(data);
131 m_view->setSceneBoundingBox(m_data.boundingBox());
132 m_controller.setMapData(m_data);
133 m_style.compile(m_data.dataSet());
134 m_controller.setStyleSheet(&m_style);
136 m_floorLevelModel->setMapData(&m_data);
137 m_view->floorLevelChanged();
145OSMElement MapItem::elementAt(
double x,
double y)
const
147 HitDetector detector;
148 const auto item = detector.
itemAt(QPointF(
x,
y), m_sg, m_view);
150 qDebug() << item->element.url();
151 for (
auto it = item->element.tagsBegin(); it != item->element.tagsEnd(); ++it) {
152 qDebug() <<
" " << (*it).key.name() << (*it).value;
154 return OSMElement(item->element);
161 if (!m_loader->isLoading() || m_sg.items().empty()) {
167 m_controller.setMapData(m_data);
175 return !m_errorMessage.isEmpty() || m_loader->hasError();
180 return m_errorMessage.
isEmpty() ? m_loader->errorMessage() : m_errorMessage;
183MapData MapItem::mapData()
const
190 return m_overlaySources;
193void MapItem::setOverlaySources(
const QVariant &overlays)
195 const auto oldOwnedOverlays = std::move(m_ownedOverlaySources);
197 std::vector<QPointer<AbstractOverlaySource>> sources;
199 const auto l = overlays.
value<QVariantList>();
200 for (
const auto &v : l) {
201 addOverlaySource(sources, v);
204 addOverlaySource(sources, overlays);
207 for (
const auto &overlay : sources) {
212 m_controller.setOverlaySources(std::move(sources));
213 Q_EMIT overlaySourcesChanged();
217void MapItem::addOverlaySource(std::vector<QPointer<AbstractOverlaySource>> &overlaySources,
const QVariant &source)
221 auto overlay = std::make_unique<ModelOverlaySource>(model);
223 m_ownedOverlaySources.push_back(std::move(overlay));
227 qWarning() <<
"unsupported overlay source:" << source << obj;
231void MapItem::overlayUpdate()
233 m_controller.overlaySourceUpdated();
237void MapItem::overlayReset()
239 m_style.compile(m_data.dataSet());
244 return m_data.regionCode();
247void MapItem::setRegion(
const QString ®ion)
249 if (m_data.regionCode() ==
region) {
253 m_data.setRegionCode(
region);
257QString MapItem::timeZoneId()
const
262void MapItem::setTimeZoneId(
const QString &tz)
264 const auto tzId = tz.
toUtf8();
265 if (m_data.timeZone().id() == tzId) {
269 m_data.setTimeZone(QTimeZone(tzId));
275 return OSMElement(m_controller.hoveredElement());
278void MapItem::setHoveredElement(
const OSMElement &element)
280 if (m_controller.hoveredElement() == element.element()) {
283 m_controller.setHoveredElement(element.element());
284 Q_EMIT hoveredElementChanged();
288#include "moc_mapitem.cpp"
void reset()
Trigger style re-compilation.
void update()
Trigger map re-rendering when the source changes.
const SceneGraphItem * itemAt(QPointF pos, const SceneGraph &sg, const View *view) const
Highest (in z-order) item at the given screen position.
static QUrl resolve(const QString &style, const QUrl &baseUrl={})
Resolve style to an absolute URL to load.
static void expire()
Expire locally cached remote MapCSS assets.
void finished()
Loading is done, successfully or with an error.
Raw OSM map data, separated by levels.
bool hasError
There's a loading error (data not found, network issue, broken style sheet, etc).
KOSMIndoorMap::OSMElement hoveredElement
Currently hovered element.
QVariant overlaySources
Sources for overlays that should be rendered on top of the map.
QString region
ISO 3166-1/2 country or region code this map area is in.
QString errorMessage
Details on the error.
Loader for OSM data for a single station or airport.
void done()
Emitted when the requested data has been loaded.
QML wrapper around an OSM element.
View transformations and transformation manipulation.
void update(Part *part, const QByteArray &data, qint64 dataSize)
OSM-based multi-floor indoor maps for buildings.
KOSMINDOORMAP_EXPORT QNetworkAccessManager * defaultNetworkAccessManagerFactory()
Default implementation if not using an application-specific QNetworkAccessManager instance.
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
bool disconnect(const QMetaObject::Connection &connection)
T qobject_cast(QObject *object)
virtual void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
QQuickWindow * window() const const
QSizeF size() const const
QSize toSize() const const
QString fromUtf8(QByteArrayView str)
bool isEmpty() const const
QByteArray toUtf8() const const
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
bool canConvert() const const