File indexing completed on 2024-05-05 03:50:39
0001 // SPDX-License-Identifier: LGPL-2.1-or-later 0002 // 0003 // SPDX-FileCopyrightText: 2014 Calin Cruceru <crucerucalincristian@gmail.com> 0004 // 0005 0006 // Self 0007 #include "MergingPolygonNodesAnimation.h" 0008 0009 // Marble 0010 #include "AreaAnnotation.h" 0011 #include "GeoDataPolygon.h" 0012 #include "GeoDataLinearRing.h" 0013 #include "GeoDataPlacemark.h" 0014 0015 0016 namespace Marble { 0017 0018 0019 MergingPolygonNodesAnimation::MergingPolygonNodesAnimation( AreaAnnotation *polygon ) : 0020 // To avoid long lines and repeated code 0021 first_i( polygon->m_firstMergedNode.first ), 0022 first_j( polygon->m_firstMergedNode.second ), 0023 second_i( polygon->m_secondMergedNode.first ), 0024 second_j( polygon->m_secondMergedNode.second ), 0025 m_timer( new QTimer( this ) ), 0026 0027 // To avoid repeating this code section too often 0028 outerRing( static_cast<GeoDataPolygon*>( polygon->placemark()->geometry() )->outerBoundary() ), 0029 innerRings( static_cast<GeoDataPolygon*>( polygon->placemark()->geometry() )->innerBoundaries() ) 0030 { 0031 if ( first_j == -1 ) { 0032 Q_ASSERT( second_j == -1 ); 0033 m_boundary = OuterBoundary; 0034 m_firstInitialCoords = outerRing.at( first_i ); 0035 m_secondInitialCoords = outerRing.at( second_i ); 0036 } else { 0037 Q_ASSERT( first_j != -1 && second_j != -1 ); 0038 m_firstInitialCoords = innerRings.at(first_i).at(first_j); 0039 m_secondInitialCoords = innerRings.at(second_i).at(second_j); 0040 m_boundary = InnerBoundary; 0041 } 0042 0043 connect( m_timer, SIGNAL(timeout()), this, SLOT(updateNodes()) ); 0044 } 0045 0046 MergingPolygonNodesAnimation::~MergingPolygonNodesAnimation() 0047 { 0048 delete m_timer; 0049 } 0050 0051 void MergingPolygonNodesAnimation::startAnimation() 0052 { 0053 static const int timeOffset = 1; 0054 m_timer->start( timeOffset ); 0055 } 0056 0057 void MergingPolygonNodesAnimation::updateNodes() 0058 { 0059 static const qreal ratio = 0.05; 0060 const qreal distanceOffset = m_firstInitialCoords.interpolate(m_secondInitialCoords, ratio) 0061 .sphericalDistanceTo(m_firstInitialCoords) + 0.001; 0062 0063 if ( nodesDistance() < distanceOffset ) { 0064 if ( m_boundary == OuterBoundary ) { 0065 outerRing[second_i] = newCoords(); 0066 outerRing.remove( first_i ); 0067 } else { 0068 innerRings[second_i][second_j] = newCoords(); 0069 innerRings[second_i].remove( first_j ); 0070 } 0071 0072 emit animationFinished(); 0073 } else { 0074 if ( m_boundary == OuterBoundary ) { 0075 outerRing[first_i] = outerRing.at(first_i).interpolate( m_secondInitialCoords, ratio ); 0076 outerRing[second_i] = outerRing.at(second_i).interpolate( m_firstInitialCoords, ratio ); 0077 } else { 0078 innerRings[first_i][first_j] = innerRings.at(first_i).at(first_j).interpolate( m_secondInitialCoords, ratio ); 0079 innerRings[second_i][second_j] = innerRings.at(second_i).at(second_j).interpolate( m_firstInitialCoords, ratio ); 0080 } 0081 0082 emit nodesMoved(); 0083 } 0084 } 0085 0086 GeoDataCoordinates MergingPolygonNodesAnimation::newCoords() 0087 { 0088 return m_boundary == OuterBoundary ? 0089 outerRing.at(first_i).interpolate( outerRing.at(second_i), 0.5 ) : 0090 innerRings.at(first_i).at(first_j).interpolate( innerRings.at(second_i).at(second_j), 0.5 ); 0091 } 0092 0093 qreal MergingPolygonNodesAnimation::nodesDistance() 0094 { 0095 return m_boundary == OuterBoundary ? 0096 outerRing.at(first_i).sphericalDistanceTo(outerRing.at(second_i)) : 0097 innerRings.at(first_i).at(first_j).sphericalDistanceTo(innerRings.at(second_i).at(second_j)); 0098 } 0099 0100 } // namespace Marble 0101 0102 #include "moc_MergingPolygonNodesAnimation.cpp"