1 /*
2     SPDX-FileCopyrightText: 2020 Volker Krause <vkrause@kde.org>
3 
4     SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 
7 #ifndef KOSMINDOORMAP_MARBLEGEOMETRYASSEMBLER_P_H
8 #define KOSMINDOORMAP_MARBLEGEOMETRYASSEMBLER_P_H
9 
10 #include "kosmindoormap_export.h"
11 
12 #include <osm/datatypes.h>
13 #include <osm/datasetmergebuffer.h>
14 
15 #include <unordered_map>
16 
17 namespace KOSMIndoorMap {
18 
19 /** Re-assemble broken up geometry in Marble vector tiles.
20  *  @internal exported only for unit tests
21  */
22 class KOSMINDOORMAP_EXPORT MarbleGeometryAssembler
23 {
24 public:
25     MarbleGeometryAssembler();
26     ~MarbleGeometryAssembler();
27 
28     /** Set the dataset to merge into.
29      *  Has to be called before the first call to merge().
30      */
31     void setDataSet(OSM::DataSet *dataSet);
32 
33     /** Merge @p mergeBuffer into @p dataSet.
34      *  Data not mergable at this point (e.g. due to missing connecting tiles)
35      *  remains in @p mergeBuffer.
36      */
37     void merge(OSM::DataSetMergeBuffer *mergeBuffer);
38     /** Processes remaining elements that couldn't be merged. */
39     void finalize();
40 
41 private:
42     void mergeNodes(OSM::DataSetMergeBuffer *mergeBuffer);
43     void mergeWays(std::vector<OSM::Way> &ways);
44     void mergeRelations(OSM::DataSetMergeBuffer *mergeBuffer);
45 
46     void deduplicateWays(std::vector<OSM::Way> &ways);
47     void remapWayNodes(std::vector<OSM::Way> &ways) const;
48     void mergeWay(OSM::Way &way, OSM::Way &otherWay) const;
49     void mergeLine(OSM::Way &way, OSM::Way &otherWay) const;
50     std::vector<OSM::Id> mergeArea(OSM::Way &way, OSM::Way &otherWay) const;
51     /**
52      * @returns @c true when @p path has been completely processed, @c false otherwise
53      */
54     bool mergeAreaSection(std::vector<OSM::Id> &assembledPath, std::vector<OSM::Id> &path, const std::vector<OSM::Id>::iterator &pathBegin, std::vector<OSM::Id> &otherPath) const;
55 
56     void mergeRelation(OSM::Relation &relation, const OSM::Relation &otherRelation) const;
57 
58     template <typename Elem>
59     OSM::Id takeMxOid(Elem &elem) const;
60 
61     OSM::DataSet *m_dataSet = nullptr;
62     OSM::TagKey m_mxoidKey;
63     OSM::TagKey m_typeKey;
64     std::unordered_map<OSM::Id, OSM::Id> m_nodeIdMap;
65     std::unordered_map<OSM::Id, OSM::Id> m_wayIdMap;
66     std::unordered_map<OSM::Id, OSM::Id> m_relIdMap;
67 
68     std::unordered_map<OSM::Id, std::vector<std::size_t>> m_duplicateWays;
69     std::vector<OSM::Way> m_pendingWays;
70 
71     static OSM::Id s_nextInternalId;
72 };
73 
74 }
75 
76 #endif // KOSMINDOORMAP_MARBLEGEOMETRYASSEMBLER_P_H
77