File indexing completed on 2024-05-19 03:53:14
0001 // SPDX-License-Identifier: LGPL-2.1-or-later 0002 // 0003 // SPDX-FileCopyrightText: 2016 Dennis Nienhüser <nienhueser@kde.org> 0004 // 0005 0006 //Self 0007 #include "OsmDocumentTagTranslator.h" 0008 0009 //Marble 0010 #include "OsmNodeTagWriter.h" 0011 #include "OsmWayTagWriter.h" 0012 #include "OsmElementDictionary.h" 0013 #include "GeoDataDocument.h" 0014 #include "GeoWriter.h" 0015 #include "GeoDataPlacemark.h" 0016 #include "GeoDataGeometry.h" 0017 #include "GeoDataPoint.h" 0018 #include "GeoDataPolygon.h" 0019 #include "GeoDataRelation.h" 0020 #include "GeoDataLinearRing.h" 0021 #include "GeoDataBuilding.h" 0022 #include "GeoDataMultiGeometry.h" 0023 #include "osm/OsmPlacemarkData.h" 0024 #include "osm/OsmObjectManager.h" 0025 #include "OsmRelationTagWriter.h" 0026 0027 #include <QDebug> 0028 0029 namespace Marble 0030 { 0031 0032 void OsmConverter::read(const GeoDataDocument *document) 0033 { 0034 m_nodes.clear(); 0035 m_ways.clear(); 0036 m_relations.clear(); 0037 0038 // Writing all the component nodes ( points, nodes of polylines, nodes of polygons ) 0039 for (auto feature: document->featureList()) { 0040 if (auto placemark = geodata_cast<GeoDataPlacemark>(feature)) { 0041 // If the placemark's osmData is not complete, it is initialized by the OsmObjectManager 0042 OsmObjectManager::initializeOsmData( placemark ); 0043 const OsmPlacemarkData & osmData = placemark->osmData(); 0044 0045 if (geodata_cast<GeoDataPoint>(placemark->geometry())) { 0046 m_nodes << OsmConverter::Node(placemark->coordinate(), osmData); 0047 } else if (const auto lineString = geodata_cast<GeoDataLineString>(placemark->geometry())) { 0048 for (auto const &coordinates: *lineString) { 0049 m_nodes << OsmConverter::Node(coordinates, osmData.nodeReference(coordinates)); 0050 } 0051 m_ways << OsmConverter::Way(lineString, osmData); 0052 } else if (const auto linearRing = geodata_cast<GeoDataLinearRing>(placemark->geometry())) { 0053 processLinearRing(linearRing, osmData); 0054 } else if (const auto polygon = geodata_cast<GeoDataPolygon>(placemark->geometry())) { 0055 processPolygon(polygon, osmData, placemark); 0056 } else if (const auto building = geodata_cast<GeoDataBuilding>(placemark->geometry())) { 0057 if (const auto linearRing = geodata_cast<GeoDataLinearRing>(&building->multiGeometry()->at(0))) { 0058 processLinearRing(linearRing, osmData); 0059 } else if (const auto polygon = geodata_cast<GeoDataPolygon>(&building->multiGeometry()->at(0))) { 0060 processPolygon(polygon, osmData, placemark); 0061 } 0062 } 0063 } else if (const auto placemark = geodata_cast<GeoDataRelation>(feature)) { 0064 m_relations.append(OsmConverter::Relation(placemark, placemark->osmData())); 0065 } 0066 } 0067 0068 // Sort by id ascending since some external tools rely on that 0069 std::sort(m_nodes.begin(), m_nodes.end(), [] (const Node &a, const Node &b) { return a.second.id() < b.second.id(); }); 0070 std::sort(m_ways.begin(), m_ways.end(), [] (const Way &a, const Way &b) { return a.second.id() < b.second.id(); }); 0071 std::sort(m_relations.begin(), m_relations.end(), [] (const Relation &a, const Relation &b) { return a.second.id() < b.second.id(); }); 0072 } 0073 0074 const OsmConverter::Nodes &OsmConverter::nodes() const 0075 { 0076 return m_nodes; 0077 } 0078 0079 const OsmConverter::Ways &OsmConverter::ways() const 0080 { 0081 return m_ways; 0082 } 0083 0084 const OsmConverter::Relations &OsmConverter::relations() const 0085 { 0086 return m_relations; 0087 } 0088 0089 void OsmConverter::processLinearRing(GeoDataLinearRing *linearRing, 0090 const OsmPlacemarkData& osmData) 0091 { 0092 for (auto const &coordinates: *linearRing) { 0093 m_nodes << OsmConverter::Node(coordinates, osmData.nodeReference(coordinates)); 0094 } 0095 m_ways << OsmConverter::Way(linearRing, osmData); 0096 } 0097 0098 void OsmConverter::processPolygon(GeoDataPolygon *polygon, 0099 const OsmPlacemarkData& osmData, 0100 GeoDataPlacemark* placemark) 0101 { 0102 int index = -1; 0103 0104 // Writing all the outerRing's nodes 0105 const GeoDataLinearRing &outerRing = polygon->outerBoundary(); 0106 const OsmPlacemarkData outerRingOsmData = osmData.memberReference( index ); 0107 for (auto const &coordinates: outerRing) { 0108 m_nodes << OsmConverter::Node(coordinates, outerRingOsmData.nodeReference(coordinates)); 0109 } 0110 m_ways << OsmConverter::Way(&outerRing, outerRingOsmData); 0111 0112 // Writing all nodes for each innerRing 0113 for (auto const &innerRing: polygon->innerBoundaries() ) { 0114 ++index; 0115 const OsmPlacemarkData innerRingOsmData = osmData.memberReference( index ); 0116 for (auto const &coordinates: innerRing) { 0117 m_nodes << OsmConverter::Node(coordinates, innerRingOsmData.nodeReference(coordinates)); 0118 } 0119 m_ways << OsmConverter::Way(&innerRing, innerRingOsmData); 0120 } 0121 m_relations.append(OsmConverter::Relation(placemark, osmData)); 0122 } 0123 0124 } 0125