7#include "vehiclelayoutquerymodel.h"
8#include "abstractquerymodel_p.h"
10#include <KPublicTransport/Attribution>
11#include <KPublicTransport/VehicleLayoutReply>
12#include <KPublicTransport/Manager>
19class VehicleLayoutQueryModelPrivate :
public AbstractQueryModelPrivate
22 void doQuery()
override;
23 void doClearResults()
override;
25 void interpolatePlatformPositionsFromSectionName();
26 template <
typename Iter>
27 void interpolatePlatformPositionsFromSectionName(Iter begin, Iter end);
29 VehicleLayoutRequest m_request;
32 Q_DECLARE_PUBLIC(VehicleLayoutQueryModel)
36void VehicleLayoutQueryModelPrivate::doQuery()
38 Q_Q(VehicleLayoutQueryModel);
39 if (!m_manager || !m_request.isValid()) {
45 m_stopover = m_request.stopover();
47 Q_EMIT q->contentChanged();
50 auto reply = m_manager->queryVehicleLayout(m_request);
53 Q_Q(VehicleLayoutQueryModel);
55 m_stopover = reply->stopover();
56 if (!m_stopover.platformLayout().isEmpty() && !m_stopover.vehicleLayout().isEmpty()
57 && !m_stopover.vehicleLayout().hasPlatformPositions() && m_stopover.vehicleLayout().hasPlatformSectionNames()) {
58 interpolatePlatformPositionsFromSectionName();
61 Q_EMIT q->contentChanged();
65void VehicleLayoutQueryModelPrivate::doClearResults()
68 Q_Q(VehicleLayoutQueryModel);
69 Q_EMIT q->contentChanged();
72void VehicleLayoutQueryModelPrivate::interpolatePlatformPositionsFromSectionName()
74 auto vehicle = m_stopover.vehicleLayout();
75 auto vehicleSections = vehicle.takeSections();
76 const auto startSection = vehicleSections.front().platformSectionName();
77 const auto endSection = vehicleSections.back().platformSectionName();
79 const auto platform = m_stopover.platformLayout();
80 for (
const auto &sec : platform.sections()) {
81 if (sec.name() == startSection) {
82 interpolatePlatformPositionsFromSectionName(vehicleSections.begin(), vehicleSections.end());
84 }
else if (sec.name() == endSection) {
85 interpolatePlatformPositionsFromSectionName(vehicleSections.rbegin(), vehicleSections.rend());
90 vehicle.setSections(std::move(vehicleSections));
91 m_stopover.setVehicleLayout(std::move(vehicle));
94template<
typename Iter>
95void VehicleLayoutQueryModelPrivate::interpolatePlatformPositionsFromSectionName(Iter begin, Iter end)
97 auto rangeBegin = begin, rangeEnd = begin;
98 float minLength = 1.0;
99 while (rangeBegin != end) {
100 while (rangeEnd != end && (*rangeBegin).platformSectionName() == (*rangeEnd).platformSectionName()) {
104 const auto platformIt = std::find_if(m_stopover.platformLayout().sections().begin(), m_stopover.platformLayout().sections().end(), [&rangeBegin](
const auto &p) {
105 return p.name() == (*rangeBegin).platformSectionName();
107 if (platformIt == m_stopover.platformLayout().sections().end()) {
108 qWarning() <<
"Failed to find platform section" << (*rangeBegin).platformSectionName();
112 auto l = ((*platformIt).end() - (*platformIt).begin()) / std::distance(rangeBegin, rangeEnd);
113 minLength = std::min(minLength, l);
115 if (rangeEnd == end) {
119 auto pos = (*platformIt).begin();
120 for (
auto it = rangeBegin; it != rangeEnd; ++it) {
121 (*it).setPlatformPositionBegin(pos);
122 (*it).setPlatformPositionEnd(pos + l);
126 rangeBegin = rangeEnd;
130 rangeEnd = std::find_if(begin, end, [&begin](
const auto &p) {
131 return p.platformSectionName() != (*begin).platformSectionName();
133 auto pos = (*std::prev(rangeEnd)).platformPositionEnd() - std::distance(begin, rangeEnd) * minLength;
134 for (
auto it = begin; it != rangeEnd; ++it) {
135 (*it).setPlatformPositionBegin(pos);
136 (*it).setPlatformPositionEnd(pos + minLength);
142VehicleLayoutQueryModel::VehicleLayoutQueryModel(QObject* parent)
147VehicleLayoutQueryModel::~VehicleLayoutQueryModel() =
default;
151 Q_D(
const VehicleLayoutQueryModel);
157 Q_D(VehicleLayoutQueryModel);
175 Q_D(
const VehicleLayoutQueryModel);
176 return d->m_stopover;
179int VehicleLayoutQueryModel::rowCount(
const QModelIndex &parent)
const
181 Q_D(
const VehicleLayoutQueryModel);
185 return d->m_stopover.vehicleLayout().sections().size();
188QVariant VehicleLayoutQueryModel::data(
const QModelIndex &index,
int role)
const
190 Q_D(
const VehicleLayoutQueryModel);
191 if (!
index.isValid()) {
196 case VehicleSectionRole:
203QHash<int, QByteArray> VehicleLayoutQueryModel::roleNames()
const
206 r.insert(VehicleSectionRole,
"vehicleSection");
210#include "moc_vehiclelayoutquerymodel.moc"
Common base class for query models, do not use directly.
void finished()
Emitted whenever the corresponding search has been completed.
Information about an arrival and/or departure of a vehicle at a stop area.
KPublicTransport::Vehicle vehicleLayout
Vehicle coach layout information at this stopover.
KPublicTransport::Platform platformLayout
Platform layout information.
KPublicTransport::Vehicle vehicle
The vehicle for which this model shows its sections.
KPublicTransport::Stopover stopover
The departure this vehicle layout belongs to.
KPublicTransport::Platform platform
The platform this vehicle is departing from.
Describes a query for vehicle layout information.
Information about the vehicle used on a journey.
Query operations and data types for accessing realtime public transport information from online servi...
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const const=0
virtual QModelIndex parent(const QModelIndex &index) const const=0
virtual QHash< int, QByteArray > roleNames() const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QVariant fromValue(T &&value)