Marble

Route.cpp
1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 //
3 // SPDX-FileCopyrightText: 2011 Dennis Nienhüser <[email protected]>
4 //
5 
6 #include "Route.h"
7 
8 namespace Marble
9 {
10 
11 Route::Route() :
12  m_distance( 0.0 ),
13  m_travelTime( 0 ),
14  m_positionDirty( true ),
15  m_closestSegmentIndex( -1 )
16 {
17  // nothing to do
18 }
19 
20 void Route::addRouteSegment( const RouteSegment &segment )
21 {
22  if ( segment.isValid() ) {
23  m_bounds = m_bounds.united( segment.bounds() );
24  m_distance += segment.distance();
25  m_path << segment.path();
26  if ( segment.maneuver().position().isValid() ) {
27  m_turnPoints << segment.maneuver().position();
28  }
29  if ( segment.maneuver().hasWaypoint() ) {
30  m_waypoints << segment.maneuver().waypoint();
31  }
32  m_segments.push_back( segment );
33  m_positionDirty = true;
34 
35  for ( int i=1; i<m_segments.size(); ++i ) {
36  m_segments[i-1].setNextRouteSegment(&m_segments[i]);
37  }
38  }
39 }
40 
41 GeoDataLatLonBox Route::bounds() const
42 {
43  return m_bounds;
44 }
45 
46 qreal Route::distance() const
47 {
48  return m_distance;
49 }
50 
51 int Route::size() const
52 {
53  return m_segments.size();
54 }
55 
56 const RouteSegment & Route::at( int index ) const
57 {
58  return m_segments[index];
59 }
60 
61 int Route::indexOf(const RouteSegment &segment) const
62 {
63  return m_segments.indexOf(segment);
64 }
65 
66 const GeoDataLineString & Route::path() const
67 {
68  return m_path;
69 }
70 
71 int Route::travelTime() const
72 {
73  return m_travelTime;
74 }
75 
76 const GeoDataLineString & Route::turnPoints() const
77 {
78  return m_turnPoints;
79 }
80 
81 const GeoDataLineString & Route::waypoints() const
82 {
83  return m_waypoints;
84 }
85 
86 void Route::setPosition( const GeoDataCoordinates &position )
87 {
88  m_position = position;
89  m_positionDirty = true;
90 }
91 
92 GeoDataCoordinates Route::position() const
93 {
94  return m_position;
95 }
96 
97 void Route::updatePosition() const
98 {
99  if ( !m_segments.isEmpty() ) {
100  if ( m_closestSegmentIndex < 0 || m_closestSegmentIndex >= m_segments.size() ) {
101  m_closestSegmentIndex = 0;
102  }
103 
104  qreal distance = m_segments[m_closestSegmentIndex].distanceTo( m_position, m_currentWaypoint, m_positionOnRoute );
105  QList<int> candidates;
106 
107  for ( int i=0; i<m_segments.size(); ++i ) {
108  if ( i != m_closestSegmentIndex && m_segments[i].minimalDistanceTo( m_position ) <= distance ) {
109  candidates << i;
110  }
111  }
112 
113  GeoDataCoordinates closest, interpolated;
114  for( int i: candidates ) {
115  qreal const dist = m_segments[i].distanceTo( m_position, closest, interpolated );
116  if ( distance < 0.0 || dist < distance ) {
117  distance = dist;
118  m_closestSegmentIndex = i;
119  m_positionOnRoute = interpolated;
120  m_currentWaypoint = closest;
121  }
122  }
123  }
124 
125  m_positionDirty = false;
126 }
127 
128 const RouteSegment & Route::currentSegment() const
129 {
130  if ( m_positionDirty ) {
131  updatePosition();
132  }
133 
134  if ( m_closestSegmentIndex < 0 || m_closestSegmentIndex >= m_segments.size() ) {
135  static RouteSegment invalid;
136  return invalid;
137  }
138 
139  return m_segments[m_closestSegmentIndex];
140 }
141 
142 GeoDataCoordinates Route::positionOnRoute() const
143 {
144  if ( m_positionDirty ) {
145  updatePosition();
146  }
147 
148  return m_positionOnRoute;
149 }
150 
151 GeoDataCoordinates Route::currentWaypoint() const
152 {
153  if ( m_positionDirty ) {
154  updatePosition();
155  }
156 
157  return m_currentWaypoint;
158 }
159 
160 }
KOSM_EXPORT double distance(const std::vector< const OSM::Node * > &path, Coordinate coord)
Binds a QML item to a specific geodetic location in screen coordinates.
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Thu Sep 21 2023 04:12:28 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.