diff --git a/src/lib/marble/geodata/graphicsitem/GeoLineStringGraphicsItem.cpp b/src/lib/marble/geodata/graphicsitem/GeoLineStringGraphicsItem.cpp index 8602a69f1..fed9c3f3f 100644 --- a/src/lib/marble/geodata/graphicsitem/GeoLineStringGraphicsItem.cpp +++ b/src/lib/marble/geodata/graphicsitem/GeoLineStringGraphicsItem.cpp @@ -1,324 +1,324 @@ // // 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 Andrew Manson // #include "GeoLineStringGraphicsItem.h" #include "GeoDataLineString.h" #include "GeoDataLineStyle.h" #include "GeoDataLabelStyle.h" #include "GeoDataPlacemark.h" #include "GeoDataPolyStyle.h" #include "GeoPainter.h" #include "StyleBuilder.h" #include "ViewportParams.h" #include "GeoDataStyle.h" #include "MarbleDebug.h" #include "MarbleMath.h" #include namespace Marble { GeoLineStringGraphicsItem::GeoLineStringGraphicsItem(const GeoDataPlacemark *placemark, const GeoDataLineString *lineString) : GeoGraphicsItem(placemark), m_lineString(lineString), m_renderLineString(lineString), m_renderLabel(false) { QString const category = StyleBuilder::visualCategoryName(placemark->visualCategory()); QStringList paintLayers; paintLayers << QLatin1String("LineString/") + category + QLatin1String("/outline"); paintLayers << QLatin1String("LineString/") + category + QLatin1String("/inline"); if (!feature()->name().isEmpty()) { paintLayers << QLatin1String("LineString/") + category + QLatin1String("/label"); } setPaintLayers(paintLayers); } void GeoLineStringGraphicsItem::setLineString( const GeoDataLineString* lineString ) { m_lineString = lineString; m_renderLineString = lineString; } const GeoDataLineString *GeoLineStringGraphicsItem::lineString() const { return m_lineString; } GeoDataLineString GeoLineStringGraphicsItem::merge(const QVector &lineStrings_) { if (lineStrings_.isEmpty()) { return GeoDataLineString(); } Q_ASSERT(!lineStrings_.isEmpty()); auto lineStrings = lineStrings_; GeoDataLineString result = *lineStrings.first(); lineStrings.pop_front(); for (bool matched = true; matched && !lineStrings.isEmpty();) { matched = false; for (auto lineString: lineStrings) { if (canMerge(result.first(), lineString->first())) { result.remove(0); result.reverse(); result << *lineString; lineStrings.removeOne(lineString); matched = true; break; } else if (canMerge(result.last(), lineString->first())) { result.remove(result.size()-1); result << *lineString; lineStrings.removeOne(lineString); matched = true; break; } else if (canMerge(result.first(), lineString->last())) { GeoDataLineString behind = result; result = *lineString; behind.remove(0); result << behind; lineStrings.removeOne(lineString); matched = true; break; } else if (canMerge(result.last(), lineString->last())) { GeoDataLineString behind = *lineString; behind.reverse(); behind.remove(0); result << behind; lineStrings.removeOne(lineString); matched = true; break; } } if (!matched) { return GeoDataLineString(); } } return lineStrings.isEmpty() ? result : GeoDataLineString(); } void GeoLineStringGraphicsItem::setMergedLineString(const GeoDataLineString &mergedLineString) { m_mergedLineString = mergedLineString; m_renderLineString = mergedLineString.isEmpty() ? m_lineString : &m_mergedLineString; } const GeoDataLatLonAltBox& GeoLineStringGraphicsItem::latLonAltBox() const { return m_renderLineString->latLonAltBox(); } void GeoLineStringGraphicsItem::paint(GeoPainter* painter, const ViewportParams* viewport , const QString &layer) { int const tileLevel = qLn( viewport->radius() / 64.0 ) / qLn( 2.0 ); setRenderContext(RenderContext(tileLevel)); if (layer.endsWith(QLatin1String("/outline"))) { qDeleteAll(m_cachedPolygons); m_cachedPolygons.clear(); painter->polygonsFromLineString(*m_renderLineString, m_cachedPolygons); if (m_cachedPolygons.empty()) { return; } if (painter->mapQuality() == HighQuality || painter->mapQuality() == PrintQuality) { - paintOutline(painter, viewport, m_cachedPolygons); + paintOutline(painter, viewport); } } else if (layer.endsWith(QLatin1String("/inline"))) { if (m_cachedPolygons.empty()) { return; } - paintInline(painter, viewport, m_cachedPolygons); + paintInline(painter, viewport); } else if (layer.endsWith(QLatin1String("/label"))) { if (!m_cachedPolygons.empty()) { if (m_renderLabel) { - paintLabel(painter, viewport, m_cachedPolygons); + paintLabel(painter, viewport); } } qDeleteAll(m_cachedPolygons); m_cachedPolygons.clear(); } else { qDeleteAll(m_cachedPolygons); m_cachedPolygons.clear(); painter->polygonsFromLineString(*m_renderLineString, m_cachedPolygons); if (m_cachedPolygons.empty()) { return; } foreach(const QPolygonF* itPolygon, m_cachedPolygons) { painter->drawPolyline(*itPolygon); } qDeleteAll(m_cachedPolygons); m_cachedPolygons.clear(); } } -void GeoLineStringGraphicsItem::paintInline(GeoPainter* painter, const ViewportParams* viewport, const QVector &polygons) +void GeoLineStringGraphicsItem::paintInline(GeoPainter* painter, const ViewportParams* viewport) { if ( ( !viewport->resolves( m_renderLineString->latLonAltBox(), 2) ) ) { return; } painter->save(); LabelPositionFlags labelPositionFlags = NoLabel; QPen currentPen = configurePainter(painter, viewport, labelPositionFlags); GeoDataStyle::ConstPtr style = this->style(); const GeoDataLineStyle& lineStyle = style->lineStyle(); if (lineStyle.cosmeticOutline() && lineStyle.penStyle() == Qt::SolidLine) { const float currentPenWidth = currentPen.widthF(); if (currentPenWidth > 2.5f) { currentPen.setWidthF(currentPenWidth - 2.0f); } currentPen.setColor(style->polyStyle().paintedColor()); painter->setPen( currentPen ); } - foreach(const QPolygonF* itPolygon, polygons) { + foreach(const QPolygonF* itPolygon, m_cachedPolygons) { painter->drawPolyline(*itPolygon); } painter->restore(); } -void GeoLineStringGraphicsItem::paintOutline(GeoPainter *painter, const ViewportParams *viewport, const QVector &polygons) +void GeoLineStringGraphicsItem::paintOutline(GeoPainter *painter, const ViewportParams *viewport) { if ( ( !viewport->resolves( m_renderLineString->latLonAltBox(), 2) ) ) { return; } painter->save(); LabelPositionFlags labelPositionFlags = NoLabel; QPen currentPen = configurePainter(painter, viewport, labelPositionFlags); m_renderLabel = !( currentPen.widthF() < 8.0f ); if (!( currentPen.widthF() < 2.5f )) { - foreach(const QPolygonF* itPolygon, polygons) { + foreach(const QPolygonF* itPolygon, m_cachedPolygons) { painter->drawPolyline(*itPolygon); } } painter->restore(); } -void GeoLineStringGraphicsItem::paintLabel(GeoPainter *painter, const ViewportParams *viewport, const QVector &polygons) +void GeoLineStringGraphicsItem::paintLabel(GeoPainter *painter, const ViewportParams *viewport) { if ( ( !viewport->resolves( m_renderLineString->latLonAltBox(), 2) ) ) { return; } painter->save(); LabelPositionFlags labelPositionFlags = NoLabel; QPen currentPen = configurePainter(painter, viewport, labelPositionFlags); GeoDataStyle::ConstPtr style = this->style(); const GeoDataLabelStyle& labelStyle = style->labelStyle(); // Activate the lines below to paint a label background which // prevents antialiasing overpainting glitches, but leads to // other glitches. //QColor const color = style->polyStyle().paintedColor(); //painter->setBackground(QBrush(color)); //painter->setBackgroundMode(Qt::OpaqueMode); - painter->drawLabelsForPolygons(polygons, feature()->name(), FollowLine, + painter->drawLabelsForPolygons(m_cachedPolygons, feature()->name(), FollowLine, labelStyle.paintedColor()); painter->restore(); } QPen GeoLineStringGraphicsItem::configurePainter(GeoPainter *painter, const ViewportParams *viewport, LabelPositionFlags &labelPositionFlags) const { QPen currentPen = painter->pen(); GeoDataStyle::ConstPtr style = this->style(); if (!style) { painter->setPen( QPen() ); } else { const GeoDataLineStyle& lineStyle = style->lineStyle(); const QColor linePaintedColor = lineStyle.paintedColor(); if (currentPen.color() != linePaintedColor) { currentPen.setColor(linePaintedColor); } const float lineWidth = lineStyle.width(); const float linePhysicalWidth = lineStyle.physicalWidth(); if (currentPen.widthF() != lineWidth || linePhysicalWidth != 0.0) { const float scaledLinePhysicalWidth = float(viewport->radius()) / EARTH_RADIUS * linePhysicalWidth; if (scaledLinePhysicalWidth < lineWidth) { currentPen.setWidthF(lineWidth); } else { currentPen.setWidthF(scaledLinePhysicalWidth); } } else if (lineWidth != 0.0 ) { currentPen.setWidthF(lineWidth); } const Qt::PenCapStyle lineCapStyle = lineStyle.capStyle(); if (currentPen.capStyle() != lineCapStyle) { currentPen.setCapStyle(lineCapStyle); } if (painter->mapQuality() == HighQuality || painter->mapQuality() == PrintQuality) { const Qt::PenStyle linePenStyle = lineStyle.penStyle(); if (currentPen.style() != linePenStyle) { currentPen.setStyle(linePenStyle); } if (linePenStyle == Qt::CustomDashLine) { currentPen.setDashPattern(lineStyle.dashPattern()); } } else { currentPen.setStyle(Qt::SolidLine); } if ( painter->mapQuality() != Marble::HighQuality && painter->mapQuality() != Marble::PrintQuality ) { QColor penColor = currentPen.color(); penColor.setAlpha( 255 ); currentPen.setColor( penColor ); } if ( painter->pen() != currentPen ) painter->setPen( currentPen ); if (lineStyle.background()) { QBrush brush = painter->background(); brush.setColor(style->polyStyle().paintedColor()); painter->setBackground( brush ); painter->setBackgroundMode( Qt::OpaqueMode ); } // label styles const GeoDataLabelStyle& labelStyle = style->labelStyle(); painter->setFont(labelStyle.font() ); switch (labelStyle.alignment()) { case GeoDataLabelStyle::Corner: case GeoDataLabelStyle::Right: labelPositionFlags |= LineStart; break; case GeoDataLabelStyle::Center: labelPositionFlags |= LineCenter; break; } } return currentPen; } bool GeoLineStringGraphicsItem::canMerge(const GeoDataCoordinates &a, const GeoDataCoordinates &b) { return distanceSphere(a, b) * EARTH_RADIUS < 0.1; } } diff --git a/src/lib/marble/geodata/graphicsitem/GeoLineStringGraphicsItem.h b/src/lib/marble/geodata/graphicsitem/GeoLineStringGraphicsItem.h index f1b74e3f8..97c6b9c18 100644 --- a/src/lib/marble/geodata/graphicsitem/GeoLineStringGraphicsItem.h +++ b/src/lib/marble/geodata/graphicsitem/GeoLineStringGraphicsItem.h @@ -1,55 +1,55 @@ // // 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 Andrew Manson // #ifndef MARBLE_GEOLINESTRINGGRAPHICSITEM_H #define MARBLE_GEOLINESTRINGGRAPHICSITEM_H #include "GeoGraphicsItem.h" #include "GeoDataCoordinates.h" #include "GeoDataLineString.h" #include "MarbleGlobal.h" #include "marble_export.h" namespace Marble { class GeoDataPlacemark; class MARBLE_EXPORT GeoLineStringGraphicsItem : public GeoGraphicsItem { public: explicit GeoLineStringGraphicsItem(const GeoDataPlacemark *placemark, const GeoDataLineString *lineString); void setLineString( const GeoDataLineString* lineString ); const GeoDataLineString* lineString() const; static GeoDataLineString merge(const QVector &lineStrings); void setMergedLineString(const GeoDataLineString &sharedLineString); virtual const GeoDataLatLonAltBox& latLonAltBox() const; void paint(GeoPainter* painter, const ViewportParams *viewport, const QString &layer); private: - void paintOutline(GeoPainter *painter, const ViewportParams *viewport, const QVector &polygons); - void paintInline(GeoPainter *painter, const ViewportParams *viewport, const QVector &polygons); - void paintLabel(GeoPainter *painter, const ViewportParams *viewport, const QVector &polygons); + void paintOutline(GeoPainter *painter, const ViewportParams *viewport); + void paintInline(GeoPainter *painter, const ViewportParams *viewport); + void paintLabel(GeoPainter *painter, const ViewportParams *viewport); QPen configurePainter(GeoPainter* painter, const ViewportParams *viewport, LabelPositionFlags &labelPositionFlags) const; static bool canMerge(const GeoDataCoordinates &a, const GeoDataCoordinates &b); const GeoDataLineString *m_lineString; const GeoDataLineString *m_renderLineString; GeoDataLineString m_mergedLineString; QVector m_cachedPolygons; bool m_renderLabel; }; } #endif