File indexing completed on 2024-04-14 03:48:51

0001 // SPDX-License-Identifier: LGPL-2.1-or-later
0002 //
0003 // SPDX-FileCopyrightText: 2011 Dennis Nienhüser <nienhueser@kde.org>
0004 //
0005 
0006 #include "OsmRegionTree.h"
0007 
0008 namespace Marble
0009 {
0010 
0011 OsmRegionTree::OsmRegionTree( const OsmRegion & node ) :
0012     m_node( node )
0013 {
0014     // nothing to do
0015 }
0016 
0017 const OsmRegion &OsmRegionTree::node() const
0018 {
0019     return m_node;
0020 }
0021 
0022 void OsmRegionTree::setChildren( const QVector<OsmRegionTree>& children )
0023 {
0024     m_children = children;
0025 }
0026 
0027 const QVector<OsmRegionTree> & OsmRegionTree::children() const
0028 {
0029     return m_children;
0030 }
0031 
0032 void OsmRegionTree::append( QList<OsmRegion> &regions )
0033 {
0034     for( const OsmRegion &candidate: regions ) {
0035         if ( candidate.parentIdentifier() == m_node.identifier() ) {
0036             m_children << OsmRegionTree( candidate );
0037         }
0038     }
0039 
0040     for( const OsmRegionTree & child: m_children ) {
0041         regions.removeAll( child.node() );
0042     }
0043 
0044     for ( int i = 0; i < m_children.size(); ++i ) {
0045         m_children[i].append( regions );
0046     }
0047 }
0048 
0049 void OsmRegionTree::traverse( int &counter )
0050 {
0051     ++counter;
0052     m_node.setLeft( counter );
0053 
0054     for( int i = 0; i < m_children.size(); ++i ) {
0055         m_children[i].traverse( counter );
0056     }
0057 
0058     ++counter;
0059     m_node.setRight( counter );
0060 }
0061 
0062 OsmRegionTree::operator QList<OsmRegion>() const
0063 {
0064     QList<OsmRegion> result;
0065     enumerate( result );
0066     return result;
0067 }
0068 
0069 void OsmRegionTree::enumerate( QList<OsmRegion> &list ) const
0070 {
0071     list << m_node;
0072     for( const OsmRegionTree & child: m_children ) {
0073         child.enumerate( list );
0074     }
0075 }
0076 
0077 int OsmRegionTree::smallestRegionId( const GeoDataCoordinates &coordinates ) const
0078 {
0079     int rootLevel = m_node.adminLevel();
0080     return smallestRegionId( coordinates, rootLevel );
0081 }
0082 
0083 int OsmRegionTree::smallestRegionId( const GeoDataCoordinates &coordinates, int &level ) const
0084 {
0085     int maxLevel = m_node.adminLevel();
0086     int minId = m_node.identifier();
0087     for( const OsmRegionTree & child: m_children ) {
0088         if ( child.node().geometry().contains( coordinates ) ) {
0089             int childLevel = level;
0090             int id = child.smallestRegionId( coordinates, childLevel );
0091             if ( childLevel >= maxLevel ) {
0092                 maxLevel = childLevel;
0093                 minId = id;
0094             }
0095         }
0096     }
0097 
0098     level = maxLevel;
0099     return minId;
0100 }
0101 
0102 }