6#include "RouteSegment.h"
8#include "GeoDataLatLonAltBox.h"
13RouteSegment::RouteSegment()
17 , m_nextRouteSegment(nullptr)
22qreal RouteSegment::distance()
const
27const Maneuver &RouteSegment::maneuver()
const
32void RouteSegment::setManeuver(
const Maneuver &maneuver)
34 m_maneuver = maneuver;
38const GeoDataLineString &RouteSegment::path()
const
43void RouteSegment::setPath(
const GeoDataLineString &path)
46 m_distance = m_path.
length(EARTH_RADIUS);
47 m_bounds = m_path.latLonAltBox();
51int RouteSegment::travelTime()
const
56void RouteSegment::setTravelTime(
int seconds)
58 m_travelTime = seconds;
62GeoDataLatLonBox RouteSegment::bounds()
const
67const RouteSegment &RouteSegment::nextRouteSegment()
const
69 if (m_nextRouteSegment) {
70 return *m_nextRouteSegment;
73 static RouteSegment invalid;
77void RouteSegment::setNextRouteSegment(
const RouteSegment *segment)
79 m_nextRouteSegment = segment;
85bool RouteSegment::isValid()
const
90qreal RouteSegment::distancePointToLine(
const GeoDataCoordinates &p,
const GeoDataCoordinates &a,
const GeoDataCoordinates &b)
92 return EARTH_RADIUS * p.sphericalDistanceTo(projected(p, a, b));
95GeoDataCoordinates RouteSegment::projected(
const GeoDataCoordinates &p,
const GeoDataCoordinates &a,
const GeoDataCoordinates &b)
97 qreal
const y0 = p.latitude();
98 qreal
const x0 = p.longitude();
99 qreal
const y1 = a.latitude();
100 qreal
const x1 = a.longitude();
101 qreal
const y2 = b.latitude();
102 qreal
const x2 = b.longitude();
103 qreal
const y01 = x0 - x1;
104 qreal
const x01 = y0 - y1;
105 qreal
const y21 = x2 - x1;
106 qreal
const x21 = y2 - y1;
107 qreal
const len = x21 * x21 + y21 * y21;
108 qreal
const t = (x01 * x21 + y01 * y21) / len;
111 }
else if (t > 1.0) {
115 qreal
const lon = x1 + t * (x2 - x1);
116 qreal
const lat = y1 + t * (y2 - y1);
121qreal RouteSegment::distanceTo(
const GeoDataCoordinates &point, GeoDataCoordinates &closest, GeoDataCoordinates &interpolated)
const
123 Q_ASSERT(!m_path.isEmpty());
125 if (m_path.size() == 1) {
126 closest = m_path.first();
127 return EARTH_RADIUS * m_path.first().sphericalDistanceTo(point);
130 qreal minDistance = -1.0;
132 for (
int i = 1; i < m_path.size(); ++i) {
133 qreal
const distance = distancePointToLine(point, m_path[i - 1], m_path[i]);
134 if (minDistance < 0.0 || distance < minDistance) {
140 closest = m_path[minIndex];
142 interpolated = closest;
144 interpolated = projected(point, m_path[minIndex - 1], m_path[minIndex]);
150qreal RouteSegment::minimalDistanceTo(
const GeoDataCoordinates &point)
const
152 if (bounds().contains(point)) {
156 qreal north(0.0), east(0.0), south(0.0), west(0.0);
157 bounds().boundaries(north, south, east, west);
158 GeoDataCoordinates
const northWest(west, north);
159 GeoDataCoordinates
const northEast(east, north);
160 GeoDataCoordinates
const southhWest(west, south);
161 GeoDataCoordinates
const southEast(east, south);
163 qreal distNorth = distancePointToLine(point, northWest, northEast);
164 qreal distEast = distancePointToLine(point, northEast, southEast);
165 qreal distSouth = distancePointToLine(point, southhWest, southEast);
166 qreal distWest = distancePointToLine(point, northWest, southhWest);
167 return qMin(qMin(distNorth, distEast), qMin(distWest, distSouth));
170qreal RouteSegment::projectedDirection(
const GeoDataCoordinates &point)
const
172 if (m_path.size() < 2) {
176 qreal minDistance = -1.0;
178 for (
int i = 1; i < m_path.size(); ++i) {
179 qreal
const distance = distancePointToLine(point, m_path[i - 1], m_path[i]);
180 if (minDistance < 0.0 || distance < minDistance) {
187 return m_path[0].bearing(m_path[1], GeoDataCoordinates::Degree, GeoDataCoordinates::FinalBearing);
189 return m_path[minIndex - 1].bearing(m_path[minIndex], GeoDataCoordinates::Degree, GeoDataCoordinates::FinalBearing);
193bool RouteSegment::operator==(
const RouteSegment &other)
const
195 return m_valid == other.m_valid && m_distance == other.m_distance && m_maneuver == other.m_maneuver && m_travelTime == other.m_travelTime
196 && m_bounds == other.m_bounds && m_nextRouteSegment == other.m_nextRouteSegment;
199bool RouteSegment::operator!=(
const RouteSegment &other)
const
201 return !(other == *
this);
QString path(const QString &relativePath)
Binds a QML item to a specific geodetic location in screen coordinates.
KOSM_EXPORT double distance(const std::vector< const OSM::Node * > &path, Coordinate coord)
qsizetype length() const const