diff --git a/src/mbgl/renderer/symbol_bucket.cpp b/src/mbgl/renderer/symbol_bucket.cpp index eed9dbcd3..ddf19f2d3 100644 --- a/src/mbgl/renderer/symbol_bucket.cpp +++ b/src/mbgl/renderer/symbol_bucket.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include namespace mbgl { @@ -269,9 +270,11 @@ void SymbolBucket::addFeature(const std::vector> &lines, layout.icon.rotation_alignment == RotationAlignmentType::Map && layout.placement == PlacementType::Line; - // TODO clip lines here + auto& clippedLines = layout.placement == PlacementType::Line ? + util::clipLines(lines, 0, 0, 4096, 4096) : + lines; - for (const std::vector &line : lines) { + for (const std::vector &line : clippedLines) { if (!line.size()) continue; // Calculate the anchor points around which you want to place labels diff --git a/src/mbgl/util/clip_lines.cpp b/src/mbgl/util/clip_lines.cpp new file mode 100644 index 000000000..47f04618a --- /dev/null +++ b/src/mbgl/util/clip_lines.cpp @@ -0,0 +1,66 @@ +#include "clip_lines.hpp" + +namespace mbgl { +namespace util { + +std::vector> clipLines(const std::vector> &lines, + const int16_t x1, const int16_t y1, const int16_t x2, const int16_t y2) { + + std::vector> clippedLines; + + for (auto& line : lines) { + + if (!line.size()) + continue; + + auto end = line.end() - 1; + for (auto it = line.begin(); it != end; it++) { + Coordinate p0 = *(it); + Coordinate p1 = *(it + 1); + + if (p0.x < x1 && p1.x < x1) { + continue; + } else if (p0.x < x1) { + p0 = { x1, static_cast(p0.y + static_cast(p1.y - p0.y) * ((x1 - p0.x) / (p1.x - p0.x))) }; + } else if (p1.x < x1) { + p1 = { x1, static_cast(p0.y + static_cast(p1.y - p0.y) * ((x1 - p0.x) / (p1.x - p0.x))) }; + } + + if (p0.y < y1 && p1.y < y1) { + continue; + } else if (p0.y < y1) { + p0 = { static_cast(p0.x + static_cast(p1.x - p0.x) * ((y1 - p0.y) / (p1.y - p0.y))), y1 }; + } else if (p1.y < y1) { + p1 = { static_cast(p0.x + static_cast(p1.x - p0.x) * ((y1 - p0.y) / (p1.y - p0.y))), y1 }; + } + + if (p0.x >= x2 && p1.x >= x2) { + continue; + } else if (p0.x >= x2) { + p0 = { x2, static_cast(p0.y + static_cast(p1.y - p0.y) * ((x2 - p0.x) / (p1.x - p0.x))) }; + } else if (p1.x >= x2) { + p1 = { x2, static_cast(p0.y + static_cast(p1.y - p0.y) * ((x2 - p0.x) / (p1.x - p0.x))) }; + } + + if (p0.y >= y2 && p1.y >= y2) { + continue; + } else if (p0.y >= y2) { + p0 = { static_cast(p0.x + static_cast(p1.x - p0.x) * ((y2 - p0.y) / (p1.y - p0.y))), y2 }; + } else if (p1.y >= y2) { + p1 = { static_cast(p0.x + static_cast(p1.x - p0.x) * ((y2 - p0.y) / (p1.y - p0.y))), y2 }; + } + + if (!clippedLines.size() || (clippedLines.back().size() && !(p0 == clippedLines.back().back()))) { + clippedLines.emplace_back(); + clippedLines.back().push_back(p0); + } + + clippedLines.back().push_back(p1); + } + } + + return clippedLines; +} + +} // end namespace util +} // end namespace mbgl diff --git a/src/mbgl/util/clip_lines.hpp b/src/mbgl/util/clip_lines.hpp new file mode 100644 index 000000000..6e49b4808 --- /dev/null +++ b/src/mbgl/util/clip_lines.hpp @@ -0,0 +1,19 @@ +#ifndef MBGL_UTIL_CLIP_LINES +#define MBGL_UTIL_CLIP_LINES + +#include +#include +#include +#include + +namespace mbgl { +namespace util { + + +std::vector> clipLines(const std::vector> &lines, + const int16_t x1, const int16_t y1, const int16_t x2, const int16_t y2); + +} // end namespace util +} // end namespace mbgl + +#endif