1 // SPDX-License-Identifier: LGPL-2.1-or-later 2 // 3 // SPDX-FileCopyrightText: 2015 Stanciu Marius-Valeriu <stanciumarius94@gmail.com> 4 // 5 6 // Self 7 #include "OsmObjectManager.h" 8 9 // Marble 10 #include "GeoDataPlacemark.h" 11 #include "GeoDataLinearRing.h" 12 #include "GeoDataPolygon.h" 13 #include "GeoDataBuilding.h" 14 #include "GeoDataMultiGeometry.h" 15 #include "osm/OsmPlacemarkData.h" 16 17 namespace Marble { 18 19 qint64 OsmObjectManager::m_minId = -1; 20 initializeOsmData(GeoDataPlacemark * placemark)21void OsmObjectManager::initializeOsmData( GeoDataPlacemark* placemark ) 22 { 23 OsmPlacemarkData &osmData = placemark->osmData(); 24 25 bool isNull = osmData.isNull(); 26 if ( isNull ) { 27 // The "--m_minId" assignments mean: assigning an id lower( by 1 ) than the current lowest, 28 // and updating the current lowest id. 29 osmData.setId( --m_minId ); 30 } 31 32 // Assigning osmData to each of the line's nodes ( if they don't already have data ) 33 if (const auto lineString = geodata_cast<GeoDataLineString>(placemark->geometry())) { 34 QVector<GeoDataCoordinates>::const_iterator it = lineString->constBegin(); 35 QVector<GeoDataCoordinates>::ConstIterator const end = lineString->constEnd(); 36 37 for ( ; it != end; ++it ) { 38 if (osmData.nodeReference(*it).isNull()) { 39 osmData.nodeReference(*it).setId(--m_minId); 40 } 41 } 42 } 43 44 const auto building = geodata_cast<GeoDataBuilding>(placemark->geometry()); 45 46 const GeoDataLinearRing* lineString; 47 if (building) { 48 lineString = geodata_cast<GeoDataLinearRing>(&static_cast<const GeoDataMultiGeometry*>(building->multiGeometry())->at(0)); 49 } else { 50 lineString = geodata_cast<GeoDataLinearRing>(placemark->geometry()); 51 } 52 // Assigning osmData to each of the line's nodes ( if they don't already have data ) 53 if (lineString) { 54 for (auto it =lineString->constBegin(), end = lineString->constEnd(); it != end; ++it ) { 55 if (osmData.nodeReference(*it).isNull()) { 56 osmData.nodeReference(*it).setId(--m_minId); 57 } 58 } 59 } 60 61 const GeoDataPolygon* polygon; 62 if (building) { 63 polygon = geodata_cast<GeoDataPolygon>(&static_cast<const GeoDataMultiGeometry*>(building->multiGeometry())->at(0)); 64 } else { 65 polygon = geodata_cast<GeoDataPolygon>(placemark->geometry()); 66 } 67 // Assigning osmData to each of the polygons boundaries, and to each of the 68 // nodes that are part of those boundaries ( if they don't already have data ) 69 if (polygon) { 70 const GeoDataLinearRing &outerBoundary = polygon->outerBoundary(); 71 int index = -1; 72 if ( isNull ) { 73 osmData.addTag(QStringLiteral("type"), QStringLiteral("multipolygon")); 74 } 75 76 // Outer boundary 77 OsmPlacemarkData &outerBoundaryData = osmData.memberReference( index ); 78 if (outerBoundaryData.isNull()) { 79 outerBoundaryData.setId(--m_minId); 80 } 81 82 // Outer boundary nodes 83 QVector<GeoDataCoordinates>::const_iterator it = outerBoundary.constBegin(); 84 QVector<GeoDataCoordinates>::ConstIterator const end = outerBoundary.constEnd(); 85 86 for ( ; it != end; ++it ) { 87 if (outerBoundaryData.nodeReference(*it).isNull()) { 88 outerBoundaryData.nodeReference(*it).setId(--m_minId); 89 } 90 } 91 92 // Each inner boundary 93 for( const GeoDataLinearRing &innerRing: polygon->innerBoundaries() ) { 94 ++index; 95 OsmPlacemarkData &innerRingData = osmData.memberReference( index ); 96 if (innerRingData.isNull()) { 97 innerRingData.setId(--m_minId); 98 } 99 100 // Inner boundary nodes 101 QVector<GeoDataCoordinates>::const_iterator it = innerRing.constBegin(); 102 QVector<GeoDataCoordinates>::ConstIterator const end = innerRing.constEnd(); 103 104 for ( ; it != end; ++it ) { 105 if (innerRingData.nodeReference(*it).isNull()) { 106 innerRingData.nodeReference(*it).setId(--m_minId); 107 } 108 } 109 } 110 } 111 } 112 registerId(qint64 id)113void OsmObjectManager::registerId( qint64 id ) 114 { 115 m_minId = qMin( id, m_minId ); 116 } 117 118 } 119 120