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"