File indexing completed on 2024-12-01 10:29:54
0001 /* 0002 SPDX-FileCopyrightText: 2020 Volker Krause <vkrause@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "pathutil.h" 0008 #include "element.h" 0009 0010 #include <cassert> 0011 0012 using namespace OSM; 0013 0014 static OSM::Id appendNextPath(const DataSet &dataSet, std::vector<const Node*> &nodes, OSM::Id startNode, std::vector<const Way*> &ways) 0015 { 0016 if (ways.empty()) { 0017 return {}; 0018 } 0019 0020 for (auto it = std::next(ways.begin()); it != ways.end(); ++it) { 0021 if ((*it)->nodes.empty()) { 0022 continue; 0023 } 0024 if ((*it)->nodes.front() == startNode) { 0025 appendNodesFromWay(dataSet, nodes, (*it)->nodes.begin(), (*it)->nodes.end()); 0026 const auto lastNodeId = (*it)->nodes.back(); 0027 ways.erase(it); 0028 return lastNodeId; 0029 } 0030 // path segments can also be backwards 0031 if ((*it)->nodes.back() == startNode) { 0032 appendNodesFromWay(dataSet, nodes, (*it)->nodes.rbegin(), (*it)->nodes.rend()); 0033 const auto lastNodeId = (*it)->nodes.front(); 0034 ways.erase(it); 0035 return lastNodeId; 0036 } 0037 } 0038 0039 return {}; 0040 } 0041 0042 void OSM::assemblePath(const DataSet &dataSet, std::vector<const Way*> &&ways, std::vector<const Node*> &path) 0043 { 0044 for (auto it = ways.begin(); it != ways.end();) { 0045 if ((*it)->nodes.empty()) { 0046 ++it; 0047 continue; 0048 } 0049 appendNodesFromWay(dataSet, path, (*it)->nodes.begin(), (*it)->nodes.end()); 0050 const auto startNode = (*it)->nodes.front(); 0051 auto lastNode = (*it)->nodes.back(); 0052 0053 do { 0054 lastNode = appendNextPath(dataSet, path, lastNode, ways); 0055 } while (lastNode && lastNode != startNode); 0056 0057 it = ways.erase(it); 0058 } 0059 } 0060 0061 void OSM::assemblePath(const OSM::DataSet &dataSet, const std::vector<OSM::Element> &ways, std::vector<const Node*> &path) 0062 { 0063 std::vector<const OSM::Way*> w; 0064 w.reserve(ways.size()); 0065 for (auto e : ways) { 0066 if (e.type() == OSM::Type::Way) { 0067 w.push_back(e.way()); 0068 } 0069 } 0070 assemblePath(dataSet, std::move(w), path); 0071 }