From d891afbfe691e53cfdef2f63f52795f4cc8f6c48 Mon Sep 17 00:00:00 2001 From: tteuling Date: Thu, 14 Oct 2021 15:02:02 +0200 Subject: [PATCH] Further clean ups and preperation for further cleanups. --- .../src/osmscout/MapPainterQt.cpp | 2 +- .../include/osmscoutmap/LabelLayouter.h | 104 ++++++++---- .../include/osmscoutmap/MapPainter.h | 6 - libosmscout-map/include/osmscoutmap/Styles.h | 12 ++ .../src/osmscoutmap/MapPainter.cpp | 148 +++++++----------- libosmscout-map/src/osmscoutmap/Styles.cpp | 14 ++ .../include/osmscout/util/Transformation.h | 4 + 7 files changed, 160 insertions(+), 130 deletions(-) diff --git a/libosmscout-map-qt/src/osmscout/MapPainterQt.cpp b/libosmscout-map-qt/src/osmscout/MapPainterQt.cpp index 8463e7714..ef86c2616 100644 --- a/libosmscout-map-qt/src/osmscout/MapPainterQt.cpp +++ b/libosmscout-map-qt/src/osmscout/MapPainterQt.cpp @@ -1016,7 +1016,7 @@ namespace osmscout { const MapParameter& parameter, const MapData& /*data*/) { - if (delegateLabelLayouter){ + if (delegateLabelLayouter !=nullptr){ return; } diff --git a/libosmscout-map/include/osmscoutmap/LabelLayouter.h b/libosmscout-map/include/osmscoutmap/LabelLayouter.h index f3aa22b51..8c2f7661b 100644 --- a/libosmscout-map/include/osmscoutmap/LabelLayouter.h +++ b/libosmscout-map/include/osmscoutmap/LabelLayouter.h @@ -606,47 +606,85 @@ namespace osmscout { } } + // should be made private + void ProcessLabel(const Projection& projection, + const MapParameter& parameter, + const Vertex2D& point, + LabelInstanceType& instance, + double& offset, + const LabelData& data, + double objectWidth) + { + typename LabelInstance::Element element; + element.labelData=data; + if (data.type==LabelData::Type::Icon || data.type==LabelData::Type::Symbol){ + instance.priority = std::min(data.priority, instance.priority); + element.x = point.GetX() - data.iconWidth / 2; + if (offset<0){ + element.y = point.GetY() - data.iconHeight / 2; + offset = point.GetY() + data.iconHeight / 2; + } else { + element.y = offset; + offset += data.iconHeight; + } + }else { + instance.priority = std::min(data.priority, instance.priority); + // TODO: should we take style into account? + // Qt allows to split text layout and style setup + element.label = textLayouter->Layout(projection, parameter, + data.text, data.fontSize, + objectWidth, + /*enable wrapping*/ true, + /*contour label*/ false); + element.x = point.GetX() - element.label->width / 2; + if (offset<0){ + element.y = point.GetY() - element.label->height / 2; + offset = point.GetY() + element.label->height / 2; + } else { + element.y = offset; + offset += element.label->height; + } + } + instance.elements.push_back(element); + } + void RegisterLabel(const Projection& projection, const MapParameter& parameter, const Vertex2D& point, - const std::vector &data, + const LabelData& data, double objectWidth = 10.0) { LabelInstanceType instance; double offset=-1; - for (const auto &d:data) { - typename LabelInstance::Element element; - element.labelData=d; - if (d.type==LabelData::Type::Icon || d.type==LabelData::Type::Symbol){ - instance.priority = std::min(d.priority, instance.priority); - element.x = point.GetX() - d.iconWidth / 2; - if (offset<0){ - element.y = point.GetY() - d.iconHeight / 2; - offset = point.GetY() + d.iconHeight / 2; - } else { - element.y = offset; - offset += d.iconHeight; - } - }else { - instance.priority = std::min(d.priority, instance.priority); - // TODO: should we take style into account? - // Qt allows to split text layout and style setup - element.label = textLayouter->Layout(projection, parameter, - d.text, d.fontSize, - objectWidth, - /*enable wrapping*/ true, - /*contour label*/ false); - element.x = point.GetX() - element.label->width / 2; - if (offset<0){ - element.y = point.GetY() - element.label->height / 2; - offset = point.GetY() + element.label->height / 2; - } else { - element.y = offset; - offset += element.label->height; - } - } - instance.elements.push_back(element); + ProcessLabel(projection, + parameter, + point, + instance, + offset, + data, + objectWidth); + + labelInstances.push_back(instance); + } + + void RegisterLabel(const Projection& projection, + const MapParameter& parameter, + const Vertex2D& point, + const std::vector& data, + double objectWidth = 10.0) + { + LabelInstanceType instance; + + double offset=-1; + for (const auto& d : data) { + ProcessLabel(projection, + parameter, + point, + instance, + offset, + d, + objectWidth); } labelInstances.push_back(instance); diff --git a/libosmscout-map/include/osmscoutmap/MapPainter.h b/libosmscout-map/include/osmscoutmap/MapPainter.h index b60faf1ba..be2e31d9c 100644 --- a/libosmscout-map/include/osmscoutmap/MapPainter.h +++ b/libosmscout-map/include/osmscoutmap/MapPainter.h @@ -474,12 +474,6 @@ namespace osmscout { const GeoBox& boundingBox, double pixelOffset) const; - void Transform(const Projection& projection, - const MapParameter& parameter, - const GeoCoord& coord, - double& x, - double& y) const; - double GetProjectedWidth(const Projection& projection, double minPixel, double width) const; diff --git a/libosmscout-map/include/osmscoutmap/Styles.h b/libosmscout-map/include/osmscoutmap/Styles.h index 172cda006..74a33d7ed 100644 --- a/libosmscout-map/include/osmscoutmap/Styles.h +++ b/libosmscout-map/include/osmscoutmap/Styles.h @@ -58,6 +58,8 @@ namespace osmscout { sidecar //!< special offset for routes, line are stacked next to way, same colors are "collapsed" }; + extern bool IsLaneOffset(OffsetRel rel); + /** * \ingroup Stylesheet * @@ -1283,11 +1285,21 @@ namespace osmscout { return symbolSpace; } + bool HasDisplayOffset() const + { + return displayOffset!=0.0; + } + double GetDisplayOffset() const { return displayOffset; } + bool HasOffset() const + { + return offset!=0.0; + } + double GetOffset() const { return offset; diff --git a/libosmscout-map/src/osmscoutmap/MapPainter.cpp b/libosmscout-map/src/osmscoutmap/MapPainter.cpp index 5a79cbebe..eea03f324 100644 --- a/libosmscout-map/src/osmscoutmap/MapPainter.cpp +++ b/libosmscout-map/src/osmscoutmap/MapPainter.cpp @@ -271,20 +271,18 @@ namespace osmscout { for (const auto& ring : area->rings) { statistic.coordCount+=ring.nodes.size(); - if (parameter.IsDebugData()) { - if (ring.IsMaster()) { - IconStyleRef iconStyle=styleConfig.GetAreaIconStyle(area->GetType(), - ring.GetFeatureValueBuffer(), - projection); - - if (iconStyle) { - statistic.iconCount++; - } + if (parameter.IsDebugData() && ring.IsMaster()) { + IconStyleRef iconStyle=styleConfig.GetAreaIconStyle(area->GetType(), + ring.GetFeatureValueBuffer(), + projection); - statistic.labelCount+=styleConfig.GetAreaTextStyleCount(area->GetType(), - ring.GetFeatureValueBuffer(), - projection); + if (iconStyle) { + statistic.iconCount++; } + + statistic.labelCount+=styleConfig.GetAreaTextStyleCount(area->GetType(), + ring.GetFeatureValueBuffer(), + projection); } } } @@ -544,16 +542,6 @@ namespace osmscout { yMax<0); } - void MapPainter::Transform(const Projection& projection, - const MapParameter& /*parameter*/, - const GeoCoord& coord, - double& x, - double& y) const - { - projection.GeoToPixel(coord, - x,y); - } - double MapPainter::GetProjectedWidth(const Projection& projection, double minPixel, double width) const @@ -603,7 +591,8 @@ namespace osmscout { shieldGridSizeVert); for (const auto& gridPoint : gridPoints) { - double x,y; + double x; + double y; projection.GeoToPixel(gridPoint,x,y); @@ -615,8 +604,7 @@ namespace osmscout { labelBox.style=style; labelBox.text=text; - std::vector vect; - vect.push_back(labelBox); + std::vector vect = {labelBox}; RegisterRegularLabel(projection, parameter, vect, Vertex2D(x,y), /*proposedWidth*/ -1); } } @@ -671,7 +659,8 @@ namespace osmscout { data.iconHeight=iconStyle->GetHeight(); labelLayoutData.push_back(data); - } else if (iconStyle->GetSymbol()) { + } + else if (iconStyle->GetSymbol()) { LabelData data; data.type=LabelData::Type::Symbol; @@ -701,8 +690,8 @@ namespace osmscout { if (projection.GetMagnification()>textStyle->GetScaleAndFadeMag() && parameter.GetDrawFadings()) { double factor=projection.GetMagnification().GetLevel()-textStyle->GetScaleAndFadeMag().GetLevel(); - data.fontSize=textStyle->GetSize()*pow(1.5,factor); + data.fontSize=textStyle->GetSize()*pow(1.5,factor); data.alpha=std::min(textStyle->GetAlpha()/factor, 1.0); } else if (textStyle->GetAutoSize()) { @@ -712,7 +701,7 @@ namespace osmscout { continue; } - // Retricts the height of a label to maxHeight + // Restricts the height of a label to maxHeight double alpha=textStyle->GetAlpha(); double maxHeight=projection.GetHeight()/5.0; @@ -729,7 +718,6 @@ namespace osmscout { } else { data.fontSize=textStyle->GetSize(); - data.alpha=textStyle->GetAlpha(); } @@ -950,12 +938,12 @@ namespace osmscout { double symbolSpace=projection.ConvertWidthToPixel(borderSymbolStyle->GetSymbolSpace()); CoordBufferRange range=areaData.coordRange; - if (borderSymbolStyle->GetOffset()!=0.0) { + if (borderSymbolStyle->HasOffset()) { lineOffset+=GetProjectedWidth(projection, borderSymbolStyle->GetOffset()); } - if (borderSymbolStyle->GetDisplayOffset()!=0.0) { + if (borderSymbolStyle->HasDisplayOffset()) { lineOffset+=projection.ConvertWidthToPixel(borderSymbolStyle->GetDisplayOffset()); } @@ -986,12 +974,11 @@ namespace osmscout { projection, textStyles); - double x,y; + double x; + double y; - Transform(projection, - parameter, - node->GetCoords(), - x,y); + projection.GeoToPixel(node->GetCoords(), + x,y); LayoutPointLabels(projection, parameter, @@ -1048,21 +1035,11 @@ namespace osmscout { const LanesFeatureValue *lanesValue=nullptr; std::vector laneTurns; // cached turns - for (const auto &pathSymbolStyle : symbolStyles) { + for (const auto& pathSymbolStyle : symbolStyles) { CoordBufferRange range=data.coordRange; double symbolSpace = projection.ConvertWidthToPixel(pathSymbolStyle->GetSymbolSpace()); - if (pathSymbolStyle->GetOffsetRel() == OffsetRel::laneForwardLeft || - pathSymbolStyle->GetOffsetRel() == OffsetRel::laneForwardThroughLeft || - pathSymbolStyle->GetOffsetRel() == OffsetRel::laneForwardThrough || - pathSymbolStyle->GetOffsetRel() == OffsetRel::laneForwardThroughRight || - pathSymbolStyle->GetOffsetRel() == OffsetRel::laneForwardRight || - pathSymbolStyle->GetOffsetRel() == OffsetRel::laneBackwardLeft || - pathSymbolStyle->GetOffsetRel() == OffsetRel::laneBackwardThroughLeft || - pathSymbolStyle->GetOffsetRel() == OffsetRel::laneBackwardThrough || - pathSymbolStyle->GetOffsetRel() == OffsetRel::laneBackwardThroughRight || - pathSymbolStyle->GetOffsetRel() == OffsetRel::laneBackwardRight ) { - + if (IsLaneOffset(pathSymbolStyle->GetOffsetRel())) { if (lanesValue==nullptr) { lanesValue=lanesReader.GetValue(*data.buffer); } @@ -1083,7 +1060,7 @@ namespace osmscout { for (const OffsetRel &laneTurn: laneTurns) { if (pathSymbolStyle->GetOffsetRel() == laneTurn) { range=coordBuffer.GenerateParallelWay(range, - laneOffset); + laneOffset); DrawContourSymbol(projection, parameter, @@ -1097,12 +1074,12 @@ namespace osmscout { else { double lineOffset = 0.0; - if (pathSymbolStyle->GetOffset() != 0.0) { + if (pathSymbolStyle->HasOffset()) { lineOffset += GetProjectedWidth(projection, pathSymbolStyle->GetOffset()); } - if (pathSymbolStyle->GetDisplayOffset() != 0.0) { + if (pathSymbolStyle->HasDisplayOffset()) { lineOffset += projection.ConvertWidthToPixel(pathSymbolStyle->GetDisplayOffset()); } @@ -1324,28 +1301,24 @@ namespace osmscout { const MapParameter& parameter, const AreaRef &area) { - std::vector td(area->rings.size()); + std::vector td(area->rings.size()); // Polygon information for each ring for (size_t i=0; irings.size(); i++) { const Area::Ring &ring = area->rings[i]; // The master ring does not have any nodes, so we skip it // Rings with less than 3 nodes should be skipped, too (no area) if (ring.IsMaster() || ring.nodes.size() < 3) { - td[i].transStart=0; - td[i].transEnd=0; + // td is initialized to empty by default continue; } if (ring.segments.size() <= 1){ - CoordBufferRange range=TransformArea(ring.nodes, - transBuffer, - coordBuffer, - projection, - parameter.GetOptimizeAreaNodes(), - errorTolerancePixel); - - td[i].transStart=range.GetStart(); - td[i].transEnd=range.GetEnd(); + td[i]=TransformArea(ring.nodes, + transBuffer, + coordBuffer, + projection, + parameter.GetOptimizeAreaNodes(), + errorTolerancePixel); } else { std::vector nodes; @@ -1354,21 +1327,19 @@ namespace osmscout { if (projection.GetDimensions().Intersects(segment.bbox, false)){ // TODO: add TransBuffer::Transform* methods with vector subrange (begin/end) nodes.insert(nodes.end(), ring.nodes.data() + segment.from, ring.nodes.data() + segment.to); - } else { + } + else { nodes.push_back(ring.nodes[segment.from]); nodes.push_back(ring.nodes[segment.to-1]); } } - CoordBufferRange range=TransformArea(nodes, - transBuffer, - coordBuffer, - projection, - parameter.GetOptimizeAreaNodes(), - errorTolerancePixel); - - td[i].transStart=range.GetStart(); - td[i].transEnd=range.GetEnd(); + td[i]=TransformArea(nodes, + transBuffer, + coordBuffer, + projection, + parameter.GetOptimizeAreaNodes(), + errorTolerancePixel); } } @@ -1379,7 +1350,8 @@ namespace osmscout { // there may be nested outer rings return true; } - if (td[i].transStart==td[i].transEnd) { + + if (!td[i].IsValid()) { return false; // ring was skipped or reduced to single point } @@ -1433,8 +1405,13 @@ namespace osmscout { // we currently assume that it does not have alpha and paints over its region and clipping is // not required. area->VisitClippingRings(i, [&a, &td](size_t j, const Area::Ring &, const TypeInfoRef &type) -> bool { - if (type->GetIgnore() && td[j].transStart < td[j].transEnd) { - a.clippings.push_back(td[j]); + if (type->GetIgnore() && td[j].IsValid()) { + PolyData data; + + data.transStart=td[j].GetStart(); + data.transEnd=td[j].GetEnd(); + + a.clippings.push_back(data); } return true; }); @@ -1444,7 +1421,7 @@ namespace osmscout { a.buffer=&ring.GetFeatureValueBuffer(); a.fillStyle=fillStyle; a.borderStyle=borderStyle; - a.coordRange=CoordBufferRange(td[i].transStart,td[i].transEnd); + a.coordRange=td[i]; areaData.push_back(a); @@ -1455,7 +1432,7 @@ namespace osmscout { double offset=0.0; - CoordBufferRange range=CoordBufferRange(td[i].transStart,td[i].transEnd); + CoordBufferRange range=td[i]; if (borderStyle->GetOffset()!=0.0) { offset+=GetProjectedWidth(projection, @@ -1591,7 +1568,8 @@ namespace osmscout { if (projection.GetDimensions().Intersects(segment.bbox, false)){ // TODO: add TransBuffer::Transform* methods with vector subrange (begin/end) nodes.insert(nodes.end(), way.nodes.data() + segment.from, way.nodes.data() + segment.to); - } else { + } + else { nodes.push_back(way.nodes[segment.from]); nodes.push_back(way.nodes[segment.to-1]); } @@ -1780,17 +1758,7 @@ namespace osmscout { laneOffset+=lanesSpace; } } - else if (lineStyle->GetOffsetRel() == OffsetRel::laneForwardLeft || - lineStyle->GetOffsetRel() == OffsetRel::laneForwardThroughLeft || - lineStyle->GetOffsetRel() == OffsetRel::laneForwardThrough || - lineStyle->GetOffsetRel() == OffsetRel::laneForwardThroughRight || - lineStyle->GetOffsetRel() == OffsetRel::laneForwardRight || - lineStyle->GetOffsetRel() == OffsetRel::laneBackwardLeft || - lineStyle->GetOffsetRel() == OffsetRel::laneBackwardThroughLeft || - lineStyle->GetOffsetRel() == OffsetRel::laneBackwardThrough || - lineStyle->GetOffsetRel() == OffsetRel::laneBackwardThroughRight || - lineStyle->GetOffsetRel() == OffsetRel::laneBackwardRight ) { - + else if (IsLaneOffset(lineStyle->GetOffsetRel())) { if (lanesValue==nullptr || lanesValue->GetLanes()<1){ continue; } diff --git a/libosmscout-map/src/osmscoutmap/Styles.cpp b/libosmscout-map/src/osmscoutmap/Styles.cpp index f9d4fb0a0..0ff89a5f1 100644 --- a/libosmscout-map/src/osmscoutmap/Styles.cpp +++ b/libosmscout-map/src/osmscoutmap/Styles.cpp @@ -24,6 +24,20 @@ namespace osmscout { + bool IsLaneOffset(OffsetRel rel) + { + return rel==OffsetRel::laneForwardLeft || + rel==OffsetRel::laneForwardThroughLeft || + rel==OffsetRel::laneForwardThrough || + rel==OffsetRel::laneForwardThroughRight || + rel==OffsetRel::laneForwardRight || + rel==OffsetRel::laneBackwardLeft || + rel==OffsetRel::laneBackwardThroughLeft || + rel==OffsetRel::laneBackwardThrough || + rel==OffsetRel::laneBackwardThroughRight || + rel==OffsetRel::laneBackwardRight; + } + class LineStyleDescriptor CLASS_FINAL : public StyleDescriptor { public: diff --git a/libosmscout/include/osmscout/util/Transformation.h b/libosmscout/include/osmscout/util/Transformation.h index 53cf935af..1abe5481b 100644 --- a/libosmscout/include/osmscout/util/Transformation.h +++ b/libosmscout/include/osmscout/util/Transformation.h @@ -341,6 +341,10 @@ namespace osmscout { { return end; } + + bool IsValid() const { + return start!=std::numeric_limits::max(); + } }; /**