diff --git a/src/datatypes/vehicle.cpp b/src/datatypes/vehicle.cpp index f04a888..c0069a0 100644 --- a/src/datatypes/vehicle.cpp +++ b/src/datatypes/vehicle.cpp @@ -1,158 +1,168 @@ /* Copyright (C) 2019 Volker Krause This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "vehicle.h" #include "json_p.h" #include "datatypes_p.h" #include #include #include #include using namespace KPublicTransport; namespace KPublicTransport { class VehicleSectionPrivate : public QSharedData { public: QString name; float platformPositionBegin = -1.0; float platformPositionEnd = -1.0; VehicleSection::Type type = VehicleSection::UnknownType; VehicleSection::Classes classes = VehicleSection::UnknownClass; VehicleSection::Features features = VehicleSection::NoFeatures; int deckCount = 1; VehicleSection::Sides connectedSides = VehicleSection::Front | VehicleSection::Back; }; class VehiclePrivate : public QSharedData { public: QString name; std::vector sections; Vehicle::Direction direction = Vehicle::UnknownDirection; }; } KPUBLICTRANSPORT_MAKE_GADGET(VehicleSection) KPUBLICTRANSPORT_MAKE_PROPERTY(VehicleSection, QString, name, setName) KPUBLICTRANSPORT_MAKE_PROPERTY(VehicleSection, float, platformPositionBegin, setPlatformPositionBegin) KPUBLICTRANSPORT_MAKE_PROPERTY(VehicleSection, float, platformPositionEnd, setPlatformPositionEnd) KPUBLICTRANSPORT_MAKE_PROPERTY(VehicleSection, VehicleSection::Type, type, setType) KPUBLICTRANSPORT_MAKE_PROPERTY(VehicleSection, VehicleSection::Classes, classes, setClasses) KPUBLICTRANSPORT_MAKE_PROPERTY(VehicleSection, VehicleSection::Features, features, setFeatures) KPUBLICTRANSPORT_MAKE_PROPERTY(VehicleSection, int, deckCount, setDeckCount) KPUBLICTRANSPORT_MAKE_PROPERTY(VehicleSection, VehicleSection::Sides, connectedSides, setConnectedSides) QJsonObject VehicleSection::toJson(const VehicleSection §ion) { return Json::toJson(section); } QJsonArray VehicleSection::toJson(const std::vector §ions) { return Json::toJson(sections); } VehicleSection VehicleSection::fromJson(const QJsonObject &obj) { return Json::fromJson(obj); } std::vector VehicleSection::fromJson(const QJsonArray &array) { return Json::fromJson(array); } QVariantList VehicleSection::featureList() const { QVariantList l; const auto me = QMetaEnum::fromType(); for (int i = 0; i < me.keyCount(); ++i) { if (features() & static_cast(1 << i)) l.push_back(static_cast(1 << i)); } return l; } KPUBLICTRANSPORT_MAKE_GADGET(Vehicle) KPUBLICTRANSPORT_MAKE_PROPERTY(Vehicle, QString, name, setName) KPUBLICTRANSPORT_MAKE_PROPERTY(Vehicle, Vehicle::Direction, direction, setDirection) const std::vector& Vehicle::sections() const { return d->sections; } std::vector&& Vehicle::takeSections() { return std::move(d->sections); } void Vehicle::setSections(std::vector &§ions) { d.detach(); d->sections = std::move(sections); } QVariantList Vehicle::sectionsVariant() const { QVariantList l; l.reserve(d->sections.size()); std::transform(d->sections.begin(), d->sections.end(), std::back_inserter(l), [](const auto &sec) { return QVariant::fromValue(sec); }); return l; } float Vehicle::platformPositionBegin() const { float p = std::numeric_limits::max(); for (const auto §ion : sections()) { p = std::min(p, section.platformPositionBegin()); } return p; } float Vehicle::platformPositionEnd() const { float p = -1.0f; for (const auto §ion : sections()) { p = std::max(p, section.platformPositionEnd()); } return p; } +float Vehicle::platformPositionForSection(const QString §ionName) const +{ + for (const auto §ion : sections()) { + if (section.name() == sectionName) { + return (section.platformPositionBegin() + section.platformPositionEnd()) / 2.0f; + } + } + return -1.0f; +} + QJsonObject Vehicle::toJson(const Vehicle &vehicle) { auto obj = Json::toJson(vehicle); if (!vehicle.sections().empty()) { obj.insert(QStringLiteral("sections"), VehicleSection::toJson(vehicle.sections())); } return obj; } Vehicle Vehicle::fromJson(const QJsonObject &obj) { auto v = Json::fromJson(obj); v.setSections(VehicleSection::fromJson(obj.value(QLatin1String("sections")).toArray())); return v; } #include "moc_vehicle.cpp" diff --git a/src/datatypes/vehicle.h b/src/datatypes/vehicle.h index c4fb1ae..e7905aa 100644 --- a/src/datatypes/vehicle.h +++ b/src/datatypes/vehicle.h @@ -1,191 +1,197 @@ /* Copyright (C) 2019 Volker Krause This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef KPUBLICTRANSPORT_VEHICLE_H #define KPUBLICTRANSPORT_VEHICLE_H #include #include "datatypes.h" namespace KPublicTransport { class VehicleSectionPrivate; /** Information about a part of a vehicle. * This typically describes a coach of a train. */ class KPUBLICTRANSPORT_EXPORT VehicleSection { KPUBLICTRANSPORT_GADGET(VehicleSection) /** Human readable identifier of this section, typically the coach number. * Can be empty for sections closed to passengers, such as train engines. */ KPUBLICTRANSPORT_PROPERTY(QString, name, setName) /** Relative position [0-1] of the begin of this vehicle section on the platform. * 0 representing the begin of the platform in platform coordinate (@see Platform), 1 being the opposite end. */ KPUBLICTRANSPORT_PROPERTY(float, platformPositionBegin, setPlatformPositionBegin) /** Relative position [0-1] of the end of this vehicle section on the platform. * 0 representing the begin of the platform in platform coordinate (@see Platform), 1 being the opposite end. */ KPUBLICTRANSPORT_PROPERTY(float, platformPositionEnd, setPlatformPositionEnd) /** Vehicle section type. */ enum Type { UnknownType, ///< no information about the vehicle section type available Engine, ///< train engine, not accessible by passengers, only shown for orientation PowerCar, ///< power car of a train, similar to Engine, distinction exists just for better visualization ControlCar, ///< usually at the head of the train, but accessible for passengers and the same way as a PassengerCar PassengerCar, ///< passenger car of a train RestaurantCar, ///< full-car restaurant }; Q_ENUM(Type) /** Type of this vehicle section. */ KPUBLICTRANSPORT_PROPERTY(Type, type, setType) /** Classes available in a vehicle section. */ enum Class { UnknownClass = 0, FirstClass = 1, ///< 1st class SecondClass = 2, ///< 2nd class ThirdClass = 4 ///< 3rd class }; Q_DECLARE_FLAGS(Classes, Class) Q_FLAG(Classes) /** Classes available in this vehicle section. * Can be more than one. */ KPUBLICTRANSPORT_PROPERTY(Classes, classes, setClasses) /** Amenities or other features available in a vehicle section. */ enum Feature { NoFeatures = 0, AirConditioning = 1, ///< vehicle section is air conditioned Restaurant = 2, ///< vehicle has a place to obtain food/drinks (but not necessarily a full-scale RestaurantCar) ToddlerArea = 4, ///< vehicle section contains infrastructure for toddler maintenance WheelchairAccessible = 8, ///< wheelchair access supported SilentArea = 16, ///< wishful thinking usually BikeStorage = 32, ///< vehicle section contains space for bikes // TODO there's a few more we get from DB }; Q_DECLARE_FLAGS(Features, Feature) Q_FLAG(Features) /** Features available in this vehicle section. * Can be more than one. */ KPUBLICTRANSPORT_PROPERTY(Features, features, setFeatures) /** Feature flag as a variant list, for consumption in QML. */ Q_PROPERTY(QVariantList featureList READ featureList STORED false) /** Number of decks in this vehicle section. */ KPUBLICTRANSPORT_PROPERTY(int, deckCount, setDeckCount) /** Vehicle section side. * Front is towards the smaller platform coordinate, Back is the opposite direction. */ enum Side { NoSide = 0, Front = 1, Back = 2 }; Q_DECLARE_FLAGS(Sides, Side) Q_FLAG(Sides) /** Sides on which this vehicle section is connected to neighboring sections * in a way that passengers can move between those sections. * This matters for example for a double segment train with to control cars * in the middle of its full layout. */ KPUBLICTRANSPORT_PROPERTY(Sides, connectedSides, setConnectedSides) /** Serializes one vehicle section to JSON. */ static QJsonObject toJson(const VehicleSection §ion); /** Serializes a vector of vehicle sections to JSON. */ static QJsonArray toJson(const std::vector §ions); /** Deserialize an object from JSON. */ static VehicleSection fromJson(const QJsonObject &obj); /** Deserialize a vector of vehicle sections from JSON. */ static std::vector fromJson(const QJsonArray &array); private: QVariantList featureList() const; }; class VehiclePrivate; /** Information about the vehicle used on a journey. * This is typically only available for trains, and describes their coach layout. */ class KPUBLICTRANSPORT_EXPORT Vehicle { KPUBLICTRANSPORT_GADGET(Vehicle) /** Human readable identifier of this vehicle, typically a train number. */ KPUBLICTRANSPORT_PROPERTY(QString, name, setName) /** Direction of travel. */ enum Direction { UnknownDirection, Forward, ///< vehicle departs toward the 0 platform coordinate Backward ///< vehicle departs toward the 1 platforma coordinate }; Q_ENUM(Direction) /** Direction of travel of this vehicle. */ KPUBLICTRANSPORT_PROPERTY(Direction, direction, setDirection) /** Journey sections for consumption by QML. */ Q_PROPERTY(QVariantList sections READ sectionsVariant) /** Relative position [0-1] of the begin of this vehicle on the platform. * 0 representing the begin of the platform in platform coordinate (@see Platform), 1 being the opposite end. */ Q_PROPERTY(float platformPositionBegin READ platformPositionBegin STORED false) /** Relative position [0-1] of the end of this vehicle on the platform. * 0 representing the begin of the platform in platform coordinate (@see Platform), 1 being the opposite end. */ Q_PROPERTY(float platformPositionEnd READ platformPositionEnd STORED false) public: /** The vehicle sections. */ const std::vector& sections() const; /** Moves the vehicle sections out of this object. */ std::vector&& takeSections(); /** Sets the vehicle sections. */ void setSections(std::vector &§ions); float platformPositionBegin() const; float platformPositionEnd() const; + /** Returns the center position of the vehicle section named @p sectionName + * in relative platform coordinates. + * Useful for centering a view on a selected section for example. + */ + Q_INVOKABLE float platformPositionForSection(const QString §ionName) const; + /** Serializes one vehicle object to JSON. */ static QJsonObject toJson(const Vehicle &vehicle); /** Deserialize an object from JSON. */ static Vehicle fromJson(const QJsonObject &obj); private: QVariantList sectionsVariant() const; }; } Q_DECLARE_OPERATORS_FOR_FLAGS(KPublicTransport::VehicleSection::Classes) Q_DECLARE_OPERATORS_FOR_FLAGS(KPublicTransport::VehicleSection::Features) Q_DECLARE_OPERATORS_FOR_FLAGS(KPublicTransport::VehicleSection::Sides) Q_DECLARE_METATYPE(KPublicTransport::VehicleSection) Q_DECLARE_METATYPE(KPublicTransport::Vehicle) #endif // KPUBLICTRANSPORT_VEHICLE_H