KPublicTransport

vehiclelayoutreply.cpp
1 /*
2  SPDX-FileCopyrightText: 2019 Volker Krause <[email protected]>
3 
4  SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 
7 #include "vehiclelayoutreply.h"
8 #include "reply_p.h"
9 #include "vehiclelayoutrequest.h"
10 #include "logging.h"
11 #include "backends/abstractbackend.h"
12 #include "backends/cache.h"
13 
14 #include <KPublicTransport/Platform>
15 #include <KPublicTransport/Stopover>
16 #include <KPublicTransport/Vehicle>
17 
18 #include <QDebug>
19 
20 using namespace KPublicTransport;
21 
22 namespace KPublicTransport {
23 class VehicleLayoutReplyPrivate: public ReplyPrivate {
24 public:
25  void finalizeResult() override {}
26 
27  VehicleLayoutRequest request;
28  Stopover stopover;
29 };
30 }
31 
32 VehicleLayoutReply::VehicleLayoutReply(const VehicleLayoutRequest &req, QObject *parent)
33  : Reply(new VehicleLayoutReplyPrivate, parent)
34 {
35  Q_D(VehicleLayoutReply);
36  d->request = req;
37  d->stopover = req.stopover();
38 }
39 
40 VehicleLayoutReply::~VehicleLayoutReply() = default;
41 
43 {
44  Q_D(const VehicleLayoutReply);
45  return d->request;
46 }
47 
49 {
50  Q_D(const VehicleLayoutReply);
51  return d->stopover;
52 }
53 
54 static bool isOneSidedCar(VehicleSection::Type type)
55 {
56  return type == VehicleSection::PowerCar || type == VehicleSection::ControlCar;
57 }
58 
59 void VehicleLayoutReply::addResult(const Stopover &stopover)
60 {
61  Q_D(VehicleLayoutReply);
62  d->stopover = Stopover::merge(d->stopover, stopover);
63 
64  if (!d->stopover.vehicleLayout().sections().empty()) {
65  // normalize section order
66  auto vehicle = d->stopover.vehicleLayout();
67  auto sections = vehicle.takeSections();
68  std::sort(sections.begin(), sections.end(), [](const auto &lhs, const auto &rhs) {
69  return lhs.platformPositionBegin() < rhs.platformPositionBegin();
70  });
71 
72  // we have no connections at the ends
73  sections.front().setConnectedSides(sections.front().connectedSides() & ~VehicleSection::Front);
74  sections.back().setConnectedSides(sections.back().connectedSides() & ~VehicleSection::Back);
75 
76  // if the leading car in driving direction is a PassengerCar, turn it into a ControlCar
77  if (vehicle.direction() == Vehicle::Forward && sections.front().type() == VehicleSection::PassengerCar) {
78  sections.front().setType(VehicleSection::ControlCar);
79  } else if (vehicle.direction() == Vehicle::Backward && sections.back().type() == VehicleSection::PassengerCar) {
80  sections.back().setType(VehicleSection::ControlCar);
81  }
82 
83  for (auto it = sections.begin(); it != sections.end(); ++it) {
84  // engines and power cars have no connections either
85  if ((*it).type() == VehicleSection::Engine) {
86  (*it).setConnectedSides(VehicleSection::NoSide);
87  }
88 
89  if (it == sections.begin()) {
90  continue;
91  }
92 
93  // connect control cars in the middle of the train to the correct side
94  if (isOneSidedCar((*(it - 1)).type()) && isOneSidedCar((*it).type())) {
95  (*it).setConnectedSides((*it).connectedSides() & ~VehicleSection::Front);
96  }
97 
98  // make sure connections are symmetric
99  if (((*(it - 1)).connectedSides() & VehicleSection::Back) == 0) {
100  (*it).setConnectedSides((*it).connectedSides() & ~VehicleSection::Front);
101  }
102  if (((*it).connectedSides() & VehicleSection::Front) == 0) {
103  (*(it - 1)).setConnectedSides((*(it - 1)).connectedSides() & ~VehicleSection::Back);
104  }
105  }
106 
107  vehicle.setSections(std::move(sections));
108  d->stopover.setVehicleLayout(std::move(vehicle));
109  }
110 
111  d->pendingOps--;
112  d->emitFinishedIfDone(this);
113 }
114 
115 void VehicleLayoutReply::addError(const AbstractBackend *backend, Reply::Error error, const QString &errorMsg)
116 {
117  if (error == Reply::NotFoundError) {
118  // TODO add negative cache entry
119  } else {
120  qCDebug(Log) << backend->backendId() << error << errorMsg;
121  }
122  Reply::addError(error, errorMsg);
123 }
Direction direction
Direction of travel of this vehicle.
Definition: vehicle.h:154
KPublicTransport::Stopover stopover
The stopover vehicle and platform layout information are requested for.
Query operations and data types for accessing realtime public transport information from online servi...
Definition: attribution.cpp:16
Stopover stopover() const
The requested Stopover information, including the vehicle and platform layout.
Information about a part of a vehicle.
Definition: vehicle.h:22
std::vector< VehicleSection > && takeSections()
Moves the vehicle sections out of this object.
Definition: vehicle.cpp:128
The requested journey/departure/place could not be found.
Definition: reply.h:34
VehicleLayoutRequest request() const
The request this is the reply for.
Describes a query for vehicle layout information.
Error
Error types.
Definition: reply.h:31
Information about an arrival and/or departure of a vehicle at a stop area.
Definition: stopover.h:25
Reply to a vehicle layout query.
void setSections(std::vector< VehicleSection > &&sections)
Sets the vehicle sections.
Definition: vehicle.cpp:134
static Stopover merge(const Stopover &lhs, const Stopover &rhs)
Merge two departure instances.
Definition: stopover.cpp:182
Query response base class.
Definition: reply.h:24
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Fri Oct 15 2021 23:07:28 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.