File indexing completed on 2024-04-28 03:49:28
0001 // SPDX-License-Identifier: LGPL-2.1-or-later 0002 // 0003 // SPDX-FileCopyrightText: 2011 Dennis Nienhüser <nienhueser@kde.org> 0004 // 0005 0006 #include "Route.h" 0007 0008 namespace Marble 0009 { 0010 0011 Route::Route() : 0012 m_distance( 0.0 ), 0013 m_travelTime( 0 ), 0014 m_positionDirty( true ), 0015 m_closestSegmentIndex( -1 ) 0016 { 0017 // nothing to do 0018 } 0019 0020 void Route::addRouteSegment( const RouteSegment &segment ) 0021 { 0022 if ( segment.isValid() ) { 0023 m_bounds = m_bounds.united( segment.bounds() ); 0024 m_distance += segment.distance(); 0025 m_path << segment.path(); 0026 if ( segment.maneuver().position().isValid() ) { 0027 m_turnPoints << segment.maneuver().position(); 0028 } 0029 if ( segment.maneuver().hasWaypoint() ) { 0030 m_waypoints << segment.maneuver().waypoint(); 0031 } 0032 m_segments.push_back( segment ); 0033 m_positionDirty = true; 0034 0035 for ( int i=1; i<m_segments.size(); ++i ) { 0036 m_segments[i-1].setNextRouteSegment(&m_segments[i]); 0037 } 0038 } 0039 } 0040 0041 GeoDataLatLonBox Route::bounds() const 0042 { 0043 return m_bounds; 0044 } 0045 0046 qreal Route::distance() const 0047 { 0048 return m_distance; 0049 } 0050 0051 int Route::size() const 0052 { 0053 return m_segments.size(); 0054 } 0055 0056 const RouteSegment & Route::at( int index ) const 0057 { 0058 return m_segments[index]; 0059 } 0060 0061 int Route::indexOf(const RouteSegment &segment) const 0062 { 0063 return m_segments.indexOf(segment); 0064 } 0065 0066 const GeoDataLineString & Route::path() const 0067 { 0068 return m_path; 0069 } 0070 0071 int Route::travelTime() const 0072 { 0073 return m_travelTime; 0074 } 0075 0076 const GeoDataLineString & Route::turnPoints() const 0077 { 0078 return m_turnPoints; 0079 } 0080 0081 const GeoDataLineString & Route::waypoints() const 0082 { 0083 return m_waypoints; 0084 } 0085 0086 void Route::setPosition( const GeoDataCoordinates &position ) 0087 { 0088 m_position = position; 0089 m_positionDirty = true; 0090 } 0091 0092 GeoDataCoordinates Route::position() const 0093 { 0094 return m_position; 0095 } 0096 0097 void Route::updatePosition() const 0098 { 0099 if ( !m_segments.isEmpty() ) { 0100 if ( m_closestSegmentIndex < 0 || m_closestSegmentIndex >= m_segments.size() ) { 0101 m_closestSegmentIndex = 0; 0102 } 0103 0104 qreal distance = m_segments[m_closestSegmentIndex].distanceTo( m_position, m_currentWaypoint, m_positionOnRoute ); 0105 QList<int> candidates; 0106 0107 for ( int i=0; i<m_segments.size(); ++i ) { 0108 if ( i != m_closestSegmentIndex && m_segments[i].minimalDistanceTo( m_position ) <= distance ) { 0109 candidates << i; 0110 } 0111 } 0112 0113 GeoDataCoordinates closest, interpolated; 0114 for( int i: candidates ) { 0115 qreal const dist = m_segments[i].distanceTo( m_position, closest, interpolated ); 0116 if ( distance < 0.0 || dist < distance ) { 0117 distance = dist; 0118 m_closestSegmentIndex = i; 0119 m_positionOnRoute = interpolated; 0120 m_currentWaypoint = closest; 0121 } 0122 } 0123 } 0124 0125 m_positionDirty = false; 0126 } 0127 0128 const RouteSegment & Route::currentSegment() const 0129 { 0130 if ( m_positionDirty ) { 0131 updatePosition(); 0132 } 0133 0134 if ( m_closestSegmentIndex < 0 || m_closestSegmentIndex >= m_segments.size() ) { 0135 static RouteSegment invalid; 0136 return invalid; 0137 } 0138 0139 return m_segments[m_closestSegmentIndex]; 0140 } 0141 0142 GeoDataCoordinates Route::positionOnRoute() const 0143 { 0144 if ( m_positionDirty ) { 0145 updatePosition(); 0146 } 0147 0148 return m_positionOnRoute; 0149 } 0150 0151 GeoDataCoordinates Route::currentWaypoint() const 0152 { 0153 if ( m_positionDirty ) { 0154 updatePosition(); 0155 } 0156 0157 return m_currentWaypoint; 0158 } 0159 0160 }