6#include "RoutingModel.h" 
    8#include "GeoDataAccuracy.h" 
    9#include "MarbleGlobal.h" 
   11#include "PlanetFactory.h" 
   12#include "PositionTracking.h" 
   14#include "RouteRequest.h" 
   22class RoutingModelPrivate
 
   31    explicit RoutingModelPrivate(PositionTracking *positionTracking, RouteRequest *request);
 
   35    PositionTracking *
const m_positionTracking;
 
   36    RouteRequest *
const m_request;
 
   37    QHash<int, QByteArray> m_roleNames;
 
   38    RouteDeviation m_deviation;
 
   40    void updateViaPoints(
const GeoDataCoordinates &position);
 
   43RoutingModelPrivate::RoutingModelPrivate(PositionTracking *positionTracking, 
RouteRequest *request)
 
   44    : m_positionTracking(positionTracking)
 
   54    qreal 
const threshold = 500 / EARTH_RADIUS;
 
   55    for (
int i = 0; i < m_request->size(); ++i) {
 
   56        if (!m_request->visited(i)) {
 
   58                m_request->setVisited(i, 
true);
 
   64RoutingModel::RoutingModel(RouteRequest *request, PositionTracking *positionTracking, 
QObject *parent)
 
   66    , d(new RoutingModelPrivate(positionTracking, request))
 
   72    roles.
insert(RoutingModel::TurnTypeIconRole, 
"turnTypeIcon");
 
   73    roles.
insert(RoutingModel::LongitudeRole, 
"longitude");
 
   74    roles.
insert(RoutingModel::LatitudeRole, 
"latitude");
 
   75    d->m_roleNames = roles;
 
   78RoutingModel::~RoutingModel()
 
   83int RoutingModel::rowCount(
const QModelIndex &parent)
 const 
   85    return parent.
isValid() ? 0 : d->m_route.turnPoints().size();
 
   91        return QStringLiteral(
"Instruction");
 
  103    if (index.
row() < d->m_route.turnPoints().size() && index.
column() == 0) {
 
  104        const RouteSegment &segment = d->m_route.at(index.
row());
 
  108            return segment.maneuver().instructionText();
 
  110            bool const smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;
 
  111            if (segment.maneuver().hasWaypoint()) {
 
  112                int const size = smallScreen ? 64 : 32;
 
  113                return d->m_request->pixmap(segment.maneuver().waypointIndex(), size, size / 4);
 
  116            QPixmap const pixmap = segment.maneuver().directionPixmap();
 
  117            return smallScreen ? pixmap : pixmap.
scaled(32, 32);
 
  120            bool const smallScreen = MarbleGlobal::getInstance()->profiles() & MarbleGlobal::SmallScreen;
 
  121            int const size = smallScreen ? 64 : 32;
 
  122            return QSize(size, size);
 
  124        case RoutingModel::CoordinateRole:
 
  126        case RoutingModel::LongitudeRole:
 
  127            return {segment.maneuver().position().longitude(GeoDataCoordinates::Degree)};
 
  128        case RoutingModel::LatitudeRole:
 
  129            return {segment.maneuver().position().latitude(GeoDataCoordinates::Degree)};
 
  130        case RoutingModel::TurnTypeIconRole:
 
  131            return segment.maneuver().directionPixmap();
 
  142    return d->m_roleNames;
 
  145void RoutingModel::setRoute(
const Route &route)
 
  148    d->m_deviation = RoutingModelPrivate::Unknown;
 
  152    Q_EMIT currentRouteChanged();
 
  155void RoutingModel::exportGpx(
QIODevice *device)
 const 
  158        "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n" 
  159        "<gpx xmlns=\"http://www.topografix.com/GPX/1/1\" creator=\"Marble\" version=\"1.1\" " 
  160        "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " 
  161        "xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 " 
  162        "http://www.topografix.com/GPX/1/1/gpx.xsd\">\n" 
  163        "<metadata>\n  <link href=\"http://edu.kde.org/marble\">\n    " 
  164        "<text>Marble Virtual Globe</text>\n  </link>\n</metadata>\n" 
  165        "  <rte>\n    <name>Route</name>\n");
 
  166    bool hasAltitude = 
false;
 
  167    for (
int i = 0; !hasAltitude && i < d->m_route.size(); ++i) {
 
  168        hasAltitude = d->m_route.at(i).maneuver().position().altitude() != 0.0;
 
  170    for (
int i = 0; i < d->m_route.size(); ++i) {
 
  171        const Maneuver &maneuver = d->m_route.at(i).maneuver();
 
  172        qreal lon = maneuver.position().longitude(GeoDataCoordinates::Degree);
 
  173        qreal lat = maneuver.position().latitude(GeoDataCoordinates::Degree);
 
  174        QString const text = maneuver.instructionText();
 
  175        content += QStringLiteral(
"    <rtept lat=\"%1\" lon=\"%2\">\n").
arg(lat, 0, 
'f', 7).
arg(lon, 0, 
'f', 7);
 
  176        content += QStringLiteral(
"        <name>%1</name>\n").
arg(text);
 
  178            content += QStringLiteral(
"        <ele>%1</ele>\n").
arg(maneuver.position().altitude(), 0, 
'f', 2);
 
  180        content += QStringLiteral(
"    </rtept>\n");
 
  184        "<trk>\n  <name>Route</name>\n    <trkseg>\n");
 
  185    GeoDataLineString points = d->m_route.path();
 
  187    for (
int i = 0; !hasAltitude && i < points.size(); ++i) {
 
  188        hasAltitude = points[i].altitude() != 0.0;
 
  190    for (
int i = 0; i < points.size(); ++i) {
 
  192        qreal lon = point.longitude(GeoDataCoordinates::Degree);
 
  193        qreal lat = point.latitude(GeoDataCoordinates::Degree);
 
  194        content += QStringLiteral(
"      <trkpt lat=\"%1\" lon=\"%2\">\n").
arg(lat, 0, 
'f', 7).
arg(lon, 0, 
'f', 7);
 
  196            content += QStringLiteral(
"        <ele>%1</ele>\n").
arg(point.
altitude(), 0, 
'f', 2);
 
  198        content += QStringLiteral(
"      </trkpt>\n");
 
  201        "    </trkseg>\n  </trk>\n" 
  207void RoutingModel::clear()
 
  209    d->m_route = Route();
 
  212    Q_EMIT currentRouteChanged();
 
  215int RoutingModel::rightNeighbor(
const GeoDataCoordinates &position, RouteRequest 
const *
const route)
 const 
  217    Q_ASSERT(route && 
"Must not pass a null route ");
 
  220    if (route->size() < 3) {
 
  221        return route->size() - 1;
 
  225    GeoDataLineString points = d->m_route.path();
 
  233    for (
int j = 1; j < route->size() - 1; ++j) {
 
  234        qreal minDistance = -1.0;
 
  235        for (
int i = mapping[j - 1]; i < points.size(); ++i) {
 
  236            const qreal 
distance = points[i].sphericalDistanceTo(route->at(j));
 
  237            if (minDistance < 0.0 || distance < minDistance) {
 
  245    qreal minWaypointDistance = -1.0;
 
  247    for (
int i = 0; i < points.size(); ++i) {
 
  248        const qreal waypointDistance = points[i].sphericalDistanceTo(position);
 
  249        if (minWaypointDistance < 0.0 || waypointDistance < minWaypointDistance) {
 
  250            minWaypointDistance = waypointDistance;
 
  256    mapping[route->size() - 1] = points.
size() - 1;
 
  260    for (; iter != mapping.
constEnd(); ++iter) {
 
  261        if (iter.value() > waypoint) {
 
  262            int index = iter.key();
 
  263            Q_ASSERT(index >= 0 && index <= route->size());
 
  268    return route->size() - 1;
 
  273    d->m_route.setPosition(location);
 
  275    d->updateViaPoints(location);
 
  276    const qreal planetRadius = PlanetFactory::construct(QStringLiteral(
"earth")).radius();
 
  277    const qreal 
distance = planetRadius * 
location.sphericalDistanceTo(d->m_route.positionOnRoute());
 
  278    Q_EMIT positionChanged();
 
  280    qreal deviation = 0.0;
 
  281    if (d->m_positionTracking && d->m_positionTracking->accuracy().vertical > 0.0) {
 
  282        deviation = qMax<qreal>(d->m_positionTracking->accuracy().vertical, d->m_positionTracking->accuracy().horizontal);
 
  284    qreal 
const threshold = deviation + qBound(10.0, speed * 10.0, 150.0);
 
  286    RoutingModelPrivate::RouteDeviation 
const deviated = 
distance < threshold ? RoutingModelPrivate::OnRoute : RoutingModelPrivate::OffRoute;
 
  287    if (d->m_deviation != deviated) {
 
  288        d->m_deviation = deviated;
 
  289        Q_EMIT deviatedFromRoute(deviated == RoutingModelPrivate::OffRoute);
 
  293bool RoutingModel::deviatedFromRoute()
 const 
  295    return d->m_deviation == RoutingModelPrivate::OffRoute;
 
  298const Route &RoutingModel::route()
 const 
  305#include "moc_RoutingModel.cpp" 
A 3d point representation.
 
qreal altitude() const
return the altitude of the Point in meters
 
qreal sphericalDistanceTo(const GeoDataCoordinates &other) const
This method calculates the shortest distance between two points on a sphere.
 
Points to be included in a route.
 
QVariant location(const QVariant &res)
 
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)
 
iterator insert(const Key &key, const T &value)
 
qint64 write(const QByteArray &data)
 
const_iterator constBegin() const const
 
const_iterator constEnd() const const
 
size_type size() const const
 
bool isValid() const const
 
QPixmap scaled(const QSize &size, Qt::AspectRatioMode aspectRatioMode, Qt::TransformationMode transformMode) const const
 
QString arg(Args &&... args) const const
 
QByteArray toUtf8() const const
 
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
 
QVariant fromValue(T &&value)