Commit c5aff6a9 authored by Bernhard Beschow's avatar Bernhard Beschow
Browse files

have house entries rendered by PlacemarkLayer

* allows them to be opened in the placemark dialog to see e.g. the address
parent b1a507ba
......@@ -29,7 +29,6 @@ BuildingGeoPolygonGraphicsItem::BuildingGeoPolygonGraphicsItem(const GeoDataPlac
const GeoDataPolygon *polygon)
: AbstractGeoPolygonGraphicsItem(placemark, polygon)
, m_buildingHeight(polygon->latLonAltBox().maxAltitude() - polygon->latLonAltBox().minAltitude())
, m_entries(extractNamedEntries(*placemark))
{
setZValue(this->zValue() + m_buildingHeight);
Q_ASSERT(m_buildingHeight > 0.0);
......@@ -44,7 +43,6 @@ BuildingGeoPolygonGraphicsItem::BuildingGeoPolygonGraphicsItem(const GeoDataPlac
const GeoDataLinearRing* ring)
: AbstractGeoPolygonGraphicsItem(placemark, ring)
, m_buildingHeight(ring->latLonAltBox().maxAltitude() - ring->latLonAltBox().minAltitude())
, m_entries(extractNamedEntries(*placemark))
{
setZValue(this->zValue() + m_buildingHeight);
Q_ASSERT(m_buildingHeight > 0.0);
......@@ -133,24 +131,6 @@ QPointF BuildingGeoPolygonGraphicsItem::buildingOffset(const QPointF &point, con
return QPointF(shiftX, shiftY);
}
QVector<BuildingGeoPolygonGraphicsItem::NamedEntry> BuildingGeoPolygonGraphicsItem::extractNamedEntries(const GeoDataPlacemark &placemark)
{
QVector<NamedEntry> entries;
const auto end = placemark.osmData().nodeReferencesEnd();
for (auto iter = placemark.osmData().nodeReferencesBegin(); iter != end; ++iter) {
const auto tagIter = iter.value().findTag(QStringLiteral("addr:housenumber"));
if (tagIter != iter.value().tagsEnd()) {
NamedEntry entry;
entry.point = iter.key();
entry.label = tagIter.value();
entries.push_back(entry);
}
}
return entries;
}
void BuildingGeoPolygonGraphicsItem::paint(GeoPainter* painter, const ViewportParams* viewport, const QString &layer)
{
if (layer.endsWith(QLatin1String("/frame"))) {
......@@ -177,30 +157,15 @@ void BuildingGeoPolygonGraphicsItem::paintRoof(GeoPainter* painter, const Viewpo
painter->save();
QPen const currentPen = configurePainter(painter, viewport);
qreal maxSize(0.0);
QPointF roofCenter;
if (hasInnerBoundaries) {
painter->setPen(Qt::NoPen);
}
// first paint the area and icon (and the outline if there are no inner boundaries)
double maxArea = 0.0;
foreach(QPolygonF* outlinePolygon, outlinePolygons) {
QRectF const boundingRect = outlinePolygon->boundingRect();
QPolygonF buildingRoof;
if (!m_entries.isEmpty()) {
QSizeF const polygonSize = boundingRect.size();
qreal size = polygonSize.width() * polygonSize.height();
if (size > maxSize) {
maxSize = size;
double area;
roofCenter = centroid(*outlinePolygon, area);
maxArea = qMax(area, maxArea);
roofCenter += buildingOffset(roofCenter, viewport);
}
}
if ( drawAccurate3D) {
buildingRoof.reserve(outlinePolygon->size());
foreach(const QPointF &point, *outlinePolygon) {
......@@ -236,32 +201,7 @@ void BuildingGeoPolygonGraphicsItem::paintRoof(GeoPainter* painter, const Viewpo
}
}
// Render additional housenumbers at building entries
if (!m_entries.isEmpty() && maxArea > 1600 * m_entries.size()) {
QBrush brush = painter->brush();
QColor const brushColor = brush.color();
QColor lighterColor = brushColor.lighter(110);
lighterColor.setAlphaF(0.9);
brush.setColor(lighterColor);
painter->setBrush(brush);
foreach(const auto &entry, m_entries) {
qreal x, y;
viewport->screenCoordinates(entry.point, x, y);
QPointF point(x, y);
point += buildingOffset(point, viewport);
auto const width = painter->fontMetrics().width(entry.label);
auto const height = painter->fontMetrics().height();
QRectF rectangle(point, QSizeF(qMax(1.2*width, 1.1*height), 1.2*height));
rectangle.moveCenter(point);
painter->drawRoundedRect(rectangle, 3, 3);
painter->drawText(rectangle, Qt::AlignCenter, entry.label);
}
brush.setColor(brushColor);
painter->setBrush(brush);
}
// then paint the outlines if there are inner boundaries
if (hasInnerBoundaries) {
painter->setPen(currentPen);
foreach(QPolygonF * polygon, outlinePolygons) {
......
......@@ -29,11 +29,6 @@ public:
virtual void paint(GeoPainter* painter, const ViewportParams *viewport, const QString &layer);
private:
struct NamedEntry {
GeoDataCoordinates point;
QString label;
};
void paintFrame(GeoPainter* painter, const ViewportParams *viewport);
void paintRoof(GeoPainter* painter, const ViewportParams *viewport);
void configureFramePainter(GeoPainter *painter) const;
......@@ -46,11 +41,9 @@ private:
static QPointF centroid(const QPolygonF &polygon, double &area);
static void screenPolygons(const ViewportParams *viewport, const GeoDataPolygon* polygon,
QVector<QPolygonF*> &polygons, QVector<QPolygonF*> &outlines);
static QVector<NamedEntry> extractNamedEntries(const GeoDataPlacemark &placemark);
private:
const double m_buildingHeight;
const QVector<NamedEntry> m_entries;
};
}
......
......@@ -10,8 +10,9 @@
#include <OsmRelation.h>
#include <MarbleDebug.h>
#include <GeoDataPlacemark.h>
#include <GeoDataLineStyle.h>
#include <GeoDataPlacemark.h>
#include <GeoDataPoint.h>
#include <GeoDataPolyStyle.h>
#include <GeoDataStyle.h>
#include <GeoDataDocument.h>
......@@ -81,9 +82,11 @@ void OsmWay::create(GeoDataDocument *document, const OsmNodes &nodes, QSet<qint6
OsmObjectManager::registerId(m_osmData.id());
const auto visualCategory = StyleBuilder::determineVisualCategory(m_osmData);
GeoDataPlacemark *placemark = new GeoDataPlacemark;
placemark->setGeometry(geometry);
placemark->setVisualCategory(StyleBuilder::determineVisualCategory(m_osmData));
placemark->setVisualCategory(visualCategory);
placemark->setName(m_osmData.tagValue(QStringLiteral("name")));
if (placemark->name().isEmpty()) {
placemark->setName(m_osmData.tagValue(QStringLiteral("ref")));
......@@ -95,9 +98,23 @@ void OsmWay::create(GeoDataDocument *document, const OsmNodes &nodes, QSet<qint6
placemark->setName(m_osmData.tagValue(QStringLiteral("addr:housenumber")));
}
placemark->setOsmData(osmData);
placemark->setVisible(placemark->visualCategory() != GeoDataPlacemark::None);
placemark->setVisible(visualCategory != GeoDataPlacemark::None);
document->append(placemark);
QVector<NamedEntry> namedEntries = extractNamedEntries(osmData);
if (!namedEntries.isEmpty()) {
foreach (const auto &namedEntry, namedEntries) {
GeoDataPlacemark *entry = new GeoDataPlacemark();
entry->setCoordinate(namedEntry.coordinates);
entry->setName(namedEntry.label);
entry->setOsmData(namedEntry.osmData);
entry->setVisualCategory(visualCategory);
entry->setVisible(visualCategory != GeoDataPlacemark::None);
document->append(entry);
}
}
}
const QVector<qint64> &OsmWay::references() const
......@@ -224,4 +241,23 @@ double OsmWay::extractBuildingHeight(const OsmPlacemarkData &osmData)
return qBound(1.0, height, 1000.0);
}
QVector<OsmWay::NamedEntry> OsmWay::extractNamedEntries(const OsmPlacemarkData &osmData)
{
QVector<NamedEntry> entries;
const auto end = osmData.nodeReferencesEnd();
for (auto iter = osmData.nodeReferencesBegin(); iter != end; ++iter) {
const auto tagIter = iter.value().findTag(QStringLiteral("addr:housenumber"));
if (tagIter != iter.value().tagsEnd()) {
NamedEntry entry;
entry.coordinates = iter.key();
entry.label = tagIter.value();
entry.osmData = *iter;
entries.push_back(entry);
}
}
return entries;
}
}
......@@ -34,11 +34,18 @@ public:
void create(GeoDataDocument* document, const OsmNodes &nodes, QSet<qint64> &usedNodes) const;
private:
struct NamedEntry {
GeoDataCoordinates coordinates;
QString label;
OsmPlacemarkData osmData;
};
bool isArea() const;
static bool isAreaTag(const StyleBuilder::OsmTag &keyValue);
static double extractBuildingHeight(const OsmPlacemarkData &osmData);
static QVector<NamedEntry> extractNamedEntries(const OsmPlacemarkData &osmData);
OsmPlacemarkData m_osmData;
QVector<qint64> m_references;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment