File indexing completed on 2024-05-12 15:29:52

0001 // SPDX-License-Identifier: LGPL-2.1-or-later
0002 //
0003 // SPDX-FileCopyrightText: 2015 Stanciu Marius-Valeriu <stanciumarius94@gmail.com>
0004 //
0005 
0006 // Self
0007 #include "OsmObjectManager.h"
0008 
0009 // Marble
0010 #include "GeoDataPlacemark.h"
0011 #include "GeoDataLinearRing.h"
0012 #include "GeoDataPolygon.h"
0013 #include "GeoDataBuilding.h"
0014 #include "GeoDataMultiGeometry.h"
0015 #include "osm/OsmPlacemarkData.h"
0016 
0017 namespace Marble {
0018 
0019 qint64 OsmObjectManager::m_minId = -1;
0020 
0021 void OsmObjectManager::initializeOsmData( GeoDataPlacemark* placemark )
0022 {
0023     OsmPlacemarkData &osmData = placemark->osmData();
0024 
0025     bool isNull = osmData.isNull();
0026     if ( isNull ) {
0027         // The "--m_minId" assignments mean: assigning an id lower( by 1 ) than the current lowest,
0028         // and updating the current lowest id.
0029         osmData.setId( --m_minId );
0030     }
0031 
0032     // Assigning osmData to each of the line's nodes ( if they don't already have data )
0033     if (const auto lineString = geodata_cast<GeoDataLineString>(placemark->geometry())) {
0034         QVector<GeoDataCoordinates>::const_iterator it =  lineString->constBegin();
0035         QVector<GeoDataCoordinates>::ConstIterator const end = lineString->constEnd();
0036 
0037         for ( ; it != end; ++it ) {
0038             if (osmData.nodeReference(*it).isNull()) {
0039                 osmData.nodeReference(*it).setId(--m_minId);
0040             }
0041         }
0042     }
0043 
0044     const auto building = geodata_cast<GeoDataBuilding>(placemark->geometry());
0045 
0046     const GeoDataLinearRing* lineString;
0047     if (building) {
0048         lineString = geodata_cast<GeoDataLinearRing>(&static_cast<const GeoDataMultiGeometry*>(building->multiGeometry())->at(0));
0049     } else {
0050         lineString = geodata_cast<GeoDataLinearRing>(placemark->geometry());
0051     }
0052     // Assigning osmData to each of the line's nodes ( if they don't already have data )
0053     if (lineString) {
0054         for (auto it =lineString->constBegin(), end = lineString->constEnd(); it != end; ++it ) {
0055             if (osmData.nodeReference(*it).isNull()) {
0056                 osmData.nodeReference(*it).setId(--m_minId);
0057             }
0058         }
0059     }
0060 
0061     const GeoDataPolygon* polygon;
0062     if (building) {
0063         polygon = geodata_cast<GeoDataPolygon>(&static_cast<const GeoDataMultiGeometry*>(building->multiGeometry())->at(0));
0064     } else {
0065         polygon = geodata_cast<GeoDataPolygon>(placemark->geometry());
0066     }
0067     // Assigning osmData to each of the polygons boundaries, and to each of the
0068     // nodes that are part of those boundaries ( if they don't already have data )
0069     if (polygon) {
0070         const GeoDataLinearRing &outerBoundary = polygon->outerBoundary();
0071         int index = -1;
0072         if ( isNull ) {
0073             osmData.addTag(QStringLiteral("type"), QStringLiteral("multipolygon"));
0074         }
0075 
0076         // Outer boundary
0077         OsmPlacemarkData &outerBoundaryData = osmData.memberReference( index );
0078         if (outerBoundaryData.isNull()) {
0079             outerBoundaryData.setId(--m_minId);
0080         }
0081 
0082         // Outer boundary nodes
0083         QVector<GeoDataCoordinates>::const_iterator it =  outerBoundary.constBegin();
0084         QVector<GeoDataCoordinates>::ConstIterator const end = outerBoundary.constEnd();
0085 
0086         for ( ; it != end; ++it ) {
0087             if (outerBoundaryData.nodeReference(*it).isNull()) {
0088                 outerBoundaryData.nodeReference(*it).setId(--m_minId);
0089             }
0090         }
0091 
0092         // Each inner boundary
0093         for( const GeoDataLinearRing &innerRing: polygon->innerBoundaries() ) {
0094             ++index;
0095             OsmPlacemarkData &innerRingData = osmData.memberReference( index );
0096             if (innerRingData.isNull()) {
0097                 innerRingData.setId(--m_minId);
0098             }
0099 
0100             // Inner boundary nodes
0101             QVector<GeoDataCoordinates>::const_iterator it =  innerRing.constBegin();
0102             QVector<GeoDataCoordinates>::ConstIterator const end = innerRing.constEnd();
0103 
0104             for ( ; it != end; ++it ) {
0105                 if (innerRingData.nodeReference(*it).isNull()) {
0106                     innerRingData.nodeReference(*it).setId(--m_minId);
0107                 }
0108             }
0109         }
0110     }
0111 }
0112 
0113 void OsmObjectManager::registerId( qint64 id )
0114 {
0115     m_minId = qMin( id, m_minId );
0116 }
0117 
0118 }
0119