diff --git a/src/apps/marble-maps/PlacemarkDialog.qml b/src/apps/marble-maps/PlacemarkDialog.qml index 4853902aa..816ad20fd 100644 --- a/src/apps/marble-maps/PlacemarkDialog.qml +++ b/src/apps/marble-maps/PlacemarkDialog.qml @@ -1,197 +1,198 @@ // // This file is part of the Marble Virtual Globe. // // This program is free software licensed under the GNU LGPL. You can // find a copy of this license in LICENSE.txt in the top directory of // the source code. // // Copyright 2015 Dennis Nienhüser // import QtQuick 2.3 import QtQuick.Window 2.2 import QtQuick.Controls 2.0 import QtQuick.Layouts 1.3 import QtQuick.Dialogs 1.2 import org.kde.marble 0.20 Item { id: root property var placemark: null property variant map property alias showOsmTags: tagsView.visible height: placemark === null ? 0 : Screen.pixelDensity * 4 + (infoLayout.height > bookmarkButton.height ? infoLayout.height : bookmarkButton.height) onPlacemarkChanged: { if (placemark) { bookmarkButton.bookmark = bookmarks.isBookmark(placemark.longitude, placemark.latitude) } } SystemPalette { id: palette colorGroup: SystemPalette.Active } Rectangle { anchors.fill: parent color: palette.base } Bookmarks { id: bookmarks } onMapChanged: bookmarks.map = root.map Column { id: infoLayout anchors { top: parent.top left: parent.left right: bookmarkButton.left margins: Screen.pixelDensity * 2 } IconText { id: name width: parent.width visible: text.length > 0 text: placemark === null ? "" : placemark.name maximumLineCount: 2 font.pointSize: 20 } IconText { width: parent.width visible: text.length > 0 text: placemark === null ? "" : placemark.description } IconText { width: parent.width visible: text.length > 0 text: placemark === null ? "" : placemark.address maximumLineCount: 4 } IconText { width: parent.width visible: routesItem.count > 0 text: "Part of " + routesItem.count + " routes" maximumLineCount: 4 linkColor: palette.text onLinkActivated: routesDialog.open() } IconText { width: parent.width visible: url.length > 0 property string url: placemark === null ? "" : placemark.website text: "" + url + "" icon: "qrc:/material/browser.svg" maximumLineCount: 4 onLinkActivated: Qt.openUrlExternally(link) } IconText { width: parent.width visible: url.length > 0 property string url: placemark === null ? "" : placemark.wikipedia text: "Wikipedia" icon: "qrc:/material/browser.svg" maximumLineCount: 4 onLinkActivated: Qt.openUrlExternally(link) } IconText { width: parent.width visible: text.length > 0 text: placemark === null ? "" : placemark.openingHours icon: "qrc:/material/access_time.svg" } IconText { width: parent.width visible: text.length > 0 text: placemark === null ? "" : placemark.wheelchairInfo icon: "qrc:/material/wheelchair.svg" } IconText { width: parent.width visible: text.length > 0 text: placemark === null ? "" : placemark.wifiAvailable icon: "qrc:/material/wlan-available.svg" } IconText { width: parent.width visible: text.length > 0 text: placemark === null ? "" : "" + placemark.coordinates + "" icon: "qrc:/material/place.svg" linkColor: palette.text onLinkActivated: marbleMaps.centerOnCoordinates(placemark.longitude, placemark.latitude) } ListView { id: tagsView visible: false width: parent.width height: Math.min(contentHeight, Screen.pixelDensity * 24) clip: true model: placemark ? placemark.tags : undefined delegate: IconText { width: tagsView.width; icon: "qrc:/material/label.svg" text: modelData } ScrollBar.vertical: ScrollBar {} } } Image { id: bookmarkButton anchors.right: parent.right anchors.top: parent.top anchors.margins: Screen.pixelDensity * 2 visible: root.height > 0 property bool bookmark: false width: Screen.pixelDensity * 6 height: width sourceSize.height: height sourceSize.width: width source: bookmark ? "qrc:/material/star.svg" : "qrc:/material/star_border.svg" MouseArea { id: touchArea anchors.fill: parent onClicked: { if (bookmarkButton.bookmark) { bookmarks.removeBookmark(root.placemark.longitude, root.placemark.latitude) } else { bookmarks.addBookmark(root.placemark, "Default") } bookmarkButton.bookmark = !bookmarkButton.bookmark } } } Dialog { id: routesDialog title: qsTr("Routes") RoutesItem { id: routesItem implicitWidth: parent.width model: placemark === null ? undefined : placemark.routeRelationModel + onHighlightChanged: map.highlightRouteRelation(oid, enabled) } } } diff --git a/src/apps/marble-maps/RoutesItem.qml b/src/apps/marble-maps/RoutesItem.qml index 3e24f81c1..903b43c3d 100644 --- a/src/apps/marble-maps/RoutesItem.qml +++ b/src/apps/marble-maps/RoutesItem.qml @@ -1,187 +1,198 @@ // // This file is part of the Marble Virtual Globe. // // This program is free software licensed under the GNU LGPL. You can // find a copy of this license in LICENSE.txt in the top directory of // the source code. // // Copyright 2017 Dennis Nienhüser // import QtQuick 2.3 import QtQuick.Window 2.2 import QtQuick.Controls 2.0 import QtQuick.Layouts 1.3 import QtGraphicalEffects 1.0 Item { id: root property alias model: listView.model property alias count: listView.count implicitHeight: Math.min(0.75 * Screen.height, listView.contentHeight) + signal highlightChanged(int oid, bool enabled) + ListView { id: listView anchors.fill: parent contentWidth: width model: placemark ? placemark.routeRelationModel : undefined clip: true spacing: Screen.pixelDensity * 2 delegate: Item { id: routeCard property bool expanded: false width: parent.width height: rectangle.height + dropShadow.verticalOffset + dropShadow.radius Rectangle { id: rectangle width: parent.width - dropShadow.horizontalOffset - dropShadow.radius height: column.height radius: Screen.pixelDensity * 1 Column { id: column width: parent.width + spacing: Screen.pixelDensity * 1 Item { width: parent.width height: Math.max(icon.height, textColumn.height) anchors { left: parent.left; right: parent.right; } Image { id: icon anchors.left: parent.left source: iconSource height: Screen.pixelDensity * 6 width: height sourceSize.height: Screen.pixelDensity * 6 sourceSize.width: width fillMode: Image.PreserveAspectFit } Column { id: textColumn anchors.left: icon.right anchors.right: parent.right Rectangle { width: parent.width height: childrenRect.height color: routeColor Text { anchors.left: parent.left anchors.margins: Screen.pixelDensity * 0.5 clip: true font.pointSize: 16 text: routeRef color: textColor width: parent.width wrapMode: Text.WrapAtWordBoundaryOrAnywhere } } Text { visible: text.length > 2 font.pointSize: 16 - text: "  " + routeFrom + text: "● " + routeFrom width: parent.width wrapMode: Text.WrapAtWordBoundaryOrAnywhere } Repeater { model: routeCard.expanded ? routeVia : undefined Text { font.pointSize: 16 - text: "◯ " + modelData + text: "○ " + modelData width: parent.width wrapMode: Text.WrapAtWordBoundaryOrAnywhere } } Text { visible: text.length > 2 font.pointSize: 16 - text: "→ " + routeTo + text: "● " + routeTo width: parent.width wrapMode: Text.WrapAtWordBoundaryOrAnywhere } Text { visible: routeCard.expanded font.pointSize: 14 text: "Network: " + network width: parent.width wrapMode: Text.WrapAtWordBoundaryOrAnywhere } Text { visible: routeCard.expanded font.pointSize: 14 text: description width: parent.width wrapMode: Text.WrapAtWordBoundaryOrAnywhere } } MouseArea { anchors.fill: parent onClicked: { routeCard.expanded = !routeCard.expanded listView.currentIndex = index } } Behavior on height { NumberAnimation { duration: 200 easing.type: Easing.OutQuart } } } Item { - // TODO Add support for route highlighting in ~GeometryLayer - visible: false && routeCard.expanded + visible: routeCard.expanded anchors.left: parent.left anchors.right: parent.right anchors.rightMargin: Screen.pixelDensity * 4 height: childrenRect.height Switch { + id: highlightSwitch anchors.right: switchText.left anchors.verticalCenter: switchText.verticalCenter + + checked: routeVisible + onCheckedChanged: root.highlightChanged(oid, checked) } Text { id: switchText anchors.right: parent.right text: "Highlight in Map" + + MouseArea { + anchors.fill: parent + onClicked: highlightSwitch.checked = !highlightSwitch.checked + } } } } } DropShadow { id: dropShadow anchors.fill: rectangle horizontalOffset: 4 verticalOffset: 4 radius: 4.0 samples: 17 color: "#40000000" source: rectangle } } ScrollBar.vertical: ScrollBar {} } } diff --git a/src/lib/marble/GeoGraphicsScene.cpp b/src/lib/marble/GeoGraphicsScene.cpp index 4fb77543f..2d6b98a81 100644 --- a/src/lib/marble/GeoGraphicsScene.cpp +++ b/src/lib/marble/GeoGraphicsScene.cpp @@ -1,271 +1,281 @@ // // This file is part of the Marble Virtual Globe. // // This program is free software licensed under the GNU LGPL. You can // find a copy of this license in LICENSE.txt in the top directory of // the source code. // // Copyright 2011 Konstantin Oblaukhov // #include "GeoGraphicsScene.h" #include "GeoDataFeature.h" #include "GeoDataLatLonAltBox.h" #include "GeoDataStyle.h" #include "GeoDataStyleMap.h" #include "GeoDataPlacemark.h" #include "GeoDataDocument.h" #include "GeoDataTypes.h" #include "GeoGraphicsItem.h" #include "TileId.h" #include "TileCoordsPyramid.h" #include "MarbleDebug.h" #include #include namespace Marble { class GeoGraphicsScenePrivate { public: GeoGraphicsScene *q; explicit GeoGraphicsScenePrivate(GeoGraphicsScene *parent) : q(parent) { } ~GeoGraphicsScenePrivate() { q->clear(); } typedef QHash FeatureItemMap; QMap m_tiledItems; QMultiHash m_features; // multi hash because multi track and multi geometry insert multiple items // Stores the items which have been clicked; QList m_selectedItems; GeoDataStyle::Ptr highlightStyle(const GeoDataDocument *document, const GeoDataStyleMap &styleMap); void selectItem( GeoGraphicsItem *item ); void applyHighlightStyle(GeoGraphicsItem *item, const GeoDataStyle::Ptr &style ); }; GeoDataStyle::Ptr GeoGraphicsScenePrivate::highlightStyle( const GeoDataDocument *document, const GeoDataStyleMap &styleMap ) { // @todo Consider QUrl parsing when external styles are suppported QString highlightStyleId = styleMap.value(QStringLiteral("highlight")); highlightStyleId.remove(QLatin1Char('#')); if ( !highlightStyleId.isEmpty() ) { GeoDataStyle::Ptr highlightStyle(new GeoDataStyle( *document->style(highlightStyleId) )); return highlightStyle; } else { return GeoDataStyle::Ptr(); } } void GeoGraphicsScenePrivate::selectItem( GeoGraphicsItem* item ) { m_selectedItems.append( item ); } void GeoGraphicsScenePrivate::applyHighlightStyle(GeoGraphicsItem* item, const GeoDataStyle::Ptr &highlightStyle ) { item->setHighlightStyle( highlightStyle ); item->setHighlighted( true ); } GeoGraphicsScene::GeoGraphicsScene( QObject* parent ): QObject( parent ), d( new GeoGraphicsScenePrivate(this) ) { } GeoGraphicsScene::~GeoGraphicsScene() { delete d; } QList< GeoGraphicsItem* > GeoGraphicsScene::items( const GeoDataLatLonBox &box, int zoomLevel ) const { if ( box.west() > box.east() ) { // Handle boxes crossing the IDL by splitting it into two separate boxes GeoDataLatLonBox left; left.setWest( -M_PI ); left.setEast( box.east() ); left.setNorth( box.north() ); left.setSouth( box.south() ); GeoDataLatLonBox right; right.setWest( box.west() ); right.setEast( M_PI ); right.setNorth( box.north() ); right.setSouth( box.south() ); return items(left, zoomLevel) + items(right, zoomLevel); } QList< GeoGraphicsItem* > result; QRect rect; qreal north, south, east, west; box.boundaries( north, south, east, west ); TileId key; key = TileId::fromCoordinates( GeoDataCoordinates(west, north, 0), zoomLevel ); rect.setLeft( key.x() ); rect.setTop( key.y() ); key = TileId::fromCoordinates( GeoDataCoordinates(east, south, 0), zoomLevel ); rect.setRight( key.x() ); rect.setBottom( key.y() ); TileCoordsPyramid pyramid( 0, zoomLevel ); pyramid.setBottomLevelCoords( rect ); for ( int level = pyramid.topLevel(); level <= pyramid.bottomLevel(); ++level ) { QRect const coords = pyramid.coords( level ); int x1, y1, x2, y2; coords.getCoords( &x1, &y1, &x2, &y2 ); for ( int x = x1; x <= x2; ++x ) { bool const isBorderX = x == x1 || x == x2; for ( int y = y1; y <= y2; ++y ) { bool const isBorder = isBorderX || y == y1 || y == y2; const TileId tileId = TileId( 0, level, x, y ); foreach(GeoGraphicsItem *object, d->m_tiledItems.value( tileId )) { if (object->minZoomLevel() <= zoomLevel && object->visible()) { if (!isBorder || object->latLonAltBox().intersects(box)) { result.push_back(object); } } } } } } return result; } QList< GeoGraphicsItem* > GeoGraphicsScene::selectedItems() const { return d->m_selectedItems; } +void GeoGraphicsScene::resetStyle() +{ + for (auto const & items: d->m_tiledItems) { + for (auto item: items) { + item->resetStyle(); + } + } + emit repaintNeeded(); +} + void GeoGraphicsScene::applyHighlight( const QVector< GeoDataPlacemark* > &selectedPlacemarks ) { /** * First set the items, which were selected previously, to * use normal style */ foreach ( GeoGraphicsItem *item, d->m_selectedItems ) { item->setHighlighted( false ); } // Also clear the list to store the new selected items d->m_selectedItems.clear(); /** * Process the placemark. which were under mouse * while clicking, and update corresponding graphics * items to use highlight style */ foreach( const GeoDataPlacemark *placemark, selectedPlacemarks ) { for (auto tileIter = d->m_features.find(placemark); tileIter != d->m_features.end(); ++tileIter) { auto const & clickedItems = d->m_tiledItems[*tileIter]; auto iter = clickedItems.find(placemark); if (iter != clickedItems.end()) { GeoDataObject *parent = placemark->parent(); if ( parent ) { auto item = *iter; if ( parent->nodeType() == GeoDataTypes::GeoDataDocumentType ) { GeoDataDocument *doc = static_cast( parent ); QString styleUrl = placemark->styleUrl(); styleUrl.remove(QLatin1Char('#')); if ( !styleUrl.isEmpty() ) { GeoDataStyleMap const &styleMap = doc->styleMap( styleUrl ); GeoDataStyle::Ptr style = d->highlightStyle( doc, styleMap ); if ( style ) { d->selectItem( item ); d->applyHighlightStyle( item, style ); } } /** * If a placemark is using an inline style instead of a shared * style ( e.g in case when theme file specifies the colorMap * attribute ) then highlight it if any of the style maps have a * highlight styleId */ else { foreach ( const GeoDataStyleMap &styleMap, doc->styleMaps() ) { GeoDataStyle::Ptr style = d->highlightStyle( doc, styleMap ); if ( style ) { d->selectItem( item ); d->applyHighlightStyle( item, style ); break; } } } } } } } } emit repaintNeeded(); } void GeoGraphicsScene::removeItem( const GeoDataFeature* feature ) { for (auto tileIter = d->m_features.find(feature), end = d->m_features.end(); tileIter != end;) { auto & tileList = d->m_tiledItems[*tileIter]; auto iter = tileList.find(feature); if (iter != tileList.end()) { auto item = iter.value(); tileIter = d->m_features.erase(tileIter); tileList.erase(iter); delete item; } else { ++tileIter; } } } void GeoGraphicsScene::clear() { foreach(auto const &list, d->m_tiledItems.values()) { qDeleteAll(list.values()); } d->m_tiledItems.clear(); d->m_features.clear(); } void GeoGraphicsScene::addItem( GeoGraphicsItem* item ) { // Select zoom level so that the object fit in single tile int zoomLevel; qreal north, south, east, west; item->latLonAltBox().boundaries( north, south, east, west ); for(zoomLevel = item->minZoomLevel(); zoomLevel >= 0; zoomLevel--) { if( TileId::fromCoordinates( GeoDataCoordinates(west, north, 0), zoomLevel ) == TileId::fromCoordinates( GeoDataCoordinates(east, south, 0), zoomLevel ) ) break; } const TileId key = TileId::fromCoordinates( GeoDataCoordinates(west, north, 0), zoomLevel ); // same as GeoDataCoordinates(east, south, 0), see above auto & tileList = d->m_tiledItems[key]; auto feature = item->feature(); tileList.insert(feature, item); d->m_features.insert(feature, key ); } } #include "moc_GeoGraphicsScene.cpp" diff --git a/src/lib/marble/GeoGraphicsScene.h b/src/lib/marble/GeoGraphicsScene.h index 5011af6fe..fd143c44b 100644 --- a/src/lib/marble/GeoGraphicsScene.h +++ b/src/lib/marble/GeoGraphicsScene.h @@ -1,88 +1,90 @@ // // This file is part of the Marble Virtual Globe. // // This program is free software licensed under the GNU LGPL. You can // find a copy of this license in LICENSE.txt in the top directory of // the source code. // // Copyright 2010 Bastian Holst // Copyright 2011 Konstantin Oblaukhov // #ifndef MARBLE_GEOGRAPHICSSCENE_H #define MARBLE_GEOGRAPHICSSCENE_H #include "marble_export.h" #include "MarbleGlobal.h" #include #include namespace Marble { class GeoGraphicsItem; class GeoDataFeature; class GeoDataLatLonBox; class GeoGraphicsScenePrivate; class GeoDataPlacemark; /** * @short This is the home of all GeoGraphicsItems to be shown on the map. */ class MARBLE_EXPORT GeoGraphicsScene : public QObject { Q_OBJECT public: /** * Creates a new instance of GeoGraphicsScene * @param parent the QObject parent of the Scene */ explicit GeoGraphicsScene( QObject *parent = 0 ); ~GeoGraphicsScene() override; /** * @brief Add an item to the GeoGraphicsScene * Adds the item @p item to the GeoGraphicsScene */ void addItem( GeoGraphicsItem *item ); /** * @brief Remove all concerned items from the GeoGraphicsScene * Removes all items which are associated with @p object from the GeoGraphicsScene */ void removeItem( const GeoDataFeature *feature ); /** * @brief Remove all items from the GeoGraphicsScene */ void clear(); /** * @brief Get the list of items in the specified Box * * @param box The box around the items. * @param maxZoomLevel The max zoom level of tiling * @return The list of items in the specified box in no specific order. */ QList items( const GeoDataLatLonBox &box, int maxZoomLevel ) const; /** * @brief Get the list of items which belong to a placemark * that has been clicked. * @return Returns a list of selected Items */ QList selectedItems() const; + void resetStyle(); + public Q_SLOTS: void applyHighlight( const QVector& ); Q_SIGNALS: void repaintNeeded(); private: GeoGraphicsScenePrivate * const d; }; } #endif // MARBLE_GEOGRAPHICSSCENE_H diff --git a/src/lib/marble/MarbleMap.cpp b/src/lib/marble/MarbleMap.cpp index d4b5154d4..968a24a06 100644 --- a/src/lib/marble/MarbleMap.cpp +++ b/src/lib/marble/MarbleMap.cpp @@ -1,1428 +1,1433 @@ // // This file is part of the Marble Virtual Globe. // // This program is free software licensed under the GNU LGPL. You can // find a copy of this license in LICENSE.txt in the top directory of // the source code. // // Copyright 2006-2009 Torsten Rahn // Copyright 2007 Inge Wallin // Copyright 2008 Carlos Licea // Copyright 2009 Jens-Michael Hoffmann // Copyright 2010-2012 Bernhard Beschow // // Own #include "MarbleMap.h" // Posix #include // Qt #include #include // Marble #include "layers/FloatItemsLayer.h" #include "layers/FogLayer.h" #include "layers/FpsLayer.h" #include "layers/GeometryLayer.h" #include "layers/GroundLayer.h" #include "layers/MarbleSplashLayer.h" #include "layers/PlacemarkLayer.h" #include "layers/TextureLayer.h" #include "layers/VectorTileLayer.h" #include "AbstractFloatItem.h" #include "DgmlAuxillaryDictionary.h" #include "FileManager.h" #include "GeoDataTreeModel.h" #include "GeoPainter.h" #include "GeoSceneDocument.h" #include "GeoSceneFilter.h" #include "GeoSceneGeodata.h" #include "GeoSceneHead.h" #include "GeoSceneLayer.h" #include "GeoSceneMap.h" #include "GeoScenePalette.h" #include "GeoSceneSettings.h" #include "GeoSceneVector.h" #include "GeoSceneVectorTileDataset.h" #include "GeoSceneTextureTileDataset.h" #include "GeoSceneZoom.h" #include "GeoDataDocument.h" #include "GeoDataFeature.h" #include "GeoDataStyle.h" #include "GeoDataStyleMap.h" #include "LayerManager.h" #include "MapThemeManager.h" #include "MarbleDebug.h" #include "MarbleDirs.h" #include "MarbleModel.h" #include "PluginManager.h" #include "RenderPlugin.h" #include "StyleBuilder.h" #include "SunLocator.h" #include "TileId.h" #include "TileCoordsPyramid.h" #include "TileCreator.h" #include "TileCreatorDialog.h" #include "TileLoader.h" #include "ViewParams.h" #include "ViewportParams.h" #include "RenderState.h" #include "BookmarkManager.h" namespace Marble { class MarbleMap::CustomPaintLayer : public LayerInterface { public: explicit CustomPaintLayer( MarbleMap *map ) : m_map( map ) { } QStringList renderPosition() const override { return QStringList() << "USER_TOOLS"; } bool render( GeoPainter *painter, ViewportParams *viewport, const QString &renderPos, GeoSceneLayer *layer ) override { Q_UNUSED( viewport ); Q_UNUSED( renderPos ); Q_UNUSED( layer ); m_map->customPaint( painter ); return true; } qreal zValue() const override { return 1.0e6; } RenderState renderState() const override { return RenderState(QStringLiteral("Custom Map Paint")); } QString runtimeTrace() const override { return QStringLiteral("CustomPaint"); } private: MarbleMap *const m_map; }; class MarbleMapPrivate { friend class MarbleWidget; public: explicit MarbleMapPrivate( MarbleMap *parent, MarbleModel *model ); void updateMapTheme(); void updateProperty( const QString &, bool ); void setDocument( QString key ); void updateTileLevel(); void addPlugins(); MarbleMap *const q; // The model we are showing. MarbleModel *const m_model; bool m_modelIsOwned; // Parameters for the maps appearance. ViewParams m_viewParams; ViewportParams m_viewport; bool m_showFrameRate; bool m_showDebugPolygons; bool m_showDebugBatchRender; StyleBuilder m_styleBuilder; QList m_renderPlugins; LayerManager m_layerManager; MarbleSplashLayer m_marbleSplashLayer; MarbleMap::CustomPaintLayer m_customPaintLayer; GeometryLayer m_geometryLayer; FloatItemsLayer m_floatItemsLayer; FogLayer m_fogLayer; GroundLayer m_groundLayer; TextureLayer m_textureLayer; PlacemarkLayer m_placemarkLayer; VectorTileLayer m_vectorTileLayer; bool m_isLockedToSubSolarPoint; bool m_isSubSolarPointIconVisible; RenderState m_renderState; }; MarbleMapPrivate::MarbleMapPrivate( MarbleMap *parent, MarbleModel *model ) : q( parent ), m_model( model ), m_viewParams(), m_showFrameRate( false ), m_showDebugPolygons( false ), m_showDebugBatchRender( false ), m_styleBuilder(), m_layerManager( parent ), m_customPaintLayer( parent ), m_geometryLayer(model->treeModel(), &m_styleBuilder), m_floatItemsLayer(parent), m_textureLayer( model->downloadManager(), model->pluginManager(), model->sunLocator(), model->groundOverlayModel() ), m_placemarkLayer( model->placemarkModel(), model->placemarkSelectionModel(), model->clock(), &m_styleBuilder ), m_vectorTileLayer( model->downloadManager(), model->pluginManager(), model->treeModel() ), m_isLockedToSubSolarPoint( false ), m_isSubSolarPointIconVisible( false ) { m_layerManager.addLayer(&m_floatItemsLayer); m_layerManager.addLayer( &m_fogLayer ); m_layerManager.addLayer( &m_groundLayer ); m_layerManager.addLayer( &m_geometryLayer ); m_layerManager.addLayer( &m_placemarkLayer ); m_layerManager.addLayer( &m_customPaintLayer ); m_model->bookmarkManager()->setStyleBuilder(&m_styleBuilder); QObject::connect( m_model, SIGNAL(themeChanged(QString)), parent, SLOT(updateMapTheme()) ); QObject::connect( m_model->fileManager(), SIGNAL(fileAdded(QString)), parent, SLOT(setDocument(QString)) ); QObject::connect( &m_placemarkLayer, SIGNAL(repaintNeeded()), parent, SIGNAL(repaintNeeded())); QObject::connect ( &m_layerManager, SIGNAL(pluginSettingsChanged()), parent, SIGNAL(pluginSettingsChanged()) ); QObject::connect ( &m_layerManager, SIGNAL(repaintNeeded(QRegion)), parent, SIGNAL(repaintNeeded(QRegion)) ); QObject::connect ( &m_layerManager, SIGNAL(renderPluginInitialized(RenderPlugin*)), parent, SIGNAL(renderPluginInitialized(RenderPlugin*)) ); QObject::connect ( &m_layerManager, SIGNAL(visibilityChanged(QString,bool)), parent, SLOT(setPropertyValue(QString,bool)) ); QObject::connect( &m_geometryLayer, SIGNAL(repaintNeeded()), parent, SIGNAL(repaintNeeded())); QObject::connect(&m_vectorTileLayer, SIGNAL(tileLevelChanged(int)), &m_geometryLayer, SLOT(setTileLevel(int))); QObject::connect(&m_vectorTileLayer, SIGNAL(tileLevelChanged(int)), &m_placemarkLayer, SLOT(setTileLevel(int))); QObject::connect(&m_textureLayer, SIGNAL(tileLevelChanged(int)), &m_placemarkLayer, SLOT(setTileLevel(int))); /* * Slot handleHighlight finds all placemarks * that contain the clicked point. * The placemarks under the clicked position may * have their styleUrl set to a style map which * doesn't specify any highlight styleId. Such * placemarks will be fletered out in GeoGraphicsScene * and will not be highlighted. */ QObject::connect( parent, SIGNAL(highlightedPlacemarksChanged(qreal,qreal,GeoDataCoordinates::Unit)), &m_geometryLayer, SLOT(handleHighlight(qreal,qreal,GeoDataCoordinates::Unit)) ); QObject::connect(&m_floatItemsLayer, SIGNAL(repaintNeeded(QRegion)), parent, SIGNAL(repaintNeeded(QRegion))); QObject::connect(&m_floatItemsLayer, SIGNAL(renderPluginInitialized(RenderPlugin*)), parent, SIGNAL(renderPluginInitialized(RenderPlugin*))); QObject::connect(&m_floatItemsLayer, SIGNAL(visibilityChanged(QString,bool)), parent, SLOT(setPropertyValue(QString,bool))); QObject::connect(&m_floatItemsLayer, SIGNAL(pluginSettingsChanged()), parent, SIGNAL(pluginSettingsChanged())); QObject::connect( &m_textureLayer, SIGNAL(tileLevelChanged(int)), parent, SLOT(updateTileLevel()) ); QObject::connect( &m_vectorTileLayer, SIGNAL(tileLevelChanged(int)), parent, SLOT(updateTileLevel()) ); QObject::connect( &m_textureLayer, SIGNAL(repaintNeeded()), parent, SIGNAL(repaintNeeded()) ); QObject::connect( parent, SIGNAL(visibleLatLonAltBoxChanged(GeoDataLatLonAltBox)), parent, SIGNAL(repaintNeeded()) ); addPlugins(); QObject::connect(model->pluginManager(), SIGNAL(renderPluginsChanged()), parent, SLOT(addPlugins())); } void MarbleMapPrivate::updateProperty( const QString &name, bool show ) { // earth if (name == QLatin1String("places")) { m_placemarkLayer.setShowPlaces( show ); } else if (name == QLatin1String("cities")) { m_placemarkLayer.setShowCities( show ); } else if (name == QLatin1String("terrain")) { m_placemarkLayer.setShowTerrain( show ); } else if (name == QLatin1String("otherplaces")) { m_placemarkLayer.setShowOtherPlaces( show ); } // other planets else if (name == QLatin1String("landingsites")) { m_placemarkLayer.setShowLandingSites( show ); } else if (name == QLatin1String("craters")) { m_placemarkLayer.setShowCraters( show ); } else if (name == QLatin1String("maria")) { m_placemarkLayer.setShowMaria( show ); } else if (name == QLatin1String("relief")) { m_textureLayer.setShowRelief( show ); } foreach(RenderPlugin *renderPlugin, m_renderPlugins) { if ( name == renderPlugin->nameId() ) { if ( renderPlugin->visible() == show ) { break; } renderPlugin->setVisible( show ); break; } } } void MarbleMapPrivate::addPlugins() { foreach (const RenderPlugin *factory, m_model->pluginManager()->renderPlugins()) { bool alreadyCreated = false; foreach(const RenderPlugin *existing, m_renderPlugins) { if (existing->nameId() == factory->nameId()) { alreadyCreated = true; break; } } if (alreadyCreated) { continue; } RenderPlugin *const renderPlugin = factory->newInstance(m_model); Q_ASSERT(renderPlugin && "Plugin must not return null when requesting a new instance."); m_renderPlugins << renderPlugin; if (AbstractFloatItem *const floatItem = qobject_cast(renderPlugin)) { m_floatItemsLayer.addFloatItem(floatItem); } else { m_layerManager.addRenderPlugin(renderPlugin); } } } // ---------------------------------------------------------------- MarbleMap::MarbleMap() : d( new MarbleMapPrivate( this, new MarbleModel( this ) ) ) { // nothing to do } MarbleMap::MarbleMap(MarbleModel *model) : d( new MarbleMapPrivate( this, model ) ) { d->m_modelIsOwned = false; } MarbleMap::~MarbleMap() { MarbleModel *model = d->m_modelIsOwned ? d->m_model : 0; d->m_layerManager.removeLayer( &d->m_customPaintLayer ); d->m_layerManager.removeLayer( &d->m_geometryLayer ); d->m_layerManager.removeLayer(&d->m_floatItemsLayer); d->m_layerManager.removeLayer( &d->m_fogLayer ); d->m_layerManager.removeLayer( &d->m_placemarkLayer ); d->m_layerManager.removeLayer( &d->m_textureLayer ); d->m_layerManager.removeLayer( &d->m_groundLayer ); qDeleteAll(d->m_renderPlugins); delete d; delete model; // delete the model after private data } MarbleModel *MarbleMap::model() const { return d->m_model; } ViewportParams *MarbleMap::viewport() { return &d->m_viewport; } const ViewportParams *MarbleMap::viewport() const { return &d->m_viewport; } void MarbleMap::setMapQualityForViewContext( MapQuality quality, ViewContext viewContext ) { d->m_viewParams.setMapQualityForViewContext( quality, viewContext ); // Update texture map during the repaint that follows: d->m_textureLayer.setNeedsUpdate(); } MapQuality MarbleMap::mapQuality( ViewContext viewContext ) const { return d->m_viewParams.mapQuality( viewContext ); } MapQuality MarbleMap::mapQuality() const { return d->m_viewParams.mapQuality(); } void MarbleMap::setViewContext( ViewContext viewContext ) { if ( d->m_viewParams.viewContext() == viewContext ) { return; } const MapQuality oldQuality = d->m_viewParams.mapQuality(); d->m_viewParams.setViewContext( viewContext ); emit viewContextChanged( viewContext ); if ( d->m_viewParams.mapQuality() != oldQuality ) { // Update texture map during the repaint that follows: d->m_textureLayer.setNeedsUpdate(); emit repaintNeeded(); } } ViewContext MarbleMap::viewContext() const { return d->m_viewParams.viewContext(); } void MarbleMap::setSize( int width, int height ) { setSize( QSize( width, height ) ); } void MarbleMap::setSize( const QSize& size ) { d->m_viewport.setSize( size ); emit visibleLatLonAltBoxChanged( d->m_viewport.viewLatLonAltBox() ); } QSize MarbleMap::size() const { return QSize( d->m_viewport.width(), d->m_viewport.height() ); } int MarbleMap::width() const { return d->m_viewport.width(); } int MarbleMap::height() const { return d->m_viewport.height(); } int MarbleMap::radius() const { return d->m_viewport.radius(); } void MarbleMap::setRadius( int radius ) { const int oldRadius = d->m_viewport.radius(); d->m_viewport.setRadius( radius ); if ( oldRadius != d->m_viewport.radius() ) { emit radiusChanged( radius ); emit visibleLatLonAltBoxChanged( d->m_viewport.viewLatLonAltBox() ); } } int MarbleMap::preferredRadiusCeil( int radius ) { return d->m_textureLayer.preferredRadiusCeil( radius ); } int MarbleMap::preferredRadiusFloor( int radius ) { return d->m_textureLayer.preferredRadiusFloor( radius ); } int MarbleMap::tileZoomLevel() const { return qMax(d->m_textureLayer.tileZoomLevel(), d->m_vectorTileLayer.tileZoomLevel()); } qreal MarbleMap::centerLatitude() const { // Calculate translation of center point const qreal centerLat = d->m_viewport.centerLatitude(); return centerLat * RAD2DEG; } bool MarbleMap::hasFeatureAt(const QPoint &position) const { return d->m_placemarkLayer.hasPlacemarkAt(position) || d->m_geometryLayer.hasFeatureAt(position, viewport()); } qreal MarbleMap::centerLongitude() const { // Calculate translation of center point const qreal centerLon = d->m_viewport.centerLongitude(); return centerLon * RAD2DEG; } int MarbleMap::minimumZoom() const { if ( d->m_model->mapTheme() ) return d->m_model->mapTheme()->head()->zoom()->minimum(); return 950; } int MarbleMap::maximumZoom() const { if ( d->m_model->mapTheme() ) return d->m_model->mapTheme()->head()->zoom()->maximum(); return 2100; } bool MarbleMap::discreteZoom() const { if ( d->m_model->mapTheme() ) return d->m_model->mapTheme()->head()->zoom()->discrete(); return false; } QVector MarbleMap::whichFeatureAt( const QPoint& curpos ) const { return d->m_placemarkLayer.whichPlacemarkAt( curpos ) + d->m_geometryLayer.whichFeatureAt( curpos, viewport() ); } void MarbleMap::reload() { d->m_textureLayer.reload(); d->m_vectorTileLayer.reload(); } void MarbleMap::downloadRegion( QVector const & pyramid ) { Q_ASSERT( textureLayer() ); Q_ASSERT( !pyramid.isEmpty() ); QTime t; t.start(); // When downloading a region (the author of these lines thinks) most users probably expect // the download to begin with the low resolution tiles and then procede level-wise to // higher resolution tiles. In order to achieve this, we start requesting downloads of // high resolution tiles and request the low resolution tiles at the end because // DownloadQueueSet (silly name) is implemented as stack. int const first = 0; int tilesCount = 0; for ( int level = pyramid[first].bottomLevel(); level >= pyramid[first].topLevel(); --level ) { QSet tileIdSet; for( int i = 0; i < pyramid.size(); ++i ) { QRect const coords = pyramid[i].coords( level ); mDebug() << "MarbleMap::downloadRegion level:" << level << "tile coords:" << coords; int x1, y1, x2, y2; coords.getCoords( &x1, &y1, &x2, &y2 ); for ( int x = x1; x <= x2; ++x ) { for ( int y = y1; y <= y2; ++y ) { TileId const stackedTileId( 0, level, x, y ); tileIdSet.insert( stackedTileId ); // FIXME: use lazy evaluation to not generate up to 100k tiles in one go // this can take considerable time even on very fast systems // in contrast generating the TileIds on the fly when they are needed // does not seem to affect download speed. } } } QSetIterator i( tileIdSet ); while( i.hasNext() ) { TileId const tileId = i.next(); d->m_textureLayer.downloadStackedTile( tileId ); } tilesCount += tileIdSet.count(); } // Needed for downloading unique tiles only. Much faster than if tiles for each level is downloaded separately int const elapsedMs = t.elapsed(); mDebug() << "MarbleMap::downloadRegion:" << tilesCount << "tiles, " << elapsedMs << "ms"; } +void MarbleMap::highlightRouteRelation(qint64 osmId, bool enabled) +{ + d->m_geometryLayer.highlightRouteRelation(osmId, enabled); +} + bool MarbleMap::propertyValue( const QString& name ) const { bool value; if ( d->m_model->mapTheme() ) { d->m_model->mapTheme()->settings()->propertyValue( name, value ); } else { value = false; mDebug() << "WARNING: Failed to access a map theme! Property: " << name; } return value; } bool MarbleMap::showOverviewMap() const { return propertyValue(QStringLiteral("overviewmap")); } bool MarbleMap::showScaleBar() const { return propertyValue(QStringLiteral("scalebar")); } bool MarbleMap::showCompass() const { return propertyValue(QStringLiteral("compass")); } bool MarbleMap::showGrid() const { return propertyValue(QStringLiteral("coordinate-grid")); } bool MarbleMap::showClouds() const { return d->m_viewParams.showClouds(); } bool MarbleMap::showSunShading() const { return d->m_textureLayer.showSunShading(); } bool MarbleMap::showCityLights() const { return d->m_textureLayer.showCityLights(); } bool MarbleMap::isLockedToSubSolarPoint() const { return d->m_isLockedToSubSolarPoint; } bool MarbleMap::isSubSolarPointIconVisible() const { return d->m_isSubSolarPointIconVisible; } bool MarbleMap::showAtmosphere() const { return d->m_viewParams.showAtmosphere(); } bool MarbleMap::showCrosshairs() const { bool visible = false; QList pluginList = renderPlugins(); QList::const_iterator i = pluginList.constBegin(); QList::const_iterator const end = pluginList.constEnd(); for (; i != end; ++i ) { if ((*i)->nameId() == QLatin1String("crosshairs")) { visible = (*i)->visible(); } } return visible; } bool MarbleMap::showPlaces() const { return propertyValue(QStringLiteral("places")); } bool MarbleMap::showCities() const { return propertyValue(QStringLiteral("cities")); } bool MarbleMap::showTerrain() const { return propertyValue(QStringLiteral("terrain")); } bool MarbleMap::showOtherPlaces() const { return propertyValue(QStringLiteral("otherplaces")); } bool MarbleMap::showRelief() const { return propertyValue(QStringLiteral("relief")); } bool MarbleMap::showIceLayer() const { return propertyValue(QStringLiteral("ice")); } bool MarbleMap::showBorders() const { return propertyValue(QStringLiteral("borders")); } bool MarbleMap::showRivers() const { return propertyValue(QStringLiteral("rivers")); } bool MarbleMap::showLakes() const { return propertyValue(QStringLiteral("lakes")); } bool MarbleMap::showFrameRate() const { return d->m_showFrameRate; } bool MarbleMap::showBackground() const { return d->m_layerManager.showBackground(); } quint64 MarbleMap::volatileTileCacheLimit() const { return d->m_textureLayer.volatileCacheLimit(); } void MarbleMap::rotateBy(qreal deltaLon, qreal deltaLat) { centerOn( d->m_viewport.centerLongitude() * RAD2DEG + deltaLon, d->m_viewport.centerLatitude() * RAD2DEG + deltaLat ); } void MarbleMap::centerOn( const qreal lon, const qreal lat ) { d->m_viewport.centerOn( lon * DEG2RAD, lat * DEG2RAD ); emit visibleLatLonAltBoxChanged( d->m_viewport.viewLatLonAltBox() ); } void MarbleMap::setCenterLatitude( qreal lat ) { centerOn( centerLongitude(), lat ); } void MarbleMap::setCenterLongitude( qreal lon ) { centerOn( lon, centerLatitude() ); } Projection MarbleMap::projection() const { return d->m_viewport.projection(); } void MarbleMap::setProjection( Projection projection ) { if ( d->m_viewport.projection() == projection ) return; emit projectionChanged( projection ); d->m_viewport.setProjection( projection ); d->m_textureLayer.setProjection( projection ); emit visibleLatLonAltBoxChanged( d->m_viewport.viewLatLonAltBox() ); } bool MarbleMap::screenCoordinates( qreal lon, qreal lat, qreal& x, qreal& y ) const { return d->m_viewport.screenCoordinates( lon * DEG2RAD, lat * DEG2RAD, x, y ); } bool MarbleMap::geoCoordinates( int x, int y, qreal& lon, qreal& lat, GeoDataCoordinates::Unit unit ) const { return d->m_viewport.geoCoordinates( x, y, lon, lat, unit ); } void MarbleMapPrivate::setDocument( QString key ) { if ( !m_model->mapTheme() ) { // Happens if no valid map theme is set or at application startup // if a file is passed via command line parameters and the last // map theme has not been loaded yet /** * @todo Do we need to queue the document and process it once a map * theme becomes available? */ return; } GeoDataDocument* doc = m_model->fileManager()->at( key ); foreach ( const GeoSceneLayer *layer, m_model->mapTheme()->map()->layers() ) { if ( layer->backend() != dgml::dgmlValue_geodata && layer->backend() != dgml::dgmlValue_vector ) continue; // look for documents foreach ( const GeoSceneAbstractDataset *dataset, layer->datasets() ) { const GeoSceneGeodata *data = static_cast( dataset ); QString containername = data->sourceFile(); QString colorize = data->colorize(); if( key == containername ) { if (colorize == QLatin1String("land")) { m_textureLayer.addLandDocument( doc ); } if (colorize == QLatin1String("sea")) { m_textureLayer.addSeaDocument( doc ); } // set visibility according to theme property if( !data->property().isEmpty() ) { bool value; m_model->mapTheme()->settings()->propertyValue( data->property(), value ); doc->setVisible( value ); m_model->treeModel()->updateFeature( doc ); } } } } } void MarbleMapPrivate::updateTileLevel() { emit q->tileLevelChanged(q->tileZoomLevel()); } // Used to be paintEvent() void MarbleMap::paint( GeoPainter &painter, const QRect &dirtyRect ) { Q_UNUSED( dirtyRect ); if (d->m_showDebugPolygons ) { if (viewContext() == Animation) { painter.setDebugPolygonsLevel(1); } else { painter.setDebugPolygonsLevel(2); } } painter.setDebugBatchRender(d->m_showDebugBatchRender); if ( !d->m_model->mapTheme() ) { mDebug() << "No theme yet!"; d->m_marbleSplashLayer.render( &painter, &d->m_viewport ); return; } QTime t; t.start(); RenderStatus const oldRenderStatus = d->m_renderState.status(); d->m_layerManager.renderLayers( &painter, &d->m_viewport ); d->m_renderState = d->m_layerManager.renderState(); bool const parsing = d->m_model->fileManager()->pendingFiles() > 0; d->m_renderState.addChild(RenderState(QStringLiteral("Files"), parsing ? WaitingForData : Complete)); RenderStatus const newRenderStatus = d->m_renderState.status(); if ( oldRenderStatus != newRenderStatus ) { emit renderStatusChanged( newRenderStatus ); } emit renderStateChanged( d->m_renderState ); if ( d->m_showFrameRate ) { FpsLayer fpsPainter( &t ); fpsPainter.paint( &painter ); } const qreal fps = 1000.0 / (qreal)( t.elapsed() ); emit framesPerSecond( fps ); } void MarbleMap::customPaint( GeoPainter *painter ) { Q_UNUSED( painter ); } QString MarbleMap::mapThemeId() const { return d->m_model->mapThemeId(); } void MarbleMap::setMapThemeId( const QString& mapThemeId ) { d->m_model->setMapThemeId( mapThemeId ); } void MarbleMapPrivate::updateMapTheme() { m_layerManager.removeLayer( &m_textureLayer ); // FIXME Find a better way to do this reset. Maybe connect to themeChanged SIGNAL? m_vectorTileLayer.reset(); m_layerManager.removeLayer( &m_vectorTileLayer ); m_layerManager.removeLayer( &m_groundLayer ); QObject::connect( m_model->mapTheme()->settings(), SIGNAL(valueChanged(QString,bool)), q, SLOT(updateProperty(QString,bool)) ); QObject::connect( m_model->mapTheme()->settings(), SIGNAL(valueChanged(QString,bool)), m_model, SLOT(updateProperty(QString,bool)) ); q->setPropertyValue(QStringLiteral("clouds_data"), m_viewParams.showClouds()); m_groundLayer.setColor( m_model->mapTheme()->map()->backgroundColor() ); // Check whether there is a texture layer and vectortile layer available: if ( m_model->mapTheme()->map()->hasTextureLayers() ) { const GeoSceneSettings *const settings = m_model->mapTheme()->settings(); const GeoSceneGroup *const textureLayerSettings = settings ? settings->group( "Texture Layers" ) : 0; const GeoSceneGroup *const vectorTileLayerSettings = settings ? settings->group( "VectorTile Layers" ) : 0; bool textureLayersOk = true; bool vectorTileLayersOk = true; // textures will contain texture layers and // vectorTiles vectortile layers QVector textures; QVector vectorTiles; foreach( GeoSceneLayer* layer, m_model->mapTheme()->map()->layers() ){ if ( layer->backend() == dgml::dgmlValue_texture ){ foreach ( const GeoSceneAbstractDataset *pos, layer->datasets() ) { const GeoSceneTextureTileDataset *const texture = dynamic_cast( pos ); if ( !texture ) continue; const QString sourceDir = texture->sourceDir(); const QString installMap = texture->installMap(); const QString role = layer->role(); // If the tiles aren't already there, put up a progress dialog // while creating them. if ( !TileLoader::baseTilesAvailable( *texture ) && !installMap.isEmpty() ) { mDebug() << "Base tiles not available. Creating Tiles ... \n" << "SourceDir: " << sourceDir << "InstallMap:" << installMap; TileCreator *tileCreator = new TileCreator( sourceDir, installMap, (role == QLatin1String("dem")) ? "true" : "false" ); tileCreator->setTileFormat( texture->fileFormat().toLower() ); QPointer tileCreatorDlg = new TileCreatorDialog( tileCreator, 0 ); tileCreatorDlg->setSummary( m_model->mapTheme()->head()->name(), m_model->mapTheme()->head()->description() ); tileCreatorDlg->exec(); if ( TileLoader::baseTilesAvailable( *texture ) ) { mDebug() << "Base tiles for" << sourceDir << "successfully created."; } else { qWarning() << "Some or all base tiles for" << sourceDir << "could not be created."; } delete tileCreatorDlg; } if ( TileLoader::baseTilesAvailable( *texture ) ) { textures.append( texture ); } else { qWarning() << "Base tiles for" << sourceDir << "not available. Skipping all texture layers."; textureLayersOk = false; } } } else if ( layer->backend() == dgml::dgmlValue_vectortile ){ foreach ( const GeoSceneAbstractDataset *pos, layer->datasets() ) { const GeoSceneVectorTileDataset *const vectorTile = dynamic_cast( pos ); if ( !vectorTile ) continue; const QString sourceDir = vectorTile->sourceDir(); const QString installMap = vectorTile->installMap(); const QString role = layer->role(); // If the tiles aren't already there, put up a progress dialog // while creating them. if ( !TileLoader::baseTilesAvailable( *vectorTile ) && !installMap.isEmpty() ) { mDebug() << "Base tiles not available. Creating Tiles ... \n" << "SourceDir: " << sourceDir << "InstallMap:" << installMap; TileCreator *tileCreator = new TileCreator( sourceDir, installMap, (role == QLatin1String("dem")) ? "true" : "false" ); tileCreator->setTileFormat( vectorTile->fileFormat().toLower() ); QPointer tileCreatorDlg = new TileCreatorDialog( tileCreator, 0 ); tileCreatorDlg->setSummary( m_model->mapTheme()->head()->name(), m_model->mapTheme()->head()->description() ); tileCreatorDlg->exec(); if ( TileLoader::baseTilesAvailable( *vectorTile ) ) { qDebug() << "Base tiles for" << sourceDir << "successfully created."; } else { qDebug() << "Some or all base tiles for" << sourceDir << "could not be created."; } delete tileCreatorDlg; } if ( TileLoader::baseTilesAvailable( *vectorTile ) ) { vectorTiles.append( vectorTile ); } else { qWarning() << "Base tiles for" << sourceDir << "not available. Skipping all texture layers."; vectorTileLayersOk = false; } } } } QString seafile, landfile; if( !m_model->mapTheme()->map()->filters().isEmpty() ) { const GeoSceneFilter *filter= m_model->mapTheme()->map()->filters().first(); if (filter->type() == QLatin1String("colorize")) { //no need to look up with MarbleDirs twice so they are left null for now QList palette = filter->palette(); foreach (const GeoScenePalette *curPalette, palette ) { if (curPalette->type() == QLatin1String("sea")) { seafile = MarbleDirs::path( curPalette->file() ); } else if (curPalette->type() == QLatin1String("land")) { landfile = MarbleDirs::path( curPalette->file() ); } } //look up locations if they are empty if( seafile.isEmpty() ) seafile = MarbleDirs::path(QStringLiteral("seacolors.leg")); if( landfile.isEmpty() ) landfile = MarbleDirs::path(QStringLiteral("landcolors.leg")); } } m_textureLayer.setMapTheme( textures, textureLayerSettings, seafile, landfile ); m_textureLayer.setProjection( m_viewport.projection() ); m_textureLayer.setShowRelief( q->showRelief() ); m_vectorTileLayer.setMapTheme( vectorTiles, vectorTileLayerSettings ); if (m_textureLayer.textureLayerCount() == 0) { m_layerManager.addLayer( &m_groundLayer ); } if ( textureLayersOk ) m_layerManager.addLayer( &m_textureLayer ); if ( vectorTileLayersOk && !vectorTiles.isEmpty() ) m_layerManager.addLayer( &m_vectorTileLayer ); } else { m_layerManager.addLayer( &m_groundLayer ); m_textureLayer.setMapTheme( QVector(), 0, "", "" ); m_vectorTileLayer.setMapTheme( QVector(), 0 ); } // earth m_placemarkLayer.setShowPlaces( q->showPlaces() ); m_placemarkLayer.setShowCities( q->showCities() ); m_placemarkLayer.setShowTerrain( q->showTerrain() ); m_placemarkLayer.setShowOtherPlaces( q->showOtherPlaces() ); m_placemarkLayer.setShowLandingSites(q->propertyValue(QStringLiteral("landingsites"))); m_placemarkLayer.setShowCraters(q->propertyValue(QStringLiteral("craters"))); m_placemarkLayer.setShowMaria(q->propertyValue(QStringLiteral("maria"))); m_styleBuilder.setDefaultLabelColor(m_model->mapTheme()->map()->labelColor()); m_placemarkLayer.requestStyleReset(); foreach (RenderPlugin *renderPlugin, m_renderPlugins) { bool propertyAvailable = false; m_model->mapTheme()->settings()->propertyAvailable( renderPlugin->nameId(), propertyAvailable ); bool propertyValue = false; m_model->mapTheme()->settings()->propertyValue( renderPlugin->nameId(), propertyValue ); if ( propertyAvailable ) { renderPlugin->setVisible( propertyValue ); } } emit q->themeChanged( m_model->mapTheme()->head()->mapThemeId() ); } void MarbleMap::setPropertyValue( const QString& name, bool value ) { mDebug() << "In MarbleMap the property " << name << "was set to " << value; if ( d->m_model->mapTheme() ) { d->m_model->mapTheme()->settings()->setPropertyValue( name, value ); d->m_textureLayer.setNeedsUpdate(); } else { mDebug() << "WARNING: Failed to access a map theme! Property: " << name; } if (d->m_textureLayer.textureLayerCount() == 0) { d->m_layerManager.addLayer( &d->m_groundLayer ); } else { d->m_layerManager.removeLayer( &d->m_groundLayer ); } } void MarbleMap::setShowOverviewMap( bool visible ) { setPropertyValue(QStringLiteral("overviewmap"), visible); } void MarbleMap::setShowScaleBar( bool visible ) { setPropertyValue(QStringLiteral("scalebar"), visible); } void MarbleMap::setShowCompass( bool visible ) { setPropertyValue(QStringLiteral("compass"), visible); } void MarbleMap::setShowAtmosphere( bool visible ) { foreach ( RenderPlugin *plugin, renderPlugins() ) { if (plugin->nameId() == QLatin1String("atmosphere")) { plugin->setVisible( visible ); } } d->m_viewParams.setShowAtmosphere( visible ); } void MarbleMap::setShowCrosshairs( bool visible ) { QList pluginList = renderPlugins(); QList::const_iterator i = pluginList.constBegin(); QList::const_iterator const end = pluginList.constEnd(); for (; i != end; ++i ) { if ((*i)->nameId() == QLatin1String("crosshairs")) { (*i)->setVisible( visible ); } } } void MarbleMap::setShowClouds( bool visible ) { d->m_viewParams.setShowClouds( visible ); setPropertyValue(QStringLiteral("clouds_data"), visible); } void MarbleMap::setShowSunShading( bool visible ) { d->m_textureLayer.setShowSunShading( visible ); } void MarbleMap::setShowCityLights( bool visible ) { d->m_textureLayer.setShowCityLights( visible ); setPropertyValue(QStringLiteral("citylights"), visible); } void MarbleMap::setLockToSubSolarPoint( bool visible ) { disconnect( d->m_model->sunLocator(), SIGNAL(positionChanged(qreal,qreal)), this, SLOT(centerOn(qreal,qreal)) ); if( isLockedToSubSolarPoint() != visible ) { d->m_isLockedToSubSolarPoint = visible; } if ( isLockedToSubSolarPoint() ) { connect( d->m_model->sunLocator(), SIGNAL(positionChanged(qreal,qreal)), this, SLOT(centerOn(qreal,qreal)) ); centerOn( d->m_model->sunLocator()->getLon(), d->m_model->sunLocator()->getLat() ); } else if ( visible ) { mDebug() << "Ignoring centering on sun, since the sun plugin is not loaded."; } } void MarbleMap::setSubSolarPointIconVisible( bool visible ) { if ( isSubSolarPointIconVisible() != visible ) { d->m_isSubSolarPointIconVisible = visible; } } void MarbleMap::setShowTileId( bool visible ) { d->m_textureLayer.setShowTileId( visible ); } void MarbleMap::setShowGrid( bool visible ) { setPropertyValue(QStringLiteral("coordinate-grid"), visible); } void MarbleMap::setShowPlaces( bool visible ) { setPropertyValue(QStringLiteral("places"), visible); } void MarbleMap::setShowCities( bool visible ) { setPropertyValue(QStringLiteral("cities"), visible); } void MarbleMap::setShowTerrain( bool visible ) { setPropertyValue(QStringLiteral("terrain"), visible); } void MarbleMap::setShowOtherPlaces( bool visible ) { setPropertyValue(QStringLiteral("otherplaces"), visible); } void MarbleMap::setShowRelief( bool visible ) { setPropertyValue(QStringLiteral("relief"), visible); } void MarbleMap::setShowIceLayer( bool visible ) { setPropertyValue(QStringLiteral("ice"), visible); } void MarbleMap::setShowBorders( bool visible ) { setPropertyValue(QStringLiteral("borders"), visible); } void MarbleMap::setShowRivers( bool visible ) { setPropertyValue(QStringLiteral("rivers"), visible); } void MarbleMap::setShowLakes( bool visible ) { setPropertyValue(QStringLiteral("lakes"), visible); } void MarbleMap::setShowFrameRate( bool visible ) { d->m_showFrameRate = visible; } void MarbleMap::setShowRuntimeTrace( bool visible ) { if (visible != d->m_layerManager.showRuntimeTrace()) { d->m_layerManager.setShowRuntimeTrace(visible); emit repaintNeeded(); } } bool MarbleMap::showRuntimeTrace() const { return d->m_layerManager.showRuntimeTrace(); } void MarbleMap::setShowDebugPolygons( bool visible) { if (visible != d->m_showDebugPolygons) { d->m_showDebugPolygons = visible; emit repaintNeeded(); } } bool MarbleMap::showDebugPolygons() const { return d->m_showDebugPolygons; } void MarbleMap::setShowDebugBatchRender( bool visible) { qDebug() << Q_FUNC_INFO << visible; if (visible != d->m_showDebugBatchRender) { d->m_showDebugBatchRender = visible; emit repaintNeeded(); } } bool MarbleMap::showDebugBatchRender() const { return d->m_showDebugBatchRender; } void MarbleMap::setShowDebugPlacemarks( bool visible) { if (visible != d->m_placemarkLayer.isDebugModeEnabled()) { d->m_placemarkLayer.setDebugModeEnabled(visible); emit repaintNeeded(); } } bool MarbleMap::showDebugPlacemarks() const { return d->m_placemarkLayer.isDebugModeEnabled(); } void MarbleMap::setShowBackground( bool visible ) { d->m_layerManager.setShowBackground( visible ); } void MarbleMap::notifyMouseClick( int x, int y ) { qreal lon = 0; qreal lat = 0; const bool valid = geoCoordinates( x, y, lon, lat, GeoDataCoordinates::Radian ); if ( valid ) { emit mouseClickGeoPosition( lon, lat, GeoDataCoordinates::Radian ); } } void MarbleMap::clearVolatileTileCache() { d->m_vectorTileLayer.reset(); d->m_textureLayer.reset(); mDebug() << "Cleared Volatile Cache!"; } void MarbleMap::setVolatileTileCacheLimit( quint64 kilobytes ) { mDebug() << "kiloBytes" << kilobytes; d->m_textureLayer.setVolatileCacheLimit( kilobytes ); } AngleUnit MarbleMap::defaultAngleUnit() const { if ( GeoDataCoordinates::defaultNotation() == GeoDataCoordinates::Decimal ) { return DecimalDegree; } else if ( GeoDataCoordinates::defaultNotation() == GeoDataCoordinates::UTM ) { return UTM; } return DMSDegree; } void MarbleMap::setDefaultAngleUnit( AngleUnit angleUnit ) { if ( angleUnit == DecimalDegree ) { GeoDataCoordinates::setDefaultNotation( GeoDataCoordinates::Decimal ); return; } else if ( angleUnit == UTM ) { GeoDataCoordinates::setDefaultNotation( GeoDataCoordinates::UTM ); return; } GeoDataCoordinates::setDefaultNotation( GeoDataCoordinates::DMS ); } QFont MarbleMap::defaultFont() const { return d->m_styleBuilder.defaultFont(); } void MarbleMap::setDefaultFont( const QFont& font ) { d->m_styleBuilder.setDefaultFont(font); d->m_placemarkLayer.requestStyleReset(); } QList MarbleMap::renderPlugins() const { return d->m_renderPlugins; } QList MarbleMap::floatItems() const { return d->m_floatItemsLayer.floatItems(); } AbstractFloatItem * MarbleMap::floatItem( const QString &nameId ) const { foreach ( AbstractFloatItem * floatItem, floatItems() ) { if ( floatItem && floatItem->nameId() == nameId ) { return floatItem; } } return 0; // No item found } QList MarbleMap::dataPlugins() const { return d->m_layerManager.dataPlugins(); } QList MarbleMap::whichItemAt( const QPoint& curpos ) const { return d->m_layerManager.whichItemAt( curpos ); } void MarbleMap::addLayer( LayerInterface *layer ) { d->m_layerManager.addLayer(layer); } void MarbleMap::removeLayer( LayerInterface *layer ) { d->m_layerManager.removeLayer(layer); } RenderStatus MarbleMap::renderStatus() const { return d->m_layerManager.renderState().status(); } RenderState MarbleMap::renderState() const { return d->m_layerManager.renderState(); } QString MarbleMap::addTextureLayer(GeoSceneTextureTileDataset *texture) { return textureLayer()->addTextureLayer(texture); } void MarbleMap::removeTextureLayer(const QString &key) { textureLayer()->removeTextureLayer(key); } // this method will only temporarily "pollute" the MarbleModel class TextureLayer *MarbleMap::textureLayer() const { return &d->m_textureLayer; } const StyleBuilder* MarbleMap::styleBuilder() const { return &d->m_styleBuilder; } } #include "moc_MarbleMap.cpp" diff --git a/src/lib/marble/MarbleMap.h b/src/lib/marble/MarbleMap.h index 2b88fdac3..fd61c2439 100644 --- a/src/lib/marble/MarbleMap.h +++ b/src/lib/marble/MarbleMap.h @@ -1,781 +1,783 @@ // // This file is part of the Marble Virtual Globe. // // This program is free software licensed under the GNU LGPL. You can // find a copy of this license in LICENSE.txt in the top directory of // the source code. // // Copyright 2006-2008 Torsten Rahn // Copyright 2007 Inge Wallin // Copyright 2009 Jens-Michael Hoffmann // #ifndef MARBLE_MARBLEMAP_H #define MARBLE_MARBLEMAP_H /** @file * This file contains the headers for MarbleMap. * * @author Torsten Rahn * @author Inge Wallin */ #include "marble_export.h" #include "GeoDataCoordinates.h" // In geodata/data/ // Qt #include #include class QFont; class QString; namespace Marble { // MarbleMap class MarbleMapPrivate; // Marble class GeoDataLatLonAltBox; class GeoDataFeature; class MarbleModel; class ViewportParams; class GeoPainter; class LayerInterface; class RenderPlugin; class RenderState; class AbstractDataPlugin; class AbstractDataPluginItem; class AbstractFloatItem; class TextureLayer; class TileCoordsPyramid; class GeoSceneTextureTileDataset; class StyleBuilder; /** * @short A class that can paint a view of the earth. * * FIXME: Change this description when we are done. * * This class can paint a view of the earth or any other globe, * depending on which dataset is used. It can be used to show the * globe in a widget like MarbleWidget does, or on any other * QPaintDevice. * * The projection and other view parameters that control how MarbleMap * paints the map is given through the class ViewParams. If the * programmer wants to allow the user to control the map, he/she has * to provide a way for the user to interact with it. An example of * this can be seen in the class MarbleWidgetInputHandler, that lets * the user control a MarbleWidget that uses MarbleMap internally. * * The MarbleMap needs to be provided with a data model to * work. This model is contained in the MarbleModel class. The widget * can also construct its own model if none is given to the * constructor. This data model contains 3 separate datatypes: * tiles which provide the background, vectors which * provide things like country borders and coastlines and * placemarks which can show points of interest, such as * cities, mountain tops or the poles. * * @see MarbleWidget * @see MarbleModel */ class MARBLE_EXPORT MarbleMap : public QObject { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "org.kde.MarbleMap") public: friend class MarbleWidget; /** * @brief Construct a new MarbleMap. * * This constructor should be used when you will only use one * MarbleMap. The widget will create its own MarbleModel when * created. */ MarbleMap(); /** * @brief Construct a new MarbleMap. * @param model the data model for the widget. * * This constructor should be used when you plan to use more than * one MarbleMap for the same MarbleModel (not yet supported, * but will be soon). */ explicit MarbleMap( MarbleModel *model ); ~MarbleMap() override; /** * @brief Return the model that this view shows. */ MarbleModel *model() const; // Accessors to internal objects; ViewportParams *viewport(); const ViewportParams *viewport() const; /** * @brief Get the Projection used for the map * @return @c Spherical a Globe * @return @c Equirectangular a flat map * @return @c Mercator another flat map */ Projection projection() const; /** * @brief Get the ID of the current map theme * To ensure that a unique identifier is being used the theme does NOT * get represented by its name but the by relative location of the file * that specifies the theme: * * Example: * maptheme = "earth/bluemarble/bluemarble.dgml" */ QString mapThemeId() const; void setMapQualityForViewContext( MapQuality qualityForViewContext, ViewContext viewContext ); MapQuality mapQuality( ViewContext viewContext ) const; /** * @brief Return the current map quality. */ MapQuality mapQuality() const; void setViewContext( ViewContext viewContext ); ViewContext viewContext() const; void setSize( int width, int height ); void setSize( const QSize& size ); QSize size() const; int width() const; int height() const; /** * @brief Return the radius of the globe in pixels. */ int radius() const; int preferredRadiusCeil( int radius ); int preferredRadiusFloor( int radius ); int tileZoomLevel() const; /** * @brief return the minimum zoom value for the current map theme. */ int minimumZoom() const; /** * @brief return the minimum zoom value for the current map theme. */ int maximumZoom() const; bool discreteZoom() const; /** * @brief Get the screen coordinates corresponding to geographical coordinates in the map. * @param lon the lon coordinate of the requested pixel position * @param lat the lat coordinate of the requested pixel position * @param x the x coordinate of the pixel is returned through this parameter * @param y the y coordinate of the pixel is returned through this parameter * @return @c true if the geographical coordinates are visible on the screen * @c false if the geographical coordinates are not visible on the screen */ bool screenCoordinates( qreal lon, qreal lat, qreal& x, qreal& y ) const; /** * @brief Get the earth coordinates corresponding to a pixel in the map. * @param x the x coordinate of the pixel * @param y the y coordinate of the pixel * @param lon the longitude angle is returned through this parameter * @param lat the latitude angle is returned through this parameter * @return @c true if the pixel (x, y) is within the globe * @c false if the pixel (x, y) is outside the globe, i.e. in space. */ bool geoCoordinates( int x, int y, qreal& lon, qreal& lat, GeoDataCoordinates::Unit = GeoDataCoordinates::Degree ) const; /** * @brief Return the longitude of the center point. * @return The longitude of the center point in degree. */ qreal centerLongitude() const; /** * @brief Return the latitude of the center point. * @return The latitude of the center point in degree. */ qreal centerLatitude() const; /** * @since 0.26.0 */ bool hasFeatureAt(const QPoint&) const; QVector whichFeatureAt( const QPoint& ) const; /** * @brief Return the property value by name. * @return The property value (usually: visibility). */ bool propertyValue( const QString& name ) const; /** * @brief Return whether the overview map is visible. * @return The overview map visibility. */ bool showOverviewMap() const; /** * @brief Return whether the scale bar is visible. * @return The scale bar visibility. */ bool showScaleBar() const; /** * @brief Return whether the compass bar is visible. * @return The compass visibility. */ bool showCompass() const; /** * @brief Return whether the cloud cover is visible. * @return The cloud cover visibility. */ bool showClouds() const; /** * @brief Return whether the night shadow is visible. * @return visibility of night shadow */ bool showSunShading() const; /** * @brief Return whether the city lights are shown instead of the night shadow. * @return visibility of city lights */ bool showCityLights() const; /** * @brief Return whether the globe is locked to the sub solar point * @return if globe is locked to sub solar point */ bool isLockedToSubSolarPoint() const; /** * @brief Return whether the sun icon is shown in the sub solar point. * @return visibility of the sun icon in the sub solar point */ bool isSubSolarPointIconVisible() const; /** * @brief Return whether the atmospheric glow is visible. * @return The cloud cover visibility. */ bool showAtmosphere() const; /** * @brief Return whether the crosshairs are visible. * @return The crosshairs' visibility. */ bool showCrosshairs() const; /** * @brief Return whether the coordinate grid is visible. * @return The coordinate grid visibility. */ bool showGrid() const; /** * @brief Return whether the place marks are visible. * @return The place mark visibility. */ bool showPlaces() const; /** * @brief Return whether the city place marks are visible. * @return The city place mark visibility. */ bool showCities() const; /** * @brief Return whether the terrain place marks are visible. * @return The terrain place mark visibility. */ bool showTerrain() const; /** * @brief Return whether other places are visible. * @return The visibility of other places. */ bool showOtherPlaces() const; /** * @brief Return whether the relief is visible. * @return The relief visibility. */ bool showRelief() const; /** * @brief Return whether the ice layer is visible. * @return The ice layer visibility. */ bool showIceLayer() const; /** * @brief Return whether the borders are visible. * @return The border visibility. */ bool showBorders() const; /** * @brief Return whether the rivers are visible. * @return The rivers' visibility. */ bool showRivers() const; /** * @brief Return whether the lakes are visible. * @return The lakes' visibility. */ bool showLakes() const; /** * @brief Return whether the frame rate gets displayed. * @return the frame rates visibility */ bool showFrameRate() const; bool showBackground() const; /** * @brief Returns the limit in kilobytes of the volatile (in RAM) tile cache. * @return the limit of volatile tile cache in kilobytes. */ quint64 volatileTileCacheLimit() const; /** * @brief Returns a list of all RenderPlugins in the model, this includes float items * @return the list of RenderPlugins */ QList renderPlugins() const; QList floatItems() const; /** * @brief Returns a list of all FloatItems in the model * @return the list of the floatItems */ AbstractFloatItem * floatItem( const QString &nameId ) const; /** * @brief Returns a list of all DataPlugins on the layer * @return the list of DataPlugins */ QList dataPlugins() const; /** * @brief Returns all widgets of dataPlugins on the position curpos */ QList whichItemAt( const QPoint& curpos ) const; AngleUnit defaultAngleUnit() const; QFont defaultFont() const; TextureLayer *textureLayer() const; /** * @brief Add a layer to be included in rendering. */ void addLayer( LayerInterface *layer ); /** * @brief Adds a texture sublayer * @return Returns a key that identifies the texture sublayer */ QString addTextureLayer(GeoSceneTextureTileDataset *texture); /** * @brief Removes a texture sublayer * @param Key that was returned from corresponding addTextureLayer */ void removeTextureLayer(const QString &key); /** * @brief Remove a layer from being included in rendering. */ void removeLayer( LayerInterface *layer ); RenderStatus renderStatus() const; RenderState renderState() const; /** * @since 0.26.0 */ const StyleBuilder* styleBuilder() const; public Q_SLOTS: /** * @brief Paint the map using a give painter. * @param painter The painter to use. * @param dirtyRect the rectangle that actually needs repainting. */ void paint( GeoPainter &painter, const QRect &dirtyRect ); /** * @brief Set the radius of the globe in pixels. * @param radius The new globe radius value in pixels. */ void setRadius( int radius ); /** * @brief Rotate the view by the two angles phi and theta. * @param deltaLon an angle that specifies the change in terms of longitude * @param deltaLat an angle that specifies the change in terms of latitude * * This function rotates the view by two angles, * deltaLon ("theta") and deltaLat ("phi"). * If we start at (0, 0), the result will be the exact equivalent * of (lon, lat), otherwise the resulting angle will be the sum of * the previous position and the two offsets. */ void rotateBy(qreal deltaLon, qreal deltaLat); /** * @brief Center the view on a geographical point * @param lat an angle parallel to the latitude lines * +90(N) - -90(S) * @param lon an angle parallel to the longitude lines * +180(W) - -180(E) */ void centerOn( const qreal lon, const qreal lat ); /** * @brief Set the latitude for the center point * @param lat the new value for the latitude in degree */ void setCenterLatitude( qreal lat ); /** * @brief Set the longitude for the center point * @param lon the new value for the longitude in degree */ void setCenterLongitude( qreal lon ); /** * @brief Set the Projection used for the map * @param projection projection type (e.g. Spherical, Equirectangular, Mercator) */ void setProjection( Projection projection ); /** * @brief Set a new map theme * @param maptheme The ID of the new maptheme. To ensure that a unique * identifier is being used the theme does NOT get represented by its * name but the by relative location of the file that specifies the theme: * * Example: * maptheme = "earth/bluemarble/bluemarble.dgml" */ void setMapThemeId( const QString& maptheme ); /** * @brief Sets the value of a map theme property * @param value value of the property (usually: visibility) * * Later on we might add a "setPropertyType and a QVariant * if needed. */ void setPropertyValue( const QString& name, bool value ); /** * @brief Set whether the overview map overlay is visible * @param visible visibility of the overview map */ void setShowOverviewMap( bool visible ); /** * @brief Set whether the scale bar overlay is visible * @param visible visibility of the scale bar */ void setShowScaleBar( bool visible ); /** * @brief Set whether the compass overlay is visible * @param visible visibility of the compass */ void setShowCompass( bool visible ); /** * @brief Set whether the cloud cover is visible * @param visible visibility of the cloud cover */ void setShowClouds( bool visible ); /** * @brief Set whether the night shadow is visible. * @param visibile visibility of shadow */ void setShowSunShading( bool visible ); /** * @brief Set whether city lights instead of night shadow are visible. * @param visible visibility of city lights */ void setShowCityLights( bool visible ); /** * @brief Set the globe locked to the sub solar point * @param vsible if globe is locked to the sub solar point */ void setLockToSubSolarPoint( bool visible ); /** * @brief Set whether the sun icon is shown in the sub solar point * @param visible if the sun icon is shown in the sub solar point */ void setSubSolarPointIconVisible( bool visible ); /** * @brief Set whether the is tile is visible * NOTE: This is part of the transitional debug API * and might be subject to changes until Marble 0.8 * @param visible visibility of the tile */ void setShowTileId( bool visible ); /** * @brief Set whether the atmospheric glow is visible * @param visible visibility of the atmospheric glow */ void setShowAtmosphere( bool visible ); /** * @brief Set whether the crosshairs are visible * @param visible visibility of the crosshairs */ void setShowCrosshairs( bool visible ); /** * @brief Set whether the coordinate grid overlay is visible * @param visible visibility of the coordinate grid */ void setShowGrid( bool visible ); /** * @brief Set whether the place mark overlay is visible * @param visible visibility of the place marks */ void setShowPlaces( bool visible ); /** * @brief Set whether the city place mark overlay is visible * @param visible visibility of the city place marks */ void setShowCities( bool visible ); /** * @brief Set whether the terrain place mark overlay is visible * @param visible visibility of the terrain place marks */ void setShowTerrain( bool visible ); /** * @brief Set whether the other places overlay is visible * @param visible visibility of other places */ void setShowOtherPlaces( bool visible ); /** * @brief Set whether the relief is visible * @param visible visibility of the relief */ void setShowRelief( bool visible ); /** * @brief Set whether the ice layer is visible * @param visible visibility of the ice layer */ void setShowIceLayer( bool visible ); /** * @brief Set whether the borders visible * @param visible visibility of the borders */ void setShowBorders( bool visible ); /** * @brief Set whether the rivers are visible * @param visible visibility of the rivers */ void setShowRivers( bool visible ); /** * @brief Set whether the lakes are visible * @param visible visibility of the lakes */ void setShowLakes( bool visible ); /** * @brief Set whether the frame rate gets shown * @param visible visibility of the frame rate */ void setShowFrameRate( bool visible ); void setShowRuntimeTrace( bool visible ); bool showRuntimeTrace() const; /** * @brief Set whether to enter the debug mode for * polygon node drawing * @param visible visibility of the node debug mode */ void setShowDebugPolygons( bool visible); bool showDebugPolygons() const; /** * @brief Set whether to enter the debug mode for * visualizing batch rendering * @param visible visibility of the batch rendering */ void setShowDebugBatchRender( bool visible); bool showDebugBatchRender() const; /** * @brief Set whether to enter the debug mode for * placemark drawing * @param visible visibility of the node debug mode */ void setShowDebugPlacemarks(bool visible); bool showDebugPlacemarks() const; void setShowBackground( bool visible ); /** * @brief used to notify about the position of the mouse click */ void notifyMouseClick( int x, int y ); void clearVolatileTileCache(); /** * @brief Set the limit of the volatile (in RAM) tile cache. * @param bytes The limit in kilobytes. */ void setVolatileTileCacheLimit( quint64 kiloBytes ); void setDefaultAngleUnit( AngleUnit angleUnit ); void setDefaultFont( const QFont& font ); /** * @brief Reload the currently displayed map by reloading texture tiles * from the Internet. In the future this should be extended to all * kinds of data which is used in the map. */ void reload(); void downloadRegion( QVector const & ); + void highlightRouteRelation(qint64 osmId, bool enabled); + Q_SIGNALS: void tileLevelChanged( int level ); /** * @brief Signal that the theme has changed * @param theme Name of the new theme. */ void themeChanged( const QString& theme ); void projectionChanged( Projection ); void radiusChanged( int radius ); void mouseMoveGeoPosition( const QString& ); void mouseClickGeoPosition( qreal lon, qreal lat, GeoDataCoordinates::Unit ); void framesPerSecond( qreal fps ); /** * This signal is emitted when the repaint of the view was requested. * If available with the @p dirtyRegion which is the region the view will change in. * If dirtyRegion.isEmpty() returns true, the whole viewport has to be repainted. */ void repaintNeeded( const QRegion& dirtyRegion = QRegion() ); /** * This signal is emitted when the visible region of the map changes. This typically happens * when the user moves the map around or zooms. */ void visibleLatLonAltBoxChanged( const GeoDataLatLonAltBox& visibleLatLonAltBox ); /** * @brief This signal is emit when the settings of a plugin changed. */ void pluginSettingsChanged(); /** * @brief Signal that a render item has been initialized */ void renderPluginInitialized( RenderPlugin *renderPlugin ); /** * @brief Emitted when the layer rendering status has changed * @param status New render status */ void renderStatusChanged( RenderStatus status ); void renderStateChanged( const RenderState &state ); void highlightedPlacemarksChanged( qreal, qreal, GeoDataCoordinates::Unit ); void viewContextChanged(ViewContext viewContext); protected: /** * @brief Enables custom drawing onto the MarbleMap straight after * @brief the globe and before all other layers have been rendered. * @param painter * * @deprecated implement LayerInterface and add it using @p addLayer() */ virtual void customPaint( GeoPainter *painter ); private: Q_PRIVATE_SLOT( d, void updateMapTheme() ) Q_PRIVATE_SLOT( d, void updateProperty( const QString &, bool ) ) Q_PRIVATE_SLOT( d, void setDocument(QString) ) Q_PRIVATE_SLOT( d, void updateTileLevel() ) Q_PRIVATE_SLOT(d, void addPlugins()) private: Q_DISABLE_COPY( MarbleMap ) MarbleMapPrivate * const d; friend class MarbleMapPrivate; class CustomPaintLayer; friend class CustomPaintLayer; }; } #endif diff --git a/src/lib/marble/StyleBuilder.cpp b/src/lib/marble/StyleBuilder.cpp index f7241427b..aea17dc90 100644 --- a/src/lib/marble/StyleBuilder.cpp +++ b/src/lib/marble/StyleBuilder.cpp @@ -1,2958 +1,2959 @@ // // This file is part of the Marble Virtual Globe. // // This program is free software licensed under the GNU LGPL. You can // find a copy of this license in LICENSE.txt in the top directory of // the source code. // // Copyright 2007 Murad Tagirov // Copyright 2009 Patrick Spendrin // Copyright 2015 Marius-Valeriu Stanciu // Copyright 2016 Dennis Nienhüser // #include "StyleBuilder.h" #include "MarbleDirs.h" #include "OsmPlacemarkData.h" #include "OsmcSymbol.h" #include "GeoDataTypes.h" #include "GeoDataGeometry.h" #include "GeoDataPlacemark.h" #include "GeoDataIconStyle.h" #include "GeoDataLabelStyle.h" #include "GeoDataLineStyle.h" #include "GeoDataPolyStyle.h" #include #include #include #include #include #include #include #include namespace Marble { class StyleBuilder::Private { public: Private(); GeoDataStyle::ConstPtr presetStyle(GeoDataPlacemark::GeoDataVisualCategory visualCategory) const; GeoDataStyle::Ptr createStyle(qreal width, qreal realWidth, const QColor& color, const QColor& outlineColor, bool fill, bool outline, Qt::BrushStyle brushStyle, Qt::PenStyle penStyle, Qt::PenCapStyle capStyle, bool lineBackground, const QVector< qreal >& dashPattern, const QFont& font, const QColor& fontColor = Qt::black, const QString& texturePath = QString()) const; GeoDataStyle::Ptr createPOIStyle(const QFont &font, const QString &bitmap, const QColor &textColor = Qt::black, const QColor &color = QColor(0xBE, 0xAD, 0xAD), const QColor &outline = QColor(0xBE, 0xAD, 0xAD).darker(), bool fill = true, bool renderOutline = true) const; GeoDataStyle::Ptr createOsmPOIStyle(const QFont &font, const QString &bitmap, const QColor &textColor = Qt::black, const QColor &color = QColor(0xBE, 0xAD, 0xAD), const QColor &outline = QColor(0xBE, 0xAD, 0xAD).darker()) const; GeoDataStyle::Ptr createOsmPOIRingStyle(const QFont &font, const QString &bitmap, const QColor &textColor = Qt::black, const QColor &color = QColor(0xBE, 0xAD, 0xAD), const QColor &outline = QColor(0xBE, 0xAD, 0xAD).darker()) const; GeoDataStyle::Ptr createOsmPOIAreaStyle(const QFont &font, const QString &bitmap, const QColor &textColor = Qt::black, const QColor &color = QColor(0xBE, 0xAD, 0xAD), const QColor &outline = QColor(0xBE, 0xAD, 0xAD).darker()) const; GeoDataStyle::Ptr createHighwayStyle(const QColor& color, const QColor& outlineColor, const QFont& font, const QColor& fontColor = Qt::black, qreal width = 1, qreal realWidth = 0.0, Qt::PenStyle penStyle = Qt::SolidLine, Qt::PenCapStyle capStyle = Qt::RoundCap, bool lineBackground = false) const; GeoDataStyle::Ptr createWayStyle(const QColor& color, const QColor& outlineColor, bool fill = true, bool outline = true, Qt::BrushStyle brushStyle = Qt::SolidPattern, const QString& texturePath = QString()) const; GeoDataStyle::Ptr createIconWayStyle(const QColor& color, const QFont &font, const QColor &textColor, double lineWidth=1.0, const QString& iconPath = QString()) const; GeoDataStyle::ConstPtr createRelationStyle(const StyleParameters ¶meters); GeoDataStyle::ConstPtr createPlacemarkStyle(const StyleParameters ¶meters); GeoDataStyle::ConstPtr adjustPisteStyle(const StyleParameters ¶meters, const GeoDataStyle::ConstPtr &style); // Having an outline with the same color as the fill results in degraded // performance and degraded display quality for no good reason // Q_ASSERT( !(outline && color == outlineColor && brushStyle == Qt::SolidPattern) ); void initializeDefaultStyles(); static QString createPaintLayerItem(const QString &itemType, GeoDataPlacemark::GeoDataVisualCategory visualCategory, const QString &subType = QString()); static void initializeOsmVisualCategories(); static void initializeMinimumZoomLevels(); int m_maximumZoomLevel; QColor m_defaultLabelColor; QFont m_defaultFont; GeoDataStyle::Ptr m_defaultStyle[GeoDataPlacemark::LastIndex]; GeoDataStyle::Ptr m_styleTreeAutumn; GeoDataStyle::Ptr m_styleTreeWinter; bool m_defaultStyleInitialized; QHash m_styleCache; QHash m_buildingStyles; QSet m_oceanianCountries; /** * @brief s_visualCategories contains osm tag mappings to GeoDataVisualCategories */ static QHash s_visualCategories; static int s_defaultMinZoomLevels[GeoDataPlacemark::LastIndex]; static bool s_defaultMinZoomLevelsInitialized; static QHash s_popularities; }; QHash StyleBuilder::Private::s_visualCategories; int StyleBuilder::Private::s_defaultMinZoomLevels[GeoDataPlacemark::LastIndex]; bool StyleBuilder::Private::s_defaultMinZoomLevelsInitialized = false; QHash StyleBuilder::Private::s_popularities; StyleBuilder::Private::Private() : m_maximumZoomLevel(15), m_defaultLabelColor(Qt::black), m_defaultFont(QStringLiteral("Sans Serif")), m_defaultStyle(), m_defaultStyleInitialized(false), m_oceanianCountries( { QLocale::Australia, QLocale::NewZealand, QLocale::Fiji, QLocale::PapuaNewGuinea, QLocale::NewCaledonia, QLocale::SolomonIslands, QLocale::Samoa, QLocale::Vanuatu, QLocale::Guam, QLocale::FrenchPolynesia, QLocale::Tonga, QLocale::Palau, QLocale::Kiribati, QLocale::CookIslands, QLocale::Micronesia, QLocale::MarshallIslands, QLocale::NauruCountry, QLocale::AmericanSamoa, QLocale::Niue, QLocale::Pitcairn, QLocale::WallisAndFutunaIslands, QLocale::NorfolkIsland }) { #if QT_VERSION >= 0x050700 m_oceanianCountries << QLocale::TuvaluCountry << QLocale::OutlyingOceania; #else m_oceanianCountries << QLocale::Tuvalu; #endif initializeMinimumZoomLevels(); for (int i = 0; i < GeoDataPlacemark::LastIndex; ++i) { m_maximumZoomLevel = qMax(m_maximumZoomLevel, s_defaultMinZoomLevels[i]); } } GeoDataStyle::Ptr StyleBuilder::Private::createPOIStyle(const QFont &font, const QString &path, const QColor &textColor, const QColor &color, const QColor &outlineColor, bool fill, bool renderOutline) const { GeoDataStyle::Ptr style = createStyle(1, 0, color, outlineColor, fill, renderOutline, Qt::SolidPattern, Qt::SolidLine, Qt::RoundCap, false, QVector(), font); style->setIconStyle(GeoDataIconStyle(path)); auto const screen = QApplication::screens().first(); double const physicalSize = 6.0; // mm int const pixelSize = qRound(physicalSize * screen->physicalDotsPerInch() / (IN2M * M2MM)); style->iconStyle().setSize(QSize(pixelSize, pixelSize)); style->setLabelStyle(GeoDataLabelStyle(font, textColor)); style->labelStyle().setAlignment(GeoDataLabelStyle::Center); return style; } GeoDataStyle::Ptr StyleBuilder::Private::createOsmPOIStyle(const QFont &font, const QString &imagePath, const QColor &textColor, const QColor &color, const QColor &outlineColor) const { QString const path = MarbleDirs::path(QLatin1String("svg/osmcarto/svg/") + imagePath + QLatin1String(".svg")); return createPOIStyle(font, path, textColor, color, outlineColor, false, false); } GeoDataStyle::Ptr StyleBuilder::Private::createOsmPOIRingStyle(const QFont &font, const QString &imagePath, const QColor &textColor, const QColor &color, const QColor &outlineColor) const { QString const path = MarbleDirs::path(QLatin1String("svg/osmcarto/svg/") + imagePath + QLatin1String(".svg")); return createPOIStyle(font, path, textColor, color, outlineColor, false, true); } GeoDataStyle::Ptr StyleBuilder::Private::createOsmPOIAreaStyle(const QFont &font, const QString &imagePath, const QColor &textColor, const QColor &color, const QColor &outlineColor) const { QString const path = MarbleDirs::path(QLatin1String("svg/osmcarto/svg/") + imagePath + QLatin1String(".svg")); return createPOIStyle(font, path, textColor, color, outlineColor, true, false); } GeoDataStyle::Ptr StyleBuilder::Private::createHighwayStyle(const QColor& color, const QColor& outlineColor, const QFont& font, const QColor& fontColor, qreal width, qreal realWidth, Qt::PenStyle penStyle, Qt::PenCapStyle capStyle, bool lineBackground) const { return createStyle(width, realWidth, color, outlineColor, true, true, Qt::SolidPattern, penStyle, capStyle, lineBackground, QVector< qreal >(), font, fontColor); } GeoDataStyle::Ptr StyleBuilder::Private::createWayStyle(const QColor& color, const QColor& outlineColor, bool fill, bool outline, Qt::BrushStyle brushStyle, const QString& texturePath) const { return createStyle(1, 0, color, outlineColor, fill, outline, brushStyle, Qt::SolidLine, Qt::RoundCap, false, QVector(), m_defaultFont, Qt::black, texturePath); } GeoDataStyle::Ptr StyleBuilder::Private::createIconWayStyle(const QColor &color, const QFont &font, const QColor &textColor, double lineWidth, const QString &iconPath) const { auto const path = iconPath.isEmpty() ? iconPath : MarbleDirs::path(iconPath); auto style = createPOIStyle(font, path, textColor, color, color, true, true); style->lineStyle().setWidth(float(lineWidth)); return style; } GeoDataStyle::ConstPtr StyleBuilder::Private::createRelationStyle(const StyleParameters ¶meters) { Q_ASSERT(parameters.relation); const GeoDataPlacemark *const placemark = parameters.placemark; auto const visualCategory = placemark->visualCategory(); - if (visualCategory >= GeoDataPlacemark::HighwaySteps && - visualCategory <= GeoDataPlacemark::HighwayMotorway) { + bool const isHighway = visualCategory >= GeoDataPlacemark::HighwaySteps && visualCategory <= GeoDataPlacemark::HighwayMotorway; + bool const isRailway = visualCategory >= GeoDataPlacemark::RailwayRail && visualCategory <= GeoDataPlacemark::RailwayFunicular; + if (isHighway || isRailway) { if (parameters.relation->relationType() == GeoDataRelation::RouteHiking && parameters.relation->osmData().containsTagKey(QStringLiteral("osmc:symbol"))) { QString const osmcSymbolValue = parameters.relation->osmData().tagValue(QStringLiteral("osmc:symbol")); // Take cached Style instance if possible QString const cacheKey = QStringLiteral("/route/hiking/%1").arg(osmcSymbolValue); if (m_styleCache.contains(cacheKey)) { return m_styleCache[cacheKey]; } auto style = presetStyle(visualCategory); auto lineStyle = style->lineStyle(); auto iconStyle = style->iconStyle(); GeoDataStyle::Ptr newStyle(new GeoDataStyle(*style)); OsmcSymbol symbol = OsmcSymbol(osmcSymbolValue); lineStyle.setColor(symbol.wayColor()); iconStyle.setIcon(symbol.icon()); newStyle->setLineStyle(lineStyle); newStyle->setIconStyle(iconStyle); style = newStyle; m_styleCache.insert(cacheKey, newStyle); return style; } - if (parameters.relation->relationType() >= GeoDataRelation::RouteBus && + if (parameters.relation->relationType() >= GeoDataRelation::RouteRoad && parameters.relation->relationType() <= GeoDataRelation::RouteInlineSkates) { auto const colorValue = parameters.relation->osmData().tagValue(QStringLiteral("colour")); QString const color = QColor::isValidColor(colorValue) ? colorValue : QStringLiteral("salmon"); // Take cached Style instance if possible QString const cacheKey = QStringLiteral("/route/hiking/%1").arg(color); if (m_styleCache.contains(cacheKey)) { return m_styleCache[cacheKey]; } auto style = presetStyle(visualCategory); auto lineStyle = style->lineStyle(); GeoDataStyle::Ptr newStyle(new GeoDataStyle(*style)); lineStyle.setColor(QColor(color)); newStyle->setLineStyle(lineStyle); style = newStyle; m_styleCache.insert(cacheKey, newStyle); return style; } } return GeoDataStyle::ConstPtr(); } GeoDataStyle::ConstPtr StyleBuilder::Private::createPlacemarkStyle(const StyleParameters ¶meters) { const GeoDataPlacemark *const placemark = parameters.placemark; QString styleCacheKey; OsmPlacemarkData const & osmData = placemark->osmData(); auto const visualCategory = placemark->visualCategory(); if (visualCategory == GeoDataPlacemark::Building) { auto const tagMap = osmTagMapping(); auto const & osmData = placemark->osmData(); auto const buildingTag = QStringLiteral("building"); for (auto iter = osmData.tagsBegin(), end = osmData.tagsEnd(); iter != end; ++iter) { auto const osmTag = StyleBuilder::OsmTag(iter.key(), iter.value()); if (iter.key() != buildingTag && tagMap.contains(osmTag)) { return m_buildingStyles.value(tagMap.value(osmTag), m_defaultStyle[visualCategory]); } } } GeoDataStyle::ConstPtr style = presetStyle(visualCategory); if (placemark->geometry()->nodeType() == GeoDataTypes::GeoDataPointType) { if (visualCategory == GeoDataPlacemark::NaturalTree) { GeoDataCoordinates const coordinates = placemark->coordinate(); qreal const lat = coordinates.latitude(GeoDataCoordinates::Degree); if (qAbs(lat) > 15) { /** @todo Should maybe auto-adjust to MarbleClock at some point */ int const month = QDate::currentDate().month(); bool const southernHemisphere = lat < 0; if (southernHemisphere) { if (month >= 3 && month <= 5) { style = m_styleTreeAutumn; } else if (month >= 6 && month <= 8) { style = m_styleTreeWinter; } } else { if (month >= 9 && month <= 11) { style = m_styleTreeAutumn; } else if (month == 12 || month == 1 || month == 2) { style = m_styleTreeWinter; } } } } } else if (placemark->geometry()->nodeType() == GeoDataTypes::GeoDataLinearRingType) { bool adjustStyle = false; GeoDataPolyStyle polyStyle = style->polyStyle(); GeoDataLineStyle lineStyle = style->lineStyle(); if (visualCategory == GeoDataPlacemark::NaturalWater) { if (osmData.containsTag(QStringLiteral("salt"), QStringLiteral("yes"))) { polyStyle.setColor("#ffff80"); lineStyle.setPenStyle(Qt::DashLine); lineStyle.setWidth(2); adjustStyle = true; } } else if (visualCategory == GeoDataPlacemark::Bathymetry) { auto tagIter = osmData.findTag(QStringLiteral("ele")); if (tagIter != osmData.tagsEnd()) { const QString& elevation = tagIter.value(); if (elevation == QLatin1String("4000")) { polyStyle.setColor("#94c2c2"); lineStyle.setColor("#94c2c2"); adjustStyle = true; } } } else if (visualCategory == GeoDataPlacemark::AmenityGraveyard || visualCategory == GeoDataPlacemark::LanduseCemetery) { auto tagIter = osmData.findTag(QStringLiteral("religion")); if (tagIter != osmData.tagsEnd()) { const QString& religion = tagIter.value(); if (religion == QLatin1String("jewish")) { polyStyle.setTexturePath(MarbleDirs::path("bitmaps/osmcarto/patterns/grave_yard_jewish.png")); adjustStyle = true; } else if (religion == QLatin1String("christian")) { polyStyle.setTexturePath(MarbleDirs::path("bitmaps/osmcarto/patterns/grave_yard_christian.png")); adjustStyle = true; } else if (religion == QLatin1String("INT-generic")) { polyStyle.setTexturePath(MarbleDirs::path("bitmaps/osmcarto/patterns/grave_yard_generic.png")); adjustStyle = true; } } } else if (visualCategory == GeoDataPlacemark::PisteDownhill) { return adjustPisteStyle(parameters, style); } if (adjustStyle) { GeoDataStyle::Ptr newStyle(new GeoDataStyle(*style)); newStyle->setPolyStyle(polyStyle); newStyle->setLineStyle(lineStyle); style = newStyle; } if (style->iconStyle().iconPath().isEmpty()) { const GeoDataPlacemark::GeoDataVisualCategory category = determineVisualCategory(osmData); const GeoDataStyle::ConstPtr categoryStyle = presetStyle(category); if (category != GeoDataPlacemark::None && !categoryStyle->iconStyle().scaledIcon().isNull()) { GeoDataStyle::Ptr newStyle(new GeoDataStyle(*style)); newStyle->setIconStyle(categoryStyle->iconStyle()); style = newStyle; } } } else if (placemark->geometry()->nodeType() == GeoDataTypes::GeoDataLineStringType) { GeoDataPolyStyle polyStyle = style->polyStyle(); GeoDataLineStyle lineStyle = style->lineStyle(); GeoDataLabelStyle labelStyle = style->labelStyle(); GeoDataIconStyle iconStyle = style->iconStyle(); lineStyle.setCosmeticOutline(true); bool adjustStyle = false; if (visualCategory == GeoDataPlacemark::AdminLevel2) { if (osmData.containsTag(QStringLiteral("maritime"), QStringLiteral("yes"))) { lineStyle.setColor("#88b3bf"); polyStyle.setColor("#88b3bf"); if (osmData.containsTag(QStringLiteral("marble:disputed"), QStringLiteral("yes"))) { lineStyle.setPenStyle(Qt::DashLine); } adjustStyle = true; } } else if ((visualCategory >= GeoDataPlacemark::HighwayService && visualCategory <= GeoDataPlacemark::HighwayMotorway) || visualCategory == GeoDataPlacemark::TransportAirportRunway) { // Take cached Style instance if possible styleCacheKey = QStringLiteral("%1/%2").arg(parameters.tileLevel).arg(visualCategory); if (m_styleCache.contains(styleCacheKey)) { style = m_styleCache[styleCacheKey]; return style; } adjustStyle = true; if (parameters.tileLevel <= 8) { /** @todo: Dummy implementation for dynamic style changes based on tile level, replace with sane values */ lineStyle.setPhysicalWidth(0.0); lineStyle.setWidth(2.0); styleCacheKey = QStringLiteral("%1/%2").arg(parameters.tileLevel).arg(visualCategory); } else if (parameters.tileLevel <= 10) { /** @todo: Dummy implementation for dynamic style changes based on tile level, replace with sane values */ lineStyle.setPhysicalWidth(0.0); lineStyle.setWidth(3.0); styleCacheKey = QStringLiteral("%1/%2").arg(parameters.tileLevel).arg(visualCategory); } else if (parameters.tileLevel <= 12) { /** @todo: Dummy implementation for dynamic style changes based on tile level, replace with sane values */ lineStyle.setPhysicalWidth(0.0); lineStyle.setWidth(4.0); styleCacheKey = QStringLiteral("%1/%2").arg(parameters.tileLevel).arg(visualCategory); } else { auto tagIter = osmData.findTag(QStringLiteral("width")); if (tagIter != osmData.tagsEnd()) { QString const widthValue = QString(tagIter.value()).remove(QStringLiteral(" meters")).remove(QStringLiteral(" m")); bool ok; float const width = widthValue.toFloat(&ok); lineStyle.setPhysicalWidth(ok ? qBound(0.1f, width, 200.0f) : 0.0f); } else { bool const isOneWay = osmData.containsTag(QStringLiteral("oneway"), QStringLiteral("yes")) || osmData.containsTag(QStringLiteral("oneway"), QStringLiteral("-1")); int const lanes = isOneWay ? 1 : 2; // also for motorway which implicitly is one way, but has two lanes and each direction has its own highway double const laneWidth = 3.0; double const margins = visualCategory == GeoDataPlacemark::HighwayMotorway ? 2.0 : (isOneWay ? 1.0 : 0.0); double const physicalWidth = margins + lanes * laneWidth; lineStyle.setPhysicalWidth(physicalWidth); } } QString const accessValue = osmData.tagValue(QStringLiteral("access")); if (accessValue == QLatin1String("private") || accessValue == QLatin1String("no") || accessValue == QLatin1String("agricultural") || accessValue == QLatin1String("delivery") || accessValue == QLatin1String("forestry")) { QColor polyColor = polyStyle.color(); qreal hue, sat, val; polyColor.getHsvF(&hue, &sat, &val); polyColor.setHsvF(0.98, qMin(1.0, 0.2 + sat), val); polyStyle.setColor(polyColor); lineStyle.setColor(lineStyle.color().darker(150)); } if (osmData.containsTag("tunnel", "yes")) { QColor polyColor = polyStyle.color(); qreal hue, sat, val; polyColor.getHsvF(&hue, &sat, &val); polyColor.setHsvF(hue, 0.25 * sat, 0.95 * val); polyStyle.setColor(polyColor); lineStyle.setColor(lineStyle.color().lighter(115)); } } else if (visualCategory >= GeoDataPlacemark::WaterwayCanal && visualCategory <= GeoDataPlacemark::WaterwayStream) { adjustStyle = true; // Take cached Style instance if possible styleCacheKey = QStringLiteral("%1/%2").arg(parameters.tileLevel).arg(visualCategory); if (m_styleCache.contains(styleCacheKey)) { style = m_styleCache[styleCacheKey]; return style; } if (parameters.tileLevel <= 3) { lineStyle.setWidth(1); lineStyle.setPhysicalWidth(0.0); styleCacheKey = QStringLiteral("%1/%2").arg(parameters.tileLevel).arg(visualCategory); } else if (parameters.tileLevel <= 7) { lineStyle.setWidth(2); lineStyle.setPhysicalWidth(0.0); styleCacheKey = QStringLiteral("%1/%2").arg(parameters.tileLevel).arg(visualCategory); } else { QString const widthValue = osmData.tagValue(QStringLiteral("width")).remove(QStringLiteral(" meters")).remove(QStringLiteral(" m")); bool ok; float const width = widthValue.toFloat(&ok); lineStyle.setPhysicalWidth(ok ? qBound(0.1f, width, 200.0f) : 0.0f); } } else if (visualCategory == GeoDataPlacemark::PisteDownhill) { return adjustPisteStyle(parameters, style); } if (adjustStyle) { GeoDataStyle::Ptr newStyle(new GeoDataStyle(*style)); newStyle->setPolyStyle(polyStyle); newStyle->setLineStyle(lineStyle); newStyle->setLabelStyle(labelStyle); newStyle->setIconStyle(iconStyle); style = newStyle; if (!styleCacheKey.isEmpty()) { m_styleCache.insert(styleCacheKey, newStyle); } } } else if (placemark->geometry()->nodeType() == GeoDataTypes::GeoDataPolygonType) { GeoDataPolyStyle polyStyle = style->polyStyle(); GeoDataLineStyle lineStyle = style->lineStyle(); bool adjustStyle = false; if (visualCategory == GeoDataPlacemark::Bathymetry) { auto tagIter = osmData.findTag(QStringLiteral("ele")); if (tagIter != osmData.tagsEnd()) { const QString& elevation = tagIter.value(); if (elevation == QLatin1String("4000")) { polyStyle.setColor("#a5c9c9"); lineStyle.setColor("#a5c9c9"); adjustStyle = true; } } } else if (visualCategory == GeoDataPlacemark::PisteDownhill) { return adjustPisteStyle(parameters, style); } if (adjustStyle) { GeoDataStyle::Ptr newStyle(new GeoDataStyle(*style)); newStyle->setPolyStyle(polyStyle); newStyle->setLineStyle(lineStyle); style = newStyle; } } return style; } GeoDataStyle::ConstPtr StyleBuilder::Private::adjustPisteStyle(const StyleParameters ¶meters, const GeoDataStyle::ConstPtr &style) { // Take cached Style instance if possible auto const & osmData = parameters.placemark->osmData(); auto const visualCategory = parameters.placemark->visualCategory(); auto const difficulty = osmData.tagValue("piste:difficulty"); QString styleCacheKey = QStringLiteral("piste/%1/%2").arg(visualCategory).arg(difficulty); if (m_styleCache.contains(styleCacheKey)) { return m_styleCache[styleCacheKey]; } GeoDataLineStyle lineStyle = style->lineStyle(); auto green = QColor("#006600");; auto red = QColor("#cc0000"); auto black = QColor("#151515"); auto yellow = Qt::yellow; auto blue = QColor("#000099"); auto orange = QColor(255, 165, 0); auto fallBack = Qt::lightGray; auto country = QLocale::system().country(); if (country == QLocale::Japan) { if (difficulty == "easy") { lineStyle.setColor(green); } else if (difficulty == "intermediate") { lineStyle.setColor(red); } else if (difficulty == "advanced") { lineStyle.setColor(black); } else { lineStyle.setColor(fallBack); } } else if (country == QLocale::UnitedStates || country == QLocale::UnitedStatesMinorOutlyingIslands || country == QLocale::Canada || m_oceanianCountries.contains(country)) { if (difficulty == "easy") { lineStyle.setColor(green); } else if (difficulty == "intermediate") { lineStyle.setColor(blue); } else if (difficulty == "advanced" || difficulty == "expert") { lineStyle.setColor(black); } else { lineStyle.setColor(fallBack); } // fallback on Europe } else { if (difficulty == "novice") { lineStyle.setColor(green); } else if (difficulty == "easy") { lineStyle.setColor(blue); } else if (difficulty == "intermediate") { lineStyle.setColor(red); } else if (difficulty == "advanced") { lineStyle.setColor(black); } else if (difficulty == "expert") { // scandinavian countries have different colors then the rest of Europe if (country == QLocale::Denmark || country == QLocale::Norway || country == QLocale::Sweden) { lineStyle.setColor(black); } else { lineStyle.setColor(orange); } } else if (difficulty == "freeride") { lineStyle.setColor(yellow); } else { lineStyle.setColor(fallBack); } } GeoDataPolyStyle polyStyle = style->polyStyle(); polyStyle.setColor(lineStyle.color()); GeoDataStyle::Ptr newStyle(new GeoDataStyle(*style)); newStyle->setPolyStyle(polyStyle); newStyle->setLineStyle(lineStyle); m_styleCache.insert(styleCacheKey, newStyle); return newStyle; } GeoDataStyle::Ptr StyleBuilder::Private::createStyle(qreal width, qreal realWidth, const QColor& color, const QColor& outlineColor, bool fill, bool outline, Qt::BrushStyle brushStyle, Qt::PenStyle penStyle, Qt::PenCapStyle capStyle, bool lineBackground, const QVector< qreal >& dashPattern, const QFont& font, const QColor& fontColor, const QString& texturePath) const { GeoDataStyle *style = new GeoDataStyle; GeoDataLineStyle lineStyle(outlineColor); lineStyle.setCapStyle(capStyle); lineStyle.setPenStyle(penStyle); lineStyle.setWidth(width); lineStyle.setPhysicalWidth(realWidth); lineStyle.setBackground(lineBackground); lineStyle.setDashPattern(dashPattern); GeoDataPolyStyle polyStyle(color); polyStyle.setOutline(outline); polyStyle.setFill(fill); polyStyle.setBrushStyle(brushStyle); polyStyle.setTexturePath(texturePath); GeoDataLabelStyle labelStyle(font, fontColor); style->setLineStyle(lineStyle); style->setPolyStyle(polyStyle); style->setLabelStyle(labelStyle); return GeoDataStyle::Ptr(style); } void StyleBuilder::Private::initializeDefaultStyles() { // We need to do this similar to the way KCmdLineOptions works in // the future: Having a PlacemarkStyleProperty properties[] would // help here greatly. if (m_defaultStyleInitialized) { return; } m_defaultStyleInitialized = true; QString defaultFamily = m_defaultFont.family(); #ifdef Q_OS_MACX int defaultSize = 10; #else int defaultSize = 8; #endif QColor const defaultLabelColor = m_defaultLabelColor; m_defaultStyle[GeoDataPlacemark::None] = GeoDataStyle::Ptr(new GeoDataStyle(QString(), QFont(defaultFamily, defaultSize, 50, false), defaultLabelColor)); m_defaultStyle[GeoDataPlacemark::Default] = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/default_location.png"), QFont(defaultFamily, defaultSize, 50, false), defaultLabelColor)); m_defaultStyle[GeoDataPlacemark::Unknown] = GeoDataStyle::Ptr(new GeoDataStyle(QString(), QFont(defaultFamily, defaultSize, 50, false), defaultLabelColor)); m_defaultStyle[GeoDataPlacemark::SmallCity] = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/city_4_white.png"), QFont(defaultFamily, defaultSize, 50, false), defaultLabelColor)); m_defaultStyle[GeoDataPlacemark::SmallCountyCapital] = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/city_4_yellow.png"), QFont(defaultFamily, defaultSize, 50, false), defaultLabelColor)); m_defaultStyle[GeoDataPlacemark::SmallStateCapital] = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/city_4_orange.png"), QFont(defaultFamily, defaultSize, 50, true), defaultLabelColor)); m_defaultStyle[GeoDataPlacemark::SmallNationCapital] = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/city_4_red.png"), QFont(defaultFamily, defaultSize, 50, false), defaultLabelColor)); m_defaultStyle[GeoDataPlacemark::MediumCity] = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/city_3_white.png"), QFont(defaultFamily, defaultSize, 50, false), defaultLabelColor)); m_defaultStyle[GeoDataPlacemark::MediumCountyCapital] = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/city_3_yellow.png"), QFont(defaultFamily, defaultSize, 50, false), defaultLabelColor)); m_defaultStyle[GeoDataPlacemark::MediumStateCapital] = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/city_3_orange.png"), QFont(defaultFamily, defaultSize, 50, true), defaultLabelColor)); m_defaultStyle[GeoDataPlacemark::MediumNationCapital] = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/city_3_red.png"), QFont(defaultFamily, defaultSize, 50, false), defaultLabelColor)); m_defaultStyle[GeoDataPlacemark::BigCity] = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/city_2_white.png"), QFont(defaultFamily, defaultSize, 50, false), defaultLabelColor)); m_defaultStyle[GeoDataPlacemark::BigCountyCapital] = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/city_2_yellow.png"), QFont(defaultFamily, defaultSize, 50, false), defaultLabelColor)); m_defaultStyle[GeoDataPlacemark::BigStateCapital] = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/city_2_orange.png"), QFont(defaultFamily, defaultSize, 50, true), defaultLabelColor)); m_defaultStyle[GeoDataPlacemark::BigNationCapital] = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/city_2_red.png"), QFont(defaultFamily, defaultSize, 50, false), defaultLabelColor)); m_defaultStyle[GeoDataPlacemark::LargeCity] = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/city_1_white.png"), QFont(defaultFamily, defaultSize, 75, false), defaultLabelColor)); m_defaultStyle[GeoDataPlacemark::LargeCountyCapital] = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/city_1_yellow.png"), QFont(defaultFamily, defaultSize, 75, false), defaultLabelColor)); m_defaultStyle[GeoDataPlacemark::LargeStateCapital] = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/city_1_orange.png"), QFont(defaultFamily, defaultSize, 75, true), defaultLabelColor)); m_defaultStyle[GeoDataPlacemark::LargeNationCapital] = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/city_1_red.png"), QFont(defaultFamily, defaultSize, 75, false), defaultLabelColor)); m_defaultStyle[GeoDataPlacemark::Nation] = GeoDataStyle::Ptr(new GeoDataStyle(QString(), QFont(defaultFamily, int(defaultSize * 1.5), 75, false), QColor("#404040"))); // Align area labels centered m_defaultStyle[GeoDataPlacemark::Nation]->labelStyle().setAlignment(GeoDataLabelStyle::Center); QFont osmCityFont = QFont(defaultFamily, int(defaultSize * 1.5), 75, false); m_defaultStyle[GeoDataPlacemark::PlaceCity] = createOsmPOIStyle(osmCityFont, "place/place-6", QColor("#202020")); m_defaultStyle[GeoDataPlacemark::PlaceCityCapital] = createOsmPOIStyle(osmCityFont, "place/place-capital-6", QColor("#202020")); m_defaultStyle[GeoDataPlacemark::PlaceCityNationalCapital] = createOsmPOIStyle(osmCityFont, "place/place-capital-adminlevel2", QColor("#202020")); m_defaultStyle[GeoDataPlacemark::PlaceSuburb] = createOsmPOIStyle(osmCityFont, QString(), QColor("#707070")); m_defaultStyle[GeoDataPlacemark::PlaceHamlet] = createOsmPOIStyle(osmCityFont, QString(), QColor("#707070")); QFont localityFont = osmCityFont; localityFont.setPointSize(defaultSize); m_defaultStyle[GeoDataPlacemark::PlaceLocality] = createOsmPOIStyle(localityFont, QString(), QColor("#707070")); m_defaultStyle[GeoDataPlacemark::PlaceTown] = createOsmPOIStyle(osmCityFont, "place/place-6", QColor("#404040")); m_defaultStyle[GeoDataPlacemark::PlaceTownCapital] = createOsmPOIStyle(osmCityFont, "place/place-capital-6", QColor("#404040")); m_defaultStyle[GeoDataPlacemark::PlaceTownNationalCapital] = createOsmPOIStyle(osmCityFont, "place/place-capital-adminlevel2", QColor("#404040")); m_defaultStyle[GeoDataPlacemark::PlaceVillage] = createOsmPOIStyle(osmCityFont, "place/place-6", QColor("#505050")); m_defaultStyle[GeoDataPlacemark::PlaceVillageCapital] = createOsmPOIStyle(osmCityFont, "place/place-capital-6", QColor("#505050")); m_defaultStyle[GeoDataPlacemark::PlaceVillageNationalCapital] = createOsmPOIStyle(osmCityFont, "place/place-capital-adminlevel2", QColor("#505050")); for (int i = GeoDataPlacemark::PlaceCity; i <= GeoDataPlacemark::PlaceVillageCapital; ++i) { m_defaultStyle[GeoDataPlacemark::GeoDataVisualCategory(i)]->polyStyle().setFill(false); m_defaultStyle[GeoDataPlacemark::GeoDataVisualCategory(i)]->polyStyle().setOutline(false); m_defaultStyle[GeoDataPlacemark::GeoDataVisualCategory(i)]->labelStyle().setAlignment(GeoDataLabelStyle::Center); if (i == GeoDataPlacemark::PlaceCityNationalCapital || i == GeoDataPlacemark::PlaceTownNationalCapital || i == GeoDataPlacemark::PlaceVillageNationalCapital) { m_defaultStyle[GeoDataPlacemark::GeoDataVisualCategory(i)]->iconStyle().setScale(0.55f); } else { m_defaultStyle[GeoDataPlacemark::GeoDataVisualCategory(i)]->iconStyle().setScale(0.25); } } m_defaultStyle[GeoDataPlacemark::Mountain] = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/mountain_1.png"), QFont(defaultFamily, int(defaultSize * 0.9), 50, false), defaultLabelColor)); m_defaultStyle[GeoDataPlacemark::Volcano] = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/volcano_1.png"), QFont(defaultFamily, int(defaultSize * 0.9), 50, false), defaultLabelColor)); m_defaultStyle[GeoDataPlacemark::Mons] = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/mountain_1.png"), QFont(defaultFamily, int(defaultSize * 0.9), 50, false), defaultLabelColor)); m_defaultStyle[GeoDataPlacemark::Valley] = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/valley.png"), QFont(defaultFamily, int(defaultSize * 0.9), 50, false), defaultLabelColor)); m_defaultStyle[GeoDataPlacemark::Continent] = GeoDataStyle::Ptr(new GeoDataStyle(QString(), QFont(defaultFamily, int(defaultSize * 1.7), 50, false), QColor("#bf0303"))); // Align area labels centered m_defaultStyle[GeoDataPlacemark::Continent]->labelStyle().setAlignment(GeoDataLabelStyle::Center); m_defaultStyle[GeoDataPlacemark::Ocean] = GeoDataStyle::Ptr(new GeoDataStyle(QString(), QFont(defaultFamily, int(defaultSize * 1.7), 50, true), QColor("#2c72c7"))); // Align area labels centered m_defaultStyle[GeoDataPlacemark::Ocean]->labelStyle().setAlignment(GeoDataLabelStyle::Center); m_defaultStyle[GeoDataPlacemark::OtherTerrain] = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/other.png"), QFont(defaultFamily, int(defaultSize * 0.9), 50, false), defaultLabelColor)); m_defaultStyle[GeoDataPlacemark::Crater] = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/crater.png"), QFont(defaultFamily, int(defaultSize * 0.9), 50, false), defaultLabelColor)); m_defaultStyle[GeoDataPlacemark::Mare] = GeoDataStyle::Ptr(new GeoDataStyle(QString(), QFont(defaultFamily, int(defaultSize * 1.7), 50, false), QColor("#bf0303"))); // Align area labels centered m_defaultStyle[GeoDataPlacemark::Mare]->labelStyle().setAlignment(GeoDataLabelStyle::Center); m_defaultStyle[GeoDataPlacemark::GeographicPole] = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/pole_1.png"), QFont(defaultFamily, defaultSize, 50, false), defaultLabelColor)); m_defaultStyle[GeoDataPlacemark::MagneticPole] = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/pole_2.png"), QFont(defaultFamily, defaultSize, 50, false), defaultLabelColor)); m_defaultStyle[GeoDataPlacemark::ShipWreck] = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/shipwreck.png"), QFont(defaultFamily, int(defaultSize * 0.8), 50, false), defaultLabelColor)); m_defaultStyle[GeoDataPlacemark::AirPort] = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/airport.png"), QFont(defaultFamily, defaultSize, 50, false), defaultLabelColor)); m_defaultStyle[GeoDataPlacemark::Observatory] = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/observatory.png"), QFont(defaultFamily, defaultSize, 50, false), defaultLabelColor)); m_defaultStyle[GeoDataPlacemark::OsmSite] = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/osm.png"), QFont(defaultFamily, defaultSize, 50, false), defaultLabelColor)); m_defaultStyle[GeoDataPlacemark::Coordinate] = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/coordinate.png"), QFont(defaultFamily, defaultSize, 50, false), defaultLabelColor)); m_defaultStyle[GeoDataPlacemark::MannedLandingSite] = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/manned_landing.png"), QFont(defaultFamily, defaultSize, 50, false), defaultLabelColor)); m_defaultStyle[GeoDataPlacemark::RoboticRover] = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/robotic_rover.png"), QFont(defaultFamily, defaultSize, 50, false), defaultLabelColor)); m_defaultStyle[GeoDataPlacemark::UnmannedSoftLandingSite] = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/unmanned_soft_landing.png"), QFont(defaultFamily, defaultSize, 50, false), defaultLabelColor)); m_defaultStyle[GeoDataPlacemark::UnmannedHardLandingSite] = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/unmanned_hard_landing.png"), QFont(defaultFamily, defaultSize, 50, false), defaultLabelColor)); m_defaultStyle[GeoDataPlacemark::Bookmark] = createPOIStyle(QFont(defaultFamily, defaultSize, 50, false), MarbleDirs::path("svg/bookmark.svg"), defaultLabelColor); m_defaultStyle[GeoDataPlacemark::Bookmark]->iconStyle().setScale(0.75); QColor const shopColor("#ac39ac"); QColor const transportationColor("#0092da"); QColor const amenityColor("#734a08"); QColor const healthColor("#da0092"); QColor const airTransportColor("#8461C4"); QColor const educationalAreasAndHospital("#f0f0d8"); QColor const buildingColor("#beadad"); QColor const waterColor("#b5d0d0"); // Allows to visualize multiple repaints of buildings // QColor const buildingColor(0, 255, 0, 64); QFont const osmFont(defaultFamily, 10, 50, false); m_defaultStyle[GeoDataPlacemark::AccomodationCamping] = createOsmPOIRingStyle(osmFont, "transportation/camping.16", transportationColor); m_defaultStyle[GeoDataPlacemark::AccomodationHostel] = createOsmPOIStyle(osmFont, "transportation/hostel.16", transportationColor); m_defaultStyle[GeoDataPlacemark::AccomodationHotel] = createOsmPOIStyle(osmFont, "transportation/hotel.16", transportationColor); m_defaultStyle[GeoDataPlacemark::AccomodationMotel] = createOsmPOIStyle(osmFont, "transportation/motel.16", transportationColor); m_defaultStyle[GeoDataPlacemark::AccomodationYouthHostel] = createOsmPOIStyle(osmFont, "transportation/hostel.16", transportationColor); m_defaultStyle[GeoDataPlacemark::AccomodationGuestHouse] = createOsmPOIStyle(osmFont, "transportation/guest_house.16", transportationColor); m_defaultStyle[GeoDataPlacemark::AmenityLibrary] = createOsmPOIStyle(osmFont, "amenity/library.20", amenityColor); m_defaultStyle[GeoDataPlacemark::AmenityKindergarten] = createOsmPOIAreaStyle(osmFont, QString(), amenityColor, educationalAreasAndHospital, amenityColor); m_defaultStyle[GeoDataPlacemark::EducationCollege] = createOsmPOIAreaStyle(osmFont, QString(), amenityColor, educationalAreasAndHospital, amenityColor); m_defaultStyle[GeoDataPlacemark::EducationSchool] = createOsmPOIAreaStyle(osmFont, QString(), amenityColor, educationalAreasAndHospital, amenityColor); m_defaultStyle[GeoDataPlacemark::EducationUniversity] = createOsmPOIAreaStyle(osmFont, QString(), amenityColor, educationalAreasAndHospital, amenityColor); m_defaultStyle[GeoDataPlacemark::FoodBar] = createOsmPOIStyle(osmFont, "amenity/bar.16", amenityColor); m_defaultStyle[GeoDataPlacemark::FoodBiergarten] = createOsmPOIStyle(osmFont, "amenity/biergarten.16", amenityColor); m_defaultStyle[GeoDataPlacemark::FoodCafe] = createOsmPOIStyle(osmFont, "amenity/cafe.16", amenityColor); m_defaultStyle[GeoDataPlacemark::FoodFastFood] = createOsmPOIStyle(osmFont, "amenity/fast_food.16", amenityColor); m_defaultStyle[GeoDataPlacemark::FoodPub] = createOsmPOIStyle(osmFont, "amenity/pub.16", amenityColor); m_defaultStyle[GeoDataPlacemark::FoodRestaurant] = createOsmPOIStyle(osmFont, "amenity/restaurant.16", amenityColor); m_defaultStyle[GeoDataPlacemark::HealthDentist] = createOsmPOIStyle(osmFont, "health/dentist.16", healthColor); m_defaultStyle[GeoDataPlacemark::HealthDoctors] = createOsmPOIStyle(osmFont, "health/doctors.16", healthColor); m_defaultStyle[GeoDataPlacemark::HealthHospital] = createOsmPOIStyle(osmFont, "health/hospital.16", healthColor, educationalAreasAndHospital, amenityColor); m_defaultStyle[GeoDataPlacemark::HealthPharmacy] = createOsmPOIStyle(osmFont, "health/pharmacy.16", healthColor); m_defaultStyle[GeoDataPlacemark::HealthVeterinary] = createOsmPOIStyle(osmFont, "health/veterinary-14", healthColor); m_defaultStyle[GeoDataPlacemark::MoneyAtm] = createOsmPOIStyle(osmFont, "amenity/atm.16", amenityColor); m_defaultStyle[GeoDataPlacemark::MoneyBank] = createOsmPOIStyle(osmFont, "amenity/bank.16", amenityColor); m_defaultStyle[GeoDataPlacemark::HistoricArchaeologicalSite] = createOsmPOIAreaStyle(osmFont, "amenity/archaeological_site.16", amenityColor, Qt::transparent); m_defaultStyle[GeoDataPlacemark::AmenityEmbassy] = createOsmPOIStyle(osmFont, "transportation/embassy.16", transportationColor); m_defaultStyle[GeoDataPlacemark::AmenityEmergencyPhone] = createOsmPOIStyle(osmFont, "amenity/emergency_phone.16", amenityColor); m_defaultStyle[GeoDataPlacemark::AmenityMountainRescue] = createOsmPOIStyle(osmFont, "amenity/mountain_rescue.16", amenityColor); m_defaultStyle[GeoDataPlacemark::LeisureWaterPark] = createOsmPOIStyle(osmFont, "amenity/water_park.16", amenityColor); m_defaultStyle[GeoDataPlacemark::AmenityCommunityCentre] = createOsmPOIStyle(osmFont, "amenity/community_centre-14", amenityColor); m_defaultStyle[GeoDataPlacemark::AmenityFountain] = createOsmPOIStyle(osmFont, "amenity/fountain-14", QColor("#7989de"), waterColor, waterColor.darker(150)); m_defaultStyle[GeoDataPlacemark::AmenityNightClub] = createOsmPOIStyle(osmFont, "amenity/nightclub.18", amenityColor); m_defaultStyle[GeoDataPlacemark::AmenityBench] = createOsmPOIStyle(osmFont, "individual/bench.16", amenityColor); m_defaultStyle[GeoDataPlacemark::AmenityCourtHouse] = createOsmPOIStyle(osmFont, "amenity/courthouse-16", amenityColor); m_defaultStyle[GeoDataPlacemark::AmenityFireStation] = createOsmPOIStyle(osmFont, "amenity/firestation.16", amenityColor); m_defaultStyle[GeoDataPlacemark::AmenityHuntingStand] = createOsmPOIStyle(osmFont, "manmade/hunting-stand.16", amenityColor); m_defaultStyle[GeoDataPlacemark::AmenityPolice] = createOsmPOIStyle(osmFont, "amenity/police.16", amenityColor); m_defaultStyle[GeoDataPlacemark::AmenityPostBox] = createOsmPOIStyle(osmFont, "amenity/post_box-12", amenityColor); m_defaultStyle[GeoDataPlacemark::AmenityPostOffice] = createOsmPOIStyle(osmFont, "amenity/post_office-14", amenityColor); m_defaultStyle[GeoDataPlacemark::AmenityPrison] = createOsmPOIStyle(osmFont, "amenity/prison.16", amenityColor); m_defaultStyle[GeoDataPlacemark::AmenityRecycling] = createOsmPOIStyle(osmFont, "amenity/recycling.16", amenityColor); m_defaultStyle[GeoDataPlacemark::AmenityShelter] = createOsmPOIStyle(osmFont, "transportation/shelter", transportationColor); m_defaultStyle[GeoDataPlacemark::AmenityTelephone] = createOsmPOIStyle(osmFont, "amenity/telephone.16", amenityColor); m_defaultStyle[GeoDataPlacemark::AmenityToilets] = createOsmPOIStyle(osmFont, "amenity/toilets.16", amenityColor); m_defaultStyle[GeoDataPlacemark::AmenityTownHall] = createOsmPOIStyle(osmFont, "amenity/town_hall.16", amenityColor); m_defaultStyle[GeoDataPlacemark::AmenityWasteBasket] = createOsmPOIStyle(osmFont, "individual/waste_basket.10", amenityColor); m_defaultStyle[GeoDataPlacemark::AmenityWasteBasket]->iconStyle().setScale(0.75); m_defaultStyle[GeoDataPlacemark::AmenityChargingStation] = createOsmPOIStyle(osmFont, "transportation/charging_station"); m_defaultStyle[GeoDataPlacemark::AmenityCarWash] = createOsmPOIStyle(osmFont, "amenity/car_wash", amenityColor); m_defaultStyle[GeoDataPlacemark::AmenitySocialFacility] = createOsmPOIStyle(osmFont, "amenity/social_facility", amenityColor); m_defaultStyle[GeoDataPlacemark::AmenityDrinkingWater] = createOsmPOIStyle(osmFont, "amenity/drinking_water.16", amenityColor); m_defaultStyle[GeoDataPlacemark::NaturalPeak] = createOsmPOIStyle(osmFont, "individual/peak", amenityColor); m_defaultStyle[GeoDataPlacemark::NaturalPeak]->iconStyle().setScale(0.33f); m_defaultStyle[GeoDataPlacemark::NaturalVolcano] = createOsmPOIStyle(osmFont, "individual/volcano", amenityColor); m_defaultStyle[GeoDataPlacemark::NaturalVolcano]->iconStyle().setScale(0.33f); m_defaultStyle[GeoDataPlacemark::NaturalTree] = createOsmPOIStyle(osmFont, "individual/tree-29", amenityColor); // tree-16 provides the official icon m_styleTreeAutumn = createOsmPOIStyle(osmFont, "individual/tree-29-autumn", amenityColor); m_styleTreeWinter = createOsmPOIStyle(osmFont, "individual/tree-29-winter", amenityColor); qreal const treeIconScale = 0.75; m_defaultStyle[GeoDataPlacemark::NaturalTree]->iconStyle().setScale(treeIconScale); m_styleTreeAutumn->iconStyle().setScale(treeIconScale); m_styleTreeWinter->iconStyle().setScale(treeIconScale); m_defaultStyle[GeoDataPlacemark::ShopBeverages] = createOsmPOIStyle(osmFont, "shop/beverages-14", shopColor); m_defaultStyle[GeoDataPlacemark::ShopHifi] = createOsmPOIStyle(osmFont, "shop/hifi-14", shopColor); m_defaultStyle[GeoDataPlacemark::ShopSupermarket] = createOsmPOIStyle(osmFont, "shop/shop_supermarket", shopColor); m_defaultStyle[GeoDataPlacemark::ShopAlcohol] = createOsmPOIStyle(osmFont, "shop/shop_alcohol.16", shopColor); m_defaultStyle[GeoDataPlacemark::ShopBakery] = createOsmPOIStyle(osmFont, "shop/shop_bakery.16", shopColor); m_defaultStyle[GeoDataPlacemark::ShopButcher] = createOsmPOIStyle(osmFont, "shop/butcher-14", shopColor); m_defaultStyle[GeoDataPlacemark::ShopConfectionery] = createOsmPOIStyle(osmFont, "shop/confectionery.14", shopColor); m_defaultStyle[GeoDataPlacemark::ShopConvenience] = createOsmPOIStyle(osmFont, "shop/shop_convenience", shopColor); m_defaultStyle[GeoDataPlacemark::ShopGreengrocer] = createOsmPOIStyle(osmFont, "shop/greengrocer-14", shopColor); m_defaultStyle[GeoDataPlacemark::ShopSeafood] = createOsmPOIStyle(osmFont, "shop/seafood-14", shopColor); m_defaultStyle[GeoDataPlacemark::ShopDepartmentStore] = createOsmPOIStyle(osmFont, "shop/department_store-16", shopColor); m_defaultStyle[GeoDataPlacemark::ShopKiosk] = createOsmPOIStyle(osmFont, "shop/kiosk-14", shopColor); m_defaultStyle[GeoDataPlacemark::ShopBag] = createOsmPOIStyle(osmFont, "shop/bag-14", shopColor); m_defaultStyle[GeoDataPlacemark::ShopClothes] = createOsmPOIStyle(osmFont, "shop/shop_clothes.16", shopColor); m_defaultStyle[GeoDataPlacemark::ShopFashion] = createOsmPOIStyle(osmFont, "shop/shop_clothes.16", shopColor); m_defaultStyle[GeoDataPlacemark::ShopJewelry] = createOsmPOIStyle(osmFont, "shop/shop_jewelry.16", shopColor); m_defaultStyle[GeoDataPlacemark::ShopShoes] = createOsmPOIStyle(osmFont, "shop/shop_shoes.16", shopColor); m_defaultStyle[GeoDataPlacemark::ShopVarietyStore] = createOsmPOIStyle(osmFont, "shop/variety_store-14", shopColor); m_defaultStyle[GeoDataPlacemark::ShopBeauty] = createOsmPOIStyle(osmFont, "shop/beauty-14", shopColor); m_defaultStyle[GeoDataPlacemark::ShopChemist] = createOsmPOIStyle(osmFont, "shop/chemist-14", shopColor); m_defaultStyle[GeoDataPlacemark::ShopCosmetics] = createOsmPOIStyle(osmFont, "shop/perfumery-14", shopColor); m_defaultStyle[GeoDataPlacemark::ShopHairdresser] = createOsmPOIStyle(osmFont, "shop/shop_hairdresser.16", shopColor); m_defaultStyle[GeoDataPlacemark::ShopOptician] = createOsmPOIStyle(osmFont, "shop/shop_optician.16", shopColor); m_defaultStyle[GeoDataPlacemark::ShopPerfumery] = createOsmPOIStyle(osmFont, "shop/perfumery-14", shopColor); m_defaultStyle[GeoDataPlacemark::ShopDoitYourself] = createOsmPOIStyle(osmFont, "shop/shop_diy.16", shopColor); m_defaultStyle[GeoDataPlacemark::ShopFlorist] = createOsmPOIStyle(osmFont, "shop/florist.16", shopColor); m_defaultStyle[GeoDataPlacemark::ShopHardware] = createOsmPOIStyle(osmFont, "shop/shop_diy.16", shopColor); m_defaultStyle[GeoDataPlacemark::ShopFurniture] = createOsmPOIStyle(osmFont, "shop/shop_furniture.16", shopColor); m_defaultStyle[GeoDataPlacemark::ShopElectronics] = createOsmPOIStyle(osmFont, "shop/shop_electronics.16", shopColor); m_defaultStyle[GeoDataPlacemark::ShopMobilePhone] = createOsmPOIStyle(osmFont, "shop/shop_mobile_phone.16", shopColor); m_defaultStyle[GeoDataPlacemark::ShopBicycle] = createOsmPOIStyle(osmFont, "shop/shop_bicycle.16", shopColor); m_defaultStyle[GeoDataPlacemark::ShopCar] = createOsmPOIStyle(osmFont, "shop/shop_car", shopColor); m_defaultStyle[GeoDataPlacemark::ShopCarRepair] = createOsmPOIStyle(osmFont, "shop/shopping_car_repair.16", shopColor); m_defaultStyle[GeoDataPlacemark::ShopCarParts] = createOsmPOIStyle(osmFont, "shop/car_parts-14", shopColor); m_defaultStyle[GeoDataPlacemark::ShopMotorcycle] = createOsmPOIStyle(osmFont, "shop/motorcycle-14", shopColor); m_defaultStyle[GeoDataPlacemark::ShopOutdoor] = createOsmPOIStyle(osmFont, "shop/outdoor-14", shopColor); m_defaultStyle[GeoDataPlacemark::ShopSports] = createOsmPOIStyle(osmFont, "shop/sports", shopColor); m_defaultStyle[GeoDataPlacemark::ShopCopy] = createOsmPOIStyle(osmFont, "shop/copyshop", shopColor); m_defaultStyle[GeoDataPlacemark::ShopArt] = createOsmPOIStyle(osmFont, "shop/art", shopColor); m_defaultStyle[GeoDataPlacemark::ShopMusicalInstrument] = createOsmPOIStyle(osmFont, "shop/musical_instrument-14", shopColor); m_defaultStyle[GeoDataPlacemark::ShopPhoto] = createOsmPOIStyle(osmFont, "shop/photo-14", shopColor); m_defaultStyle[GeoDataPlacemark::ShopBook] = createOsmPOIStyle(osmFont, "shop/shop_books.16", shopColor); m_defaultStyle[GeoDataPlacemark::ShopGift] = createOsmPOIStyle(osmFont, "shop/shop_gift.16", shopColor); m_defaultStyle[GeoDataPlacemark::ShopStationery] = createOsmPOIStyle(osmFont, "shop/stationery-14", shopColor); m_defaultStyle[GeoDataPlacemark::ShopLaundry] = createOsmPOIStyle(osmFont, "shop/laundry-14", shopColor); m_defaultStyle[GeoDataPlacemark::ShopPet] = createOsmPOIStyle(osmFont, "shop/shop_pet.16", shopColor); m_defaultStyle[GeoDataPlacemark::ShopToys] = createOsmPOIStyle(osmFont, "shop/toys-14", shopColor); m_defaultStyle[GeoDataPlacemark::ShopTravelAgency] = createOsmPOIStyle(osmFont, "shop/travel_agency-14", shopColor); m_defaultStyle[GeoDataPlacemark::ShopDeli] = createOsmPOIStyle(osmFont, "shop/deli", shopColor); m_defaultStyle[GeoDataPlacemark::ShopTobacco] = createOsmPOIStyle(osmFont, "shop/tobacco", shopColor); m_defaultStyle[GeoDataPlacemark::ShopTea] = createOsmPOIStyle(osmFont, "shop/tea", shopColor); m_defaultStyle[GeoDataPlacemark::Shop] = createOsmPOIStyle(osmFont, "shop/shop-14", shopColor); m_defaultStyle[GeoDataPlacemark::ManmadeBridge] = createWayStyle(QColor("#b8b8b8"), Qt::transparent, true, true); m_defaultStyle[GeoDataPlacemark::ManmadeLighthouse] = createOsmPOIStyle(osmFont, "transportation/lighthouse.16", transportationColor, "#f2efe9", QColor("#f2efe9").darker()); m_defaultStyle[GeoDataPlacemark::ManmadePier] = createStyle(0.0, 3.0, "#f2efe9", "#f2efe9", true, false, Qt::SolidPattern, Qt::SolidLine, Qt::FlatCap, false, QVector(), osmFont); m_defaultStyle[GeoDataPlacemark::ManmadeWaterTower] = createOsmPOIStyle(osmFont, "amenity/water_tower.16", amenityColor); m_defaultStyle[GeoDataPlacemark::ManmadeWindMill] = createOsmPOIStyle(osmFont, "amenity/windmill.16", amenityColor); m_defaultStyle[GeoDataPlacemark::HistoricCastle] = createOsmPOIRingStyle(osmFont, "amenity/cinema.16", amenityColor); m_defaultStyle[GeoDataPlacemark::HistoricMemorial] = createOsmPOIStyle(osmFont, "amenity/tourist_memorial.16", amenityColor); m_defaultStyle[GeoDataPlacemark::HistoricMonument] = createOsmPOIStyle(osmFont, "amenity/monument.16", amenityColor); m_defaultStyle[GeoDataPlacemark::HistoricRuins] = createOsmPOIRingStyle(osmFont, QString(), amenityColor); m_defaultStyle[GeoDataPlacemark::TourismAttraction] = createOsmPOIStyle(osmFont, "amenity/tourist_memorial.16", amenityColor); m_defaultStyle[GeoDataPlacemark::TourismArtwork] = createOsmPOIStyle(osmFont, "amenity/artwork", amenityColor); m_defaultStyle[GeoDataPlacemark::AmenityCinema] = createOsmPOIStyle(osmFont, "amenity/cinema.16", amenityColor); m_defaultStyle[GeoDataPlacemark::TourismInformation] = createOsmPOIStyle(osmFont, "amenity/information.16", amenityColor); m_defaultStyle[GeoDataPlacemark::TourismMuseum] = createOsmPOIStyle(osmFont, "amenity/museum.16", amenityColor); m_defaultStyle[GeoDataPlacemark::AmenityTheatre] = createOsmPOIStyle(osmFont, "amenity/theatre.16", amenityColor); m_defaultStyle[GeoDataPlacemark::TourismThemePark] = createOsmPOIStyle(osmFont, QString(), amenityColor); m_defaultStyle[GeoDataPlacemark::TourismViewPoint] = createOsmPOIStyle(osmFont, "amenity/viewpoint.16", amenityColor); m_defaultStyle[GeoDataPlacemark::TourismZoo] = createOsmPOIRingStyle(osmFont, QString(), amenityColor, Qt::transparent); m_defaultStyle[GeoDataPlacemark::TourismAlpineHut] = createOsmPOIStyle(osmFont, "transportation/alpinehut.16", transportationColor); m_defaultStyle[GeoDataPlacemark::TourismWildernessHut] = createOsmPOIStyle(osmFont, "transportation/wilderness_hut", transportationColor); m_defaultStyle[GeoDataPlacemark::TransportAerodrome] = createOsmPOIStyle(osmFont, "airtransport/aerodrome", airTransportColor); m_defaultStyle[GeoDataPlacemark::TransportHelipad] = createOsmPOIStyle(osmFont, "airtransport/helipad", airTransportColor); m_defaultStyle[GeoDataPlacemark::TransportAirportTerminal] = createOsmPOIAreaStyle(osmFont, QString(), airTransportColor); m_defaultStyle[GeoDataPlacemark::TransportAirportGate] = createOsmPOIAreaStyle(osmFont, QString(), airTransportColor); m_defaultStyle[GeoDataPlacemark::TransportBusStation] = createOsmPOIStyle(osmFont, "transportation/bus_station.16", transportationColor); m_defaultStyle[GeoDataPlacemark::TransportBusStop] = createOsmPOIStyle(osmFont, "transportation/bus_stop.12", transportationColor); m_defaultStyle[GeoDataPlacemark::TransportCarShare] = createOsmPOIStyle(osmFont, "transportation/car_share.16", transportationColor); m_defaultStyle[GeoDataPlacemark::TransportFuel] = createOsmPOIStyle(osmFont, "transportation/fuel.16", transportationColor); m_defaultStyle[GeoDataPlacemark::TransportParking] = createOsmPOIAreaStyle(osmFont, "transportation/parking", transportationColor, "#F6EEB6", QColor("#F6EEB6").darker()); m_defaultStyle[GeoDataPlacemark::TransportBicycleParking] = createOsmPOIAreaStyle(osmFont, "transportation/bicycle_parking.16", transportationColor); m_defaultStyle[GeoDataPlacemark::TransportMotorcycleParking] = createOsmPOIAreaStyle(osmFont, "transportation/motorcycle_parking.16", transportationColor); qreal const parkingIconScale = 0.75; m_defaultStyle[GeoDataPlacemark::TransportParking]->iconStyle().setScale(parkingIconScale); m_defaultStyle[GeoDataPlacemark::TransportBicycleParking]->iconStyle().setScale(parkingIconScale); m_defaultStyle[GeoDataPlacemark::TransportMotorcycleParking]->iconStyle().setScale(parkingIconScale); m_defaultStyle[GeoDataPlacemark::TransportParkingSpace] = createWayStyle("#F6EEB6", QColor("#F6EEB6").darker(), true, true); m_defaultStyle[GeoDataPlacemark::TransportPlatform] = createWayStyle("#bbbbbb", Qt::transparent, true, false); m_defaultStyle[GeoDataPlacemark::TransportTrainStation] = createOsmPOIStyle(osmFont, "individual/railway_station", transportationColor); m_defaultStyle[GeoDataPlacemark::TransportTrainStation]->iconStyle().setScale(0.5); m_defaultStyle[GeoDataPlacemark::TransportTramStop] = createOsmPOIStyle(osmFont, "individual/railway_station", transportationColor); m_defaultStyle[GeoDataPlacemark::TransportTramStop]->iconStyle().setScale(0.33f); m_defaultStyle[GeoDataPlacemark::TransportRentalBicycle] = createOsmPOIStyle(osmFont, "transportation/rental_bicycle.16", transportationColor); m_defaultStyle[GeoDataPlacemark::TransportRentalCar] = createOsmPOIStyle(osmFont, "transportation/rental_car.16", transportationColor); m_defaultStyle[GeoDataPlacemark::TransportRentalSki] = createOsmPOIStyle(osmFont, "transportation/rental_ski.16", transportationColor); m_defaultStyle[GeoDataPlacemark::TransportTaxiRank] = createOsmPOIStyle(osmFont, "transportation/taxi.16", transportationColor); m_defaultStyle[GeoDataPlacemark::TransportSubwayEntrance] = createOsmPOIStyle(osmFont, "transportation/subway_entrance", transportationColor); m_defaultStyle[GeoDataPlacemark::ReligionPlaceOfWorship] = createOsmPOIStyle(osmFont, QString() /* "black/place_of_worship.16" */); m_defaultStyle[GeoDataPlacemark::ReligionBahai] = createOsmPOIStyle(osmFont, QString()); m_defaultStyle[GeoDataPlacemark::ReligionBuddhist] = createOsmPOIStyle(osmFont, "black/buddhist.16"); m_defaultStyle[GeoDataPlacemark::ReligionChristian] = createOsmPOIStyle(osmFont, "black/christian.16"); m_defaultStyle[GeoDataPlacemark::ReligionMuslim] = createOsmPOIStyle(osmFont, "black/muslim.16"); m_defaultStyle[GeoDataPlacemark::ReligionHindu] = createOsmPOIStyle(osmFont, "black/hinduist.16"); m_defaultStyle[GeoDataPlacemark::ReligionJain] = createOsmPOIStyle(osmFont, QString()); m_defaultStyle[GeoDataPlacemark::ReligionJewish] = createOsmPOIStyle(osmFont, "black/jewish.16"); m_defaultStyle[GeoDataPlacemark::ReligionShinto] = createOsmPOIStyle(osmFont, "black/shintoist.16"); m_defaultStyle[GeoDataPlacemark::ReligionSikh] = createOsmPOIStyle(osmFont, "black/sikhist.16"); m_defaultStyle[GeoDataPlacemark::HighwayTrafficSignals] = createOsmPOIStyle(osmFont, "individual/traffic_light"); m_defaultStyle[GeoDataPlacemark::HighwayTrafficSignals]->iconStyle().setScale(0.75); m_defaultStyle[GeoDataPlacemark::PowerTower] = createOsmPOIStyle(osmFont, "individual/power_tower", QColor("#888888")); m_defaultStyle[GeoDataPlacemark::PowerTower]->iconStyle().setScale(0.6f); m_defaultStyle[GeoDataPlacemark::BarrierCityWall] = createStyle(6.0, 3.0, "#787878", Qt::transparent, true, false, Qt::SolidPattern, Qt::SolidLine, Qt::FlatCap, false, QVector(), osmFont, Qt::transparent); m_defaultStyle[GeoDataPlacemark::BarrierGate] = createOsmPOIStyle(osmFont, "individual/gate"); m_defaultStyle[GeoDataPlacemark::BarrierGate]->iconStyle().setScale(0.75); m_defaultStyle[GeoDataPlacemark::BarrierLiftGate] = createOsmPOIStyle(osmFont, "individual/liftgate"); m_defaultStyle[GeoDataPlacemark::BarrierLiftGate]->iconStyle().setScale(0.75); m_defaultStyle[GeoDataPlacemark::BarrierWall] = createStyle(2.0, 0.0, "#787878", Qt::transparent, true, false, Qt::SolidPattern, Qt::SolidLine, Qt::FlatCap, false, QVector(), osmFont, Qt::transparent); m_defaultStyle[GeoDataPlacemark::HighwaySteps] = createStyle(0.0, 2.0, "#fa8072", QColor(Qt::white), true, true, Qt::SolidPattern, Qt::CustomDashLine, Qt::FlatCap, false, QVector< qreal >() << 0.3 << 0.3, osmFont); m_defaultStyle[GeoDataPlacemark::HighwayUnknown] = createHighwayStyle("#dddddd", "#bbbbbb", osmFont, "000000", 0, 1); m_defaultStyle[GeoDataPlacemark::HighwayPath] = createHighwayStyle("#dddde8", "#999999", osmFont, "000000", 0, 1, Qt::DotLine, Qt::SquareCap, true); m_defaultStyle[GeoDataPlacemark::HighwayTrack] = createHighwayStyle("#996600", QColor(Qt::white), osmFont, QColor(Qt::transparent), 1, 1, Qt::DashLine, Qt::SquareCap, true); m_defaultStyle[GeoDataPlacemark::HighwayPedestrian] = createHighwayStyle("#dddde8", "#999999", osmFont, "000000", 0, 2); m_defaultStyle[GeoDataPlacemark::HighwayPedestrian]->polyStyle().setOutline(false); m_defaultStyle[GeoDataPlacemark::HighwayFootway] = createHighwayStyle("#fa8072", QColor(Qt::white), osmFont, "000000", 0, 2, Qt::DotLine, Qt::SquareCap, true); m_defaultStyle[GeoDataPlacemark::HighwayCycleway] = createHighwayStyle(QColor(Qt::blue), QColor(Qt::white), osmFont, "000000", 0, 2, Qt::DotLine, Qt::SquareCap, true); m_defaultStyle[GeoDataPlacemark::HighwayService] = createHighwayStyle("#ffffff", "#bbbbbb", osmFont, "000000", 1, 6); m_defaultStyle[GeoDataPlacemark::HighwayResidential] = createHighwayStyle("#ffffff", "#bbbbbb", osmFont, "000000", 3, 6); m_defaultStyle[GeoDataPlacemark::HighwayLivingStreet] = createHighwayStyle("#ffffff", "#bbbbbb", osmFont, "000000", 3, 6); m_defaultStyle[GeoDataPlacemark::HighwayRoad] = createHighwayStyle("#dddddd", "#bbbbbb", osmFont, "000000", 3, 6); m_defaultStyle[GeoDataPlacemark::HighwayUnclassified] = createHighwayStyle("#ffffff", "#bbbbbb", osmFont, "000000", 3, 6); m_defaultStyle[GeoDataPlacemark::HighwayTertiary] = createHighwayStyle("#ffffff", "#8f8f8f", osmFont, "000000", 6, 6); m_defaultStyle[GeoDataPlacemark::HighwayTertiaryLink] = createHighwayStyle("#ffffff", "#8f8f8f", osmFont, "000000", 6, 6); m_defaultStyle[GeoDataPlacemark::HighwaySecondary] = createHighwayStyle("#f7fabf", "#707d05", osmFont, "000000", 6, 6); m_defaultStyle[GeoDataPlacemark::HighwaySecondaryLink] = createHighwayStyle("#f7fabf", "#707d05", osmFont, "000000", 6, 6); m_defaultStyle[GeoDataPlacemark::HighwayPrimary] = createHighwayStyle("#fcd6a4", "#a06b00", osmFont, "000000", 9, 6); m_defaultStyle[GeoDataPlacemark::HighwayPrimaryLink] = createHighwayStyle("#fcd6a4", "#a06b00", osmFont, "000000", 6, 6); m_defaultStyle[GeoDataPlacemark::HighwayRaceway] = createHighwayStyle("#ffc0cb", "#ffc0cb", osmFont, "000000", 1, 5); m_defaultStyle[GeoDataPlacemark::HighwayTrunk] = createHighwayStyle("#f9b29c", "#c84e2f", osmFont, "000000", 9, 6); m_defaultStyle[GeoDataPlacemark::HighwayTrunkLink] = createHighwayStyle("#f9b29c", "#c84e2f", osmFont, "000000", 9, 6); m_defaultStyle[GeoDataPlacemark::HighwayMotorway] = createHighwayStyle("#e892a2", "#dc2a67", osmFont, "000000", 9, 10); m_defaultStyle[GeoDataPlacemark::HighwayMotorwayLink] = createHighwayStyle("#e892a2", "#dc2a67", osmFont, "000000", 9, 10); m_defaultStyle[GeoDataPlacemark::HighwayCorridor] = createHighwayStyle("#ffffff", "#bbbbbb", osmFont, "000000", 1, 3); m_defaultStyle[GeoDataPlacemark::TransportAirportRunway] = createHighwayStyle("#bbbbcc", "#bbbbcc", osmFont, "000000", 0, 1, Qt::NoPen); m_defaultStyle[GeoDataPlacemark::TransportAirportTaxiway] = createHighwayStyle("#bbbbcc", "#bbbbcc", osmFont, "000000", 0, 1, Qt::NoPen); m_defaultStyle[GeoDataPlacemark::TransportAirportApron] = createWayStyle("#e9d1ff", Qt::transparent, true, false); m_defaultStyle[GeoDataPlacemark::TransportSpeedCamera] = createOsmPOIStyle(osmFont, "individual/speedcamera"); m_defaultStyle[GeoDataPlacemark::NaturalWater] = createStyle(4, 0, waterColor, waterColor, true, false, Qt::SolidPattern, Qt::SolidLine, Qt::RoundCap, false, QVector< qreal >(), osmFont, waterColor.darker(150)); m_defaultStyle[GeoDataPlacemark::WaterwayRiver] = createStyle(4, 0, waterColor, waterColor, true, false, Qt::SolidPattern, Qt::SolidLine, Qt::RoundCap, false, QVector< qreal >(), osmFont, waterColor.darker(150)); m_defaultStyle[GeoDataPlacemark::WaterwayCanal] = m_defaultStyle[GeoDataPlacemark::WaterwayRiver]; m_defaultStyle[GeoDataPlacemark::WaterwayDitch] = m_defaultStyle[GeoDataPlacemark::WaterwayRiver]; m_defaultStyle[GeoDataPlacemark::WaterwayDrain] = m_defaultStyle[GeoDataPlacemark::WaterwayRiver]; m_defaultStyle[GeoDataPlacemark::WaterwayStream] = m_defaultStyle[GeoDataPlacemark::WaterwayRiver]; m_defaultStyle[GeoDataPlacemark::WaterwayWeir] = createStyle(4, 0, "#ffffff", "#87939b", true, false, Qt::SolidPattern, Qt::DotLine, Qt::RoundCap, true, QVector< qreal >(), osmFont, waterColor.darker(150)); m_defaultStyle[GeoDataPlacemark::CrossingIsland] = createOsmPOIStyle(osmFont, "transportation/zebra_crossing", transportationColor); m_defaultStyle[GeoDataPlacemark::CrossingIsland]->iconStyle().setScale(0.75); m_defaultStyle[GeoDataPlacemark::CrossingRailway] = createOsmPOIStyle(osmFont, "transportation/railway_crossing", transportationColor); m_defaultStyle[GeoDataPlacemark::CrossingRailway]->iconStyle().setScale(0.5); m_defaultStyle[GeoDataPlacemark::CrossingSignals] = createOsmPOIStyle(osmFont, "transportation/traffic_light_crossing", transportationColor); m_defaultStyle[GeoDataPlacemark::CrossingSignals]->iconStyle().setScale(0.75); m_defaultStyle[GeoDataPlacemark::CrossingZebra] = createOsmPOIStyle(osmFont, "transportation/zebra_crossing", transportationColor); m_defaultStyle[GeoDataPlacemark::CrossingZebra]->iconStyle().setScale(0.75); m_defaultStyle[GeoDataPlacemark::NaturalReef] = createStyle(5.5, 0, "#36677c", "#36677c", true, false, Qt::Dense7Pattern, Qt::DotLine, Qt::RoundCap, false, QVector< qreal >(), osmFont, waterColor.darker(150)); m_defaultStyle[GeoDataPlacemark::AmenityGraveyard] = createWayStyle("#AACBAF", "#AACBAF", true, false, Qt::SolidPattern, MarbleDirs::path("bitmaps/osmcarto/patterns/grave_yard_generic.png")); m_defaultStyle[GeoDataPlacemark::NaturalWood] = createWayStyle("#8DC46C", "#8DC46C", true, false, Qt::SolidPattern, MarbleDirs::path("bitmaps/osmcarto/patterns/forest.png")); m_defaultStyle[GeoDataPlacemark::NaturalBeach] = createWayStyle("#FFF1BA", "#FFF1BA", true, false, Qt::SolidPattern, MarbleDirs::path("bitmaps/osmcarto/patterns/beach.png")); m_defaultStyle[GeoDataPlacemark::NaturalWetland] = createWayStyle("#DDECEC", "#DDECEC", true, false, Qt::SolidPattern, MarbleDirs::path("bitmaps/osmcarto/patterns/wetland.png")); m_defaultStyle[GeoDataPlacemark::NaturalGlacier] = createWayStyle("#DDECEC", "#DDECEC", true, false, Qt::SolidPattern, MarbleDirs::path("bitmaps/osmcarto/patterns/glacier.png")); m_defaultStyle[GeoDataPlacemark::NaturalIceShelf] = createWayStyle("#8ebebe", "#8ebebe", true, false, Qt::SolidPattern, MarbleDirs::path("bitmaps/osmcarto/patterns/glacier.png")); m_defaultStyle[GeoDataPlacemark::NaturalScrub] = createWayStyle("#B5E3B5", "#B5E3B5", true, false, Qt::SolidPattern, MarbleDirs::path("bitmaps/osmcarto/patterns/scrub.png")); m_defaultStyle[GeoDataPlacemark::NaturalCliff] = createWayStyle(Qt::transparent, Qt::transparent, true, false, Qt::SolidPattern, MarbleDirs::path("bitmaps/osmcarto/patterns/cliff2.png")); m_defaultStyle[GeoDataPlacemark::NaturalCave] = createOsmPOIStyle(osmFont, "amenities/cave", amenityColor); m_defaultStyle[GeoDataPlacemark::NaturalHeath] = createWayStyle("#d6d99f", QColor("#d6d99f").darker(150), true, false); m_defaultStyle[GeoDataPlacemark::LeisureGolfCourse] = createOsmPOIAreaStyle(osmFont, "leisure/golf", "#39ac39", "#b5e3b5", QColor(Qt::transparent)); m_defaultStyle[GeoDataPlacemark::LeisureMinigolfCourse] = createOsmPOIAreaStyle(osmFont, "leisure/miniature_golf", "#39ac39", "#b5e3b5", QColor(Qt::transparent)); m_defaultStyle[GeoDataPlacemark::LeisureMarina] = createOsmPOIStyle(osmFont, QString(), QColor("#95abd5"), QColor("#aec8d1"), QColor("#95abd5").darker(150)); m_defaultStyle[GeoDataPlacemark::LeisurePark] = createWayStyle(QColor("#c8facc"), QColor("#c8facc").darker(150), true, true); m_defaultStyle[GeoDataPlacemark::LeisurePlayground] = createOsmPOIAreaStyle(osmFont, "amenity/playground.16", amenityColor, "#CCFFF1", "#BDFFED"); m_defaultStyle[GeoDataPlacemark::LeisurePitch] = createWayStyle("#8ad3af", QColor("#8ad3af").darker(150), true, true); m_defaultStyle[GeoDataPlacemark::LeisureSportsCentre] = createWayStyle("#33cc99", QColor("#33cc99").darker(150), true, true); m_defaultStyle[GeoDataPlacemark::LeisureStadium] = createWayStyle("#33cc99", QColor("#33cc99").darker(150), true, true); m_defaultStyle[GeoDataPlacemark::LeisureTrack] = createWayStyle("#74dcba", QColor("#74dcba").darker(150), true, true); m_defaultStyle[GeoDataPlacemark::LeisureSwimmingPool] = createWayStyle(waterColor, waterColor.darker(150), true, true); m_defaultStyle[GeoDataPlacemark::LanduseAllotments] = createWayStyle("#E4C6AA", "#E4C6AA", true, false, Qt::SolidPattern, MarbleDirs::path("bitmaps/osmcarto/patterns/allotments.png")); m_defaultStyle[GeoDataPlacemark::LanduseBasin] = createWayStyle(QColor(0xB5, 0xD0, 0xD0, 0x80), QColor(0xB5, 0xD0, 0xD0)); m_defaultStyle[GeoDataPlacemark::LanduseCemetery] = createWayStyle("#AACBAF", "#AACBAF", true, false, Qt::SolidPattern, MarbleDirs::path("bitmaps/osmcarto/patterns/grave_yard_generic.png")); m_defaultStyle[GeoDataPlacemark::LanduseCommercial] = createWayStyle("#F2DAD9", "#D1B2B0", true, true); m_defaultStyle[GeoDataPlacemark::LanduseConstruction] = createWayStyle("#b6b592", "#b6b592", true, false); m_defaultStyle[GeoDataPlacemark::LanduseFarmland] = createWayStyle("#EDDDC9", "#C8B69E", true, true); m_defaultStyle[GeoDataPlacemark::LanduseFarmyard] = createWayStyle("#EFD6B5", "#D1B48C", true, true); m_defaultStyle[GeoDataPlacemark::LanduseGarages] = createWayStyle("#E0DDCD", "#E0DDCD", true, false); m_defaultStyle[GeoDataPlacemark::LanduseGrass] = createWayStyle("#A8C8A5", "#A8C8A5", true, false); m_defaultStyle[GeoDataPlacemark::LanduseIndustrial] = createWayStyle("#DED0D5", "#DED0D5", true, false); m_defaultStyle[GeoDataPlacemark::LanduseLandfill] = createWayStyle("#b6b592", "#b6b592", true, false); m_defaultStyle[GeoDataPlacemark::LanduseMeadow] = createWayStyle("#cdebb0", "#cdebb0", true, false); m_defaultStyle[GeoDataPlacemark::LanduseMilitary] = createWayStyle("#F3D8D2", "#F3D8D2", true, true, Qt::BDiagPattern, MarbleDirs::path("bitmaps/osmcarto/patterns/military_red_hatch.png")); m_defaultStyle[GeoDataPlacemark::LanduseQuarry] = createWayStyle("#C4C2C2", "#C4C2C2", true, false, Qt::SolidPattern, MarbleDirs::path("bitmaps/osmcarto/patterns/quarry.png")); m_defaultStyle[GeoDataPlacemark::LanduseRailway] = createWayStyle("#DED0D5", "#DED0D5", true, false); m_defaultStyle[GeoDataPlacemark::LanduseReservoir] = createWayStyle(waterColor, waterColor, true, false); m_defaultStyle[GeoDataPlacemark::LanduseResidential] = createWayStyle("#DCDCDC", "#DCDCDC", true, false); m_defaultStyle[GeoDataPlacemark::LanduseRetail] = createWayStyle("#FFD6D1", "#D99C95", true, true); m_defaultStyle[GeoDataPlacemark::LanduseOrchard] = createWayStyle("#AEDFA3", "#AEDFA3", true, false, Qt::SolidPattern, MarbleDirs::path("bitmaps/osmcarto/patterns/orchard.png")); m_defaultStyle[GeoDataPlacemark::LanduseVineyard] = createWayStyle("#AEDFA3", "#AEDFA3", true, false, Qt::SolidPattern, MarbleDirs::path("bitmaps/osmcarto/patterns/vineyard.png")); m_defaultStyle[GeoDataPlacemark::MilitaryDangerArea] = createWayStyle("#FFC0CB", "#FFC0CB", true, false, Qt::SolidPattern, MarbleDirs::path("bitmaps/osmcarto/patterns/danger.png")); m_defaultStyle[GeoDataPlacemark::RailwayRail] = createStyle(2.0, 1.435, "#706E70", "#EEEEEE", true, true, Qt::SolidPattern, Qt::CustomDashLine, Qt::FlatCap, true, QVector< qreal >() << 2 << 3, osmFont, QColor(Qt::transparent)); m_defaultStyle[GeoDataPlacemark::RailwayNarrowGauge] = createStyle(2.0, 1.0, "#706E70", "#EEEEEE", true, true, Qt::SolidPattern, Qt::CustomDashLine, Qt::FlatCap, true, QVector< qreal >() << 2 << 3, osmFont, QColor(Qt::transparent)); // FIXME: the tram is currently being rendered as a polygon. m_defaultStyle[GeoDataPlacemark::RailwayTram] = createStyle(2.0, 1.435, "#706E70", "#B7B6B7", false, true, Qt::SolidPattern, Qt::SolidLine, Qt::FlatCap, false, QVector(), osmFont, QColor(Qt::transparent)); m_defaultStyle[GeoDataPlacemark::RailwayLightRail] = createStyle(2.0, 1.435, "#706E70", "#706E70", false, true, Qt::SolidPattern, Qt::SolidLine, Qt::FlatCap, false, QVector(), osmFont, QColor(Qt::transparent)); m_defaultStyle[GeoDataPlacemark::RailwayAbandoned] = createStyle(2.0, 1.435, Qt::transparent, "#706E70", false, false, Qt::SolidPattern, Qt::DotLine, Qt::FlatCap, false, QVector(), osmFont, QColor(Qt::transparent)); m_defaultStyle[GeoDataPlacemark::RailwaySubway] = createStyle(2.0, 1.435, "#706E70", "#EEEEEE", false, true, Qt::SolidPattern, Qt::SolidLine, Qt::FlatCap, false, QVector(), osmFont, QColor(Qt::transparent)); m_defaultStyle[GeoDataPlacemark::RailwayPreserved] = createStyle(2.0, 1.435, "#EEEEEE", "#706E70", true, true, Qt::SolidPattern, Qt::DotLine, Qt::FlatCap, true, QVector(), osmFont, QColor(Qt::transparent)); m_defaultStyle[GeoDataPlacemark::RailwayMiniature] = createStyle(2.0, 1.435, "#706E70", "#EEEEEE", false, true, Qt::SolidPattern, Qt::SolidLine, Qt::FlatCap, false, QVector(), osmFont, QColor(Qt::transparent)); m_defaultStyle[GeoDataPlacemark::RailwayConstruction] = createStyle(2.0, 1.435, "#EEEEEE", "#706E70", true, true, Qt::SolidPattern, Qt::DotLine, Qt::FlatCap, true, QVector(), osmFont, QColor(Qt::transparent)); m_defaultStyle[GeoDataPlacemark::RailwayMonorail] = createStyle(2.0, 1.435, "#706E70", "#EEEEEE", false, true, Qt::SolidPattern, Qt::SolidLine, Qt::FlatCap, false, QVector(), osmFont, QColor(Qt::transparent)); m_defaultStyle[GeoDataPlacemark::RailwayFunicular] = createStyle(2.0, 1.435, "#706E70", "#EEEEEE", false, true, Qt::SolidPattern, Qt::SolidLine, Qt::FlatCap, false, QVector(), osmFont, QColor(Qt::transparent)); m_defaultStyle[GeoDataPlacemark::Landmass] = createWayStyle("#F1EEE8", "#F1EEE8", true, false); m_defaultStyle[GeoDataPlacemark::UrbanArea] = createWayStyle("#E6E3DD", "#E6E3DD", true, false); m_defaultStyle[GeoDataPlacemark::InternationalDateLine] = createStyle(1.0, 0.0, "#000000", "#000000", false, true, Qt::SolidPattern, Qt::SolidLine, Qt::FlatCap, false, QVector(), osmFont); m_defaultStyle[GeoDataPlacemark::Bathymetry] = createWayStyle("#a5c9c9", "#a5c9c9", true, false); m_defaultStyle[GeoDataPlacemark::AerialwayStation] = createOsmPOIStyle(osmFont, "individual/railway_station", transportationColor); m_defaultStyle[GeoDataPlacemark::AerialwayStation]->iconStyle().setScale(0.33f); m_defaultStyle[GeoDataPlacemark::AerialwayPylon] = createOsmPOIStyle(osmFont, "individual/pylon", QColor("#dddddd")); m_defaultStyle[GeoDataPlacemark::AerialwayPylon]->iconStyle().setScale(0.33f); m_defaultStyle[GeoDataPlacemark::AerialwayCableCar] = createIconWayStyle("#bbbbbb", osmFont, transportationColor, 1.0, QStringLiteral("svg/thenounproject/transportation-583813-cable-car.svg")); m_defaultStyle[GeoDataPlacemark::AerialwayGondola] = createIconWayStyle("#bbbbbb", osmFont, transportationColor, 1.0, QStringLiteral("svg/thenounproject/transportation-21636-gondola.svg")); m_defaultStyle[GeoDataPlacemark::AerialwayChairLift] = createIconWayStyle("#bbbbbb", osmFont, transportationColor, 1.0, QStringLiteral("svg/thenounproject/transportation-231-chair-lift.svg")); m_defaultStyle[GeoDataPlacemark::AerialwayMixedLift] = createIconWayStyle("#bbbbbb", osmFont, transportationColor); m_defaultStyle[GeoDataPlacemark::AerialwayDragLift] = createIconWayStyle("#bbbbbb", osmFont, transportationColor, 1.0, QStringLiteral("svg/thenounproject/transportation-8803-platter-lift.svg")); m_defaultStyle[GeoDataPlacemark::AerialwayTBar] = createIconWayStyle("#bbbbbb", osmFont, transportationColor, 1.0, QStringLiteral("svg/thenounproject/transportation-8803-platter-lift.svg")); m_defaultStyle[GeoDataPlacemark::AerialwayJBar] = createIconWayStyle("#bbbbbb", osmFont, transportationColor, 1.0, QStringLiteral("svg/thenounproject/transportation-8803-platter-lift.svg")); m_defaultStyle[GeoDataPlacemark::AerialwayPlatter] = createIconWayStyle("#bbbbbb", osmFont, transportationColor, 1.0, QStringLiteral("svg/thenounproject/transportation-8803-platter-lift.svg")); m_defaultStyle[GeoDataPlacemark::AerialwayRopeTow] = createIconWayStyle("#bbbbbb", osmFont, transportationColor); m_defaultStyle[GeoDataPlacemark::AerialwayMagicCarpet] = createIconWayStyle("#bbbbbb", osmFont, transportationColor); m_defaultStyle[GeoDataPlacemark::AerialwayZipLine] = createIconWayStyle("#bbbbbb", osmFont, transportationColor); m_defaultStyle[GeoDataPlacemark::AerialwayGoods] = createIconWayStyle("#bbbbbb", osmFont, transportationColor); m_defaultStyle[GeoDataPlacemark::PisteDownhill] = createStyle(9, 0.0, "#dddddd", Qt::transparent, true, false, Qt::SolidPattern, Qt::SolidLine, Qt::RoundCap, false, QVector< qreal >(), osmFont, Qt::transparent); m_defaultStyle[GeoDataPlacemark::PisteNordic] = createStyle(3, 0.0, "#fffafa", "#006666", true, false, Qt::SolidPattern, Qt::SolidLine, Qt::RoundCap, false, QVector< qreal >(), osmFont, Qt::transparent, MarbleDirs::path("bitmaps/osmcarto/patterns/ice.png")); m_defaultStyle[GeoDataPlacemark::PisteSkitour] = m_defaultStyle[GeoDataPlacemark::PisteNordic]; m_defaultStyle[GeoDataPlacemark::PisteSled] = m_defaultStyle[GeoDataPlacemark::PisteNordic]; m_defaultStyle[GeoDataPlacemark::PisteHike] = m_defaultStyle[GeoDataPlacemark::PisteNordic]; m_defaultStyle[GeoDataPlacemark::PisteSleigh] = m_defaultStyle[GeoDataPlacemark::PisteNordic]; m_defaultStyle[GeoDataPlacemark::PisteIceSkate] = m_defaultStyle[GeoDataPlacemark::PisteNordic]; m_defaultStyle[GeoDataPlacemark::PisteSnowPark] = m_defaultStyle[GeoDataPlacemark::PisteNordic]; m_defaultStyle[GeoDataPlacemark::PistePlayground] = m_defaultStyle[GeoDataPlacemark::PisteNordic]; m_defaultStyle[GeoDataPlacemark::PisteSkiJump] = createIconWayStyle("#bbbbbb", osmFont, transportationColor, 1.0, QStringLiteral("svg/thenounproject/sports-245-ski-jump.svg")); m_defaultStyle[GeoDataPlacemark::AdminLevel1] = createStyle(0.0, 0.0, "#DF9CCF", "#DF9CCF", false, true, Qt::SolidPattern, Qt::CustomDashLine, Qt::FlatCap, false, QVector< qreal >() << 0.3 << 0.3, osmFont); m_defaultStyle[GeoDataPlacemark::AdminLevel2] = createStyle(2.0, 0.0, "#DF9CCF", "#DF9CCF", false, true, Qt::SolidPattern, Qt::SolidLine, Qt::FlatCap, false, QVector< qreal >() << 0.3 << 0.3, osmFont); m_defaultStyle[GeoDataPlacemark::AdminLevel3] = createStyle(1.8, 0.0, "#DF9CCF", "#DF9CCF", false, true, Qt::SolidPattern, Qt::DashLine, Qt::FlatCap, false, QVector< qreal >() << 0.3 << 0.3, osmFont); m_defaultStyle[GeoDataPlacemark::AdminLevel4] = createStyle(1.5, 0.0, "#DF9CCF", "#DF9CCF", false, true, Qt::SolidPattern, Qt::DotLine, Qt::FlatCap, false, QVector< qreal >() << 0.3 << 0.3, osmFont); m_defaultStyle[GeoDataPlacemark::AdminLevel5] = createStyle(1.25, 0.0, "#DF9CCF", "#DF9CCF", false, true, Qt::SolidPattern, Qt::DashDotDotLine, Qt::FlatCap, false, QVector< qreal >() << 0.3 << 0.3, osmFont); m_defaultStyle[GeoDataPlacemark::AdminLevel6] = createStyle(1, 0.0, "#DF9CCF", "#DF9CCF", false, true, Qt::SolidPattern, Qt::DashDotLine, Qt::FlatCap, false, QVector< qreal >() << 0.3 << 0.3, osmFont); m_defaultStyle[GeoDataPlacemark::AdminLevel7] = createStyle(1, 0.0, "#DF9CCF", "#DF9CCF", false, true, Qt::SolidPattern, Qt::DashLine, Qt::FlatCap, false, QVector< qreal >() << 0.3 << 0.3, osmFont); m_defaultStyle[GeoDataPlacemark::AdminLevel8] = createStyle(1, 0.0, "#DF9CCF", "#DF9CCF", false, true, Qt::SolidPattern, Qt::DashLine, Qt::FlatCap, false, QVector< qreal >() << 0.3 << 0.3, osmFont); m_defaultStyle[GeoDataPlacemark::AdminLevel9] = createStyle(1.5, 0.0, "#DF9CCF", "#DF9CCF", false, true, Qt::SolidPattern, Qt::DotLine, Qt::FlatCap, false, QVector< qreal >() << 0.3 << 0.3, osmFont); m_defaultStyle[GeoDataPlacemark::AdminLevel10] = createStyle(1.5, 0.0, "#DF9CCF", "#DF9CCF", false, true, Qt::SolidPattern, Qt::DotLine, Qt::FlatCap, false, QVector< qreal >() << 0.3 << 0.3, osmFont); m_defaultStyle[GeoDataPlacemark::AdminLevel11] = createStyle(1.5, 0.0, "#DF9CCF", "#DF9CCF", false, true, Qt::SolidPattern, Qt::DotLine, Qt::FlatCap, false, QVector< qreal >() << 0.3 << 0.3, osmFont); m_defaultStyle[GeoDataPlacemark::BoundaryMaritime] = createStyle(2.0, 0.0, "#88b3bf", "#88b3bf", false, true, Qt::SolidPattern, Qt::SolidLine, Qt::FlatCap, false, QVector(), osmFont); m_defaultStyle[GeoDataPlacemark::Satellite] = GeoDataStyle::Ptr(new GeoDataStyle(MarbleDirs::path("bitmaps/satellite.png"), QFont(defaultFamily, defaultSize, 50, false), defaultLabelColor)); QFont tmp; // Fonts for areas ... tmp = m_defaultStyle[GeoDataPlacemark::Continent]->labelStyle().font(); tmp.setLetterSpacing(QFont::AbsoluteSpacing, 2); tmp.setCapitalization(QFont::AllUppercase); tmp.setBold(true); m_defaultStyle[GeoDataPlacemark::Continent]->labelStyle().setFont(tmp); // Fonts for areas ... tmp = m_defaultStyle[GeoDataPlacemark::Mare]->labelStyle().font(); tmp.setLetterSpacing(QFont::AbsoluteSpacing, 2); tmp.setCapitalization(QFont::AllUppercase); tmp.setBold(true); m_defaultStyle[GeoDataPlacemark::Mare]->labelStyle().setFont(tmp); // Now we need to underline the capitals ... tmp = m_defaultStyle[GeoDataPlacemark::SmallNationCapital]->labelStyle().font(); tmp.setUnderline(true); m_defaultStyle[GeoDataPlacemark::SmallNationCapital]->labelStyle().setFont(tmp); tmp = m_defaultStyle[GeoDataPlacemark::MediumNationCapital]->labelStyle().font(); tmp.setUnderline(true); m_defaultStyle[GeoDataPlacemark::MediumNationCapital]->labelStyle().setFont(tmp); tmp = m_defaultStyle[GeoDataPlacemark::BigNationCapital]->labelStyle().font(); tmp.setUnderline(true); m_defaultStyle[GeoDataPlacemark::BigNationCapital]->labelStyle().setFont(tmp); tmp = m_defaultStyle[GeoDataPlacemark::LargeNationCapital]->labelStyle().font(); tmp.setUnderline(true); m_defaultStyle[GeoDataPlacemark::LargeNationCapital]->labelStyle().setFont(tmp); // Buildings m_defaultStyle[GeoDataPlacemark::Building] = createStyle(1, 0, buildingColor, buildingColor.darker(), true, true, Qt::SolidPattern, Qt::SolidLine, Qt::RoundCap, false, QVector(), osmFont); for (int i = 0; i < GeoDataPlacemark::LastIndex; ++i) { if (m_defaultStyle[i] && !m_defaultStyle[i]->iconStyle().iconPath().isEmpty()) { auto const category = GeoDataPlacemark::GeoDataVisualCategory(i); m_buildingStyles[category] = GeoDataStyle::Ptr(new GeoDataStyle(*m_defaultStyle[GeoDataPlacemark::Building])); m_buildingStyles[category]->iconStyle() = m_defaultStyle[i]->iconStyle(); m_buildingStyles[category]->labelStyle() = m_defaultStyle[i]->labelStyle(); } } } QString StyleBuilder::Private::createPaintLayerItem(const QString &itemType, GeoDataPlacemark::GeoDataVisualCategory visualCategory, const QString &subType) { QString const category = visualCategoryName(visualCategory); if (subType.isEmpty()) { return itemType + QLatin1Char('/') + category; } else { return itemType + QLatin1Char('/') + category + QLatin1Char('/') + subType; } } void StyleBuilder::Private::initializeOsmVisualCategories() { // Only initialize the map once if (!s_visualCategories.isEmpty()) { return; } s_visualCategories[OsmTag("admin_level", "1")] = GeoDataPlacemark::AdminLevel1; s_visualCategories[OsmTag("admin_level", "2")] = GeoDataPlacemark::AdminLevel2; s_visualCategories[OsmTag("admin_level", "3")] = GeoDataPlacemark::AdminLevel3; s_visualCategories[OsmTag("admin_level", "4")] = GeoDataPlacemark::AdminLevel4; s_visualCategories[OsmTag("admin_level", "5")] = GeoDataPlacemark::AdminLevel5; s_visualCategories[OsmTag("admin_level", "6")] = GeoDataPlacemark::AdminLevel6; s_visualCategories[OsmTag("admin_level", "7")] = GeoDataPlacemark::AdminLevel7; s_visualCategories[OsmTag("admin_level", "8")] = GeoDataPlacemark::AdminLevel8; s_visualCategories[OsmTag("admin_level", "9")] = GeoDataPlacemark::AdminLevel9; s_visualCategories[OsmTag("admin_level", "10")] = GeoDataPlacemark::AdminLevel10; s_visualCategories[OsmTag("admin_level", "11")] = GeoDataPlacemark::AdminLevel11; s_visualCategories[OsmTag("boundary", "maritime")] = GeoDataPlacemark::BoundaryMaritime; s_visualCategories[OsmTag("amenity", "restaurant")] = GeoDataPlacemark::FoodRestaurant; s_visualCategories[OsmTag("amenity", "fast_food")] = GeoDataPlacemark::FoodFastFood; s_visualCategories[OsmTag("amenity", "pub")] = GeoDataPlacemark::FoodPub; s_visualCategories[OsmTag("amenity", "bar")] = GeoDataPlacemark::FoodBar; s_visualCategories[OsmTag("amenity", "cafe")] = GeoDataPlacemark::FoodCafe; s_visualCategories[OsmTag("amenity", "biergarten")] = GeoDataPlacemark::FoodBiergarten; s_visualCategories[OsmTag("amenity", "college")] = GeoDataPlacemark::EducationCollege; s_visualCategories[OsmTag("amenity", "school")] = GeoDataPlacemark::EducationSchool; s_visualCategories[OsmTag("amenity", "university")] = GeoDataPlacemark::EducationUniversity; s_visualCategories[OsmTag("amenity", "childcare")] = GeoDataPlacemark::AmenityKindergarten; s_visualCategories[OsmTag("amenity", "kindergarten")] = GeoDataPlacemark::AmenityKindergarten; s_visualCategories[OsmTag("amenity", "library")] = GeoDataPlacemark::AmenityLibrary; s_visualCategories[OsmTag("amenity", "bus_station")] = GeoDataPlacemark::TransportBusStation; s_visualCategories[OsmTag("amenity", "car_sharing")] = GeoDataPlacemark::TransportCarShare; s_visualCategories[OsmTag("amenity", "fuel")] = GeoDataPlacemark::TransportFuel; s_visualCategories[OsmTag("amenity", "parking")] = GeoDataPlacemark::TransportParking; s_visualCategories[OsmTag("amenity", "parking_space")] = GeoDataPlacemark::TransportParkingSpace; s_visualCategories[OsmTag("amenity", "atm")] = GeoDataPlacemark::MoneyAtm; s_visualCategories[OsmTag("amenity", "bank")] = GeoDataPlacemark::MoneyBank; s_visualCategories[OsmTag("historic", "archaeological_site")] = GeoDataPlacemark::HistoricArchaeologicalSite; s_visualCategories[OsmTag("historic", "castle")] = GeoDataPlacemark::HistoricCastle; s_visualCategories[OsmTag("historic", "fort")] = GeoDataPlacemark::HistoricCastle; s_visualCategories[OsmTag("historic", "memorial")] = GeoDataPlacemark::HistoricMemorial; s_visualCategories[OsmTag("historic", "monument")] = GeoDataPlacemark::HistoricMonument; s_visualCategories[OsmTag("historic", "ruins")] = GeoDataPlacemark::HistoricRuins; s_visualCategories[OsmTag("amenity", "bench")] = GeoDataPlacemark::AmenityBench; s_visualCategories[OsmTag("amenity", "car_wash")] = GeoDataPlacemark::AmenityCarWash; s_visualCategories[OsmTag("amenity", "charging_station")] = GeoDataPlacemark::AmenityChargingStation; s_visualCategories[OsmTag("amenity", "cinema")] = GeoDataPlacemark::AmenityCinema; s_visualCategories[OsmTag("amenity", "community_centre")] = GeoDataPlacemark::AmenityCommunityCentre; s_visualCategories[OsmTag("amenity", "courthouse")] = GeoDataPlacemark::AmenityCourtHouse; s_visualCategories[OsmTag("amenity", "drinking_water")] = GeoDataPlacemark::AmenityDrinkingWater; s_visualCategories[OsmTag("amenity", "embassy")] = GeoDataPlacemark::AmenityEmbassy; s_visualCategories[OsmTag("amenity", "fire_station")] = GeoDataPlacemark::AmenityFireStation; s_visualCategories[OsmTag("amenity", "fountain")] = GeoDataPlacemark::AmenityFountain; s_visualCategories[OsmTag("amenity", "graveyard")] = GeoDataPlacemark::AmenityGraveyard; s_visualCategories[OsmTag("amenity", "hunting_stand")] = GeoDataPlacemark::AmenityHuntingStand; s_visualCategories[OsmTag("amenity", "nightclub")] = GeoDataPlacemark::AmenityNightClub; s_visualCategories[OsmTag("amenity", "police")] = GeoDataPlacemark::AmenityPolice; s_visualCategories[OsmTag("amenity", "post_box")] = GeoDataPlacemark::AmenityPostBox; s_visualCategories[OsmTag("amenity", "post_office")] = GeoDataPlacemark::AmenityPostOffice; s_visualCategories[OsmTag("amenity", "prison")] = GeoDataPlacemark::AmenityPrison; s_visualCategories[OsmTag("amenity", "recycling")] = GeoDataPlacemark::AmenityRecycling; s_visualCategories[OsmTag("amenity", "shelter")] = GeoDataPlacemark::AmenityShelter; s_visualCategories[OsmTag("amenity", "social_facility")] = GeoDataPlacemark::AmenitySocialFacility; s_visualCategories[OsmTag("amenity", "telephone")] = GeoDataPlacemark::AmenityTelephone; s_visualCategories[OsmTag("amenity", "theatre")] = GeoDataPlacemark::AmenityTheatre; s_visualCategories[OsmTag("amenity", "toilets")] = GeoDataPlacemark::AmenityToilets; s_visualCategories[OsmTag("amenity", "townhall")] = GeoDataPlacemark::AmenityTownHall; s_visualCategories[OsmTag("amenity", "waste_basket")] = GeoDataPlacemark::AmenityWasteBasket; s_visualCategories[OsmTag("emergency", "phone")] = GeoDataPlacemark::AmenityEmergencyPhone; s_visualCategories[OsmTag("amenity", "mountain_rescue")] = GeoDataPlacemark::AmenityMountainRescue; s_visualCategories[OsmTag("amenity", "dentist")] = GeoDataPlacemark::HealthDentist; s_visualCategories[OsmTag("amenity", "doctors")] = GeoDataPlacemark::HealthDoctors; s_visualCategories[OsmTag("amenity", "hospital")] = GeoDataPlacemark::HealthHospital; s_visualCategories[OsmTag("amenity", "pharmacy")] = GeoDataPlacemark::HealthPharmacy; s_visualCategories[OsmTag("amenity", "veterinary")] = GeoDataPlacemark::HealthVeterinary; s_visualCategories[OsmTag("amenity", "place_of_worship")] = GeoDataPlacemark::ReligionPlaceOfWorship; s_visualCategories[OsmTag("tourism", "information")] = GeoDataPlacemark::TourismInformation; s_visualCategories[OsmTag("natural", "cave_entrance")] = GeoDataPlacemark::NaturalCave; s_visualCategories[OsmTag("natural", "peak")] = GeoDataPlacemark::NaturalPeak; s_visualCategories[OsmTag("natural", "tree")] = GeoDataPlacemark::NaturalTree; s_visualCategories[OsmTag("natural", "volcano")] = GeoDataPlacemark::NaturalVolcano; s_visualCategories[OsmTag("shop", "alcohol")] = GeoDataPlacemark::ShopAlcohol; s_visualCategories[OsmTag("shop", "art")] = GeoDataPlacemark::ShopArt; s_visualCategories[OsmTag("shop", "bag")] = GeoDataPlacemark::ShopBag; s_visualCategories[OsmTag("shop", "bakery")] = GeoDataPlacemark::ShopBakery; s_visualCategories[OsmTag("shop", "beauty")] = GeoDataPlacemark::ShopBeauty; s_visualCategories[OsmTag("shop", "beverages")] = GeoDataPlacemark::ShopBeverages; s_visualCategories[OsmTag("shop", "bicycle")] = GeoDataPlacemark::ShopBicycle; s_visualCategories[OsmTag("shop", "books")] = GeoDataPlacemark::ShopBook; s_visualCategories[OsmTag("shop", "butcher")] = GeoDataPlacemark::ShopButcher; s_visualCategories[OsmTag("shop", "car")] = GeoDataPlacemark::ShopCar; s_visualCategories[OsmTag("shop", "car_parts")] = GeoDataPlacemark::ShopCarParts; s_visualCategories[OsmTag("shop", "car_repair")] = GeoDataPlacemark::ShopCarRepair; s_visualCategories[OsmTag("shop", "chemist")] = GeoDataPlacemark::ShopChemist; s_visualCategories[OsmTag("shop", "clothes")] = GeoDataPlacemark::ShopClothes; s_visualCategories[OsmTag("shop", "confectionery")] = GeoDataPlacemark::ShopConfectionery; s_visualCategories[OsmTag("shop", "convenience")] = GeoDataPlacemark::ShopConvenience; s_visualCategories[OsmTag("shop", "copy")] = GeoDataPlacemark::ShopCopy; s_visualCategories[OsmTag("shop", "cosmetics")] = GeoDataPlacemark::ShopCosmetics; s_visualCategories[OsmTag("shop", "deli")] = GeoDataPlacemark::ShopDeli; s_visualCategories[OsmTag("shop", "department_store")] = GeoDataPlacemark::ShopDepartmentStore; s_visualCategories[OsmTag("shop", "doityourself")] = GeoDataPlacemark::ShopDoitYourself; s_visualCategories[OsmTag("shop", "electronics")] = GeoDataPlacemark::ShopElectronics; s_visualCategories[OsmTag("shop", "fashion")] = GeoDataPlacemark::ShopFashion; s_visualCategories[OsmTag("shop", "florist")] = GeoDataPlacemark::ShopFlorist; s_visualCategories[OsmTag("shop", "furniture")] = GeoDataPlacemark::ShopFurniture; s_visualCategories[OsmTag("shop", "gift")] = GeoDataPlacemark::ShopGift; s_visualCategories[OsmTag("shop", "greengrocer")] = GeoDataPlacemark::ShopGreengrocer; s_visualCategories[OsmTag("shop", "hairdresser")] = GeoDataPlacemark::ShopHairdresser; s_visualCategories[OsmTag("shop", "hardware")] = GeoDataPlacemark::ShopHardware; s_visualCategories[OsmTag("shop", "hifi")] = GeoDataPlacemark::ShopHifi; s_visualCategories[OsmTag("shop", "jewelry")] = GeoDataPlacemark::ShopJewelry; s_visualCategories[OsmTag("shop", "kiosk")] = GeoDataPlacemark::ShopKiosk; s_visualCategories[OsmTag("shop", "laundry")] = GeoDataPlacemark::ShopLaundry; s_visualCategories[OsmTag("shop", "mobile_phone")] = GeoDataPlacemark::ShopMobilePhone; s_visualCategories[OsmTag("shop", "motorcycle")] = GeoDataPlacemark::ShopMotorcycle; s_visualCategories[OsmTag("shop", "musical_instrument")] = GeoDataPlacemark::ShopMusicalInstrument; s_visualCategories[OsmTag("shop", "optician")] = GeoDataPlacemark::ShopOptician; s_visualCategories[OsmTag("shop", "outdoor")] = GeoDataPlacemark::ShopOutdoor; s_visualCategories[OsmTag("shop", "perfumery")] = GeoDataPlacemark::ShopPerfumery; s_visualCategories[OsmTag("shop", "pet")] = GeoDataPlacemark::ShopPet; s_visualCategories[OsmTag("shop", "photo")] = GeoDataPlacemark::ShopPhoto; s_visualCategories[OsmTag("shop", "seafood")] = GeoDataPlacemark::ShopSeafood; s_visualCategories[OsmTag("shop", "shoes")] = GeoDataPlacemark::ShopShoes; s_visualCategories[OsmTag("shop", "sports")] = GeoDataPlacemark::ShopSports; s_visualCategories[OsmTag("shop", "stationery")] = GeoDataPlacemark::ShopStationery; s_visualCategories[OsmTag("shop", "supermarket")] = GeoDataPlacemark::ShopSupermarket; s_visualCategories[OsmTag("shop", "tea")] = GeoDataPlacemark::ShopTea; s_visualCategories[OsmTag("shop", "tobacco")] = GeoDataPlacemark::ShopTobacco; s_visualCategories[OsmTag("shop", "toys")] = GeoDataPlacemark::ShopToys; s_visualCategories[OsmTag("shop", "travel_agency")] = GeoDataPlacemark::ShopTravelAgency; s_visualCategories[OsmTag("shop", "variety_store")] = GeoDataPlacemark::ShopVarietyStore; // Default for all other shops foreach (const QString &value, shopValues()) { s_visualCategories[OsmTag("shop", value)] = GeoDataPlacemark::Shop; } s_visualCategories[OsmTag("man_made", "bridge")] = GeoDataPlacemark::ManmadeBridge; s_visualCategories[OsmTag("man_made", "lighthouse")] = GeoDataPlacemark::ManmadeLighthouse; s_visualCategories[OsmTag("man_made", "pier")] = GeoDataPlacemark::ManmadePier; s_visualCategories[OsmTag("man_made", "water_tower")] = GeoDataPlacemark::ManmadeWaterTower; s_visualCategories[OsmTag("man_made", "windmill")] = GeoDataPlacemark::ManmadeWindMill; s_visualCategories[OsmTag("religion", "")] = GeoDataPlacemark::ReligionPlaceOfWorship; s_visualCategories[OsmTag("religion", "bahai")] = GeoDataPlacemark::ReligionBahai; s_visualCategories[OsmTag("religion", "buddhist")] = GeoDataPlacemark::ReligionBuddhist; s_visualCategories[OsmTag("religion", "christian")] = GeoDataPlacemark::ReligionChristian; s_visualCategories[OsmTag("religion", "hindu")] = GeoDataPlacemark::ReligionHindu; s_visualCategories[OsmTag("religion", "jain")] = GeoDataPlacemark::ReligionJain; s_visualCategories[OsmTag("religion", "jewish")] = GeoDataPlacemark::ReligionJewish; s_visualCategories[OsmTag("religion", "muslim")] = GeoDataPlacemark::ReligionMuslim; s_visualCategories[OsmTag("religion", "shinto")] = GeoDataPlacemark::ReligionShinto; s_visualCategories[OsmTag("religion", "sikh")] = GeoDataPlacemark::ReligionSikh; s_visualCategories[OsmTag("tourism", "camp_site")] = GeoDataPlacemark::AccomodationCamping; s_visualCategories[OsmTag("tourism", "guest_house")] = GeoDataPlacemark::AccomodationGuestHouse; s_visualCategories[OsmTag("tourism", "hostel")] = GeoDataPlacemark::AccomodationHostel; s_visualCategories[OsmTag("tourism", "hotel")] = GeoDataPlacemark::AccomodationHotel; s_visualCategories[OsmTag("tourism", "motel")] = GeoDataPlacemark::AccomodationMotel; s_visualCategories[OsmTag("tourism", "alpine_hut")] = GeoDataPlacemark::TourismAlpineHut; s_visualCategories[OsmTag("tourism", "artwork")] = GeoDataPlacemark::TourismArtwork; s_visualCategories[OsmTag("tourism", "attraction")] = GeoDataPlacemark::TourismAttraction; s_visualCategories[OsmTag("tourism", "museum")] = GeoDataPlacemark::TourismMuseum; s_visualCategories[OsmTag("tourism", "theme_park")] = GeoDataPlacemark::TourismThemePark; s_visualCategories[OsmTag("tourism", "viewpoint")] = GeoDataPlacemark::TourismViewPoint; s_visualCategories[OsmTag("tourism", "wilderness_hut")] = GeoDataPlacemark::TourismWildernessHut; s_visualCategories[OsmTag("tourism", "zoo")] = GeoDataPlacemark::TourismZoo; s_visualCategories[OsmTag("barrier", "city_wall")] = GeoDataPlacemark::BarrierCityWall; s_visualCategories[OsmTag("barrier", "gate")] = GeoDataPlacemark::BarrierGate; s_visualCategories[OsmTag("barrier", "lift_gate")] = GeoDataPlacemark::BarrierLiftGate; s_visualCategories[OsmTag("barrier", "wall")] = GeoDataPlacemark::BarrierWall; s_visualCategories[OsmTag("highway", "traffic_signals")] = GeoDataPlacemark::HighwayTrafficSignals; s_visualCategories[OsmTag("highway", "cycleway")] = GeoDataPlacemark::HighwayCycleway; s_visualCategories[OsmTag("highway", "footway")] = GeoDataPlacemark::HighwayFootway; s_visualCategories[OsmTag("highway", "living_street")] = GeoDataPlacemark::HighwayLivingStreet; s_visualCategories[OsmTag("highway", "motorway")] = GeoDataPlacemark::HighwayMotorway; s_visualCategories[OsmTag("highway", "motorway_link")] = GeoDataPlacemark::HighwayMotorwayLink; s_visualCategories[OsmTag("highway", "path")] = GeoDataPlacemark::HighwayPath; s_visualCategories[OsmTag("highway", "pedestrian")] = GeoDataPlacemark::HighwayPedestrian; s_visualCategories[OsmTag("highway", "primary")] = GeoDataPlacemark::HighwayPrimary; s_visualCategories[OsmTag("highway", "primary_link")] = GeoDataPlacemark::HighwayPrimaryLink; s_visualCategories[OsmTag("highway", "raceway")] = GeoDataPlacemark::HighwayRaceway; s_visualCategories[OsmTag("highway", "residential")] = GeoDataPlacemark::HighwayResidential; s_visualCategories[OsmTag("highway", "road")] = GeoDataPlacemark::HighwayRoad; s_visualCategories[OsmTag("highway", "secondary")] = GeoDataPlacemark::HighwaySecondary; s_visualCategories[OsmTag("highway", "secondary_link")] = GeoDataPlacemark::HighwaySecondaryLink; s_visualCategories[OsmTag("highway", "service")] = GeoDataPlacemark::HighwayService; s_visualCategories[OsmTag("highway", "steps")] = GeoDataPlacemark::HighwaySteps; s_visualCategories[OsmTag("highway", "tertiary")] = GeoDataPlacemark::HighwayTertiary; s_visualCategories[OsmTag("highway", "tertiary_link")] = GeoDataPlacemark::HighwayTertiaryLink; s_visualCategories[OsmTag("highway", "track")] = GeoDataPlacemark::HighwayTrack; s_visualCategories[OsmTag("highway", "trunk")] = GeoDataPlacemark::HighwayTrunk; s_visualCategories[OsmTag("highway", "trunk_link")] = GeoDataPlacemark::HighwayTrunkLink; s_visualCategories[OsmTag("highway", "unclassified")] = GeoDataPlacemark::HighwayUnclassified; s_visualCategories[OsmTag("highway", "unknown")] = GeoDataPlacemark::HighwayUnknown; s_visualCategories[OsmTag("highway", "corridor")] = GeoDataPlacemark::HighwayCorridor; s_visualCategories[OsmTag("natural", "bay")] = GeoDataPlacemark::NaturalWater; s_visualCategories[OsmTag("natural", "coastline")] = GeoDataPlacemark::NaturalWater; s_visualCategories[OsmTag("natural", "reef")] = GeoDataPlacemark::NaturalReef; s_visualCategories[OsmTag("natural", "water")] = GeoDataPlacemark::NaturalWater; s_visualCategories[OsmTag("waterway", "canal")] = GeoDataPlacemark::WaterwayCanal; s_visualCategories[OsmTag("waterway", "ditch")] = GeoDataPlacemark::WaterwayDitch; s_visualCategories[OsmTag("waterway", "drain")] = GeoDataPlacemark::WaterwayDrain; s_visualCategories[OsmTag("waterway", "river")] = GeoDataPlacemark::WaterwayRiver; s_visualCategories[OsmTag("waterway", "riverbank")] = GeoDataPlacemark::NaturalWater; s_visualCategories[OsmTag("waterway", "weir")] = GeoDataPlacemark::WaterwayWeir; s_visualCategories[OsmTag("waterway", "stream")] = GeoDataPlacemark::WaterwayStream; s_visualCategories[OsmTag("natural", "beach")] = GeoDataPlacemark::NaturalBeach; s_visualCategories[OsmTag("natural", "cliff")] = GeoDataPlacemark::NaturalCliff; s_visualCategories[OsmTag("natural", "glacier")] = GeoDataPlacemark::NaturalGlacier; s_visualCategories[OsmTag("glacier:type", "shelf")] = GeoDataPlacemark::NaturalIceShelf; s_visualCategories[OsmTag("natural", "scrub")] = GeoDataPlacemark::NaturalScrub; s_visualCategories[OsmTag("natural", "wetland")] = GeoDataPlacemark::NaturalWetland; s_visualCategories[OsmTag("natural", "wood")] = GeoDataPlacemark::NaturalWood; s_visualCategories[OsmTag("military", "danger_area")] = GeoDataPlacemark::MilitaryDangerArea; s_visualCategories[OsmTag("landuse", "allotments")] = GeoDataPlacemark::LanduseAllotments; s_visualCategories[OsmTag("landuse", "basin")] = GeoDataPlacemark::LanduseBasin; s_visualCategories[OsmTag("landuse", "brownfield")] = GeoDataPlacemark::LanduseConstruction; s_visualCategories[OsmTag("landuse", "cemetery")] = GeoDataPlacemark::LanduseCemetery; s_visualCategories[OsmTag("landuse", "commercial")] = GeoDataPlacemark::LanduseCommercial; s_visualCategories[OsmTag("landuse", "construction")] = GeoDataPlacemark::LanduseConstruction; s_visualCategories[OsmTag("landuse", "farm")] = GeoDataPlacemark::LanduseFarmland; s_visualCategories[OsmTag("landuse", "farmland")] = GeoDataPlacemark::LanduseFarmland; s_visualCategories[OsmTag("landuse", "farmyard")] = GeoDataPlacemark::LanduseFarmland; s_visualCategories[OsmTag("landuse", "forest")] = GeoDataPlacemark::NaturalWood; s_visualCategories[OsmTag("landuse", "garages")] = GeoDataPlacemark::LanduseGarages; s_visualCategories[OsmTag("landuse", "grass")] = GeoDataPlacemark::LanduseGrass; s_visualCategories[OsmTag("landuse", "greenfield")] = GeoDataPlacemark::LanduseConstruction; s_visualCategories[OsmTag("landuse", "greenhouse_horticulture")] = GeoDataPlacemark::LanduseFarmland; s_visualCategories[OsmTag("landuse", "industrial")] = GeoDataPlacemark::LanduseIndustrial; s_visualCategories[OsmTag("landuse", "landfill")] = GeoDataPlacemark::LanduseLandfill; s_visualCategories[OsmTag("landuse", "meadow")] = GeoDataPlacemark::LanduseMeadow; s_visualCategories[OsmTag("landuse", "military")] = GeoDataPlacemark::LanduseMilitary; s_visualCategories[OsmTag("landuse", "orchard")] = GeoDataPlacemark::LanduseFarmland; s_visualCategories[OsmTag("landuse", "orchard")] = GeoDataPlacemark::LanduseOrchard; s_visualCategories[OsmTag("landuse", "quarry")] = GeoDataPlacemark::LanduseQuarry; s_visualCategories[OsmTag("landuse", "railway")] = GeoDataPlacemark::LanduseRailway; s_visualCategories[OsmTag("landuse", "recreation_ground")] = GeoDataPlacemark::LeisurePark; s_visualCategories[OsmTag("landuse", "reservoir")] = GeoDataPlacemark::LanduseReservoir; s_visualCategories[OsmTag("landuse", "residential")] = GeoDataPlacemark::LanduseResidential; s_visualCategories[OsmTag("landuse", "retail")] = GeoDataPlacemark::LanduseRetail; s_visualCategories[OsmTag("landuse", "village_green")] = GeoDataPlacemark::LanduseGrass; s_visualCategories[OsmTag("landuse", "vineyard")] = GeoDataPlacemark::LanduseVineyard; s_visualCategories[OsmTag("leisure", "common")] = GeoDataPlacemark::LanduseGrass; s_visualCategories[OsmTag("leisure", "garden")] = GeoDataPlacemark::LanduseGrass; s_visualCategories[OsmTag("leisure", "golf_course")] = GeoDataPlacemark::LeisureGolfCourse; s_visualCategories[OsmTag("leisure", "marina")] = GeoDataPlacemark::LeisureMarina; s_visualCategories[OsmTag("leisure", "miniature_golf")] = GeoDataPlacemark::LeisureMinigolfCourse; s_visualCategories[OsmTag("leisure", "park")] = GeoDataPlacemark::LeisurePark; s_visualCategories[OsmTag("leisure", "pitch")] = GeoDataPlacemark::LeisurePitch; s_visualCategories[OsmTag("leisure", "playground")] = GeoDataPlacemark::LeisurePlayground; s_visualCategories[OsmTag("leisure", "sports_centre")] = GeoDataPlacemark::LeisureSportsCentre; s_visualCategories[OsmTag("leisure", "stadium")] = GeoDataPlacemark::LeisureStadium; s_visualCategories[OsmTag("leisure", "swimming_pool")] = GeoDataPlacemark::LeisureSwimmingPool; s_visualCategories[OsmTag("leisure", "track")] = GeoDataPlacemark::LeisureTrack; s_visualCategories[OsmTag("leisure", "water_park")] = GeoDataPlacemark::LeisureWaterPark; s_visualCategories[OsmTag("railway", "abandoned")] = GeoDataPlacemark::RailwayAbandoned; s_visualCategories[OsmTag("railway", "construction")] = GeoDataPlacemark::RailwayConstruction; s_visualCategories[OsmTag("railway", "disused")] = GeoDataPlacemark::RailwayAbandoned; s_visualCategories[OsmTag("railway", "funicular")] = GeoDataPlacemark::RailwayFunicular; s_visualCategories[OsmTag("railway", "halt")] = GeoDataPlacemark::TransportTrainStation; s_visualCategories[OsmTag("railway", "light_rail")] = GeoDataPlacemark::RailwayLightRail; s_visualCategories[OsmTag("railway", "miniature")] = GeoDataPlacemark::RailwayMiniature; s_visualCategories[OsmTag("railway", "monorail")] = GeoDataPlacemark::RailwayMonorail; s_visualCategories[OsmTag("railway", "narrow_gauge")] = GeoDataPlacemark::RailwayNarrowGauge; s_visualCategories[OsmTag("railway", "platform")] = GeoDataPlacemark::TransportPlatform; s_visualCategories[OsmTag("railway", "preserved")] = GeoDataPlacemark::RailwayPreserved; s_visualCategories[OsmTag("railway", "rail")] = GeoDataPlacemark::RailwayRail; s_visualCategories[OsmTag("railway", "razed")] = GeoDataPlacemark::RailwayAbandoned; s_visualCategories[OsmTag("railway", "station")] = GeoDataPlacemark::TransportTrainStation; s_visualCategories[OsmTag("public_transport", "station")] = GeoDataPlacemark::TransportTrainStation; s_visualCategories[OsmTag("railway", "subway")] = GeoDataPlacemark::RailwaySubway; s_visualCategories[OsmTag("railway", "tram")] = GeoDataPlacemark::RailwayTram; s_visualCategories[OsmTag("power", "tower")] = GeoDataPlacemark::PowerTower; s_visualCategories[OsmTag("aeroway", "aerodrome")] = GeoDataPlacemark::TransportAerodrome; s_visualCategories[OsmTag("aeroway", "apron")] = GeoDataPlacemark::TransportAirportApron; s_visualCategories[OsmTag("aeroway", "gate")] = GeoDataPlacemark::TransportAirportGate; s_visualCategories[OsmTag("aeroway", "helipad")] = GeoDataPlacemark::TransportHelipad; s_visualCategories[OsmTag("aeroway", "runway")] = GeoDataPlacemark::TransportAirportRunway; s_visualCategories[OsmTag("aeroway", "taxiway")] = GeoDataPlacemark::TransportAirportTaxiway; s_visualCategories[OsmTag("aeroway", "terminal")] = GeoDataPlacemark::TransportAirportTerminal; s_visualCategories[OsmTag("piste:type", "downhill")] = GeoDataPlacemark::PisteDownhill; s_visualCategories[OsmTag("piste:type", "nordic")] = GeoDataPlacemark::PisteNordic; s_visualCategories[OsmTag("piste:type", "skitour")] = GeoDataPlacemark::PisteSkitour; s_visualCategories[OsmTag("piste:type", "sled")] = GeoDataPlacemark::PisteSled; s_visualCategories[OsmTag("piste:type", "hike")] = GeoDataPlacemark::PisteHike; s_visualCategories[OsmTag("piste:type", "sleigh")] = GeoDataPlacemark::PisteSleigh; s_visualCategories[OsmTag("piste:type", "ice_skate")] = GeoDataPlacemark::PisteIceSkate; s_visualCategories[OsmTag("piste:type", "snow_park")] = GeoDataPlacemark::PisteSnowPark; s_visualCategories[OsmTag("piste:type", "playground")] = GeoDataPlacemark::PistePlayground; s_visualCategories[OsmTag("piste:type", "ski_jump")] = GeoDataPlacemark::PisteSkiJump; s_visualCategories[OsmTag("amenity", "bicycle_parking")] = GeoDataPlacemark::TransportBicycleParking; s_visualCategories[OsmTag("amenity", "bicycle_rental")] = GeoDataPlacemark::TransportRentalBicycle; s_visualCategories[OsmTag("rental", "bicycle")] = GeoDataPlacemark::TransportRentalBicycle; s_visualCategories[OsmTag("amenity", "car_rental")] = GeoDataPlacemark::TransportRentalCar; s_visualCategories[OsmTag("rental", "car")] = GeoDataPlacemark::TransportRentalCar; s_visualCategories[OsmTag("amenity", "ski_rental")] = GeoDataPlacemark::TransportRentalSki; s_visualCategories[OsmTag("rental", "ski")] = GeoDataPlacemark::TransportRentalSki; s_visualCategories[OsmTag("amenity", "motorcycle_parking")] = GeoDataPlacemark::TransportMotorcycleParking; s_visualCategories[OsmTag("amenity", "taxi")] = GeoDataPlacemark::TransportTaxiRank; s_visualCategories[OsmTag("highway", "bus_stop")] = GeoDataPlacemark::TransportBusStop; s_visualCategories[OsmTag("highway", "speed_camera")] = GeoDataPlacemark::TransportSpeedCamera; s_visualCategories[OsmTag("public_transport", "platform")] = GeoDataPlacemark::TransportPlatform; s_visualCategories[OsmTag("railway", "subway_entrance")] = GeoDataPlacemark::TransportSubwayEntrance; s_visualCategories[OsmTag("railway", "tram_stop")] = GeoDataPlacemark::TransportTramStop; s_visualCategories[OsmTag("place", "city")] = GeoDataPlacemark::PlaceCity; s_visualCategories[OsmTag("place", "hamlet")] = GeoDataPlacemark::PlaceHamlet; s_visualCategories[OsmTag("place", "locality")] = GeoDataPlacemark::PlaceLocality; s_visualCategories[OsmTag("place", "suburb")] = GeoDataPlacemark::PlaceSuburb; s_visualCategories[OsmTag("place", "town")] = GeoDataPlacemark::PlaceTown; s_visualCategories[OsmTag("place", "village")] = GeoDataPlacemark::PlaceVillage; s_visualCategories[OsmTag("aerialway", "station")] = GeoDataPlacemark::AerialwayStation; s_visualCategories[OsmTag("aerialway", "pylon")] = GeoDataPlacemark::AerialwayPylon; s_visualCategories[OsmTag("aerialway", "cable_car")] = GeoDataPlacemark::AerialwayCableCar; s_visualCategories[OsmTag("aerialway", "gondola")] = GeoDataPlacemark::AerialwayGondola; s_visualCategories[OsmTag("aerialway", "chair_lift")] = GeoDataPlacemark::AerialwayChairLift; s_visualCategories[OsmTag("aerialway", "mixed_lift")] = GeoDataPlacemark::AerialwayMixedLift; s_visualCategories[OsmTag("aerialway", "drag_lift")] = GeoDataPlacemark::AerialwayDragLift; s_visualCategories[OsmTag("aerialway", "t-bar")] = GeoDataPlacemark::AerialwayTBar; s_visualCategories[OsmTag("aerialway", "j-bar")] = GeoDataPlacemark::AerialwayJBar; s_visualCategories[OsmTag("aerialway", "platter")] = GeoDataPlacemark::AerialwayPlatter; s_visualCategories[OsmTag("aerialway", "rope_tow")] = GeoDataPlacemark::AerialwayRopeTow; s_visualCategories[OsmTag("aerialway", "magic_carpet")] = GeoDataPlacemark::AerialwayMagicCarpet; s_visualCategories[OsmTag("aerialway", "zip_line")] = GeoDataPlacemark::AerialwayZipLine; s_visualCategories[OsmTag("aerialway", "goods")] = GeoDataPlacemark::AerialwayGoods; //Custom Marble OSM Tags s_visualCategories[OsmTag("marble_land", "landmass")] = GeoDataPlacemark::Landmass; s_visualCategories[OsmTag("settlement", "yes")] = GeoDataPlacemark::UrbanArea; s_visualCategories[OsmTag("marble_line", "date")] = GeoDataPlacemark::InternationalDateLine; s_visualCategories[OsmTag("marble:feature", "bathymetry")] = GeoDataPlacemark::Bathymetry; // Default for buildings foreach (const auto &tag, buildingTags()) { s_visualCategories[tag] = GeoDataPlacemark::Building; } } void StyleBuilder::Private::initializeMinimumZoomLevels() { if (s_defaultMinZoomLevelsInitialized) { return; } s_defaultMinZoomLevelsInitialized = true; for (int i = 0; i < GeoDataPlacemark::LastIndex; i++) { s_defaultMinZoomLevels[i] = -1; } s_defaultMinZoomLevels[GeoDataPlacemark::AdminLevel10] = 8; s_defaultMinZoomLevels[GeoDataPlacemark::AdminLevel11] = 8; s_defaultMinZoomLevels[GeoDataPlacemark::AdminLevel1] = 0; s_defaultMinZoomLevels[GeoDataPlacemark::AdminLevel2] = 1; s_defaultMinZoomLevels[GeoDataPlacemark::AdminLevel3] = 1; s_defaultMinZoomLevels[GeoDataPlacemark::AdminLevel4] = 2; s_defaultMinZoomLevels[GeoDataPlacemark::AdminLevel5] = 4; s_defaultMinZoomLevels[GeoDataPlacemark::AdminLevel6] = 5; s_defaultMinZoomLevels[GeoDataPlacemark::AdminLevel7] = 5; s_defaultMinZoomLevels[GeoDataPlacemark::AdminLevel8] = 7; s_defaultMinZoomLevels[GeoDataPlacemark::AdminLevel9] = 7; s_defaultMinZoomLevels[GeoDataPlacemark::HistoricArchaeologicalSite] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::AmenityBench] = 19; s_defaultMinZoomLevels[GeoDataPlacemark::AmenityFountain] = 17; s_defaultMinZoomLevels[GeoDataPlacemark::AmenityGraveyard] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::AmenityTelephone] = 17; s_defaultMinZoomLevels[GeoDataPlacemark::AmenityKindergarten] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::AmenityLibrary] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::AmenityWasteBasket] = 19; s_defaultMinZoomLevels[GeoDataPlacemark::AmenityToilets] = 17; s_defaultMinZoomLevels[GeoDataPlacemark::AmenityTownHall] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::LeisureWaterPark] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::AmenityDrinkingWater] = 17; s_defaultMinZoomLevels[GeoDataPlacemark::AmenityEmbassy] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::AmenityEmergencyPhone] = 17; s_defaultMinZoomLevels[GeoDataPlacemark::AmenityMountainRescue] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::AmenityCommunityCentre] = 17; s_defaultMinZoomLevels[GeoDataPlacemark::AmenityFountain] = 17; s_defaultMinZoomLevels[GeoDataPlacemark::AmenityNightClub] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::AmenityCourtHouse] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::AmenityFireStation] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::AmenityHuntingStand] = 17; s_defaultMinZoomLevels[GeoDataPlacemark::AmenityPolice] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::AmenityPostBox] = 17; s_defaultMinZoomLevels[GeoDataPlacemark::AmenityPostOffice] = 17; s_defaultMinZoomLevels[GeoDataPlacemark::AmenityPrison] = 17; s_defaultMinZoomLevels[GeoDataPlacemark::AmenityRecycling] = 17; s_defaultMinZoomLevels[GeoDataPlacemark::AmenityShelter] = 17; s_defaultMinZoomLevels[GeoDataPlacemark::AmenityChargingStation] = 17; s_defaultMinZoomLevels[GeoDataPlacemark::AmenityCarWash] = 17; s_defaultMinZoomLevels[GeoDataPlacemark::AmenitySocialFacility] = 17; s_defaultMinZoomLevels[GeoDataPlacemark::BarrierCityWall] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::BarrierGate] = 17; s_defaultMinZoomLevels[GeoDataPlacemark::BarrierLiftGate] = 17; s_defaultMinZoomLevels[GeoDataPlacemark::BarrierWall] = 17; s_defaultMinZoomLevels[GeoDataPlacemark::Bathymetry] = 1; s_defaultMinZoomLevels[GeoDataPlacemark::BoundaryMaritime] = 1; s_defaultMinZoomLevels[GeoDataPlacemark::Building] = 17; s_defaultMinZoomLevels[GeoDataPlacemark::Default] = 1; s_defaultMinZoomLevels[GeoDataPlacemark::EducationCollege] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::EducationSchool] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::EducationUniversity] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::FoodBar] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::FoodBiergarten] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::FoodCafe] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::FoodFastFood] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::FoodPub] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::FoodRestaurant] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::HealthHospital] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::HealthPharmacy] = 17; s_defaultMinZoomLevels[GeoDataPlacemark::HealthDentist] = 17; s_defaultMinZoomLevels[GeoDataPlacemark::HealthDoctors] = 17; s_defaultMinZoomLevels[GeoDataPlacemark::HealthVeterinary] = 17; s_defaultMinZoomLevels[GeoDataPlacemark::HistoricMemorial] = 17; s_defaultMinZoomLevels[GeoDataPlacemark::HighwayCycleway] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::HighwayFootway] = 17; s_defaultMinZoomLevels[GeoDataPlacemark::HighwayLivingStreet] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::HighwayMotorwayLink] = 10; s_defaultMinZoomLevels[GeoDataPlacemark::HighwayMotorway] = 6; s_defaultMinZoomLevels[GeoDataPlacemark::HighwayPath] = 13; s_defaultMinZoomLevels[GeoDataPlacemark::HighwayPedestrian] = 13; s_defaultMinZoomLevels[GeoDataPlacemark::HighwayPrimaryLink] = 10; s_defaultMinZoomLevels[GeoDataPlacemark::HighwayPrimary] = 8; s_defaultMinZoomLevels[GeoDataPlacemark::HighwayRaceway] = 12; s_defaultMinZoomLevels[GeoDataPlacemark::HighwayResidential] = 14; s_defaultMinZoomLevels[GeoDataPlacemark::HighwayRoad] = 13; s_defaultMinZoomLevels[GeoDataPlacemark::HighwaySecondaryLink] = 10; s_defaultMinZoomLevels[GeoDataPlacemark::HighwaySecondary] = 9; s_defaultMinZoomLevels[GeoDataPlacemark::HighwayService] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::HighwaySteps] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::HighwayTertiaryLink] = 10; s_defaultMinZoomLevels[GeoDataPlacemark::HighwayTertiary] = 10; s_defaultMinZoomLevels[GeoDataPlacemark::HighwayTrack] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::HighwayTrunkLink] = 10; s_defaultMinZoomLevels[GeoDataPlacemark::HighwayTrunk] = 7; s_defaultMinZoomLevels[GeoDataPlacemark::HighwayUnknown] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::HighwayUnclassified] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::HighwayTrafficSignals] = 17; s_defaultMinZoomLevels[GeoDataPlacemark::HighwayCorridor] = 18; s_defaultMinZoomLevels[GeoDataPlacemark::AccomodationCamping] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::AccomodationHostel] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::AccomodationHotel] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::AccomodationMotel] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::AccomodationYouthHostel] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::AccomodationGuestHouse] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::InternationalDateLine] = 1; s_defaultMinZoomLevels[GeoDataPlacemark::Landmass] = 0; s_defaultMinZoomLevels[GeoDataPlacemark::LanduseAllotments] = 11; s_defaultMinZoomLevels[GeoDataPlacemark::LanduseBasin] = 11; s_defaultMinZoomLevels[GeoDataPlacemark::LanduseCemetery] = 11; s_defaultMinZoomLevels[GeoDataPlacemark::LanduseCommercial] = 13; s_defaultMinZoomLevels[GeoDataPlacemark::LanduseConstruction] = 11; s_defaultMinZoomLevels[GeoDataPlacemark::LanduseFarmland] = 13; s_defaultMinZoomLevels[GeoDataPlacemark::LanduseFarmyard] = 13; s_defaultMinZoomLevels[GeoDataPlacemark::LanduseGarages] = 11; s_defaultMinZoomLevels[GeoDataPlacemark::LanduseGrass] = 13; s_defaultMinZoomLevels[GeoDataPlacemark::LanduseIndustrial] = 13; s_defaultMinZoomLevels[GeoDataPlacemark::LanduseLandfill] = 11; s_defaultMinZoomLevels[GeoDataPlacemark::LanduseMeadow] = 13; s_defaultMinZoomLevels[GeoDataPlacemark::LanduseMilitary] = 11; s_defaultMinZoomLevels[GeoDataPlacemark::LanduseOrchard] = 14; s_defaultMinZoomLevels[GeoDataPlacemark::LanduseQuarry] = 11; s_defaultMinZoomLevels[GeoDataPlacemark::LanduseRailway] = 11; s_defaultMinZoomLevels[GeoDataPlacemark::LanduseReservoir] = 11; s_defaultMinZoomLevels[GeoDataPlacemark::LanduseResidential] = 11; s_defaultMinZoomLevels[GeoDataPlacemark::LanduseRetail] = 13; s_defaultMinZoomLevels[GeoDataPlacemark::LanduseVineyard] = 14; s_defaultMinZoomLevels[GeoDataPlacemark::LeisureGolfCourse] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::LeisureMarina] = 13; s_defaultMinZoomLevels[GeoDataPlacemark::LeisurePark] = 11; s_defaultMinZoomLevels[GeoDataPlacemark::LeisurePlayground] = 17; s_defaultMinZoomLevels[GeoDataPlacemark::LeisurePitch] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::LeisureStadium] = 13; s_defaultMinZoomLevels[GeoDataPlacemark::LeisureSwimmingPool] = 17; s_defaultMinZoomLevels[GeoDataPlacemark::LeisureSportsCentre] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::LeisureTrack] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::LeisureMinigolfCourse] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::ManmadeBridge] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::ManmadeLighthouse] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::ManmadePier] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::ManmadeWaterTower] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::ManmadeWindMill] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::MilitaryDangerArea] = 11; s_defaultMinZoomLevels[GeoDataPlacemark::MoneyAtm] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::MoneyBank] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::NaturalBeach] = 13; s_defaultMinZoomLevels[GeoDataPlacemark::NaturalCliff] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::NaturalGlacier] = 3; s_defaultMinZoomLevels[GeoDataPlacemark::NaturalHeath] = 13; s_defaultMinZoomLevels[GeoDataPlacemark::NaturalIceShelf] = 3; s_defaultMinZoomLevels[GeoDataPlacemark::NaturalVolcano] = 13; s_defaultMinZoomLevels[GeoDataPlacemark::NaturalPeak] = 11; s_defaultMinZoomLevels[GeoDataPlacemark::NaturalReef] = 3; s_defaultMinZoomLevels[GeoDataPlacemark::NaturalScrub] = 13; s_defaultMinZoomLevels[GeoDataPlacemark::NaturalTree] = 17; s_defaultMinZoomLevels[GeoDataPlacemark::NaturalCave] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::NaturalWater] = 3; s_defaultMinZoomLevels[GeoDataPlacemark::NaturalWetland] = 10; s_defaultMinZoomLevels[GeoDataPlacemark::NaturalWood] = 8; s_defaultMinZoomLevels[GeoDataPlacemark::PlaceCityNationalCapital] = 9; s_defaultMinZoomLevels[GeoDataPlacemark::PlaceCityCapital] = 9; s_defaultMinZoomLevels[GeoDataPlacemark::PlaceCity] = 9; s_defaultMinZoomLevels[GeoDataPlacemark::PlaceHamlet] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::PlaceLocality] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::PlaceSuburb] = 13; s_defaultMinZoomLevels[GeoDataPlacemark::PlaceTownNationalCapital] = 11; s_defaultMinZoomLevels[GeoDataPlacemark::PlaceTownCapital] = 11; s_defaultMinZoomLevels[GeoDataPlacemark::PlaceTown] = 11; s_defaultMinZoomLevels[GeoDataPlacemark::PlaceVillageNationalCapital] = 13; s_defaultMinZoomLevels[GeoDataPlacemark::PlaceVillageCapital] = 13; s_defaultMinZoomLevels[GeoDataPlacemark::PlaceVillage] = 13; s_defaultMinZoomLevels[GeoDataPlacemark::PowerTower] = 18; s_defaultMinZoomLevels[GeoDataPlacemark::RailwayAbandoned] = 10; s_defaultMinZoomLevels[GeoDataPlacemark::RailwayConstruction] = 10; s_defaultMinZoomLevels[GeoDataPlacemark::RailwayFunicular] = 13; s_defaultMinZoomLevels[GeoDataPlacemark::RailwayLightRail] = 12; s_defaultMinZoomLevels[GeoDataPlacemark::RailwayMiniature] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::RailwayMonorail] = 12; s_defaultMinZoomLevels[GeoDataPlacemark::RailwayNarrowGauge] = 6; s_defaultMinZoomLevels[GeoDataPlacemark::RailwayPreserved] = 13; s_defaultMinZoomLevels[GeoDataPlacemark::RailwayRail] = 6; s_defaultMinZoomLevels[GeoDataPlacemark::RailwaySubway] = 13; s_defaultMinZoomLevels[GeoDataPlacemark::RailwayTram] = 14; s_defaultMinZoomLevels[GeoDataPlacemark::Satellite] = 0; for (int shop = GeoDataPlacemark::ShopBeverages; shop <= GeoDataPlacemark::Shop; ++shop) { s_defaultMinZoomLevels[shop] = 17; } s_defaultMinZoomLevels[GeoDataPlacemark::ShopSupermarket] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::ShopDepartmentStore] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::ShopDoitYourself] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::TourismAlpineHut] = 13; s_defaultMinZoomLevels[GeoDataPlacemark::TourismWildernessHut] = 13; s_defaultMinZoomLevels[GeoDataPlacemark::TourismAttraction] = 17; s_defaultMinZoomLevels[GeoDataPlacemark::TourismArtwork] = 17; s_defaultMinZoomLevels[GeoDataPlacemark::HistoricCastle] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::AmenityCinema] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::TourismMuseum] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::HistoricRuins] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::AmenityTheatre] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::TourismThemePark] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::TourismViewPoint] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::TourismZoo] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::HistoricMonument] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::TourismInformation] = 17; s_defaultMinZoomLevels[GeoDataPlacemark::TransportAerodrome] = 9; s_defaultMinZoomLevels[GeoDataPlacemark::TransportAirportApron] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::TransportAirportRunway] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::TransportAirportTaxiway] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::TransportBusStation] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::TransportCarShare] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::TransportFuel] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::TransportHelipad] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::TransportAirportTerminal] = 17; s_defaultMinZoomLevels[GeoDataPlacemark::TransportAirportGate] = 17; s_defaultMinZoomLevels[GeoDataPlacemark::TransportPlatform] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::TransportSpeedCamera] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::TransportRentalCar] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::TransportRentalBicycle] = 17; s_defaultMinZoomLevels[GeoDataPlacemark::TransportRentalSki] = 17; s_defaultMinZoomLevels[GeoDataPlacemark::TransportTaxiRank] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::TransportParking] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::TransportBusStop] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::TransportTrainStation] = 13; s_defaultMinZoomLevels[GeoDataPlacemark::TransportTramStop] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::TransportParkingSpace] = 17; s_defaultMinZoomLevels[GeoDataPlacemark::TransportBicycleParking] = 17; s_defaultMinZoomLevels[GeoDataPlacemark::TransportMotorcycleParking] = 17; s_defaultMinZoomLevels[GeoDataPlacemark::TransportSubwayEntrance] = 17; for (int religion = GeoDataPlacemark::ReligionPlaceOfWorship; religion <= GeoDataPlacemark::ReligionSikh; ++religion) { s_defaultMinZoomLevels[religion] = 17; } s_defaultMinZoomLevels[GeoDataPlacemark::UrbanArea] = 3; s_defaultMinZoomLevels[GeoDataPlacemark::WaterwayCanal] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::WaterwayDitch] = 17; s_defaultMinZoomLevels[GeoDataPlacemark::WaterwayDrain] = 17; s_defaultMinZoomLevels[GeoDataPlacemark::WaterwayStream] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::WaterwayRiver] = 3; s_defaultMinZoomLevels[GeoDataPlacemark::WaterwayWeir] = 17; s_defaultMinZoomLevels[GeoDataPlacemark::CrossingIsland] = 18; s_defaultMinZoomLevels[GeoDataPlacemark::CrossingRailway] = 18; s_defaultMinZoomLevels[GeoDataPlacemark::CrossingSignals] = 18; s_defaultMinZoomLevels[GeoDataPlacemark::CrossingZebra] = 18; s_defaultMinZoomLevels[GeoDataPlacemark::PisteDownhill] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::PisteNordic] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::PisteSkitour] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::PisteSled] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::PisteHike] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::PisteSleigh] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::PisteIceSkate] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::PisteSnowPark] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::PistePlayground] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::PisteSkiJump] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::AerialwayStation] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::AerialwayPylon] = 16; s_defaultMinZoomLevels[GeoDataPlacemark::AerialwayCableCar] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::AerialwayGondola] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::AerialwayChairLift] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::AerialwayMixedLift] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::AerialwayDragLift] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::AerialwayTBar] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::AerialwayJBar] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::AerialwayPlatter] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::AerialwayRopeTow] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::AerialwayMagicCarpet] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::AerialwayZipLine] = 15; s_defaultMinZoomLevels[GeoDataPlacemark::AerialwayGoods] = 15; for (int i = GeoDataPlacemark::PlaceCity; i < GeoDataPlacemark::LastIndex; i++) { if (s_defaultMinZoomLevels[i] < 0) { qDebug() << "Missing default min zoom level for GeoDataPlacemark::GeoDataVisualCategory " << i; Q_ASSERT(false && "StyleBuilder::Private::initializeMinimumZoomLevels is incomplete"); s_defaultMinZoomLevels[i] = 15; } } } StyleBuilder::StyleBuilder() : d(new Private) { // nothing to do } StyleBuilder::~StyleBuilder() { delete d; } QFont StyleBuilder::defaultFont() const { return d->m_defaultFont; } void StyleBuilder::setDefaultFont(const QFont& font) { d->m_defaultFont = font; reset(); } QColor StyleBuilder::defaultLabelColor() const { return d->m_defaultLabelColor; } void StyleBuilder::setDefaultLabelColor(const QColor& color) { d->m_defaultLabelColor = color; reset(); } GeoDataStyle::ConstPtr StyleBuilder::createStyle(const StyleParameters ¶meters) const { const GeoDataPlacemark *const placemark = parameters.placemark; if (!placemark) { Q_ASSERT(false && "Must not pass a null placemark to StyleBuilder::createStyle"); return GeoDataStyle::Ptr(); } if (placemark->customStyle()) { return placemark->customStyle(); } if (parameters.relation) { auto style = d->createRelationStyle(parameters); if (style) { return style; } } return d->createPlacemarkStyle(parameters); } GeoDataStyle::ConstPtr StyleBuilder::Private::presetStyle(GeoDataPlacemark::GeoDataVisualCategory visualCategory) const { if (!m_defaultStyleInitialized) { const_cast(this)->initializeDefaultStyles(); // const cast due to lazy initialization } if (visualCategory != GeoDataPlacemark::None && m_defaultStyle[visualCategory]) { return m_defaultStyle[visualCategory]; } else { return m_defaultStyle[GeoDataPlacemark::Default]; } } QStringList StyleBuilder::renderOrder() const { static QStringList paintLayerOrder; if (paintLayerOrder.isEmpty()) { paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::Landmass); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::UrbanArea); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LanduseResidential); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LanduseAllotments); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LanduseBasin); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LanduseCemetery); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LanduseCommercial); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LanduseConstruction); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LanduseFarmland); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LanduseFarmyard); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LanduseGarages); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LanduseIndustrial); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LanduseLandfill); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LanduseMeadow); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LanduseMilitary); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LanduseQuarry); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LanduseRailway); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LanduseReservoir); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LanduseRetail); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LanduseOrchard); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LanduseVineyard); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::Bathymetry); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LeisureGolfCourse); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LeisureMinigolfCourse); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::NaturalBeach); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::NaturalWetland); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::NaturalGlacier); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::NaturalIceShelf); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::NaturalVolcano); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::NaturalCliff); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::NaturalPeak); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::MilitaryDangerArea); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LeisurePark); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LeisurePitch); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LeisureSportsCentre); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LeisureStadium); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::NaturalWood); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LanduseGrass); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::HighwayPedestrian); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LeisurePlayground); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::NaturalScrub); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LeisureTrack); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::TransportParking); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::TransportParkingSpace); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::ManmadeBridge); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::BarrierCityWall); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::AmenityGraveyard); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::AmenityKindergarten); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::EducationCollege); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::EducationSchool); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::EducationUniversity); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::HealthHospital); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LeisureSwimmingPool); paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::Landmass); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::NaturalWater); for (int i = GeoDataPlacemark::WaterwayCanal; i <= GeoDataPlacemark::WaterwayStream; ++i) { paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::GeoDataVisualCategory(i), "outline"); paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::GeoDataVisualCategory(i), "inline"); paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::GeoDataVisualCategory(i), "label"); } paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::NaturalReef, "outline"); paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::NaturalReef, "inline"); paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::NaturalReef, "label"); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::LeisureMarina); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::ManmadePier); paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::ManmadePier, "outline"); paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::ManmadePier, "inline"); paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::ManmadePier, "label"); paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::TransportAirportApron); for (int i = GeoDataPlacemark::HighwaySteps; i <= GeoDataPlacemark::HighwayMotorway; i++) { paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::GeoDataVisualCategory(i), "outline"); } for (int i = GeoDataPlacemark::HighwaySteps; i <= GeoDataPlacemark::HighwayMotorway; i++) { paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::GeoDataVisualCategory(i), "inline"); } for (int i = GeoDataPlacemark::RailwayRail; i <= GeoDataPlacemark::RailwayFunicular; i++) { paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::GeoDataVisualCategory(i), "outline"); } for (int i = GeoDataPlacemark::RailwayRail; i <= GeoDataPlacemark::RailwayFunicular; i++) { paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::GeoDataVisualCategory(i), "inline"); } // Highway labels shall appear on top of railways, hence here and not already above for (int i = GeoDataPlacemark::HighwaySteps; i <= GeoDataPlacemark::HighwayMotorway; i++) { paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::GeoDataVisualCategory(i), "label"); } for (int i = GeoDataPlacemark::RailwayRail; i <= GeoDataPlacemark::RailwayFunicular; i++) { paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::GeoDataVisualCategory(i), "label"); } paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::TransportPlatform); paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::TransportPlatform, "outline"); paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::TransportPlatform, "inline"); paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::TransportPlatform, "label"); for (int i = GeoDataPlacemark::PisteDownhill; i <= GeoDataPlacemark::PisteSkiJump; ++i) { paintLayerOrder << Private::createPaintLayerItem("Polygon", GeoDataPlacemark::GeoDataVisualCategory(i)); paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::GeoDataVisualCategory(i), "outline"); paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::GeoDataVisualCategory(i), "inline"); paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::GeoDataVisualCategory(i), "label"); } for (int i = GeoDataPlacemark::AerialwayCableCar; i <= GeoDataPlacemark::AerialwayGoods; ++i) { paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::GeoDataVisualCategory(i), "outline"); paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::GeoDataVisualCategory(i), "inline"); paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::GeoDataVisualCategory(i), "label"); } for (int i = GeoDataPlacemark::AdminLevel1; i <= GeoDataPlacemark::AdminLevel11; i++) { paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::GeoDataVisualCategory(i), "outline"); } for (int i = GeoDataPlacemark::AdminLevel1; i <= GeoDataPlacemark::AdminLevel11; i++) { paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::GeoDataVisualCategory(i), "inline"); } for (int i = GeoDataPlacemark::AdminLevel1; i <= GeoDataPlacemark::AdminLevel11; i++) { paintLayerOrder << Private::createPaintLayerItem("LineString", GeoDataPlacemark::GeoDataVisualCategory(i), "label"); } paintLayerOrder << QStringLiteral("Polygon/Building/frame"); paintLayerOrder << QStringLiteral("Polygon/Building/roof"); paintLayerOrder << QStringLiteral("Photo"); Q_ASSERT(QSet::fromList(paintLayerOrder).size() == paintLayerOrder.size()); } return paintLayerOrder; } void StyleBuilder::reset() { d->m_defaultStyleInitialized = false; } int StyleBuilder::minimumZoomLevel(const GeoDataPlacemark &placemark) const { Q_ASSERT(Private::s_defaultMinZoomLevelsInitialized); return Private::s_defaultMinZoomLevels[placemark.visualCategory()]; } int StyleBuilder::minimumZoomLevel(const GeoDataPlacemark::GeoDataVisualCategory &visualCategory) { Private::initializeMinimumZoomLevels(); return Private::s_defaultMinZoomLevels[visualCategory]; } qint64 StyleBuilder::popularity(const GeoDataPlacemark *placemark) { qint64 const defaultValue = 100; int const offset = 10; if (StyleBuilder::Private::s_popularities.isEmpty()) { QVector popularities; popularities << GeoDataPlacemark::PlaceCityNationalCapital; popularities << GeoDataPlacemark::PlaceTownNationalCapital; popularities << GeoDataPlacemark::PlaceCityCapital; popularities << GeoDataPlacemark::PlaceTownCapital; popularities << GeoDataPlacemark::PlaceCity; popularities << GeoDataPlacemark::PlaceTown; popularities << GeoDataPlacemark::PlaceSuburb; popularities << GeoDataPlacemark::PlaceVillageNationalCapital; popularities << GeoDataPlacemark::PlaceVillageCapital; popularities << GeoDataPlacemark::PlaceVillage; popularities << GeoDataPlacemark::PlaceHamlet; popularities << GeoDataPlacemark::PlaceLocality; popularities << GeoDataPlacemark::AmenityEmergencyPhone; popularities << GeoDataPlacemark::AmenityMountainRescue; popularities << GeoDataPlacemark::HealthHospital; popularities << GeoDataPlacemark::AmenityToilets; popularities << GeoDataPlacemark::MoneyAtm; popularities << GeoDataPlacemark::TransportSpeedCamera; popularities << GeoDataPlacemark::NaturalPeak; popularities << GeoDataPlacemark::NaturalVolcano; popularities << GeoDataPlacemark::AccomodationHotel; popularities << GeoDataPlacemark::AccomodationMotel; popularities << GeoDataPlacemark::AccomodationGuestHouse; popularities << GeoDataPlacemark::AccomodationYouthHostel; popularities << GeoDataPlacemark::AccomodationHostel; popularities << GeoDataPlacemark::AccomodationCamping; popularities << GeoDataPlacemark::HealthDentist; popularities << GeoDataPlacemark::HealthDoctors; popularities << GeoDataPlacemark::HealthPharmacy; popularities << GeoDataPlacemark::HealthVeterinary; popularities << GeoDataPlacemark::AmenityLibrary; popularities << GeoDataPlacemark::EducationCollege; popularities << GeoDataPlacemark::EducationSchool; popularities << GeoDataPlacemark::EducationUniversity; popularities << GeoDataPlacemark::FoodBar; popularities << GeoDataPlacemark::FoodBiergarten; popularities << GeoDataPlacemark::FoodCafe; popularities << GeoDataPlacemark::FoodFastFood; popularities << GeoDataPlacemark::FoodPub; popularities << GeoDataPlacemark::FoodRestaurant; popularities << GeoDataPlacemark::MoneyBank; popularities << GeoDataPlacemark::HistoricArchaeologicalSite; popularities << GeoDataPlacemark::AmenityCarWash; popularities << GeoDataPlacemark::AmenityEmbassy; popularities << GeoDataPlacemark::LeisureWaterPark; popularities << GeoDataPlacemark::AmenityCommunityCentre; popularities << GeoDataPlacemark::AmenityFountain; popularities << GeoDataPlacemark::AmenityNightClub; popularities << GeoDataPlacemark::AmenityCourtHouse; popularities << GeoDataPlacemark::AmenityFireStation; popularities << GeoDataPlacemark::AmenityShelter; popularities << GeoDataPlacemark::AmenityHuntingStand; popularities << GeoDataPlacemark::AmenityPolice; popularities << GeoDataPlacemark::AmenityPostBox; popularities << GeoDataPlacemark::AmenityPostOffice; popularities << GeoDataPlacemark::AmenityPrison; popularities << GeoDataPlacemark::AmenityRecycling; popularities << GeoDataPlacemark::AmenitySocialFacility; popularities << GeoDataPlacemark::AmenityTelephone; popularities << GeoDataPlacemark::AmenityTownHall; popularities << GeoDataPlacemark::AmenityDrinkingWater; popularities << GeoDataPlacemark::AmenityGraveyard; popularities << GeoDataPlacemark::ManmadeBridge; popularities << GeoDataPlacemark::ManmadeLighthouse; popularities << GeoDataPlacemark::ManmadePier; popularities << GeoDataPlacemark::ManmadeWaterTower; popularities << GeoDataPlacemark::ManmadeWindMill; popularities << GeoDataPlacemark::TourismAttraction; popularities << GeoDataPlacemark::TourismArtwork; popularities << GeoDataPlacemark::HistoricCastle; popularities << GeoDataPlacemark::AmenityCinema; popularities << GeoDataPlacemark::TourismInformation; popularities << GeoDataPlacemark::HistoricMonument; popularities << GeoDataPlacemark::TourismMuseum; popularities << GeoDataPlacemark::HistoricRuins; popularities << GeoDataPlacemark::AmenityTheatre; popularities << GeoDataPlacemark::TourismThemePark; popularities << GeoDataPlacemark::TourismViewPoint; popularities << GeoDataPlacemark::TourismZoo; popularities << GeoDataPlacemark::TourismAlpineHut; popularities << GeoDataPlacemark::TourismWildernessHut; popularities << GeoDataPlacemark::HistoricMemorial; popularities << GeoDataPlacemark::TransportAerodrome; popularities << GeoDataPlacemark::TransportHelipad; popularities << GeoDataPlacemark::TransportAirportTerminal; popularities << GeoDataPlacemark::TransportBusStation; popularities << GeoDataPlacemark::TransportBusStop; popularities << GeoDataPlacemark::TransportCarShare; popularities << GeoDataPlacemark::TransportFuel; popularities << GeoDataPlacemark::TransportParking; popularities << GeoDataPlacemark::TransportParkingSpace; popularities << GeoDataPlacemark::TransportPlatform; popularities << GeoDataPlacemark::TransportRentalBicycle; popularities << GeoDataPlacemark::TransportRentalCar; popularities << GeoDataPlacemark::TransportRentalSki; popularities << GeoDataPlacemark::TransportTaxiRank; popularities << GeoDataPlacemark::TransportTrainStation; popularities << GeoDataPlacemark::TransportTramStop; popularities << GeoDataPlacemark::TransportBicycleParking; popularities << GeoDataPlacemark::TransportMotorcycleParking; popularities << GeoDataPlacemark::TransportSubwayEntrance; popularities << GeoDataPlacemark::AerialwayStation; popularities << GeoDataPlacemark::ShopBeverages; popularities << GeoDataPlacemark::ShopHifi; popularities << GeoDataPlacemark::ShopSupermarket; popularities << GeoDataPlacemark::ShopAlcohol; popularities << GeoDataPlacemark::ShopBakery; popularities << GeoDataPlacemark::ShopButcher; popularities << GeoDataPlacemark::ShopConfectionery; popularities << GeoDataPlacemark::ShopConvenience; popularities << GeoDataPlacemark::ShopGreengrocer; popularities << GeoDataPlacemark::ShopSeafood; popularities << GeoDataPlacemark::ShopDepartmentStore; popularities << GeoDataPlacemark::ShopKiosk; popularities << GeoDataPlacemark::ShopBag; popularities << GeoDataPlacemark::ShopClothes; popularities << GeoDataPlacemark::ShopFashion; popularities << GeoDataPlacemark::ShopJewelry; popularities << GeoDataPlacemark::ShopShoes; popularities << GeoDataPlacemark::ShopVarietyStore; popularities << GeoDataPlacemark::ShopBeauty; popularities << GeoDataPlacemark::ShopChemist; popularities << GeoDataPlacemark::ShopCosmetics; popularities << GeoDataPlacemark::ShopHairdresser; popularities << GeoDataPlacemark::ShopOptician; popularities << GeoDataPlacemark::ShopPerfumery; popularities << GeoDataPlacemark::ShopDoitYourself; popularities << GeoDataPlacemark::ShopFlorist; popularities << GeoDataPlacemark::ShopHardware; popularities << GeoDataPlacemark::ShopFurniture; popularities << GeoDataPlacemark::ShopElectronics; popularities << GeoDataPlacemark::ShopMobilePhone; popularities << GeoDataPlacemark::ShopBicycle; popularities << GeoDataPlacemark::ShopCar; popularities << GeoDataPlacemark::ShopCarRepair; popularities << GeoDataPlacemark::ShopCarParts; popularities << GeoDataPlacemark::ShopMotorcycle; popularities << GeoDataPlacemark::ShopOutdoor; popularities << GeoDataPlacemark::ShopSports; popularities << GeoDataPlacemark::ShopCopy; popularities << GeoDataPlacemark::ShopArt; popularities << GeoDataPlacemark::ShopMusicalInstrument; popularities << GeoDataPlacemark::ShopPhoto; popularities << GeoDataPlacemark::ShopBook; popularities << GeoDataPlacemark::ShopGift; popularities << GeoDataPlacemark::ShopStationery; popularities << GeoDataPlacemark::ShopLaundry; popularities << GeoDataPlacemark::ShopPet; popularities << GeoDataPlacemark::ShopToys; popularities << GeoDataPlacemark::ShopTravelAgency; popularities << GeoDataPlacemark::ShopDeli; popularities << GeoDataPlacemark::ShopTobacco; popularities << GeoDataPlacemark::ShopTea; popularities << GeoDataPlacemark::Shop; popularities << GeoDataPlacemark::LeisureGolfCourse; popularities << GeoDataPlacemark::LeisureMinigolfCourse; popularities << GeoDataPlacemark::LeisurePark; popularities << GeoDataPlacemark::LeisurePlayground; popularities << GeoDataPlacemark::LeisurePitch; popularities << GeoDataPlacemark::LeisureSportsCentre; popularities << GeoDataPlacemark::LeisureStadium; popularities << GeoDataPlacemark::LeisureTrack; popularities << GeoDataPlacemark::LeisureSwimmingPool; popularities << GeoDataPlacemark::CrossingIsland; popularities << GeoDataPlacemark::CrossingRailway; popularities << GeoDataPlacemark::CrossingSignals; popularities << GeoDataPlacemark::CrossingZebra; popularities << GeoDataPlacemark::HighwayTrafficSignals; popularities << GeoDataPlacemark::BarrierGate; popularities << GeoDataPlacemark::BarrierLiftGate; popularities << GeoDataPlacemark::AmenityBench; popularities << GeoDataPlacemark::NaturalTree; popularities << GeoDataPlacemark::NaturalCave; popularities << GeoDataPlacemark::AmenityWasteBasket; popularities << GeoDataPlacemark::AerialwayPylon; popularities << GeoDataPlacemark::PowerTower; int value = defaultValue + offset * popularities.size(); for (auto popularity : popularities) { StyleBuilder::Private::s_popularities[popularity] = value; value -= offset; } } bool const isPrivate = placemark->osmData().containsTag(QStringLiteral("access"), QStringLiteral("private")); int const base = defaultValue + (isPrivate ? 0 : offset * StyleBuilder::Private::s_popularities.size()); return base + StyleBuilder::Private::s_popularities.value(placemark->visualCategory(), defaultValue); } int StyleBuilder::maximumZoomLevel() const { return d->m_maximumZoomLevel; } QString StyleBuilder::visualCategoryName(GeoDataPlacemark::GeoDataVisualCategory category) { static QHash visualCategoryNames; if (visualCategoryNames.isEmpty()) { visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::None] = "None"; visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::Default] = "Default"; visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::Unknown] = "Unknown"; visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::SmallCity] = "SmallCity"; visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::SmallCountyCapital] = "SmallCountyCapital"; visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::SmallStateCapital] = "SmallStateCapital"; visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::SmallNationCapital] = "SmallNationCapital"; visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::MediumCity] = "MediumCity"; visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::MediumCountyCapital] = "MediumCountyCapital"; visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::MediumStateCapital] = "MediumStateCapital"; visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::MediumNationCapital] = "MediumNationCapital"; visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::BigCity] = "BigCity"; visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::BigCountyCapital] = "BigCountyCapital"; visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::BigStateCapital] = "BigStateCapital"; visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::BigNationCapital] = "BigNationCapital"; visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::LargeCity] = "LargeCity"; visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::LargeCountyCapital] = "LargeCountyCapital"; visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::LargeStateCapital] = "LargeStateCapital"; visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::LargeNationCapital] = "LargeNationCapital"; visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::Nation] = "Nation"; visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::PlaceCity] = "PlaceCity"; visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::PlaceCityCapital] = "PlaceCityCapital"; visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::PlaceCityNationalCapital] = "PlaceCityNationalCapital"; visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::PlaceSuburb] = "PlaceSuburb"; visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::PlaceHamlet] = "PlaceHamlet"; visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::PlaceLocality] = "PlaceLocality"; visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::PlaceTown] = "PlaceTown"; visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::PlaceTownCapital] = "PlaceTownCapital"; visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::PlaceTownNationalCapital] = "PlaceTownNationalCapital"; visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::PlaceVillage] = "PlaceVillage"; visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::PlaceVillageCapital] = "PlaceVillageCapital"; visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::PlaceVillageNationalCapital] = "PlaceVillageNationalCapital"; visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::Mountain] = "Mountain"; visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::Volcano] = "Volcano"; visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::Mons] = "Mons"; visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::Valley] = "Valley"; visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::Continent] = "Continent"; visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::Ocean] = "Ocean"; visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::OtherTerrain] = "OtherTerrain"; visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::Crater] = "Crater"; visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::Mare] = "Mare"; visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::GeographicPole] = "GeographicPole"; visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::MagneticPole] = "MagneticPole"; visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::ShipWreck] = "ShipWreck"; visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::AirPort] = "AirPort"; visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::Observatory] = "Observatory"; visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::MilitaryDangerArea] = "MilitaryDangerArea"; visualCategoryNames[GeoDataPlacemark::GeoDataPlacemark::OsmSite] = "OsmSite"; visualCategoryNames[GeoDataPlacemark::Coordinate] = "Coordinate"; visualCategoryNames[GeoDataPlacemark::MannedLandingSite] = "MannedLandingSite"; visualCategoryNames[GeoDataPlacemark::RoboticRover] = "RoboticRover"; visualCategoryNames[GeoDataPlacemark::UnmannedSoftLandingSite] = "UnmannedSoftLandingSite"; visualCategoryNames[GeoDataPlacemark::UnmannedHardLandingSite] = "UnmannedHardLandingSite"; visualCategoryNames[GeoDataPlacemark::Bookmark] = "Bookmark"; visualCategoryNames[GeoDataPlacemark::NaturalWater] = "NaturalWater"; visualCategoryNames[GeoDataPlacemark::NaturalReef] = "NaturalReef"; visualCategoryNames[GeoDataPlacemark::NaturalWood] = "NaturalWood"; visualCategoryNames[GeoDataPlacemark::NaturalBeach] = "NaturalBeach"; visualCategoryNames[GeoDataPlacemark::NaturalWetland] = "NaturalWetland"; visualCategoryNames[GeoDataPlacemark::NaturalGlacier] = "NaturalGlacier"; visualCategoryNames[GeoDataPlacemark::NaturalIceShelf] = "NaturalIceShelf"; visualCategoryNames[GeoDataPlacemark::NaturalScrub] = "NaturalScrub"; visualCategoryNames[GeoDataPlacemark::NaturalCliff] = "NaturalCliff"; visualCategoryNames[GeoDataPlacemark::NaturalHeath] = "NaturalHeath"; visualCategoryNames[GeoDataPlacemark::HighwayTrafficSignals] = "HighwayTrafficSignals"; visualCategoryNames[GeoDataPlacemark::HighwaySteps] = "HighwaySteps"; visualCategoryNames[GeoDataPlacemark::HighwayUnknown] = "HighwayUnknown"; visualCategoryNames[GeoDataPlacemark::HighwayPath] = "HighwayPath"; visualCategoryNames[GeoDataPlacemark::HighwayFootway] = "HighwayFootway"; visualCategoryNames[GeoDataPlacemark::HighwayTrack] = "HighwayTrack"; visualCategoryNames[GeoDataPlacemark::HighwayPedestrian] = "HighwayPedestrian"; visualCategoryNames[GeoDataPlacemark::HighwayCycleway] = "HighwayCycleway"; visualCategoryNames[GeoDataPlacemark::HighwayService] = "HighwayService"; visualCategoryNames[GeoDataPlacemark::HighwayRoad] = "HighwayRoad"; visualCategoryNames[GeoDataPlacemark::HighwayResidential] = "HighwayResidential"; visualCategoryNames[GeoDataPlacemark::HighwayLivingStreet] = "HighwayLivingStreet"; visualCategoryNames[GeoDataPlacemark::HighwayUnclassified] = "HighwayUnclassified"; visualCategoryNames[GeoDataPlacemark::HighwayTertiaryLink] = "HighwayTertiaryLink"; visualCategoryNames[GeoDataPlacemark::HighwayTertiary] = "HighwayTertiary"; visualCategoryNames[GeoDataPlacemark::HighwaySecondaryLink] = "HighwaySecondaryLink"; visualCategoryNames[GeoDataPlacemark::HighwaySecondary] = "HighwaySecondary"; visualCategoryNames[GeoDataPlacemark::HighwayPrimaryLink] = "HighwayPrimaryLink"; visualCategoryNames[GeoDataPlacemark::HighwayPrimary] = "HighwayPrimary"; visualCategoryNames[GeoDataPlacemark::HighwayRaceway] = "HighwayRaceway"; visualCategoryNames[GeoDataPlacemark::HighwayTrunkLink] = "HighwayTrunkLink"; visualCategoryNames[GeoDataPlacemark::HighwayTrunk] = "HighwayTrunk"; visualCategoryNames[GeoDataPlacemark::HighwayMotorwayLink] = "HighwayMotorwayLink"; visualCategoryNames[GeoDataPlacemark::HighwayMotorway] = "HighwayMotorway"; visualCategoryNames[GeoDataPlacemark::HighwayCorridor] = "HighwayCorridor"; visualCategoryNames[GeoDataPlacemark::Building] = "Building"; visualCategoryNames[GeoDataPlacemark::AccomodationCamping] = "AccomodationCamping"; visualCategoryNames[GeoDataPlacemark::AccomodationHostel] = "AccomodationHostel"; visualCategoryNames[GeoDataPlacemark::AccomodationHotel] = "AccomodationHotel"; visualCategoryNames[GeoDataPlacemark::AccomodationMotel] = "AccomodationMotel"; visualCategoryNames[GeoDataPlacemark::AccomodationYouthHostel] = "AccomodationYouthHostel"; visualCategoryNames[GeoDataPlacemark::AccomodationGuestHouse] = "AccomodationGuestHouse"; visualCategoryNames[GeoDataPlacemark::AmenityLibrary] = "AmenityLibrary"; visualCategoryNames[GeoDataPlacemark::AmenityKindergarten] = "AmenityKindergarten"; visualCategoryNames[GeoDataPlacemark::EducationCollege] = "EducationCollege"; visualCategoryNames[GeoDataPlacemark::EducationSchool] = "EducationSchool"; visualCategoryNames[GeoDataPlacemark::EducationUniversity] = "EducationUniversity"; visualCategoryNames[GeoDataPlacemark::FoodBar] = "FoodBar"; visualCategoryNames[GeoDataPlacemark::FoodBiergarten] = "FoodBiergarten"; visualCategoryNames[GeoDataPlacemark::FoodCafe] = "FoodCafe"; visualCategoryNames[GeoDataPlacemark::FoodFastFood] = "FoodFastFood"; visualCategoryNames[GeoDataPlacemark::FoodPub] = "FoodPub"; visualCategoryNames[GeoDataPlacemark::FoodRestaurant] = "FoodRestaurant"; visualCategoryNames[GeoDataPlacemark::HealthDentist] = "HealthDentist"; visualCategoryNames[GeoDataPlacemark::HealthDoctors] = "HealthDoctors"; visualCategoryNames[GeoDataPlacemark::HealthHospital] = "HealthHospital"; visualCategoryNames[GeoDataPlacemark::HealthPharmacy] = "HealthPharmacy"; visualCategoryNames[GeoDataPlacemark::HealthVeterinary] = "HealthVeterinary"; visualCategoryNames[GeoDataPlacemark::MoneyAtm] = "MoneyAtm"; visualCategoryNames[GeoDataPlacemark::MoneyBank] = "MoneyBank"; visualCategoryNames[GeoDataPlacemark::AmenityEmbassy] = "AmenityEmbassy"; visualCategoryNames[GeoDataPlacemark::AmenityEmergencyPhone] = "AmenityEmergencyPhone"; visualCategoryNames[GeoDataPlacemark::AmenityMountainRescue] = "AmenityMountainRescue"; visualCategoryNames[GeoDataPlacemark::LeisureWaterPark] = "LeisureWaterPark"; visualCategoryNames[GeoDataPlacemark::AmenityCommunityCentre] = "AmenityCommunityCentre"; visualCategoryNames[GeoDataPlacemark::AmenityFountain] = "AmenityFountain"; visualCategoryNames[GeoDataPlacemark::AmenityNightClub] = "AmenityNightClub"; visualCategoryNames[GeoDataPlacemark::AmenityBench] = "AmenityBench"; visualCategoryNames[GeoDataPlacemark::AmenityCourtHouse] = "AmenityCourtHouse"; visualCategoryNames[GeoDataPlacemark::AmenityFireStation] = "AmenityFireStation"; visualCategoryNames[GeoDataPlacemark::AmenityHuntingStand] = "AmenityHuntingStand"; visualCategoryNames[GeoDataPlacemark::AmenityPolice] = "AmenityPolice"; visualCategoryNames[GeoDataPlacemark::AmenityPostBox] = "AmenityPostBox"; visualCategoryNames[GeoDataPlacemark::AmenityPostOffice] = "AmenityPostOffice"; visualCategoryNames[GeoDataPlacemark::AmenityPrison] = "AmenityPrison"; visualCategoryNames[GeoDataPlacemark::AmenityRecycling] = "AmenityRecycling"; visualCategoryNames[GeoDataPlacemark::AmenityShelter] = "AmenityShelter"; visualCategoryNames[GeoDataPlacemark::AmenityTelephone] = "AmenityTelephone"; visualCategoryNames[GeoDataPlacemark::AmenityToilets] = "AmenityToilets"; visualCategoryNames[GeoDataPlacemark::AmenityTownHall] = "AmenityTownHall"; visualCategoryNames[GeoDataPlacemark::AmenityWasteBasket] = "AmenityWasteBasket"; visualCategoryNames[GeoDataPlacemark::AmenityDrinkingWater] = "AmenityDrinkingWater"; visualCategoryNames[GeoDataPlacemark::AmenityGraveyard] = "AmenityGraveyard"; visualCategoryNames[GeoDataPlacemark::AmenityChargingStation] = "ChargingStation"; visualCategoryNames[GeoDataPlacemark::AmenityCarWash] = "CarWash"; visualCategoryNames[GeoDataPlacemark::AmenitySocialFacility] = "SocialFacility"; visualCategoryNames[GeoDataPlacemark::BarrierCityWall] = "BarrierCityWall"; visualCategoryNames[GeoDataPlacemark::BarrierGate] = "BarrierGate"; visualCategoryNames[GeoDataPlacemark::BarrierLiftGate] = "BarrierLiftGate"; visualCategoryNames[GeoDataPlacemark::BarrierWall] = "BarrierWall"; visualCategoryNames[GeoDataPlacemark::NaturalVolcano] = "NaturalVolcano"; visualCategoryNames[GeoDataPlacemark::NaturalPeak] = "NaturalPeak"; visualCategoryNames[GeoDataPlacemark::NaturalTree] = "NaturalTree"; visualCategoryNames[GeoDataPlacemark::NaturalCave] = "NaturalCave"; visualCategoryNames[GeoDataPlacemark::ShopBeverages] = "ShopBeverages"; visualCategoryNames[GeoDataPlacemark::ShopHifi] = "ShopHifi"; visualCategoryNames[GeoDataPlacemark::ShopSupermarket] = "ShopSupermarket"; visualCategoryNames[GeoDataPlacemark::ShopAlcohol] = "ShopAlcohol"; visualCategoryNames[GeoDataPlacemark::ShopBakery] = "ShopBakery"; visualCategoryNames[GeoDataPlacemark::ShopButcher] = "ShopButcher"; visualCategoryNames[GeoDataPlacemark::ShopConfectionery] = "ShopConfectionery"; visualCategoryNames[GeoDataPlacemark::ShopConvenience] = "ShopConvenience"; visualCategoryNames[GeoDataPlacemark::ShopGreengrocer] = "ShopGreengrocer"; visualCategoryNames[GeoDataPlacemark::ShopSeafood] = "ShopSeafood"; visualCategoryNames[GeoDataPlacemark::ShopDepartmentStore] = "ShopDepartmentStore"; visualCategoryNames[GeoDataPlacemark::ShopKiosk] = "ShopKiosk"; visualCategoryNames[GeoDataPlacemark::ShopBag] = "ShopBag"; visualCategoryNames[GeoDataPlacemark::ShopClothes] = "ShopClothes"; visualCategoryNames[GeoDataPlacemark::ShopFashion] = "ShopFashion"; visualCategoryNames[GeoDataPlacemark::ShopJewelry] = "ShopJewelry"; visualCategoryNames[GeoDataPlacemark::ShopShoes] = "ShopShoes"; visualCategoryNames[GeoDataPlacemark::ShopVarietyStore] = "ShopVarietyStore"; visualCategoryNames[GeoDataPlacemark::ShopBeauty] = "ShopBeauty"; visualCategoryNames[GeoDataPlacemark::ShopChemist] = "ShopChemist"; visualCategoryNames[GeoDataPlacemark::ShopCosmetics] = "ShopCosmetics"; visualCategoryNames[GeoDataPlacemark::ShopHairdresser] = "ShopHairdresser"; visualCategoryNames[GeoDataPlacemark::ShopOptician] = "ShopOptician"; visualCategoryNames[GeoDataPlacemark::ShopPerfumery] = "ShopPerfumery"; visualCategoryNames[GeoDataPlacemark::ShopDoitYourself] = "ShopDoitYourself"; visualCategoryNames[GeoDataPlacemark::ShopFlorist] = "ShopFlorist"; visualCategoryNames[GeoDataPlacemark::ShopHardware] = "ShopHardware"; visualCategoryNames[GeoDataPlacemark::ShopFurniture] = "ShopFurniture"; visualCategoryNames[GeoDataPlacemark::ShopElectronics] = "ShopElectronics"; visualCategoryNames[GeoDataPlacemark::ShopMobilePhone] = "ShopMobilePhone"; visualCategoryNames[GeoDataPlacemark::ShopBicycle] = "ShopBicycle"; visualCategoryNames[GeoDataPlacemark::ShopCar] = "ShopCar"; visualCategoryNames[GeoDataPlacemark::ShopCarRepair] = "ShopCarRepair"; visualCategoryNames[GeoDataPlacemark::ShopCarParts] = "ShopCarParts"; visualCategoryNames[GeoDataPlacemark::ShopMotorcycle] = "ShopMotorcycle"; visualCategoryNames[GeoDataPlacemark::ShopOutdoor] = "ShopOutdoor"; visualCategoryNames[GeoDataPlacemark::ShopSports] = "ShopSports"; visualCategoryNames[GeoDataPlacemark::ShopCopy] = "ShopCopy"; visualCategoryNames[GeoDataPlacemark::ShopArt] = "ShopArt"; visualCategoryNames[GeoDataPlacemark::ShopMusicalInstrument] = "ShopMusicalInstrument"; visualCategoryNames[GeoDataPlacemark::ShopPhoto] = "ShopPhoto"; visualCategoryNames[GeoDataPlacemark::ShopBook] = "ShopBook"; visualCategoryNames[GeoDataPlacemark::ShopGift] = "ShopGift"; visualCategoryNames[GeoDataPlacemark::ShopStationery] = "ShopStationery"; visualCategoryNames[GeoDataPlacemark::ShopLaundry] = "ShopLaundry"; visualCategoryNames[GeoDataPlacemark::ShopPet] = "ShopPet"; visualCategoryNames[GeoDataPlacemark::ShopToys] = "ShopToys"; visualCategoryNames[GeoDataPlacemark::ShopTravelAgency] = "ShopTravelAgency"; visualCategoryNames[GeoDataPlacemark::ShopDeli] = "ShopDeli"; visualCategoryNames[GeoDataPlacemark::ShopTobacco] = "ShopTobacco"; visualCategoryNames[GeoDataPlacemark::ShopTea] = "ShopTea"; visualCategoryNames[GeoDataPlacemark::Shop] = "Shop"; visualCategoryNames[GeoDataPlacemark::ManmadeBridge] = "ManmadeBridge"; visualCategoryNames[GeoDataPlacemark::ManmadeLighthouse] = "ManmadeLighthouse"; visualCategoryNames[GeoDataPlacemark::ManmadePier] = "ManmadePier"; visualCategoryNames[GeoDataPlacemark::ManmadeWaterTower] = "ManmadeWaterTower"; visualCategoryNames[GeoDataPlacemark::ManmadeWindMill] = "ManmadeWindMill"; visualCategoryNames[GeoDataPlacemark::TourismAttraction] = "TouristAttraction"; visualCategoryNames[GeoDataPlacemark::TourismArtwork] = "TouristArtwork"; visualCategoryNames[GeoDataPlacemark::HistoricArchaeologicalSite] = "HistoricArchaeologicalSite"; visualCategoryNames[GeoDataPlacemark::HistoricCastle] = "HistoricCastle"; visualCategoryNames[GeoDataPlacemark::HistoricMemorial] = "HistoricMemorial"; visualCategoryNames[GeoDataPlacemark::HistoricMonument] = "HistoricMonument"; visualCategoryNames[GeoDataPlacemark::AmenityCinema] = "TouristCinema"; visualCategoryNames[GeoDataPlacemark::TourismInformation] = "TouristInformation"; visualCategoryNames[GeoDataPlacemark::TourismMuseum] = "TouristMuseum"; visualCategoryNames[GeoDataPlacemark::HistoricRuins] = "TouristRuin"; visualCategoryNames[GeoDataPlacemark::AmenityTheatre] = "TouristTheatre"; visualCategoryNames[GeoDataPlacemark::TourismThemePark] = "TouristThemePark"; visualCategoryNames[GeoDataPlacemark::TourismViewPoint] = "TouristViewPoint"; visualCategoryNames[GeoDataPlacemark::TourismZoo] = "TouristZoo"; visualCategoryNames[GeoDataPlacemark::TourismAlpineHut] = "TouristAlpineHut"; visualCategoryNames[GeoDataPlacemark::TourismWildernessHut] = "TouristWildernessHut"; visualCategoryNames[GeoDataPlacemark::TransportAerodrome] = "TransportAerodrome"; visualCategoryNames[GeoDataPlacemark::TransportHelipad] = "TransportHelipad"; visualCategoryNames[GeoDataPlacemark::TransportAirportTerminal] = "TransportAirportTerminal"; visualCategoryNames[GeoDataPlacemark::TransportAirportGate] = "TransportAirportGate"; visualCategoryNames[GeoDataPlacemark::TransportAirportRunway] = "TransportAirportRunway"; visualCategoryNames[GeoDataPlacemark::TransportAirportTaxiway] = "TransportAirportTaxiway"; visualCategoryNames[GeoDataPlacemark::TransportAirportApron] = "TransportAirportApron"; visualCategoryNames[GeoDataPlacemark::TransportBusStation] = "TransportBusStation"; visualCategoryNames[GeoDataPlacemark::TransportBusStop] = "TransportBusStop"; visualCategoryNames[GeoDataPlacemark::TransportCarShare] = "TransportCarShare"; visualCategoryNames[GeoDataPlacemark::TransportFuel] = "TransportFuel"; visualCategoryNames[GeoDataPlacemark::TransportParking] = "TransportParking"; visualCategoryNames[GeoDataPlacemark::TransportParkingSpace] = "TransportParkingSpace"; visualCategoryNames[GeoDataPlacemark::TransportPlatform] = "TransportPlatform"; visualCategoryNames[GeoDataPlacemark::TransportRentalBicycle] = "TransportRentalBicycle"; visualCategoryNames[GeoDataPlacemark::TransportRentalCar] = "TransportRentalCar"; visualCategoryNames[GeoDataPlacemark::TransportRentalSki] = "TransportRentalSki"; visualCategoryNames[GeoDataPlacemark::TransportTaxiRank] = "TransportTaxiRank"; visualCategoryNames[GeoDataPlacemark::TransportTrainStation] = "TransportTrainStation"; visualCategoryNames[GeoDataPlacemark::TransportTramStop] = "TransportTramStop"; visualCategoryNames[GeoDataPlacemark::TransportSpeedCamera] = "TransportSpeedCamera"; visualCategoryNames[GeoDataPlacemark::TransportBicycleParking] = "TransportBicycleParking"; visualCategoryNames[GeoDataPlacemark::TransportMotorcycleParking] = "TransportMotorcycleParking"; visualCategoryNames[GeoDataPlacemark::TransportSubwayEntrance] = "TransportSubwayEntrance"; visualCategoryNames[GeoDataPlacemark::ReligionPlaceOfWorship] = "ReligionPlaceOfWorship"; visualCategoryNames[GeoDataPlacemark::ReligionBahai] = "ReligionBahai"; visualCategoryNames[GeoDataPlacemark::ReligionBuddhist] = "ReligionBuddhist"; visualCategoryNames[GeoDataPlacemark::ReligionChristian] = "ReligionChristian"; visualCategoryNames[GeoDataPlacemark::ReligionMuslim] = "ReligionMuslim"; visualCategoryNames[GeoDataPlacemark::ReligionHindu] = "ReligionHindu"; visualCategoryNames[GeoDataPlacemark::ReligionJain] = "ReligionJain"; visualCategoryNames[GeoDataPlacemark::ReligionJewish] = "ReligionJewish"; visualCategoryNames[GeoDataPlacemark::ReligionShinto] = "ReligionShinto"; visualCategoryNames[GeoDataPlacemark::ReligionSikh] = "ReligionSikh"; visualCategoryNames[GeoDataPlacemark::LeisureGolfCourse] = "LeisureGolfCourse"; visualCategoryNames[GeoDataPlacemark::LeisureMarina] = "LeisureMarina"; visualCategoryNames[GeoDataPlacemark::LeisurePark] = "LeisurePark"; visualCategoryNames[GeoDataPlacemark::LeisurePlayground] = "LeisurePlayground"; visualCategoryNames[GeoDataPlacemark::LeisurePitch] = "LeisurePitch"; visualCategoryNames[GeoDataPlacemark::LeisureSportsCentre] = "LeisureSportsCentre"; visualCategoryNames[GeoDataPlacemark::LeisureStadium] = "LeisureStadium"; visualCategoryNames[GeoDataPlacemark::LeisureTrack] = "LeisureTrack"; visualCategoryNames[GeoDataPlacemark::LeisureSwimmingPool] = "LeisureSwimmingPool"; visualCategoryNames[GeoDataPlacemark::LeisureMinigolfCourse] = "LeisureMinigolfCourse"; visualCategoryNames[GeoDataPlacemark::LanduseAllotments] = "LanduseAllotments"; visualCategoryNames[GeoDataPlacemark::LanduseBasin] = "LanduseBasin"; visualCategoryNames[GeoDataPlacemark::LanduseCemetery] = "LanduseCemetery"; visualCategoryNames[GeoDataPlacemark::LanduseCommercial] = "LanduseCommercial"; visualCategoryNames[GeoDataPlacemark::LanduseConstruction] = "LanduseConstruction"; visualCategoryNames[GeoDataPlacemark::LanduseFarmland] = "LanduseFarmland"; visualCategoryNames[GeoDataPlacemark::LanduseFarmyard] = "LanduseFarmyard"; visualCategoryNames[GeoDataPlacemark::LanduseGarages] = "LanduseGarages"; visualCategoryNames[GeoDataPlacemark::LanduseGrass] = "LanduseGrass"; visualCategoryNames[GeoDataPlacemark::LanduseIndustrial] = "LanduseIndustrial"; visualCategoryNames[GeoDataPlacemark::LanduseLandfill] = "LanduseLandfill"; visualCategoryNames[GeoDataPlacemark::LanduseMeadow] = "LanduseMeadow"; visualCategoryNames[GeoDataPlacemark::LanduseMilitary] = "LanduseMilitary"; visualCategoryNames[GeoDataPlacemark::LanduseQuarry] = "LanduseQuarry"; visualCategoryNames[GeoDataPlacemark::LanduseRailway] = "LanduseRailway"; visualCategoryNames[GeoDataPlacemark::LanduseReservoir] = "LanduseReservoir"; visualCategoryNames[GeoDataPlacemark::LanduseResidential] = "LanduseResidential"; visualCategoryNames[GeoDataPlacemark::LanduseRetail] = "LanduseRetail"; visualCategoryNames[GeoDataPlacemark::LanduseOrchard] = "LanduseOrchard"; visualCategoryNames[GeoDataPlacemark::LanduseVineyard] = "LanduseVineyard"; visualCategoryNames[GeoDataPlacemark::RailwayRail] = "RailwayRail"; visualCategoryNames[GeoDataPlacemark::RailwayNarrowGauge] = "RailwayNarrowGauge"; visualCategoryNames[GeoDataPlacemark::RailwayTram] = "RailwayTram"; visualCategoryNames[GeoDataPlacemark::RailwayLightRail] = "RailwayLightRail"; visualCategoryNames[GeoDataPlacemark::RailwayAbandoned] = "RailwayAbandoned"; visualCategoryNames[GeoDataPlacemark::RailwaySubway] = "RailwaySubway"; visualCategoryNames[GeoDataPlacemark::RailwayPreserved] = "RailwayPreserved"; visualCategoryNames[GeoDataPlacemark::RailwayMiniature] = "RailwayMiniature"; visualCategoryNames[GeoDataPlacemark::RailwayConstruction] = "RailwayConstruction"; visualCategoryNames[GeoDataPlacemark::RailwayMonorail] = "RailwayMonorail"; visualCategoryNames[GeoDataPlacemark::RailwayFunicular] = "RailwayFunicular"; visualCategoryNames[GeoDataPlacemark::PowerTower] = "PowerTower"; visualCategoryNames[GeoDataPlacemark::AerialwayStation] = "AerialwayStation"; visualCategoryNames[GeoDataPlacemark::AerialwayPylon] = "AerialwayPylon"; visualCategoryNames[GeoDataPlacemark::AerialwayCableCar] = "AerialwayCableCar"; visualCategoryNames[GeoDataPlacemark::AerialwayGondola] = "AerialwayGondola"; visualCategoryNames[GeoDataPlacemark::AerialwayChairLift] = "AerialwayChairLift"; visualCategoryNames[GeoDataPlacemark::AerialwayMixedLift] = "AerialwayMixedLift"; visualCategoryNames[GeoDataPlacemark::AerialwayDragLift] = "AerialwayDragLift"; visualCategoryNames[GeoDataPlacemark::AerialwayTBar] = "AerialwayTBar"; visualCategoryNames[GeoDataPlacemark::AerialwayJBar] = "AerialwayJBar"; visualCategoryNames[GeoDataPlacemark::AerialwayPlatter] = "AerialwayPlatter"; visualCategoryNames[GeoDataPlacemark::AerialwayRopeTow] = "AerialwayRopeTow"; visualCategoryNames[GeoDataPlacemark::AerialwayMagicCarpet] = "AerialwayMagicCarpet"; visualCategoryNames[GeoDataPlacemark::AerialwayZipLine] = "AerialwayZipLine"; visualCategoryNames[GeoDataPlacemark::AerialwayGoods] = "AerialwayGoods"; visualCategoryNames[GeoDataPlacemark::PisteDownhill] = "PisteDownhill"; visualCategoryNames[GeoDataPlacemark::PisteNordic] = "PisteNordic"; visualCategoryNames[GeoDataPlacemark::PisteSkitour] = "PisteSkitour"; visualCategoryNames[GeoDataPlacemark::PisteSled] = "PisteSled"; visualCategoryNames[GeoDataPlacemark::PisteHike] = "PisteHike"; visualCategoryNames[GeoDataPlacemark::PisteSleigh] = "PisteSleigh"; visualCategoryNames[GeoDataPlacemark::PisteIceSkate] = "PisteIceSkate"; visualCategoryNames[GeoDataPlacemark::PisteSnowPark] = "PisteSnowPark"; visualCategoryNames[GeoDataPlacemark::PistePlayground] = "PistePlayground"; visualCategoryNames[GeoDataPlacemark::PisteSkiJump] = "PisteSkiJump"; visualCategoryNames[GeoDataPlacemark::Satellite] = "Satellite"; visualCategoryNames[GeoDataPlacemark::Landmass] = "Landmass"; visualCategoryNames[GeoDataPlacemark::UrbanArea] = "UrbanArea"; visualCategoryNames[GeoDataPlacemark::InternationalDateLine] = "InternationalDateLine"; visualCategoryNames[GeoDataPlacemark::Bathymetry] = "Bathymetry"; visualCategoryNames[GeoDataPlacemark::AdminLevel1] = "AdminLevel1"; visualCategoryNames[GeoDataPlacemark::AdminLevel2] = "AdminLevel2"; visualCategoryNames[GeoDataPlacemark::AdminLevel3] = "AdminLevel3"; visualCategoryNames[GeoDataPlacemark::AdminLevel4] = "AdminLevel4"; visualCategoryNames[GeoDataPlacemark::AdminLevel5] = "AdminLevel5"; visualCategoryNames[GeoDataPlacemark::AdminLevel6] = "AdminLevel6"; visualCategoryNames[GeoDataPlacemark::AdminLevel7] = "AdminLevel7"; visualCategoryNames[GeoDataPlacemark::AdminLevel8] = "AdminLevel8"; visualCategoryNames[GeoDataPlacemark::AdminLevel9] = "AdminLevel9"; visualCategoryNames[GeoDataPlacemark::AdminLevel10] = "AdminLevel10"; visualCategoryNames[GeoDataPlacemark::AdminLevel11] = "AdminLevel11"; visualCategoryNames[GeoDataPlacemark::BoundaryMaritime] = "BoundaryMaritime"; visualCategoryNames[GeoDataPlacemark::WaterwayCanal] = "WaterwayCanal"; visualCategoryNames[GeoDataPlacemark::WaterwayDitch] = "WaterwayDitch"; visualCategoryNames[GeoDataPlacemark::WaterwayDrain] = "WaterwayDrain"; visualCategoryNames[GeoDataPlacemark::WaterwayStream] = "WaterwayStream"; visualCategoryNames[GeoDataPlacemark::WaterwayRiver] = "WaterwayRiver"; visualCategoryNames[GeoDataPlacemark::WaterwayWeir] = "WaterwayWeir"; visualCategoryNames[GeoDataPlacemark::CrossingIsland] = "CrossingIsland"; visualCategoryNames[GeoDataPlacemark::CrossingRailway] = "CrossingRailway"; visualCategoryNames[GeoDataPlacemark::CrossingSignals] = "CrossingSignals"; visualCategoryNames[GeoDataPlacemark::CrossingZebra] = "CrossingZebra"; visualCategoryNames[GeoDataPlacemark::LastIndex] = "LastIndex"; } Q_ASSERT(visualCategoryNames.contains(category)); return visualCategoryNames[category]; } QHash StyleBuilder::osmTagMapping() { Private::initializeOsmVisualCategories(); return Private::s_visualCategories; } QStringList StyleBuilder::shopValues() { // from https://taginfo.openstreetmap.org/keys/building#values static const QStringList osmShopValues = QStringList() << "cheese" << "chocolate" << "coffee" << "dairy" << "farm" << "pasta" << "pastry" << "wine" << "general" << "mall" << "baby_goods" << "boutique" << "fabric" << "leather" << "tailor" << "watches" << "charity" << "second_hand" << "erotic" << "hearing_aids" << "herbalist" << "massage" << "medical_supply" << "tattoo" << "bathroom_furnishing" << "electrical" << "energy" << "furnace" << "garden_centre" << "garden_furniture" << "gas" << "glaziery" << "houseware" << "locksmith" << "paint" << "trade" << "antiques" << "bed" << "candles" << "carpet" << "curtain" << "interior_decoration" << "kitchen" << "lamps" << "window_blind" << "computer" << "radiotechnics" << "vacuum_cleaner" << "fishing" << "free_flying" << "hunting" << "outdoor" << "scuba_diving" << "sports" << "tyres" << "swimming_pool" << "art" << "craft" << "frame" << "games" << "model" << "music" << "trophy" << "video" << "video_games" << "anime" << "ticket" << "copyshop" << "dry_cleaning" << "e-cigarette" << "funeral_directors" << "money_lender" << "pawnbroker" << "pyrotechnics" << "religion" << "storage_rental" << "weapons" << "user defined"; return osmShopValues; } QSet StyleBuilder::buildingTags() { static const QString building = QStringLiteral("building"); // from https://taginfo.openstreetmap.org/keys/building#values static const QSet osmBuildingTags = QSet() << OsmTag(building, "yes") << OsmTag(building, "house") << OsmTag(building, "residential") << OsmTag(building, "garage") << OsmTag(building, "apartments") << OsmTag(building, "hut") << OsmTag(building, "industrial") << OsmTag(building, "detached") << OsmTag(building, "roof") << OsmTag(building, "garages") << OsmTag(building, "commercial") << OsmTag(building, "terrace") << OsmTag(building, "shed") << OsmTag(building, "school") << OsmTag(building, "retail") << OsmTag(building, "farm_auxiliary") << OsmTag(building, "church") << OsmTag(building, "cathedral") << OsmTag(building, "greenhouse") << OsmTag(building, "barn") << OsmTag(building, "service") << OsmTag(building, "manufacture") << OsmTag(building, "construction") << OsmTag(building, "cabin") << OsmTag(building, "farm") << OsmTag(building, "warehouse") << OsmTag(building, "House") << OsmTag(building, "office") << OsmTag(building, "civic") << OsmTag(building, "Residential") << OsmTag(building, "hangar") << OsmTag(building, "public") << OsmTag(building, "university") << OsmTag(building, "hospital") << OsmTag(building, "chapel") << OsmTag(building, "hotel") << OsmTag(building, "train_station") << OsmTag(building, "dormitory") << OsmTag(building, "kindergarten") << OsmTag(building, "stable") << OsmTag(building, "storage_tank") << OsmTag(building, "shop") << OsmTag(building, "college") << OsmTag(building, "supermarket") << OsmTag(building, "factory") << OsmTag(building, "bungalow") << OsmTag(building, "tower") << OsmTag(building, "silo") << OsmTag(building, "storage") << OsmTag(building, "station") << OsmTag(building, "education") << OsmTag(building, "carport") << OsmTag(building, "houseboat") << OsmTag(building, "castle") << OsmTag(building, "social_facility") << OsmTag(building, "water_tower") << OsmTag(building, "container") << OsmTag(building, "exhibition_hall") << OsmTag(building, "monastery") << OsmTag(building, "bunker") << OsmTag(building, "shelter") << OsmTag("building:part", "yes") << OsmTag("building:part", "antenna"); return osmBuildingTags; } GeoDataPlacemark::GeoDataVisualCategory StyleBuilder::determineVisualCategory(const OsmPlacemarkData &osmData) { QString const yes(QStringLiteral("yes")); if (osmData.containsTagKey(QStringLiteral("area:highway")) || // Not supported yet osmData.containsTag(QStringLiteral("boundary"), QStringLiteral("protected_area")) || // Not relevant for the default map osmData.containsTag(QStringLiteral("boundary"), QStringLiteral("postal_code")) || osmData.containsTag(QStringLiteral("boundary"), QStringLiteral("aerial_views")) || // Created by OSM editor(s) application for digitalization osmData.containsTagKey(QStringLiteral("closed:highway")) || osmData.containsTagKey(QStringLiteral("abandoned:highway")) || osmData.containsTagKey(QStringLiteral("abandoned:natural")) || osmData.containsTagKey(QStringLiteral("abandoned:building")) || osmData.containsTagKey(QStringLiteral("abandoned:leisure")) || osmData.containsTagKey(QStringLiteral("disused:highway")) || osmData.containsTag(QStringLiteral("highway"), QStringLiteral("razed")) || osmData.containsTag(QStringLiteral("piste:abandoned"), yes)) { return GeoDataPlacemark::None; } if (osmData.containsTag(QStringLiteral("building"), yes)) { return GeoDataPlacemark::Building; } if (osmData.containsTag(QStringLiteral("historic"), QStringLiteral("castle")) && osmData.containsTag(QStringLiteral("castle_type"), QStringLiteral("kremlin"))) { return GeoDataPlacemark::None; } if (osmData.containsTag(QStringLiteral("natural"), QStringLiteral("glacier")) && osmData.containsTag(QStringLiteral("glacier:type"), QStringLiteral("shelf"))) { return GeoDataPlacemark::NaturalIceShelf; } if (osmData.containsTag(QStringLiteral("highway"), QStringLiteral("crossing"))) { QStringList const crossings = osmData.tagValue(QStringLiteral("crossing")).split(';'); QString const crossingRef = osmData.tagValue(QStringLiteral("crossing_ref")); if (crossingRef == QStringLiteral("zebra") || crossingRef == QStringLiteral("tiger") || crossings.contains(QStringLiteral("zebra")) || crossings.contains(QStringLiteral("tiger"))) { return GeoDataPlacemark::CrossingZebra; } else if (crossingRef == QStringLiteral("toucan") || crossingRef == QStringLiteral("pelican") || crossings.contains(QStringLiteral("traffic_signals")) || crossings.contains(QStringLiteral("toucan")) || crossings.contains(QStringLiteral("pelican"))) { return GeoDataPlacemark::CrossingSignals; } else if (crossings.contains(QStringLiteral("island"))) { return GeoDataPlacemark::CrossingIsland; } } if (osmData.containsTag(QStringLiteral("railway"), QStringLiteral("crossing")) || osmData.containsTag(QStringLiteral("railway"), QStringLiteral("level_crossing"))) { return GeoDataPlacemark::CrossingRailway; } Private::initializeOsmVisualCategories(); QString const capital(QStringLiteral("capital")); QString const admin_level(QStringLiteral("admin_level")); // National capitals have admin_level=2 // More at http://wiki.openstreetmap.org/wiki/Key:capital#Using_relations_for_capitals QString const national_level(QStringLiteral("2")); for (auto iter = osmData.tagsBegin(), end = osmData.tagsEnd(); iter != end; ++iter) { const auto tag = OsmTag(iter.key(), iter.value()); GeoDataPlacemark::GeoDataVisualCategory category = Private::s_visualCategories.value(tag, GeoDataPlacemark::None); if (category != GeoDataPlacemark::None) { if (category == GeoDataPlacemark::PlaceCity && osmData.containsTag(admin_level, national_level)) { category = GeoDataPlacemark::PlaceCityNationalCapital; } else if (category == GeoDataPlacemark::PlaceCity && osmData.containsTag(capital, yes)) { category = GeoDataPlacemark::PlaceCityCapital; } else if (category == GeoDataPlacemark::PlaceTown && osmData.containsTag(admin_level, national_level)) { category = GeoDataPlacemark::PlaceTownNationalCapital; } else if (category == GeoDataPlacemark::PlaceTown && osmData.containsTag(capital, yes)) { category = GeoDataPlacemark::PlaceTownCapital; } else if (category == GeoDataPlacemark::PlaceVillage && osmData.containsTag(admin_level, national_level)) { category = GeoDataPlacemark::PlaceVillageNationalCapital; } else if (category == GeoDataPlacemark::PlaceVillage && osmData.containsTag(capital, yes)) { category = GeoDataPlacemark::PlaceVillageCapital; } } if (category != GeoDataPlacemark::None) { return category; } } return GeoDataPlacemark::None; } StyleParameters::StyleParameters(const GeoDataPlacemark *placemark_, int tileLevel_) : placemark(placemark_), tileLevel(tileLevel_), relation(nullptr) { // nothing to do } } diff --git a/src/lib/marble/declarative/MarbleQuickItem.cpp b/src/lib/marble/declarative/MarbleQuickItem.cpp index b0c70f029..58a7bae79 100644 --- a/src/lib/marble/declarative/MarbleQuickItem.cpp +++ b/src/lib/marble/declarative/MarbleQuickItem.cpp @@ -1,1006 +1,1011 @@ // // This file is part of the Marble Virtual Globe. // // This program is free software licensed under the GNU LGPL. You can // find a copy of this license in LICENSE.txt in the top directory of // the source code. // // Copyright 2014 Adam Dabrowski // #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "GeoDataRelation.h" #include "osm/OsmPlacemarkData.h" #include "GeoDataDocument.h" namespace Marble { //TODO - move to separate files class QuickItemSelectionRubber : public AbstractSelectionRubber { //TODO: support rubber selection in MarbleQuickItem public: QuickItemSelectionRubber(); void show() override { m_visible = true; } void hide() override { m_visible = false; } bool isVisible() const override { return m_visible; } const QRect &geometry() const override { return m_geometry; } void setGeometry(const QRect &/*geometry*/) override {} private: QRect m_geometry; bool m_visible; }; //TODO - implement missing functionalities class MarbleQuickInputHandler : public MarbleDefaultInputHandler { public: MarbleQuickInputHandler(MarbleAbstractPresenter *marblePresenter, MarbleQuickItem *marbleQuick) : MarbleDefaultInputHandler(marblePresenter) ,m_marbleQuick(marbleQuick) { setInertialEarthRotationEnabled(false); //Disabled by default, it's buggy. TODO - fix } bool acceptMouse() override { return true; } void pinch(QPointF center, qreal scale, Qt::GestureState state) { //TODO - this whole thing should be moved to MarbleAbstractPresenter (void)handlePinch(center, scale, state); } void handleMouseButtonPressAndHold(const QPoint &position) override { m_marbleQuick->reverseGeocoding(position); } private Q_SLOTS: void showLmbMenu(int x, int y) override { m_marbleQuick->selectPlacemarkAt(x, y); } void showRmbMenu(int, int) override {} void openItemToolTip() override {} void setCursor(const QCursor &cursor) override { m_marbleQuick->setCursor(cursor); } private Q_SLOTS: void installPluginEventFilter(RenderPlugin *) override {} private: bool layersEventFilter(QObject *o, QEvent *e) override { return m_marbleQuick->layersEventFilter(o, e); } //empty - don't check. It would be invalid with quick items void checkReleasedMove(QMouseEvent *) override {} bool handleTouch(QTouchEvent *event) override { if (event->touchPoints().count() > 1) { //not handling multi-touch at all, let PinchArea or MultiPointTouchArea take care of it return false; } if (event->touchPoints().count() == 1) { //handle - but do not accept. I.e. pinchArea still needs to get this QTouchEvent::TouchPoint p = event->touchPoints().at(0); if (event->type() == QEvent::TouchBegin) { QMouseEvent press(QMouseEvent::MouseButtonPress, p.pos(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); handleMouseEvent(&press); } else if (event->type() == QEvent::TouchUpdate) { QMouseEvent move(QMouseEvent::MouseMove, p.pos(), Qt::NoButton, Qt::LeftButton, Qt::NoModifier); handleMouseEvent(&move); } else if (event->type() == QEvent::TouchEnd) { QMouseEvent release(QMouseEvent::MouseButtonRelease, p.pos(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); handleMouseEvent(&release); } } return false; } AbstractSelectionRubber *selectionRubber() override { return &m_selectionRubber; } MarbleQuickItem *m_marbleQuick; QuickItemSelectionRubber m_selectionRubber; bool m_usePinchArea; }; class MarbleQuickItemPrivate { public: explicit MarbleQuickItemPrivate(MarbleQuickItem *marble) : m_marble(marble), m_model(), m_map(&m_model), m_presenter(&m_map), m_positionVisible(false), m_currentPosition(marble), m_inputHandler(&m_presenter, marble), m_placemarkDelegate(nullptr), m_placemarkItem(nullptr), m_placemark(nullptr), m_reverseGeocoding(&m_model), m_showScaleBar(false) { m_currentPosition.setName(QObject::tr("Current Location")); } private: MarbleQuickItem *m_marble; friend class MarbleQuickItem; MarbleModel m_model; MarbleMap m_map; MarbleAbstractPresenter m_presenter; bool m_positionVisible; Placemark m_currentPosition; MarbleQuickInputHandler m_inputHandler; QQmlComponent* m_placemarkDelegate; QQuickItem* m_placemarkItem; Placemark* m_placemark; ReverseGeocodingRunnerManager m_reverseGeocoding; bool m_showScaleBar; }; MarbleQuickItem::MarbleQuickItem(QQuickItem *parent) : QQuickPaintedItem(parent) ,d(new MarbleQuickItemPrivate(this)) { setRenderTarget(QQuickPaintedItem::FramebufferObject); setOpaquePainting(true); qRegisterMetaType("Placemark*"); foreach (AbstractFloatItem *item, d->m_map.floatItems()) { if (item->nameId() == QLatin1String("license")) { item->setPosition(QPointF(5.0, -10.0)); } else { item->hide(); } } d->m_model.positionTracking()->setTrackVisible(false); connect(&d->m_map, SIGNAL(repaintNeeded(QRegion)), this, SLOT(update())); connect(this, SIGNAL(widthChanged()), this, SLOT(resizeMap())); connect(this, SIGNAL(heightChanged()), this, SLOT(resizeMap())); connect(&d->m_map, SIGNAL(visibleLatLonAltBoxChanged(GeoDataLatLonAltBox)), this, SLOT(updatePositionVisibility())); connect(&d->m_map, SIGNAL(visibleLatLonAltBoxChanged(GeoDataLatLonAltBox)), this, SIGNAL(visibleLatLonAltBoxChanged())); connect(&d->m_map, SIGNAL(radiusChanged(int)), this, SIGNAL(radiusChanged(int))); connect(&d->m_map, SIGNAL(radiusChanged(int)), this, SIGNAL(zoomChanged())); connect(&d->m_reverseGeocoding, SIGNAL(reverseGeocodingFinished(GeoDataCoordinates,GeoDataPlacemark)), this, SLOT(handleReverseGeocoding(GeoDataCoordinates,GeoDataPlacemark))); setAcceptedMouseButtons(Qt::AllButtons); installEventFilter(&d->m_inputHandler); } void MarbleQuickItem::resizeMap() { const int minWidth = 100; const int minHeight = 100; int newWidth = width() > minWidth ? (int)width() : minWidth; int newHeight = height() > minHeight ? (int)height() : minHeight; d->m_map.setSize(newWidth, newHeight); update(); updatePositionVisibility(); } void MarbleQuickItem::positionDataStatusChanged(PositionProviderStatus status) { if (status == PositionProviderStatusAvailable) { emit positionAvailableChanged(true); } else { emit positionAvailableChanged(false); } updatePositionVisibility(); } void MarbleQuickItem::positionChanged(const GeoDataCoordinates &, GeoDataAccuracy) { updatePositionVisibility(); } void MarbleQuickItem::updatePositionVisibility() { updatePlacemarks(); bool isVisible = false; if ( positionAvailable() ) { qreal x, y; bool globeHidesPoint; bool const valid = d->m_map.viewport()->screenCoordinates(d->m_model.positionTracking()->currentLocation(), x, y, globeHidesPoint); isVisible = valid && !globeHidesPoint; } if ( isVisible != d->m_positionVisible ) { d->m_positionVisible = isVisible; emit positionVisibleChanged( isVisible ); } } void MarbleQuickItem::updateCurrentPosition(const GeoDataCoordinates &coordinates) { d->m_currentPosition.placemark().setCoordinate(coordinates); emit currentPositionChanged(&d->m_currentPosition); } void MarbleQuickItem::updatePlacemarks() { if (!d->m_placemarkDelegate || !d->m_placemark) { return; } if (!d->m_placemarkItem) { QQmlContext * context = new QQmlContext(qmlContext(d->m_placemarkDelegate)); QObject * component = d->m_placemarkDelegate->create(context); d->m_placemarkItem = qobject_cast( component ); if (d->m_placemarkItem) { d->m_placemarkItem->setParentItem( this ); d->m_placemarkItem->setProperty("placemark", QVariant::fromValue(d->m_placemark)); } else { delete component; return; } } qreal x = 0; qreal y = 0; const bool visible = d->m_map.viewport()->screenCoordinates(d->m_placemark->placemark().coordinate(), x, y); d->m_placemarkItem->setVisible(visible); if (visible) { d->m_placemarkItem->setProperty("xPos", QVariant(x)); d->m_placemarkItem->setProperty("yPos", QVariant(y)); } } void MarbleQuickItem::handleReverseGeocoding(const GeoDataCoordinates &coordinates, const GeoDataPlacemark &placemark) { if (d->m_placemark && d->m_placemark->placemark().coordinate() == coordinates) { d->m_placemark->setGeoDataPlacemark(placemark); updatePlacemarks(); } } void MarbleQuickItem::paint(QPainter *painter) { //TODO - much to be done here still, i.e paint !enabled version QPaintDevice *paintDevice = painter->device(); QRect rect = contentsBoundingRect().toRect(); painter->end(); { GeoPainter geoPainter(paintDevice, d->m_map.viewport(), d->m_map.mapQuality()); d->m_map.paint(geoPainter, rect); } painter->begin(paintDevice); } void MarbleQuickItem::classBegin() { } void MarbleQuickItem::componentComplete() { } int MarbleQuickItem::mapWidth() const { return d->m_map.width(); } int MarbleQuickItem::mapHeight() const { return d->m_map.height(); } bool MarbleQuickItem::showFrameRate() const { return d->m_map.showFrameRate(); } MarbleQuickItem::Projection MarbleQuickItem::projection() const { return (Projection)d->m_map.projection(); } QString MarbleQuickItem::mapThemeId() const { return d->m_map.mapThemeId(); } bool MarbleQuickItem::showAtmosphere() const { return d->m_map.showAtmosphere(); } bool MarbleQuickItem::showCompass() const { return d->m_map.showCompass(); } bool MarbleQuickItem::showClouds() const { return d->m_map.showClouds(); } bool MarbleQuickItem::showCrosshairs() const { return d->m_map.showCrosshairs(); } bool MarbleQuickItem::showGrid() const { return d->m_map.showGrid(); } bool MarbleQuickItem::showOverviewMap() const { return d->m_map.showOverviewMap(); } bool MarbleQuickItem::showOtherPlaces() const { return d->m_map.showOtherPlaces(); } bool MarbleQuickItem::showScaleBar() const { return d->m_showScaleBar; } bool MarbleQuickItem::showBackground() const { return d->m_map.showBackground(); } bool MarbleQuickItem::showPositionMarker() const { QList plugins = d->m_map.renderPlugins(); foreach (const RenderPlugin * plugin, plugins) { if (plugin->nameId() == QLatin1String("positionMarker")) { return plugin->visible(); } } return false; } QString MarbleQuickItem::positionProvider() const { if ( d->m_model.positionTracking()->positionProviderPlugin() ) { return d->m_model.positionTracking()->positionProviderPlugin()->nameId(); } return QString(); } MarbleModel* MarbleQuickItem::model() { return &d->m_model; } const MarbleModel* MarbleQuickItem::model() const { return &d->m_model; } MarbleMap* MarbleQuickItem::map() { return &d->m_map; } const MarbleMap* MarbleQuickItem::map() const { return &d->m_map; } bool MarbleQuickItem::inertialGlobeRotation() const { return d->m_inputHandler.inertialEarthRotationEnabled(); } bool MarbleQuickItem::animationViewContext() const { return d->m_map.viewContext() == Animation; } QQmlComponent *MarbleQuickItem::placemarkDelegate() const { return d->m_placemarkDelegate; } void MarbleQuickItem::reverseGeocoding(const QPoint &point) { qreal lon, lat; d->m_map.viewport()->geoCoordinates(point.x(), point.y(), lon, lat); auto const coordinates = GeoDataCoordinates(lon, lat, 0.0, GeoDataCoordinates::Degree); delete d->m_placemarkItem; d->m_placemarkItem = nullptr; delete d->m_placemark; d->m_placemark = new Placemark(this); d->m_placemark->placemark().setCoordinate(coordinates); d->m_reverseGeocoding.reverseGeocoding(coordinates); } qreal MarbleQuickItem::speed() const { return d->m_model.positionTracking()->speed(); } qreal MarbleQuickItem::angle() const { bool routeExists = d->m_model.routingManager()->routingModel()->route().distance() != 0; bool onRoute = !d->m_model.routingManager()->routingModel()->deviatedFromRoute(); if ( routeExists && onRoute) { GeoDataCoordinates curPoint = d->m_model.positionTracking()->positionProviderPlugin()->position(); return d->m_model.routingManager()->routingModel()->route().currentSegment().projectedDirection(curPoint); } else { return d->m_model.positionTracking()->direction(); } } bool MarbleQuickItem::positionAvailable() const { return d->m_model.positionTracking()->status() == PositionProviderStatusAvailable; } bool MarbleQuickItem::positionVisible() { return d->m_positionVisible; } qreal MarbleQuickItem::distanceFromPointToCurrentLocation(const QPoint & position) const { if ( positionAvailable() ) { qreal lon1; qreal lat1; d->m_map.viewport()->geoCoordinates(position.x(), position.y(), lon1, lat1, GeoDataCoordinates::Radian ); GeoDataCoordinates currentCoordinates = d->m_model.positionTracking()->currentLocation(); qreal lon2 = currentCoordinates.longitude(); qreal lat2 = currentCoordinates.latitude(); return distanceSphere(lon1, lat1, lon2, lat2) * d->m_model.planetRadius(); } return 0; } qreal MarbleQuickItem::angleFromPointToCurrentLocation( const QPoint & position ) const { if ( positionAvailable() ) { qreal x, y; PositionTracking const * positionTracking = d->m_model.positionTracking(); map()->viewport()->screenCoordinates( positionTracking->currentLocation(), x, y ); return atan2( y-position.y(), x-position.x() ) * RAD2DEG; } return 0; } Placemark * MarbleQuickItem::currentPosition() const { return &d->m_currentPosition; } QPointF MarbleQuickItem::screenCoordinatesFromCoordinate(Coordinate * coordinate) const { qreal x; qreal y; d->m_map.viewport()->screenCoordinates(coordinate->coordinates(), x, y); return QPointF(x, y); } void MarbleQuickItem::setRadius(int radius) { d->m_map.setRadius(radius); } void MarbleQuickItem::setZoom(int newZoom, FlyToMode mode) { d->m_presenter.setZoom(newZoom, mode); } void MarbleQuickItem::setZoomToMaximumLevel() { d->m_presenter.setZoom(d->m_map.maximumZoom()); } void MarbleQuickItem::centerOn(const GeoDataPlacemark& placemark, bool animated) { d->m_presenter.centerOn(placemark, animated); } void MarbleQuickItem::centerOn(const GeoDataLatLonBox& box, bool animated) { d->m_presenter.centerOn(box, animated); } void MarbleQuickItem::centerOn(const GeoDataCoordinates &coordinate) { GeoDataLookAt target = d->m_presenter.lookAt(); target.setCoordinates(coordinate); d->m_presenter.flyTo(target, Automatic); } void MarbleQuickItem::centerOn(qreal longitude, qreal latitude) { d->m_presenter.centerOn(longitude, latitude); } void MarbleQuickItem::centerOnCoordinates(qreal longitude, qreal latitude) { centerOn(longitude, latitude); } void MarbleQuickItem::centerOnCurrentPosition() { GeoDataCoordinates coordinates = d->m_model.positionTracking()->currentLocation(); if ( coordinates == GeoDataCoordinates() ) { return; } d->m_presenter.centerOn(coordinates, true); if (d->m_presenter.zoom() < 3000) { d->m_presenter.setZoom(3500); } } void MarbleQuickItem::selectPlacemarkAt(int x, int y) { auto features = d->m_map.whichFeatureAt(QPoint(x, y)); QVector placemarks; foreach(auto feature, features) { if (feature->nodeType() == GeoDataTypes::GeoDataPlacemarkType) { placemarks << static_cast(feature); } } foreach(auto placemark, placemarks) { if (d->m_placemark && placemark->coordinate() == d->m_placemark->placemark().coordinate()) { d->m_placemark->deleteLater(); d->m_placemark = nullptr; } else { if (d->m_placemark) { d->m_placemark->deleteLater(); } d->m_placemark = new Placemark(this); d->m_placemark->setGeoDataPlacemark(*placemark); } delete d->m_placemarkItem; d->m_placemarkItem = nullptr; updatePlacemarks(); return; } if (d->m_placemark) { d->m_placemark->deleteLater(); d->m_placemark = nullptr; delete d->m_placemarkItem; d->m_placemarkItem = nullptr; updatePlacemarks(); } } void MarbleQuickItem::goHome() { d->m_presenter.goHome(); } void MarbleQuickItem::zoomIn(FlyToMode mode) { d->m_presenter.zoomIn(mode); } void MarbleQuickItem::zoomOut(FlyToMode mode) { d->m_presenter.zoomOut(mode); } void MarbleQuickItem::handlePinchStarted(const QPointF &point) { pinch(point, 1, Qt::GestureStarted); } void MarbleQuickItem::handlePinchFinished(const QPointF &point) { pinch(point, 1, Qt::GestureFinished); } void MarbleQuickItem::handlePinchUpdated(const QPointF &point, qreal scale) { scale = sqrt(sqrt(scale)); scale = qBound(static_cast(0.5), scale, static_cast(2.0)); pinch(point, scale, Qt::GestureUpdated); } void MarbleQuickItem::setMapWidth(int mapWidth) { if (d->m_map.width() == mapWidth) { return; } d->m_map.setSize(mapWidth, mapHeight()); emit mapWidthChanged(mapWidth); } void MarbleQuickItem::setMapHeight(int mapHeight) { if (this->mapHeight() == mapHeight) { return; } d->m_map.setSize(mapWidth(), mapHeight); emit mapHeightChanged(mapHeight); } void MarbleQuickItem::setShowFrameRate(bool showFrameRate) { if (this->showFrameRate() == showFrameRate) { return; } d->m_map.setShowFrameRate(showFrameRate); emit showFrameRateChanged(showFrameRate); } void MarbleQuickItem::setProjection(Projection projection) { if (this->projection() == projection) { return; } d->m_map.setProjection((Marble::Projection)projection); emit projectionChanged(projection); } void MarbleQuickItem::setMapThemeId(const QString& mapThemeId) { if (this->mapThemeId() == mapThemeId) { return; } bool const showCompass = d->m_map.showCompass(); bool const showOverviewMap = d->m_map.showOverviewMap(); bool const showOtherPlaces = d->m_map.showOtherPlaces(); bool const showGrid = d->m_map.showGrid(); d->m_map.setMapThemeId(mapThemeId); // Map themes are allowed to change properties. Enforce ours. d->m_map.setShowCompass(showCompass); d->m_map.setShowOverviewMap(showOverviewMap); d->m_map.setShowOtherPlaces(showOtherPlaces); d->m_map.setShowGrid(showGrid); d->m_map.setShowScaleBar(d->m_showScaleBar); emit mapThemeIdChanged(mapThemeId); } void MarbleQuickItem::setShowAtmosphere(bool showAtmosphere) { if (this->showAtmosphere() == showAtmosphere) { return; } d->m_map.setShowAtmosphere(showAtmosphere); emit showAtmosphereChanged(showAtmosphere); } void MarbleQuickItem::setShowCompass(bool showCompass) { if (this->showCompass() == showCompass) { return; } d->m_map.setShowCompass(showCompass); emit showCompassChanged(showCompass); } void MarbleQuickItem::setShowClouds(bool showClouds) { if (this->showClouds() == showClouds) { return; } d->m_map.setShowClouds(showClouds); emit showCloudsChanged(showClouds); } void MarbleQuickItem::setShowCrosshairs(bool showCrosshairs) { if (this->showCrosshairs() == showCrosshairs) { return; } d->m_map.setShowCrosshairs(showCrosshairs); emit showCrosshairsChanged(showCrosshairs); } void MarbleQuickItem::setShowGrid(bool showGrid) { if (this->showGrid() == showGrid) { return; } d->m_map.setShowGrid(showGrid); emit showGridChanged(showGrid); } void MarbleQuickItem::setShowOverviewMap(bool showOverviewMap) { if (this->showOverviewMap() == showOverviewMap) { return; } d->m_map.setShowOverviewMap(showOverviewMap); emit showOverviewMapChanged(showOverviewMap); } void MarbleQuickItem::setShowOtherPlaces(bool showOtherPlaces) { if (this->showOtherPlaces() == showOtherPlaces) { return; } d->m_map.setShowOtherPlaces(showOtherPlaces); emit showOtherPlacesChanged(showOtherPlaces); } void MarbleQuickItem::setShowScaleBar(bool showScaleBar) { if (d->m_showScaleBar == showScaleBar) { return; } d->m_showScaleBar = showScaleBar; d->m_map.setShowScaleBar(d->m_showScaleBar); emit showScaleBarChanged(showScaleBar); } void MarbleQuickItem::setShowBackground(bool showBackground) { if (this->showBackground() == showBackground) { return; } d->m_map.setShowBackground(showBackground); emit showBackgroundChanged(showBackground); } void MarbleQuickItem::setShowPositionMarker(bool showPositionMarker) { if (this->showPositionMarker() == showPositionMarker) { return; } QList plugins = d->m_map.renderPlugins(); foreach ( RenderPlugin * plugin, plugins ) { if (plugin->nameId() == QLatin1String("positionMarker")) { plugin->setVisible(showPositionMarker); break; } } emit showPositionMarkerChanged(showPositionMarker); } void MarbleQuickItem::setPositionProvider(const QString &positionProvider) { QString name; if ( d->m_model.positionTracking()->positionProviderPlugin() ) { name = d->m_model.positionTracking()->positionProviderPlugin()->nameId(); if ( name == positionProvider ) { return; } } if ( positionProvider.isEmpty() ) { d->m_model.positionTracking()->setPositionProviderPlugin( nullptr ); return; } QList plugins = d->m_model.pluginManager()->positionProviderPlugins(); foreach (const PositionProviderPlugin* plugin, plugins) { if ( plugin->nameId() == positionProvider) { PositionProviderPlugin * newPlugin = plugin->newInstance(); d->m_model.positionTracking()->setPositionProviderPlugin(newPlugin); connect(newPlugin, SIGNAL(statusChanged(PositionProviderStatus)), this, SLOT(positionDataStatusChanged(PositionProviderStatus))); connect(newPlugin, SIGNAL(positionChanged(GeoDataCoordinates,GeoDataAccuracy)), this, SLOT(updateCurrentPosition(GeoDataCoordinates))); connect(newPlugin, SIGNAL(positionChanged(GeoDataCoordinates,GeoDataAccuracy)), this, SIGNAL(speedChanged())); connect(newPlugin, SIGNAL(positionChanged(GeoDataCoordinates,GeoDataAccuracy)), this, SIGNAL(angleChanged())); emit positionProviderChanged(positionProvider); break; } } } void MarbleQuickItem::setInertialGlobeRotation(bool inertialGlobeRotation) { if (inertialGlobeRotation == d->m_inputHandler.inertialEarthRotationEnabled()) { return; } d->m_inputHandler.setInertialEarthRotationEnabled(inertialGlobeRotation); emit inertialGlobeRotationChanged(inertialGlobeRotation); } void MarbleQuickItem::setAnimationViewContext(bool animationViewContext) { d->m_map.setViewContext(animationViewContext ? Animation : Still ); emit inertialGlobeRotationChanged(animationViewContext); } void MarbleQuickItem::setPluginSetting(const QString &pluginId, const QString &key, const QString &value) { foreach (RenderPlugin* plugin, d->m_map.renderPlugins()) { if (plugin->nameId() == pluginId) { plugin->setSetting(key, value); } } } void MarbleQuickItem::setPropertyEnabled(const QString &property, bool enabled) { d->m_map.setPropertyValue(property, enabled); } bool MarbleQuickItem::isPropertyEnabled(const QString &property) const { return d->m_map.propertyValue(property); } void MarbleQuickItem::setShowRuntimeTrace(bool showRuntimeTrace) { d->m_map.setShowRuntimeTrace(showRuntimeTrace); update(); } void MarbleQuickItem::setShowDebugPolygons(bool showDebugPolygons) { d->m_map.setShowDebugPolygons(showDebugPolygons); update(); } void MarbleQuickItem::setShowDebugPlacemarks(bool showDebugPlacemarks) { d->m_map.setShowDebugPlacemarks(showDebugPlacemarks); update(); } void MarbleQuickItem::setShowDebugBatches(bool showDebugBatches) { d->m_map.setShowDebugBatchRender(showDebugBatches); update(); } void MarbleQuickItem::setPlacemarkDelegate(QQmlComponent *placemarkDelegate) { if (d->m_placemarkDelegate == placemarkDelegate) { return; } delete d->m_placemarkItem; d->m_placemarkItem = nullptr; d->m_placemarkDelegate = placemarkDelegate; emit placemarkDelegateChanged(placemarkDelegate); } void MarbleQuickItem::loadSettings() { QSettings settings; settings.beginGroup(QStringLiteral("MarbleQuickItem")); double lon = settings.value(QStringLiteral("centerLon"), QVariant(0.0)).toDouble(); double lat = settings.value(QStringLiteral("centerLat"), QVariant(0.0)).toDouble(); if (lat == 0.0 && lon == 0.0) { centerOnCurrentPosition(); } else { centerOn(lon, lat); } int const zoom = settings.value(QStringLiteral("zoom"), QVariant(0)).toInt(); if (zoom > 0) { setZoom(zoom); } settings.endGroup(); d->m_model.routingManager()->readSettings(); d->m_model.bookmarkManager()->loadFile(QStringLiteral("bookmarks/bookmarks.kml")); d->m_model.bookmarkManager()->setShowBookmarks(true); } void MarbleQuickItem::writeSettings() { QSettings settings; settings.beginGroup(QStringLiteral("MarbleQuickItem")); settings.setValue(QStringLiteral("centerLon"), QVariant(d->m_map.centerLongitude())); settings.setValue(QStringLiteral("centerLat"), QVariant(d->m_map.centerLatitude())); settings.setValue(QStringLiteral("zoom"), QVariant(zoom())); settings.endGroup(); d->m_model.routingManager()->writeSettings(); } void MarbleQuickItem::reloadTiles() { d->m_map.reload(); } + void MarbleQuickItem::highlightRouteRelation(qint64 osmId, bool enabled) + { + d->m_map.highlightRouteRelation(osmId, enabled); + } + QObject *MarbleQuickItem::getEventFilter() const { //We would want to install the same event filter for abstract layer QuickItems such as PinchArea return &d->m_inputHandler; } void MarbleQuickItem::pinch(const QPointF& center, qreal scale, Qt::GestureState state) { d->m_inputHandler.pinch(center, scale, state); } MarbleInputHandler *MarbleQuickItem::inputHandler() { return &d->m_inputHandler; } int MarbleQuickItem::radius() const { return d->m_map.radius(); } int MarbleQuickItem::zoom() const { return d->m_presenter.logzoom(); } bool MarbleQuickItem::layersEventFilter(QObject *, QEvent *) { //Does nothing, but can be reimplemented in a subclass return false; } QuickItemSelectionRubber::QuickItemSelectionRubber() : m_visible(false) { // nothing to do } } diff --git a/src/lib/marble/declarative/MarbleQuickItem.h b/src/lib/marble/declarative/MarbleQuickItem.h index fbb688fd2..6760ff022 100644 --- a/src/lib/marble/declarative/MarbleQuickItem.h +++ b/src/lib/marble/declarative/MarbleQuickItem.h @@ -1,240 +1,241 @@ // // This file is part of the Marble Virtual Globe. // // This program is free software licensed under the GNU LGPL. You can // find a copy of this license in LICENSE.txt in the top directory of // the source code. // // Copyright 2014 Adam Dabrowski // #ifndef MARBLEQUICKITEM_H #define MARBLEQUICKITEM_H #include "marble_declarative_export.h" #include #include #include "GeoDataAccuracy.h" #include "MarbleGlobal.h" #include "PositionProviderPluginInterface.h" #include "MarbleMap.h" #include "Placemark.h" #include "Coordinate.h" namespace Marble { class GeoDataLatLonBox; class GeoDataPlacemark; class MarbleModel; class MarbleInputHandler; class MarbleQuickItemPrivate; //Class is still being developed class MARBLE_DECLARATIVE_EXPORT MarbleQuickItem : public QQuickPaintedItem { Q_OBJECT Q_ENUMS(Projection) Q_PROPERTY(int mapWidth READ mapWidth WRITE setMapWidth NOTIFY mapWidthChanged) Q_PROPERTY(int mapHeight READ mapHeight WRITE setMapHeight NOTIFY mapHeightChanged) Q_PROPERTY(int zoom READ zoom WRITE setZoom NOTIFY zoomChanged) Q_PROPERTY(int radius READ radius WRITE setRadius NOTIFY radiusChanged) Q_PROPERTY(bool showFrameRate READ showFrameRate WRITE setShowFrameRate NOTIFY showFrameRateChanged) Q_PROPERTY(Projection projection READ projection WRITE setProjection NOTIFY projectionChanged) Q_PROPERTY(QString mapThemeId READ mapThemeId WRITE setMapThemeId NOTIFY mapThemeIdChanged) Q_PROPERTY(bool showAtmosphere READ showAtmosphere WRITE setShowAtmosphere NOTIFY showAtmosphereChanged) Q_PROPERTY(bool showCompass READ showCompass WRITE setShowCompass NOTIFY showCompassChanged) Q_PROPERTY(bool showClouds READ showClouds WRITE setShowClouds NOTIFY showCloudsChanged) Q_PROPERTY(bool showCrosshairs READ showCrosshairs WRITE setShowCrosshairs NOTIFY showCrosshairsChanged) Q_PROPERTY(bool showGrid READ showGrid WRITE setShowGrid NOTIFY showGridChanged) Q_PROPERTY(bool showOverviewMap READ showOverviewMap WRITE setShowOverviewMap NOTIFY showOverviewMapChanged) Q_PROPERTY(bool showOtherPlaces READ showOtherPlaces WRITE setShowOtherPlaces NOTIFY showOtherPlacesChanged) Q_PROPERTY(bool showScaleBar READ showScaleBar WRITE setShowScaleBar NOTIFY showScaleBarChanged) Q_PROPERTY(bool showBackground READ showBackground WRITE setShowBackground NOTIFY showBackgroundChanged) Q_PROPERTY(bool showPositionMarker READ showPositionMarker WRITE setShowPositionMarker NOTIFY showPositionMarkerChanged) Q_PROPERTY(QString positionProvider READ positionProvider WRITE setPositionProvider NOTIFY positionProviderChanged) Q_PROPERTY(bool positionAvailable READ positionAvailable NOTIFY positionAvailableChanged) Q_PROPERTY(bool positionVisible READ positionVisible NOTIFY positionVisibleChanged) Q_PROPERTY(MarbleMap* marbleMap READ map NOTIFY marbleMapChanged) Q_PROPERTY(Placemark* currentPosition READ currentPosition NOTIFY currentPositionChanged) Q_PROPERTY(qreal speed READ speed NOTIFY speedChanged) Q_PROPERTY(qreal angle READ angle NOTIFY angleChanged) Q_PROPERTY(bool inertialGlobeRotation READ inertialGlobeRotation WRITE setInertialGlobeRotation NOTIFY inertialGlobeRotationChanged) Q_PROPERTY(bool animationViewContext READ animationViewContext WRITE setAnimationViewContext NOTIFY animationViewContextChanged) Q_PROPERTY(QQmlComponent* placemarkDelegate READ placemarkDelegate WRITE setPlacemarkDelegate NOTIFY placemarkDelegateChanged) public: explicit MarbleQuickItem(QQuickItem *parent = 0); enum Projection{ Spherical = Marble::Spherical, Equirectangular = Marble::Equirectangular, Mercator = Marble::Mercator, Gnomonic = Marble::Gnomonic, Stereographic = Marble::Stereographic, LambertAzimuthal = Marble::LambertAzimuthal, AzimuthalEquidistant = Marble::AzimuthalEquidistant, VerticalPerspective = Marble::VerticalPerspective }; MarbleInputHandler *inputHandler(); int zoom() const; int radius() const; public Q_SLOTS: void goHome(); void setZoom(int zoom, FlyToMode mode = Instant); Q_INVOKABLE void setZoomToMaximumLevel(); void setRadius(int radius); void centerOn(const GeoDataPlacemark& placemark, bool animated = false); void centerOn(const GeoDataLatLonBox& box, bool animated = false); void centerOn(const GeoDataCoordinates& coordinate); void centerOn(qreal longitude, qreal latitude); Q_INVOKABLE void centerOnCoordinates(qreal longitude, qreal latitude); Q_INVOKABLE void centerOnCurrentPosition(); Q_INVOKABLE void selectPlacemarkAt(int x, int y); void zoomIn(FlyToMode mode = Automatic); void zoomOut(FlyToMode mode = Automatic); Q_INVOKABLE void handlePinchStarted(const QPointF &point); Q_INVOKABLE void handlePinchFinished(const QPointF &point); Q_INVOKABLE void handlePinchUpdated(const QPointF &point, qreal scale); void setMapWidth(int mapWidth); void setMapHeight(int mapHeight); void setShowFrameRate(bool showFrameRate); void setProjection(Projection projection); void setMapThemeId(const QString& mapThemeId); void setShowAtmosphere(bool showAtmosphere); void setShowCompass(bool showCompass); void setShowClouds(bool showClouds); void setShowCrosshairs(bool showCrosshairs); void setShowGrid(bool showGrid); void setShowOverviewMap(bool showOverviewMap); void setShowOtherPlaces(bool showOtherPlaces); void setShowScaleBar(bool showScaleBar); void setShowBackground(bool showBackground); void setShowPositionMarker(bool showPositionMarker); void setPositionProvider(const QString & positionProvider); void setInertialGlobeRotation(bool inertialGlobeRotation); void setAnimationViewContext(bool animationViewContext); void setPluginSetting(const QString &plugin, const QString &key, const QString &value); void setPropertyEnabled(const QString &property, bool enabled); bool isPropertyEnabled(const QString &property) const; Q_INVOKABLE void setShowRuntimeTrace(bool showRuntimeTrace); Q_INVOKABLE void setShowDebugPolygons(bool showDebugPolygons); Q_INVOKABLE void setShowDebugPlacemarks(bool showDebugPlacemarks); Q_INVOKABLE void setShowDebugBatches(bool showDebugBatches); void setPlacemarkDelegate(QQmlComponent* placemarkDelegate); Q_INVOKABLE void loadSettings(); Q_INVOKABLE void writeSettings(); Q_INVOKABLE void reloadTiles(); + Q_INVOKABLE void highlightRouteRelation(qint64 osmId, bool enabled); public: void paint(QPainter *painter) override; // QQmlParserStatus interface public: void classBegin() override; void componentComplete() override; public: virtual bool layersEventFilter(QObject *o, QEvent *e); int mapWidth() const; int mapHeight() const; bool showFrameRate() const; Projection projection() const; QString mapThemeId() const; bool showAtmosphere() const; bool showCompass() const; bool showClouds() const; bool showCrosshairs() const; bool showGrid() const; bool showOverviewMap() const; bool showOtherPlaces() const; bool showScaleBar() const; bool showBackground() const; bool showPositionMarker() const; QString positionProvider() const; bool positionAvailable() const; bool positionVisible(); Q_INVOKABLE qreal distanceFromPointToCurrentLocation(const QPoint & position) const; Q_INVOKABLE qreal angleFromPointToCurrentLocation(const QPoint & position) const; Placemark* currentPosition() const; Q_INVOKABLE QPointF screenCoordinatesFromCoordinate(Coordinate * coordinate) const; qreal speed() const; qreal angle() const; MarbleModel* model(); const MarbleModel* model() const; MarbleMap* map(); const MarbleMap* map() const; bool inertialGlobeRotation() const; bool animationViewContext() const; QQmlComponent* placemarkDelegate() const; void reverseGeocoding(const QPoint &point); Q_SIGNALS: void mapWidthChanged(int mapWidth); void mapHeightChanged(int mapHeight); void showFrameRateChanged(bool showFrameRate); void projectionChanged(Projection projection); void mapThemeIdChanged(const QString& mapThemeId); void showAtmosphereChanged(bool showAtmosphere); void showCompassChanged(bool showCompass); void showCloudsChanged(bool showClouds); void showCrosshairsChanged(bool showCrosshairs); void showGridChanged(bool showGrid); void showOverviewMapChanged(bool showOverviewMap); void showOtherPlacesChanged(bool showOtherPlaces); void showScaleBarChanged(bool showScaleBar); void showBackgroundChanged(bool showBackground); void showPositionMarkerChanged(bool showPositionMarker); void positionProviderChanged(const QString & positionProvider); void positionAvailableChanged(bool positionAvailable); void positionVisibleChanged(bool positionVisible); void marbleMapChanged(); void visibleLatLonAltBoxChanged(); void currentPositionChanged(Placemark* currentPosition); void angleChanged(); void speedChanged(); void zoomChanged(); void radiusChanged(int radius); void inertialGlobeRotationChanged(bool inertialGlobeRotation); void animationViewContextChanged(bool animationViewContext); void placemarkDelegateChanged(QQmlComponent* placemarkDelegate); protected: QObject *getEventFilter() const; void pinch(const QPointF& center, qreal scale, Qt::GestureState state); private Q_SLOTS: void resizeMap(); void positionDataStatusChanged(PositionProviderStatus status); void positionChanged(const GeoDataCoordinates &, GeoDataAccuracy); void updatePositionVisibility(); void updateCurrentPosition(const GeoDataCoordinates & coordinates); void updatePlacemarks(); void handleReverseGeocoding(const GeoDataCoordinates &coordinates, const GeoDataPlacemark &placemark); private: typedef QSharedPointer MarbleQuickItemPrivatePtr; MarbleQuickItemPrivatePtr d; friend class MarbleQuickItemPrivate; }; } #endif // MARBLEQUICKITEM_H diff --git a/src/lib/marble/declarative/RouteRelationModel.cpp b/src/lib/marble/declarative/RouteRelationModel.cpp index a1d90c75d..3186ab7e8 100644 --- a/src/lib/marble/declarative/RouteRelationModel.cpp +++ b/src/lib/marble/declarative/RouteRelationModel.cpp @@ -1,173 +1,179 @@ // // This file is part of the Marble Virtual Globe. // // This program is free software licensed under the GNU LGPL. You can // find a copy of this license in LICENSE.txt in the top directory of // the source code. // // Copyright 2017 Sergey Popov // #include "RouteRelationModel.h" #include "MarbleDirs.h" #include "osm/OsmPlacemarkData.h" namespace Marble { RouteRelationModel::RouteRelationModel(QObject *parent) : QAbstractListModel(parent) { m_networks[QStringLiteral("iwn")] = tr("International walking route"); m_networks[QStringLiteral("nwn")] = tr("National walking route"); m_networks[QStringLiteral("rwn")] = tr("Regional walking route"); m_networks[QStringLiteral("lwn")] = tr("Local walking route"); m_networks[QStringLiteral("icn")] = tr("International cycling route"); m_networks[QStringLiteral("ncn")] = tr("National cycling route"); m_networks[QStringLiteral("rcn")] = tr("Regional cycling route"); m_networks[QStringLiteral("lcn")] = tr("Local cycling route"); m_networks[QStringLiteral("US:TX:FM")] = tr("Farm to Market Road", "State or county road in Texas, USA"); m_networks[QStringLiteral("regional")] = tr("Regional route"); m_networks[QStringLiteral("national")] = tr("National route"); m_networks[QStringLiteral("municipal")] = tr("Municipal route"); m_networks[QStringLiteral("territorial")] = tr("Territorial route"); m_networks[QStringLiteral("local")] = tr("Local route"); m_networks[QStringLiteral("prefectural")] = tr("Prefectural route"); m_networks[QStringLiteral("US")] = tr("United States route"); } void RouteRelationModel::setRelations(const QSet &relations) { if (!m_relations.isEmpty()) { beginRemoveRows(QModelIndex(), 0, m_relations.count() - 1); m_relations.clear(); endRemoveRows(); } if (!relations.isEmpty()) { beginInsertRows(QModelIndex(), 0, relations.count() - 1); m_relations.reserve(relations.size()); std::copy_if(relations.begin(), relations.end(), std::back_inserter(m_relations), [](const GeoDataRelation * relation) { return relation->relationType() >= GeoDataRelation::RouteRoad && relation->relationType() <= GeoDataRelation::RouteSled; }); std::sort(m_relations.begin(), m_relations.end(), [](const GeoDataRelation * a, const GeoDataRelation * b) { if (a->relationType() == b->relationType()) { auto const refA = a->osmData().tagValue(QStringLiteral("ref")); auto const refB = b->osmData().tagValue(QStringLiteral("ref")); if (refA == refB) { return a->name() < b->name(); } return refA < refB; } return a->relationType() < b->relationType(); }); endInsertRows(); } } int RouteRelationModel::rowCount(const QModelIndex & parent) const { return parent.isValid() ? 0 : m_relations.count(); } QVariant RouteRelationModel::data(const QModelIndex & index, int role) const { if (!index.isValid() || index.row() < 0 || index.row() >= m_relations.count()) { return QVariant(); } if (role == Qt::DisplayRole) { return m_relations.at(index.row())->name(); } else if (role == IconSource) { switch (m_relations.at(index.row())->relationType()) { case GeoDataRelation::RouteRoad: return svgFile("material/maps/ic_directions_car_48px.svg"); case GeoDataRelation::RouteDetour: return svgFile("material/maps/ic_directions_car_48px.svg"); case GeoDataRelation::RouteFerry: return svgFile("material/maps/ic_directions_boat_48px.svg"); case GeoDataRelation::RouteTrain: return svgFile("material/maps/ic_directions_railway_48px.svg"); case GeoDataRelation::RouteSubway: return svgFile("material/maps/ic_directions_subway_48px.svg"); case GeoDataRelation::RouteTram: return svgFile("material/maps/ic_tram_48px.svg"); case GeoDataRelation::RouteBus: return svgFile("material/maps/ic_directions_bus_48px.svg"); case GeoDataRelation::RouteTrolleyBus: return svgFile("material/maps/ic_directions_bus_48px.svg"); case GeoDataRelation::RouteBicycle: return svgFile("material/maps/ic_directions_bike_48px.svg"); case GeoDataRelation::RouteMountainbike: return svgFile("material/maps/ic_directions_bike_48px.svg"); case GeoDataRelation::RouteFoot: return svgFile("material/maps/ic_directions_walk_48px.svg"); case GeoDataRelation::RouteHiking: return svgFile("thenounproject/204712-hiker.svg"); case GeoDataRelation::RouteHorse: return svgFile("thenounproject/78374-horse-riding.svg"); case GeoDataRelation::RouteInlineSkates: return svgFile("thenounproject/101965-inline-skater.svg"); case GeoDataRelation::RouteSkiDownhill: return svgFile("thenounproject/2412-skiing-downhill.svg"); case GeoDataRelation::RouteSkiNordic: return svgFile("thenounproject/30231-skiing-cross-country.svg"); case GeoDataRelation::RouteSkitour: return svgFile("thenounproject/29366-skitour.svg"); case GeoDataRelation::RouteSled: return svgFile("thenounproject/365217-sled.svg"); case GeoDataRelation::UnknownType: return QVariant(QString()); } } else if (role == Description) { return m_relations.at(index.row())->osmData().tagValue(QStringLiteral("description")); } else if (role == Network) { auto const network = m_relations.at(index.row())->osmData().tagValue(QStringLiteral("network")); auto iter = m_networks.find(network); if (iter != m_networks.end()) { return *iter; } auto const fields = network.split(':', QString::SkipEmptyParts); for (auto const &field: fields) { auto iter = m_networks.find(field); if (iter != m_networks.end()) { return *iter; } } return network; } else if (role == RouteColor) { auto const color = m_relations.at(index.row())->osmData().tagValue(QStringLiteral("colour")); return color.isEmpty() ? QStringLiteral("white") : color; } else if (role == TextColor) { auto const colorValue = m_relations.at(index.row())->osmData().tagValue(QStringLiteral("colour")); auto const color = QColor(colorValue.isEmpty() ? QStringLiteral("white") : colorValue); return color.valueF() > 0.85 ? QStringLiteral("black") : QStringLiteral("white"); } else if (role == RouteFrom) { return m_relations.at(index.row())->osmData().tagValue(QStringLiteral("from")); } else if (role == RouteTo) { return m_relations.at(index.row())->osmData().tagValue(QStringLiteral("to")); } else if (role == RouteRef) { auto const ref = m_relations.at(index.row())->osmData().tagValue(QStringLiteral("ref")); return ref.isEmpty() ? m_relations.at(index.row())->name() : ref; } else if (role == RouteVia) { auto const viaValue = m_relations.at(index.row())->osmData().tagValue(QStringLiteral("via")); auto viaList = viaValue.split(';', QString::SkipEmptyParts); for (auto &via: viaList) { via = via.trimmed(); } return viaList; + } else if (role == OsmId) { + return m_relations.at(index.row())->osmData().oid(); + } else if (role == RouteVisible) { + return m_relations.at(index.row())->isVisible(); } return QVariant(); } QHash RouteRelationModel::roleNames() const { QHash roles; roles[Qt::DisplayRole] = "display"; roles[IconSource] = "iconSource"; roles[Description] = "description"; roles[Network] = "network"; roles[RouteColor] = "routeColor"; roles[TextColor] = "textColor"; roles[RouteFrom] = "routeFrom"; roles[RouteTo] = "routeTo"; roles[RouteRef] = "routeRef"; roles[RouteVia] = "routeVia"; + roles[OsmId] = "oid"; + roles[RouteVisible] = "routeVisible"; return roles; } QString RouteRelationModel::svgFile(const QString &path) const { #ifdef Q_OS_ANDROID return MarbleDirs::path(QStringLiteral("svg/%1").arg(path)); #else return QStringLiteral("file:///") + MarbleDirs::path(QStringLiteral("svg/%1").arg(path)); #endif } } diff --git a/src/lib/marble/declarative/RouteRelationModel.h b/src/lib/marble/declarative/RouteRelationModel.h index 5328a38d6..d2045c0ad 100644 --- a/src/lib/marble/declarative/RouteRelationModel.h +++ b/src/lib/marble/declarative/RouteRelationModel.h @@ -1,58 +1,60 @@ // // This file is part of the Marble Virtual Globe. // // This program is free software licensed under the GNU LGPL. You can // find a copy of this license in LICENSE.txt in the top directory of // the source code. // // Copyright 2017 Sergey Popov // #ifndef MARBLE_DECLARATIVE_ROUTERELATIONMODEL_H #define MARBLE_DECLARATIVE_ROUTERELATIONMODEL_H #include #include #include "GeoDataRelation.h" namespace Marble { class RouteRelationModel : public QAbstractListModel { Q_OBJECT public: enum RouteRelationRoles { IconSource = Qt::UserRole + 1, Description, Network, RouteColor, TextColor, RouteFrom, RouteTo, RouteRef, - RouteVia + RouteVia, + OsmId, + RouteVisible }; RouteRelationModel(QObject* parent = 0); void setRelations(const QSet &relations); int rowCount(const QModelIndex & parent = QModelIndex()) const override; QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override; protected: QHash roleNames() const override; private: QString svgFile(const QString &path) const; QVector m_relations; QMap m_networks; }; } #endif // ROUTERELATIONMODEL diff --git a/src/lib/marble/graphicsview/GeoGraphicsItem.cpp b/src/lib/marble/graphicsview/GeoGraphicsItem.cpp index 7c3884d14..9c87cc287 100644 --- a/src/lib/marble/graphicsview/GeoGraphicsItem.cpp +++ b/src/lib/marble/graphicsview/GeoGraphicsItem.cpp @@ -1,211 +1,216 @@ // // This file is part of the Marble Virtual Globe. // // This program is free software licensed under the GNU LGPL. You can // find a copy of this license in LICENSE.txt in the top directory of // the source code. // // Copyright 2009 Bastian Holst // // Self #include "GeoGraphicsItem.h" #include "GeoGraphicsItem_p.h" #include "GeoDataTypes.h" #include "GeoDataPlacemark.h" // Qt #include "MarbleDebug.h" #include using namespace Marble; GeoGraphicsItem::GeoGraphicsItem( const GeoDataFeature *feature ) : d( new GeoGraphicsItemPrivate( feature ) ) { setFlag( ItemIsVisible, true ); } GeoGraphicsItem::~GeoGraphicsItem() { delete d; } bool GeoGraphicsItem::visible() const { return d->m_flags & ItemIsVisible; } void GeoGraphicsItem::setVisible( bool visible ) { setFlag( ItemIsVisible, visible ); } GeoGraphicsItem::GeoGraphicsItemFlags GeoGraphicsItem::flags() const { return d->m_flags; } void GeoGraphicsItem::setFlag( GeoGraphicsItemFlag flag, bool enabled ) { if( enabled ) { d->m_flags = d->m_flags | flag; } else { d->m_flags = d->m_flags & ~flag; } } void GeoGraphicsItem::setFlags( GeoGraphicsItemFlags flags ) { d->m_flags = flags; } const GeoDataFeature* GeoGraphicsItem::feature() const { return d->m_feature; } void GeoGraphicsItem::setHighlightStyle( const GeoDataStyle::ConstPtr &highlightStyle) { /** * Delete any previously set style * and assign the new style @highlightStyle */ d->m_highlightStyle = highlightStyle; } GeoDataStyle::ConstPtr GeoGraphicsItem::style() const { /** * m_isHighlight is set true when the item is * supposed to be colored highlighted */ if ( d->m_highlighted && d->m_highlightStyle ) { return d->m_highlightStyle; } if (!d->m_style) { if (d->m_feature->nodeType() == GeoDataTypes::GeoDataPlacemarkType) { const GeoDataPlacemark *placemark = static_cast(d->m_feature); auto styling = StyleParameters(placemark, d->m_renderContext.tileLevel()); for (auto relation: d->m_relations) { if (relation->isVisible()) { styling.relation = relation; break; } } d->m_style = d->m_styleBuilder->createStyle(styling); } else { d->m_style = d->m_feature->style(); } } return d->m_style; } void GeoGraphicsItem::setStyleBuilder(const StyleBuilder *styleBuilder) { d->m_styleBuilder = styleBuilder; } +void GeoGraphicsItem::resetStyle() +{ + d->m_style = GeoDataStyle::ConstPtr(); +} + qreal GeoGraphicsItem::zValue() const { return d->m_zValue; } void GeoGraphicsItem::setZValue( qreal z ) { d->m_zValue = z; } void GeoGraphicsItem::setHighlighted( bool highlight ) { d->m_highlighted = highlight; } bool GeoGraphicsItem::isHighlighted() const { return d->m_highlighted; } QStringList GeoGraphicsItem::paintLayers() const { return d->m_paintLayers; } void GeoGraphicsItem::setPaintLayers(const QStringList &paintLayers) { d->m_paintLayers = paintLayers; } void GeoGraphicsItem::setRenderContext(const RenderContext &renderContext) { if (renderContext != d->m_renderContext) { d->m_renderContext = renderContext; d->m_style = GeoDataStyle::ConstPtr(); } } bool GeoGraphicsItem::contains(const QPoint &, const ViewportParams *) const { return false; } void GeoGraphicsItem::setRelations(const QSet &relations) { d->m_relations = relations; d->m_style = GeoDataStyle::ConstPtr(); } int GeoGraphicsItem::minZoomLevel() const { return d->m_minZoomLevel; } void GeoGraphicsItem::setMinZoomLevel(int zoomLevel) { d->m_minZoomLevel = zoomLevel; } bool GeoGraphicsItem::zValueLessThan(GeoGraphicsItem *one, GeoGraphicsItem *two) { return one->d->m_zValue < two->d->m_zValue; } bool GeoGraphicsItem::styleLessThan(GeoGraphicsItem *one, GeoGraphicsItem *two) { return reinterpret_cast(one->d->m_style.data()) < reinterpret_cast(two->d->m_style.data()); } bool GeoGraphicsItem::zValueAndStyleLessThan(GeoGraphicsItem *one, GeoGraphicsItem *two) { if (one->d->m_zValue == two->d->m_zValue) { return reinterpret_cast(one->d->m_style.data()) < reinterpret_cast(two->d->m_style.data()); } return one->d->m_zValue < two->d->m_zValue; } bool RenderContext::operator==(const RenderContext &other) const { return m_tileLevel == other.m_tileLevel; } bool RenderContext::operator!=(const RenderContext &other) const { return !operator==(other); } int RenderContext::tileLevel() const { return m_tileLevel; } RenderContext::RenderContext(int tileLevel) : m_tileLevel(tileLevel) { // nothing to do } diff --git a/src/lib/marble/graphicsview/GeoGraphicsItem.h b/src/lib/marble/graphicsview/GeoGraphicsItem.h index 37e48ac84..20cc894a6 100644 --- a/src/lib/marble/graphicsview/GeoGraphicsItem.h +++ b/src/lib/marble/graphicsview/GeoGraphicsItem.h @@ -1,170 +1,172 @@ // // This file is part of the Marble Virtual Globe. // // This program is free software licensed under the GNU LGPL. You can // find a copy of this license in LICENSE.txt in the top directory of // the source code. // // Copyright 2009 Bastian Holst // Copyright 2009 Andrew Manson // #ifndef MARBLE_GEOGRAPHICSITEM_H #define MARBLE_GEOGRAPHICSITEM_H // Marble #include "marble_export.h" #include "GeoDataStyle.h" class QString; namespace Marble { class GeoDataFeature; class GeoDataLatLonAltBox; class GeoDataCoordinates; class GeoGraphicsItemPrivate; class GeoPainter; class StyleBuilder; class ViewportParams; class GeoDataRelation; class RenderContext { public: bool operator==(const RenderContext &other) const; bool operator!=(const RenderContext &other) const; explicit RenderContext(int tileLevel = -1); int tileLevel() const; private: int m_tileLevel; }; class MARBLE_EXPORT GeoGraphicsItem { public: explicit GeoGraphicsItem( const GeoDataFeature *feature ); virtual ~GeoGraphicsItem(); enum GeoGraphicsItemFlag { NoOptions = 0x0, ItemIsMovable = 0x1, ItemIsSelectable = 0x2, ItemIsVisible = 0x4 }; Q_DECLARE_FLAGS(GeoGraphicsItemFlags, GeoGraphicsItemFlag) bool visible() const; void setVisible( bool visible ); /** * Get the GeoGraphicItemFlags value that describes which flags are set on * this item. @see QFlags */ GeoGraphicsItemFlags flags() const; /** * Set or unset a single flag * @param enabled sets if the flag is to be set or unset */ void setFlag( GeoGraphicsItemFlag flag, bool enabled = true ); /** * Replace all of the current flags. * @param flags is the new value for this item's flags. */ void setFlags( GeoGraphicsItemFlags flags ); /** * Returns the minim zoom level on which item will be active. */ int minZoomLevel() const; /** * Sets the minimum zoom level */ void setMinZoomLevel( int zoomLevel ); /** * Returns the placemark for that item. */ const GeoDataFeature* feature() const; /** * Returns the bounding box covered by the item. */ virtual const GeoDataLatLonAltBox &latLonAltBox() const = 0; /** * Returns the style of item. */ GeoDataStyle::ConstPtr style() const; /** * Set the style for the item. */ void setStyleBuilder(const StyleBuilder *styleBuilder); + void resetStyle(); + /** * Set the style which will be used when * placemark is highlighted. * GeoGraphicsItem takes ownership of the * passed style and deletes it when appropriate. */ void setHighlightStyle( const GeoDataStyle::ConstPtr &highlightStyle ); /** * Returns the z value of the item */ qreal zValue() const; /** * Set the z value of the item */ void setZValue( qreal z ); static bool zValueLessThan(GeoGraphicsItem* one, GeoGraphicsItem* two); static bool styleLessThan(GeoGraphicsItem* one, GeoGraphicsItem* two); static bool zValueAndStyleLessThan(GeoGraphicsItem* one, GeoGraphicsItem* two); /** * Paints the item using the given GeoPainter. * * Note that depending on the projection and zoom level, the item may be visible more than once, * which is taken care of by GeoPainter. */ virtual void paint(GeoPainter *painter, const ViewportParams *viewport, const QString &layer, int tileZoomLevel) = 0; void setHighlighted( bool highlight ); bool isHighlighted() const; QStringList paintLayers() const; void setPaintLayers(const QStringList &paintLayers); void setRenderContext(const RenderContext &renderContext); /** * @brief contains Returns true if the item contains the given coordinates * @param coordinates * @param screenPosition * @return */ virtual bool contains(const QPoint &screenPosition, const ViewportParams *viewport) const; void setRelations(const QSet &relations); protected: GeoGraphicsItemPrivate *const d; }; } // Namespace Marble Q_DECLARE_OPERATORS_FOR_FLAGS(Marble::GeoGraphicsItem::GeoGraphicsItemFlags) #endif diff --git a/src/lib/marble/layers/GeometryLayer.cpp b/src/lib/marble/layers/GeometryLayer.cpp index 458633189..68953eb5b 100644 --- a/src/lib/marble/layers/GeometryLayer.cpp +++ b/src/lib/marble/layers/GeometryLayer.cpp @@ -1,660 +1,674 @@ // // This file is part of the Marble Virtual Globe. // // This program is free software licensed under the GNU LGPL. You can // find a copy of this license in LICENSE.txt in the top directory of // the source code. // // Copyright 2008-2009 Patrick Spendrin // Copyright 2010 Thibaut Gridel // Copyright 2011-2012 Bernhard Beschow // Copyright 2014 Gábor Péterffy // #include "GeometryLayer.h" // Marble #include "GeoDataLatLonAltBox.h" #include "GeoDataDocument.h" #include "GeoDataFolder.h" #include "GeoDataLineStyle.h" #include "GeoDataMultiTrack.h" #include "GeoDataObject.h" #include "GeoDataPlacemark.h" #include "GeoDataLinearRing.h" #include "GeoDataMultiGeometry.h" #include "GeoDataPolygon.h" #include "GeoDataPolyStyle.h" #include "GeoDataStyle.h" #include "GeoDataIconStyle.h" #include "GeoDataStyleMap.h" #include "GeoDataTrack.h" #include "GeoDataTypes.h" #include "GeoDataFeature.h" #include "MarbleDebug.h" #include "GeoPainter.h" #include "ViewportParams.h" #include "RenderState.h" #include "GeoGraphicsScene.h" #include "GeoGraphicsItem.h" #include "GeoLineStringGraphicsItem.h" #include "GeoPolygonGraphicsItem.h" #include "GeoTrackGraphicsItem.h" #include "GeoDataPhotoOverlay.h" #include "GeoDataScreenOverlay.h" #include "GeoPhotoGraphicsItem.h" #include "ScreenOverlayGraphicsItem.h" #include "TileId.h" #include "MarbleGraphicsItem.h" #include "MarblePlacemarkModel.h" #include "GeoDataTreeModel.h" #include #include "StyleBuilder.h" #include "AbstractGeoPolygonGraphicsItem.h" #include "GeoLineStringGraphicsItem.h" #include "GeoDataRelation.h" // Qt #include #include #include namespace Marble { class GeometryLayerPrivate { public: typedef QVector OsmLineStringItems; typedef QSet Relations; typedef QHash FeatureRelationHash; struct PaintFragments { // Three lists for different z values // A z value of 0 is default and used by the majority of items, so sorting // can be avoided for it QVector negative; // subways QVector null; // areas and roads QVector positive; // buildings }; explicit GeometryLayerPrivate(const QAbstractItemModel *model, const StyleBuilder *styleBuilder); void createGraphicsItems(const GeoDataObject *object); void createGraphicsItems(const GeoDataObject *object, FeatureRelationHash &relations); void createGraphicsItemFromGeometry(const GeoDataGeometry *object, const GeoDataPlacemark *placemark, const Relations &relations); void createGraphicsItemFromOverlay(const GeoDataOverlay *overlay); void removeGraphicsItems(const GeoDataFeature *feature); void updateTiledLineStrings(const GeoDataPlacemark *placemark, GeoLineStringGraphicsItem* lineStringItem); void updateTiledLineStrings(OsmLineStringItems &lineStringItems); void clearCache(); const QAbstractItemModel *const m_model; const StyleBuilder *const m_styleBuilder; GeoGraphicsScene m_scene; QString m_runtimeTrace; QList m_screenOverlays; QHash m_osmLineStringItems; int m_tileLevel; GeoGraphicsItem* m_lastFeatureAt; bool m_dirty; int m_cachedItemCount; QHash m_cachedPaintFragments; typedef QPair LayerItem; QList m_cachedDefaultLayer; QDateTime m_cachedDateTime; GeoDataLatLonBox m_cachedLatLonBox; + QSet m_highlightedRouteRelations; }; GeometryLayerPrivate::GeometryLayerPrivate(const QAbstractItemModel *model, const StyleBuilder *styleBuilder) : m_model(model), m_styleBuilder(styleBuilder), m_tileLevel(0), m_lastFeatureAt(nullptr), m_dirty(true), m_cachedItemCount(0) { } void GeometryLayerPrivate::createGraphicsItems(const GeoDataObject *object) { FeatureRelationHash noRelations; createGraphicsItems(object, noRelations); } GeometryLayer::GeometryLayer(const QAbstractItemModel *model, const StyleBuilder *styleBuilder) : d(new GeometryLayerPrivate(model, styleBuilder)) { const GeoDataObject *object = static_cast(d->m_model->index(0, 0, QModelIndex()).internalPointer()); if (object && object->parent()) { d->createGraphicsItems(object->parent()); } connect(model, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this, SLOT(resetCacheData())); connect(model, SIGNAL(rowsInserted(QModelIndex, int, int)), this, SLOT(addPlacemarks(QModelIndex, int, int))); connect(model, SIGNAL(rowsAboutToBeRemoved(QModelIndex, int, int)), this, SLOT(removePlacemarks(QModelIndex, int, int))); connect(model, SIGNAL(modelReset()), this, SLOT(resetCacheData())); connect(this, SIGNAL(highlightedPlacemarksChanged(QVector)), &d->m_scene, SLOT(applyHighlight(QVector))); connect(&d->m_scene, SIGNAL(repaintNeeded()), this, SIGNAL(repaintNeeded())); } GeometryLayer::~GeometryLayer() { delete d; } QStringList GeometryLayer::renderPosition() const { return QStringList(QStringLiteral("HOVERS_ABOVE_SURFACE")); } bool GeometryLayer::render(GeoPainter *painter, ViewportParams *viewport, const QString& renderPos, GeoSceneLayer * layer) { Q_UNUSED(renderPos) Q_UNUSED(layer) painter->save(); auto const & box = viewport->viewLatLonAltBox(); bool isEqual = GeoDataLatLonBox::fuzzyCompare(d->m_cachedLatLonBox, box, 0.05); if (d->m_cachedLatLonBox.isEmpty() || !isEqual) { d->m_dirty = true; } // update the items cache at least every second since the last request auto const now = QDateTime::currentDateTime(); if (!d->m_cachedDateTime.isValid() || d->m_cachedDateTime.msecsTo(now) > 1000) { d->m_dirty = true; } if (d->m_dirty) { d->m_dirty = false; const int maxZoomLevel = qMin(d->m_tileLevel, d->m_styleBuilder->maximumZoomLevel()); auto const items = d->m_scene.items(box, maxZoomLevel);; d->m_cachedLatLonBox = box; d->m_cachedDateTime = now; d->m_cachedItemCount = items.size(); d->m_cachedDefaultLayer.clear(); d->m_cachedPaintFragments.clear(); QSet const knownLayers = QSet::fromList(d->m_styleBuilder->renderOrder()); foreach (GeoGraphicsItem* item, items) { QStringList paintLayers = item->paintLayers(); if (paintLayers.isEmpty()) { mDebug() << item << " provides no paint layers, so I force one onto it."; paintLayers << QString(); } foreach (const auto &layer, paintLayers) { if (knownLayers.contains(layer)) { GeometryLayerPrivate::PaintFragments & fragments = d->m_cachedPaintFragments[layer]; double const zValue = item->zValue(); // assign subway stations if (zValue == 0.0) { fragments.null << item; // assign areas and streets } else if (zValue < 0.0) { fragments.negative << item; // assign buildings } else { fragments.positive << item; } } else { // assign symbols d->m_cachedDefaultLayer << GeometryLayerPrivate::LayerItem(layer, item); static QSet missingLayers; if (!missingLayers.contains(layer)) { mDebug() << "Missing layer " << layer << ", in render order, will render it on top"; missingLayers << layer; } } } } // Sort each fragment by z-level foreach (const QString &layer, d->m_styleBuilder->renderOrder()) { GeometryLayerPrivate::PaintFragments & layerItems = d->m_cachedPaintFragments[layer]; std::sort(layerItems.negative.begin(), layerItems.negative.end(), GeoGraphicsItem::zValueLessThan); // The idea here is that layerItems.null has most items and does not need to be sorted by z-value // since they are all equal (=0). We do sort them by style pointer though for batch rendering std::sort(layerItems.null.begin(), layerItems.null.end(), GeoGraphicsItem::styleLessThan); std::sort(layerItems.positive.begin(), layerItems.positive.end(), GeoGraphicsItem::zValueAndStyleLessThan); } } foreach (const QString &layer, d->m_styleBuilder->renderOrder()) { GeometryLayerPrivate::PaintFragments & layerItems = d->m_cachedPaintFragments[layer]; AbstractGeoPolygonGraphicsItem::s_previousStyle = 0; GeoLineStringGraphicsItem::s_previousStyle = 0; foreach (auto item, layerItems.negative) { item->paint(painter, viewport, layer, d->m_tileLevel); } foreach (auto item, layerItems.null) { item->paint(painter, viewport, layer, d->m_tileLevel); } foreach (auto item, layerItems.positive) { item->paint(painter, viewport, layer, d->m_tileLevel); } } foreach (const auto & item, d->m_cachedDefaultLayer) { item.second->paint(painter, viewport, item.first, d->m_tileLevel); } foreach (ScreenOverlayGraphicsItem* item, d->m_screenOverlays) { item->paintEvent(painter, viewport); } painter->restore(); d->m_runtimeTrace = QStringLiteral("Geometries: %1 Zoom: %2") .arg(d->m_cachedItemCount) .arg(d->m_tileLevel); return true; } RenderState GeometryLayer::renderState() const { return RenderState(QStringLiteral("GeoGraphicsScene")); } QString GeometryLayer::runtimeTrace() const { return d->m_runtimeTrace; } bool GeometryLayer::hasFeatureAt(const QPoint &curpos, const ViewportParams *viewport) { if (d->m_lastFeatureAt && d->m_lastFeatureAt->contains(curpos, viewport)) { return true; } auto const renderOrder = d->m_styleBuilder->renderOrder(); for (int i = renderOrder.size() - 1; i >= 0; --i) { GeometryLayerPrivate::PaintFragments & layerItems = d->m_cachedPaintFragments[renderOrder[i]]; for (auto item : layerItems.positive) { if (item->contains(curpos, viewport)) { d->m_lastFeatureAt = item; return true; } } for (auto item : layerItems.null) { if (item->contains(curpos, viewport)) { d->m_lastFeatureAt = item; return true; } } for (auto item : layerItems.negative) { if (item->contains(curpos, viewport)) { d->m_lastFeatureAt = item; return true; } } } return false; } void GeometryLayerPrivate::createGraphicsItems(const GeoDataObject *object, FeatureRelationHash &relations) { clearCache(); if (object->nodeType() == GeoDataTypes::GeoDataDocumentType) { auto document = static_cast(object); for (auto feature: document->featureList()) { if (feature->nodeType() == GeoDataTypes::GeoDataRelationType) { auto relation = static_cast(feature); + if (m_highlightedRouteRelations.contains(relation->osmData().oid())) { + relation->setVisible(true); + } for (auto member: relation->members()) { relations[member] << relation; } } } } if (object->nodeType() == GeoDataTypes::GeoDataPlacemarkType) { auto placemark = static_cast(object); createGraphicsItemFromGeometry(placemark->geometry(), placemark, relations.value(placemark)); } else if (const GeoDataOverlay* overlay = dynamic_cast(object)) { createGraphicsItemFromOverlay(overlay); } // parse all child objects of the container if (const GeoDataContainer *container = dynamic_cast(object)) { int rowCount = container->size(); for (int row = 0; row < rowCount; ++row) { createGraphicsItems(container->child(row), relations); } } } void GeometryLayerPrivate::updateTiledLineStrings(const GeoDataPlacemark* placemark, GeoLineStringGraphicsItem* lineStringItem) { if (!placemark->hasOsmData()) { return; } qint64 const osmId = placemark->osmData().oid(); if (osmId <= 0) { return; } auto & lineStringItems = m_osmLineStringItems[osmId]; lineStringItems << lineStringItem; updateTiledLineStrings(lineStringItems); } void GeometryLayerPrivate::updateTiledLineStrings(OsmLineStringItems &lineStringItems) { GeoDataLineString merged; if (lineStringItems.size() > 1) { QVector lineStrings; for (auto item : lineStringItems) { lineStrings << item->lineString(); } merged = GeoLineStringGraphicsItem::merge(lineStrings); } // If merging failed, reset all. Otherwise only the first one // gets the merge result and becomes visible. bool visible = true; for (auto item : lineStringItems) { item->setVisible(visible); if (visible) { item->setMergedLineString(merged); visible = merged.isEmpty(); } } } void GeometryLayerPrivate::clearCache() { m_lastFeatureAt = nullptr; m_dirty = true; m_cachedDateTime = QDateTime(); m_cachedItemCount = 0; m_cachedPaintFragments.clear(); m_cachedDefaultLayer.clear(); m_cachedLatLonBox = GeoDataLatLonBox(); } void GeometryLayerPrivate::createGraphicsItemFromGeometry(const GeoDataGeometry* object, const GeoDataPlacemark *placemark, const Relations &relations) { if (!placemark->isGloballyVisible()) { return; // Reconsider this when visibility can be changed dynamically } GeoGraphicsItem *item = 0; if (object->nodeType() == GeoDataTypes::GeoDataLineStringType) { const GeoDataLineString* line = static_cast(object); auto lineStringItem = new GeoLineStringGraphicsItem(placemark, line); item = lineStringItem; updateTiledLineStrings(placemark, lineStringItem); } else if (object->nodeType() == GeoDataTypes::GeoDataLinearRingType) { const GeoDataLinearRing *ring = static_cast(object); item = GeoPolygonGraphicsItem::createGraphicsItem(placemark, ring); } else if (object->nodeType() == GeoDataTypes::GeoDataPolygonType) { const GeoDataPolygon *poly = static_cast(object); item = GeoPolygonGraphicsItem::createGraphicsItem(placemark, poly); if (item->zValue() == 0) { item->setZValue(poly->renderOrder()); } } else if (object->nodeType() == GeoDataTypes::GeoDataMultiGeometryType) { const GeoDataMultiGeometry *multigeo = static_cast(object); int rowCount = multigeo->size(); for (int row = 0; row < rowCount; ++row) { createGraphicsItemFromGeometry(multigeo->child(row), placemark, relations); } } else if (object->nodeType() == GeoDataTypes::GeoDataMultiTrackType) { const GeoDataMultiTrack *multitrack = static_cast(object); int rowCount = multitrack->size(); for (int row = 0; row < rowCount; ++row) { createGraphicsItemFromGeometry(multitrack->child(row), placemark, relations); } } else if (object->nodeType() == GeoDataTypes::GeoDataTrackType) { const GeoDataTrack *track = static_cast(object); item = new GeoTrackGraphicsItem(placemark, track); } if (!item) { return; } item->setRelations(relations); item->setStyleBuilder(m_styleBuilder); item->setVisible(item->visible() && placemark->isGloballyVisible()); item->setMinZoomLevel(m_styleBuilder->minimumZoomLevel(*placemark)); m_scene.addItem(item); } void GeometryLayerPrivate::createGraphicsItemFromOverlay(const GeoDataOverlay *overlay) { if (!overlay->isGloballyVisible()) { return; // Reconsider this when visibility can be changed dynamically } GeoGraphicsItem* item = 0; if (overlay->nodeType() == GeoDataTypes::GeoDataPhotoOverlayType) { GeoDataPhotoOverlay const * photoOverlay = static_cast(overlay); GeoPhotoGraphicsItem *photoItem = new GeoPhotoGraphicsItem(overlay); photoItem->setPoint(photoOverlay->point()); item = photoItem; } else if (overlay->nodeType() == GeoDataTypes::GeoDataScreenOverlayType) { GeoDataScreenOverlay const * screenOverlay = static_cast(overlay); ScreenOverlayGraphicsItem *screenItem = new ScreenOverlayGraphicsItem(screenOverlay); m_screenOverlays.push_back(screenItem); } if (item) { item->setStyleBuilder(m_styleBuilder); item->setVisible(overlay->isGloballyVisible()); m_scene.addItem(item); } } void GeometryLayerPrivate::removeGraphicsItems(const GeoDataFeature *feature) { clearCache(); if (feature->nodeType() == GeoDataTypes::GeoDataPlacemarkType) { GeoDataPlacemark const * placemark = static_cast(feature); if (placemark->isGloballyVisible() && placemark->geometry()->nodeType() == GeoDataTypes::GeoDataLineStringType && placemark->hasOsmData() && placemark->osmData().oid() > 0) { auto & items = m_osmLineStringItems[placemark->osmData().oid()]; bool removed = false; for (auto item : items) { if (item->feature() == feature) { items.removeOne(item); removed = true; break; } } Q_ASSERT(removed); updateTiledLineStrings(items); } m_scene.removeItem(feature); } else if (feature->nodeType() == GeoDataTypes::GeoDataFolderType || feature->nodeType() == GeoDataTypes::GeoDataDocumentType) { const GeoDataContainer *container = static_cast(feature); foreach (const GeoDataFeature *child, container->featureList()) { removeGraphicsItems(child); } } else if (feature->nodeType() == GeoDataTypes::GeoDataScreenOverlayType) { foreach (ScreenOverlayGraphicsItem *item, m_screenOverlays) { if (item->screenOverlay() == feature) { m_screenOverlays.removeAll(item); } } } } void GeometryLayer::addPlacemarks(const QModelIndex& parent, int first, int last) { Q_ASSERT(first < d->m_model->rowCount(parent)); Q_ASSERT(last < d->m_model->rowCount(parent)); for (int i = first; i <= last; ++i) { QModelIndex index = d->m_model->index(i, 0, parent); Q_ASSERT(index.isValid()); const GeoDataObject *object = qvariant_cast(index.data(MarblePlacemarkModel::ObjectPointerRole)); Q_ASSERT(object); d->createGraphicsItems(object); } emit repaintNeeded(); } void GeometryLayer::removePlacemarks(const QModelIndex& parent, int first, int last) { Q_ASSERT(last < d->m_model->rowCount(parent)); bool isRepaintNeeded = false; for (int i = first; i <= last; ++i) { QModelIndex index = d->m_model->index(i, 0, parent); Q_ASSERT(index.isValid()); const GeoDataObject *object = qvariant_cast(index.data(MarblePlacemarkModel::ObjectPointerRole)); const GeoDataFeature *feature = dynamic_cast(object); if (feature != 0) { d->removeGraphicsItems(feature); isRepaintNeeded = true; } } if (isRepaintNeeded) { emit repaintNeeded(); } } void GeometryLayer::resetCacheData() { d->clearCache(); d->m_scene.clear(); qDeleteAll(d->m_screenOverlays); d->m_screenOverlays.clear(); d->m_osmLineStringItems.clear(); const GeoDataObject *object = static_cast(d->m_model->index(0, 0, QModelIndex()).internalPointer()); if (object && object->parent()) { d->createGraphicsItems(object->parent()); } emit repaintNeeded(); } void GeometryLayer::setTileLevel(int tileLevel) { d->m_tileLevel = tileLevel; } QVector GeometryLayer::whichFeatureAt(const QPoint &curpos, const ViewportParams *viewport) { QVector result; auto const renderOrder = d->m_styleBuilder->renderOrder(); for (int i = renderOrder.size() - 1; i >= 0; --i) { GeometryLayerPrivate::PaintFragments & layerItems = d->m_cachedPaintFragments[renderOrder[i]]; for (auto item : layerItems.positive) { if (item->contains(curpos, viewport)) { result << item->feature(); } } for (auto item : layerItems.null) { if (item->contains(curpos, viewport)) { result << item->feature(); } } for (auto item : layerItems.negative) { if (item->contains(curpos, viewport)) { result << item->feature(); } } } return result; } +void GeometryLayer::highlightRouteRelation(qint64 osmId, bool enabled) +{ + if (enabled) { + d->m_highlightedRouteRelations << osmId; + } else { + d->m_highlightedRouteRelations.remove(osmId); + } + d->m_scene.resetStyle(); +} + void GeometryLayer::handleHighlight(qreal lon, qreal lat, GeoDataCoordinates::Unit unit) { GeoDataCoordinates clickedPoint(lon, lat, 0, unit); QVector selectedPlacemarks; for (int i = 0; i < d->m_model->rowCount(); ++i) { QVariant const data = d->m_model->data(d->m_model->index(i, 0), MarblePlacemarkModel::ObjectPointerRole); GeoDataObject *object = qvariant_cast (data); Q_ASSERT(object); if (object->nodeType() == GeoDataTypes::GeoDataDocumentType) { Q_ASSERT(dynamic_cast(object) != 0); GeoDataDocument* doc = static_cast(object); bool isHighlight = false; foreach (const GeoDataStyleMap &styleMap, doc->styleMaps()) { if (styleMap.contains(QStringLiteral("highlight"))) { isHighlight = true; break; } } /* * If a document doesn't specify any highlight * styleId in its style maps then there is no need * to further check that document for placemarks * which have been clicked because we won't * highlight them. */ if (isHighlight) { QVector::Iterator iter = doc->begin(); QVector::Iterator const end = doc->end(); for (; iter != end; ++iter) { if ((*iter)->nodeType() == GeoDataTypes::GeoDataPlacemarkType) { GeoDataPlacemark *placemark = static_cast(*iter); GeoDataPolygon *polygon = dynamic_cast(placemark->geometry()); GeoDataLineString *lineString = dynamic_cast(placemark->geometry()); GeoDataMultiGeometry *multiGeometry = dynamic_cast(placemark->geometry()); if (polygon && polygon->contains(clickedPoint)) { selectedPlacemarks.push_back(placemark); } if (lineString && lineString->nodeType() == GeoDataTypes::GeoDataLinearRingType) { GeoDataLinearRing *linearRing = static_cast(lineString); if (linearRing->contains(clickedPoint)) { selectedPlacemarks.push_back(placemark); } } if (multiGeometry) { QVector::Iterator multiIter = multiGeometry->begin(); QVector::Iterator const multiEnd = multiGeometry->end(); for (; multiIter != multiEnd; ++multiIter) { GeoDataPolygon *poly = dynamic_cast(*multiIter); GeoDataLineString *linestring = dynamic_cast(*multiIter); if (poly && poly->contains(clickedPoint)) { selectedPlacemarks.push_back(placemark); break; } if (linestring && linestring->nodeType() == GeoDataTypes::GeoDataLinearRingType) { GeoDataLinearRing *linearRing = static_cast(linestring); if (linearRing->contains(clickedPoint)) { selectedPlacemarks.push_back(placemark); break; } } } } } } } } } emit highlightedPlacemarksChanged(selectedPlacemarks); } } #include "moc_GeometryLayer.cpp" diff --git a/src/lib/marble/layers/GeometryLayer.h b/src/lib/marble/layers/GeometryLayer.h index 010d020f2..6b3ae8fb5 100644 --- a/src/lib/marble/layers/GeometryLayer.h +++ b/src/lib/marble/layers/GeometryLayer.h @@ -1,90 +1,92 @@ // // This file is part of the Marble Virtual Globe. // // This program is free software licensed under the GNU LGPL. You can // find a copy of this license in LICENSE.txt in the top directory of // the source code. // // Copyright 2008 Patrick Spendrin // Copyright 2010 Thibaut Gridel // Copyright 2011-2012 Bernhard Beschow // #ifndef MARBLE_GEOMETRYLAYER_H #define MARBLE_GEOMETRYLAYER_H #include #include "LayerInterface.h" #include "GeoDataCoordinates.h" class QAbstractItemModel; class QModelIndex; class QPoint; namespace Marble { class GeoPainter; class GeoDataFeature; class GeoDataPlacemark; class GeoDataRelation; class StyleBuilder; class ViewportParams; class GeometryLayerPrivate; class GeometryLayer : public QObject, public LayerInterface { Q_OBJECT public: explicit GeometryLayer(const QAbstractItemModel *model, const StyleBuilder *styleBuilder); ~GeometryLayer() override; QStringList renderPosition() const override; bool render( GeoPainter *painter, ViewportParams *viewport, const QString& renderPos = QLatin1String("NONE"), GeoSceneLayer * layer = 0 ) override; RenderState renderState() const override; QString runtimeTrace() const override; bool hasFeatureAt(const QPoint& curpos, const ViewportParams * viewport); QVector whichFeatureAt( const QPoint& curpos, const ViewportParams * viewport ); + void highlightRouteRelation(qint64 osmId, bool enabled); + public Q_SLOTS: void addPlacemarks( const QModelIndex& index, int first, int last ); void removePlacemarks( const QModelIndex& index, int first, int last ); void resetCacheData(); void setTileLevel(int tileLevel); /** * Finds all placemarks that contain the clicked point. * * The placemarks under the clicked position may * have their styleUrl set to a style map which * doesn't specify any highlight styleId. Such * placemarks will be fletered out in GeoGraphicsScene * and will not be highlighted. */ void handleHighlight( qreal lon, qreal lat, GeoDataCoordinates::Unit unit ); Q_SIGNALS: void repaintNeeded(); /** * @p selectedPlacemarks may contain placemarks which don't have * their styleUrl set to id of the style map which specifies * a highlight styleId. Such placemarks will be filtered out * in GeoGraphicsScene which will query for placemark->styleUrl() * to decide whether the placemark should be highlighted ot not. */ void highlightedPlacemarksChanged( const QVector& clickedPlacemarks ); private: GeometryLayerPrivate *d; }; } // namespace Marble #endif // MARBLE_GEOMETRYLAYER_H