From 1c91f09fdafdaced5b48ac66390bc9733e50a4c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Fri, 23 Jan 2015 11:14:09 +0100 Subject: [PATCH] move merge_lines implementation to its own source files to avoid duplicate symbols --- src/mbgl/util/merge_lines.cpp | 99 +++++++++++++++++++++++++++++++++ src/mbgl/util/merge_lines.hpp | 100 ++++------------------------------ 2 files changed, 110 insertions(+), 89 deletions(-) create mode 100644 src/mbgl/util/merge_lines.cpp diff --git a/src/mbgl/util/merge_lines.cpp b/src/mbgl/util/merge_lines.cpp new file mode 100644 index 000000000..7eb830670 --- /dev/null +++ b/src/mbgl/util/merge_lines.cpp @@ -0,0 +1,99 @@ +#include "merge_lines.hpp" +#include + +namespace mbgl { +namespace util { + +unsigned int mergeFromRight(std::vector &features, + std::map &rightIndex, + std::map::iterator left, + std::string &rightKey, + std::vector> &geom) { + + unsigned int index = left->second; + rightIndex.erase(left); + rightIndex[rightKey] = index; + features[index].geometry[0].pop_back(); + features[index].geometry[0].insert( + features[index].geometry[0].end(), geom[0].begin(), geom[0].end()); + geom[0].clear(); + return index; +} + +unsigned int mergeFromLeft(std::vector &features, + std::map &leftIndex, + std::string &leftKey, + std::map::iterator right, + std::vector> &geom) { + + unsigned int index = right->second; + leftIndex.erase(right); + leftIndex[leftKey] = index; + geom[0].pop_back(); + geom[0].insert( + geom[0].end(), features[index].geometry[0].begin(), features[index].geometry[0].end()); + features[index].geometry[0].clear(); + std::swap(features[index].geometry[0], geom[0]); + return index; +} + +std::string +getKey(const std::u32string &text, const std::vector> &geom, bool onRight) { + const Coordinate &coord = onRight ? geom[0].back() : geom[0].front(); + std::ostringstream key; + for (const char32_t &c : text) { + key << (char)c; + } + key << ":" << coord.x << ":" << coord.y; + return key.str(); +} + +void mergeLines(std::vector &features) { + + std::map leftIndex; + std::map rightIndex; + + for (unsigned int k = 0; k < features.size(); k++) { + SymbolFeature &feature = features[k]; + std::vector> &geometry = feature.geometry; + + if (!feature.label.length()) { + continue; + } + + std::string leftKey = getKey(feature.label, geometry, false); + std::string rightKey = getKey(feature.label, geometry, true); + + auto left = rightIndex.find(leftKey); + auto right = leftIndex.find(rightKey); + + if ((left != rightIndex.end()) && (right != leftIndex.end()) && + (left->second != right->second)) { + // found lines with the same text adjacent to both ends of the current line, merge all + // three + unsigned int j = mergeFromLeft(features, leftIndex, leftKey, right, geometry); + unsigned int i = + mergeFromRight(features, rightIndex, left, rightKey, features[j].geometry); + + leftIndex.erase(leftKey); + rightIndex.erase(rightKey); + rightIndex[getKey(feature.label, features[i].geometry, true)] = i; + + } else if (left != rightIndex.end()) { + // found mergeable line adjacent to the start of the current line, merge + mergeFromRight(features, rightIndex, left, rightKey, geometry); + + } else if (right != leftIndex.end()) { + // found mergeable line adjacent to the end of the current line, merge + mergeFromLeft(features, leftIndex, leftKey, right, geometry); + + } else { + // no adjacent lines, add as a new item + leftIndex[leftKey] = k; + rightIndex[rightKey] = k; + } + } +} + +} // end namespace util +} // end namespace mbgl diff --git a/src/mbgl/util/merge_lines.hpp b/src/mbgl/util/merge_lines.hpp index e0dd4c641..4460a0bce 100644 --- a/src/mbgl/util/merge_lines.hpp +++ b/src/mbgl/util/merge_lines.hpp @@ -4,102 +4,24 @@ #include #include #include -#include #include - namespace mbgl { namespace util { -unsigned int mergeFromRight( - std::vector &features, - std::map &rightIndex, - std::map::iterator left, - std::string &rightKey, - std::vector> &geom) { +unsigned int mergeFromRight(std::vector &features, + std::map &rightIndex, + std::map::iterator left, + std::string &rightKey, + std::vector> &geom); - unsigned int index = left->second; - rightIndex.erase(left); - rightIndex[rightKey] = index; - features[index].geometry[0].pop_back(); - features[index].geometry[0].insert(features[index].geometry[0].end(), geom[0].begin(), geom[0].end()); - geom[0].clear(); - return index; -} +unsigned int mergeFromLeft(std::vector &features, + std::map &leftIndex, + std::string &leftKey, + std::map::iterator right, + std::vector> &geom); -unsigned int mergeFromLeft( - std::vector &features, - std::map &leftIndex, - std::string &leftKey, - std::map::iterator right, - std::vector> &geom) { - - unsigned int index = right->second; - leftIndex.erase(right); - leftIndex[leftKey] = index; - geom[0].pop_back(); - geom[0].insert(geom[0].end(), features[index].geometry[0].begin(), features[index].geometry[0].end()); - features[index].geometry[0].clear(); - std::swap(features[index].geometry[0], geom[0]); - return index; -} - -std::string getKey(const std::u32string &text, const std::vector> &geom, bool onRight) { - const Coordinate &coord = onRight ? geom[0].back() : geom[0].front(); - std::ostringstream key; - for (const char32_t &c : text) { - key << (char)c; - } - key << ":" << coord.x << ":" << coord.y; - return key.str(); -} - - -void mergeLines(std::vector &features) { - - std::map leftIndex; - std::map rightIndex; - - for (unsigned int k = 0; k < features.size(); k++) { - SymbolFeature &feature = features[k]; - std::vector> &geometry = feature.geometry; - - if (!feature.label.length()) { - continue; - } - - std::string leftKey = getKey(feature.label, geometry, false); - std::string rightKey = getKey(feature.label, geometry, true); - - auto left = rightIndex.find(leftKey); - auto right = leftIndex.find(rightKey); - - if ((left != rightIndex.end()) && (right != leftIndex.end()) && (left->second != right->second)) { - // found lines with the same text adjacent to both ends of the current line, merge all three - unsigned int j = mergeFromLeft(features, leftIndex, leftKey, right, geometry); - unsigned int i = mergeFromRight(features, rightIndex, left, rightKey, features[j].geometry); - - leftIndex.erase(leftKey); - rightIndex.erase(rightKey); - rightIndex[getKey(feature.label, features[i].geometry, true)] = i; - - } else if (left != rightIndex.end()) { - // found mergeable line adjacent to the start of the current line, merge - mergeFromRight(features, rightIndex, left, rightKey, geometry); - - } else if (right != leftIndex.end()) { - // found mergeable line adjacent to the end of the current line, merge - mergeFromLeft(features, leftIndex, leftKey, right, geometry); - - } else { - // no adjacent lines, add as a new item - leftIndex[leftKey] = k; - rightIndex[rightKey] = k; - } - - } - -} +void mergeLines(std::vector &features); } // end namespace util } // end namespace mbgl