summaryrefslogtreecommitdiff
path: root/navit/traffic.h
diff options
context:
space:
mode:
Diffstat (limited to 'navit/traffic.h')
-rw-r--r--navit/traffic.h996
1 files changed, 996 insertions, 0 deletions
diff --git a/navit/traffic.h b/navit/traffic.h
new file mode 100644
index 000000000..f1c8f8b34
--- /dev/null
+++ b/navit/traffic.h
@@ -0,0 +1,996 @@
+/**
+ * Navit, a modular navigation system.
+ * Copyright (C) 2005-2017 Navit Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * 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 Library General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/** @file
+ *
+ * @brief Contains exported code for traffic.c, the traffic module
+ *
+ * This file contains types and function prototypes exported from the traffic module, which enables
+ * Navit to route around traffic problems.
+ *
+ * The traffic module consists of two parts:
+ *
+ * The traffic core interacts with the Navit core and converts traffic messages into traffic
+ * distortions (future versions may add support for other traffic information).
+ *
+ * The traffic backends obtain traffic information from a source of their choice (e.g. from a TMC
+ * receiver or a network service), translate them into Navit data structures and report them to the
+ * traffic plugin.
+ *
+ * Traffic messages and related structures are considered immutable once created (when information
+ * changes, the old message is replaced with a new one). For this reason, there are very few data
+ * manipulation methods. Those that exist are intended for the creation of new messages rather than
+ * for extensive manipulation.
+ *
+ * As a rule, responsibility for freeing up any `traffic_*` instances normally lies with the
+ * traffic plugin, which frees messages as they expire or are replaced. Since this also frees all child
+ * data structures, traffic backends will seldom need to call any of the destructors. The only case in
+ * which this would be necessary is if a backend has instantiated an object which is not going to be
+ * used (i.e. attached to a parent object or, in the case of `traffic_message`, reported to the
+ * traffic plugin: these need to be freed up manually by calling the destructor of the topmost object in
+ * the hierarchy.
+ *
+ * Any other references passed in functions (including pointer arrays and `quantifier` instances)
+ * must be freed up by the caller. This is safe to do as soon as the function returns.
+ */
+
+#ifndef NAVIT_TRAFFIC_H
+#define NAVIT_TRAFFIC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Classes for events.
+ */
+/* If additional event classes are introduced, traffic_event_is_valid() must be adapted to recognize them. */
+enum event_class {
+ event_class_invalid = 0, /*!< Invalid event which should be ignored */
+ event_class_congestion, /*!< Traffic congestion, typically indicating the approximate speed */
+ event_class_delay, /*!< Delays, typically indicating the amount of extra waiting time */
+ event_class_restriction, /*!< Temporary traffic restrictions, such as road or lane closures or size,
+ * weight or access restrictions */
+};
+
+/**
+ * @brief Event types.
+ */
+/* If additional events are introduced, remember to do the following:
+ * - If the events belong to an existing class, insert them right after the last existing event for that class.
+ * - If the events belong to a new class, insert them at the end of the list.
+ * - Always keep events of the same class together.
+ * - After adding events (of any class) at the end of the list, adapt traffic_event_is_valid() to recognize them. */
+enum event_type {
+ event_invalid = 0, /*!< Invalid event which should be ignored */
+ event_congestion_cleared, /*!< Traffic congestion cleared */
+ event_congestion_forecast_withdrawn, /*!< Traffic congestion forecast withdrawn */
+ event_congestion_heavy_traffic, /*!< Heavy traffic with average speeds of `speed` */
+ event_congestion_long_queue, /*!< Long queues with average speeds of `speed` */
+ event_congestion_none, /*!< No problems to report */
+ event_congestion_normal_traffic, /*!< Traffic has returned to normal */
+ event_congestion_queue, /*!< Queuing traffic with average speeds of `speed` */
+ event_congestion_queue_likely, /*!< Danger of queuing traffic with average speeds
+ * of `speed` */
+ event_congestion_slow_traffic, /*!< Slow traffic with average speeds of `speed` */
+ event_congestion_stationary_traffic, /*!< Stationary traffic (frequent standstills) */
+ event_congestion_stationary_traffic_likely, /*!< Danger of stationary traffic */
+ event_congestion_traffic_building_up, /*!< Traffic building up with average speeds of
+ * `speed` */
+ event_congestion_traffic_congestion, /*!< Traffic congestion with average speeds of
+ * `speed` */
+ event_congestion_traffic_easing, /*!< Traffic easing */
+ event_congestion_traffic_flowing_freely, /*!< Traffic flowing freely with average speeds
+ * of `speed` */
+ event_congestion_traffic_heavier_than_normal, /*!< Traffic heavier than normal with average
+ * speeds of `speed` */
+ event_congestion_traffic_lighter_than_normal, /*!< Traffic lighter than normal with average
+ * speeds of `speed` */
+ event_congestion_traffic_much_heavier_than_normal, /*!< Traffic very much heavier than normal with
+ * average speeds of `speed` (increased density
+ * but no significant decrease in speed) */
+ event_congestion_traffic_problem, /*!< Traffic problem */
+ event_delay_clearance, /*!< Delays cleared */
+ event_delay_delay, /*!< Delays up to `q_timespan` */
+ event_delay_delay_possible, /*!< Delays up to `q_timespan` possible */
+ event_delay_forecast_withdrawn, /*!< Delay forecast withdrawn */
+ event_delay_long_delay, /*!< Long delays up to `q_timespan` */
+ event_delay_several_hours, /*!< Delays of several hours */
+ event_delay_uncertain_duration, /*!< Delays of uncertain duration */
+ event_delay_very_long_delay, /*!< Very long delays up to `q_timespan` */
+ event_restriction_access_restrictions_lifted, /*!< Traffic restrictions lifted: reopened for all
+ * traffic, other restrictions (overtaking etc.)
+ * remain in place */
+ event_restriction_all_carriageways_cleared, /*!< All carriageways cleared */
+ event_restriction_all_carriageways_reopened, /*!< All carriageways reopened */
+ event_restriction_batch_service, /*!< Batch service (to limit the amount of traffic
+ * passing through a section, unlike single
+ * alternate line traffic) */
+ event_restriction_blocked, /*!< Blocked (refers to the entire road; separate
+ * codes exist for blockages of individual lanes
+ * or carriageways) */
+ event_restriction_blocked_ahead, /*!< Blocked ahead (at a point beyond the
+ * indicated location) */
+ event_restriction_carriageway_blocked, /*!< Carriageway blocked (main carriageway, unless
+ * otherwise indicated in supplementary information) */
+ event_restriction_carriageway_closed, /*!< Carriageway closed (main carriageway, unless
+ * otherwise indicated in supplementary information) */
+ event_restriction_contraflow, /*!< Contraflow */
+ event_restriction_closed, /*!< Closed until `q_time` (refers to the entire
+ * road; separate codes exist for closures of
+ * individual lanes or carriageways) */
+ event_restriction_closed_ahead, /*!< Closed ahead (at a point beyond the indicated
+ * location) */
+ event_restriction_entry_blocked, /*!< `q_int` th entry slip road blocked */
+ event_restriction_entry_reopened, /*!< Entry reopened */
+ event_restriction_exit_blocked, /*!< `q_int` th exit slip road blocked */
+ event_restriction_exit_reopened, /*!< Exit reopened */
+ event_restriction_intermittent_closures, /*!< Intermittent short term closures */
+ event_restriction_lane_blocked, /*!< `q:int` lanes blocked */
+ event_restriction_lane_closed, /*!< `q:int` lanes closed */
+ event_restriction_open, /*!< Open */
+ event_restriction_ramp_blocked, /*!< Ramps blocked */
+ event_restriction_ramp_closed, /*!< Ramps closed */
+ event_restriction_ramp_reopened, /*!< Ramps reopened */
+ event_restriction_reduced_lanes, /*!< Carriageway reduced from `q_ints[1]` lanes to `q_int[0]`
+ * lanes (quantifiers are currently not implemented for this
+ * event type) */
+ event_restriction_reopened, /*!< Reopened */
+ event_restriction_road_cleared, /*!< Road cleared */
+ event_restriction_single_alternate_line_traffic, /*!< Single alternate line traffic (because the
+ * affected stretch of road can only be used in
+ * one direction at a time, different from batch
+ * service) */
+ event_restriction_speed_limit, /*!< Speed limit `speed` in force */
+ event_restriction_speed_limit_lifted, /*!< Speed limit lifted */
+};
+
+/**
+ * @brief The directionality of a location.
+ */
+enum location_dir {
+ location_dir_one = 1, /*!< Indicates a unidirectional location. */
+ location_dir_both = 2, /*!< Indicates a bidirectional location. */
+};
+
+/**
+ * @brief The fuzziness of a location.
+ */
+enum location_fuzziness {
+ location_fuzziness_none = 0, /*!< No fuzziness information is given. */
+ location_fuzziness_low_res, /*!< Locations are constrained to a predefined table; the actual
+ * extent of the condition may be shorter than indicated. */
+ location_fuzziness_end_unknown, /*!< The end is unknown, e.g. a traffic jam reported by a driver
+ * who has just entered it. */
+ location_fuzziness_start_unknown, /*!< The start is unknown, e.g. a traffic jam reported by a driver
+ who has just passed the obstruction which caused it. */
+ location_fuzziness_extent_unknown, /*!< Start and end are unknown, e.g. a traffic jam reported by a
+ driver who is in the middle of it. */
+};
+
+/**
+ * @brief Whether a location refers to the main carriageway or the ramps.
+ */
+enum location_ramps {
+ location_ramps_none = 0, /*!< The location refers to the carriageways of the main road. */
+ location_ramps_all, /*!< The location refers to the entry and exit ramps, not the main carriageway. */
+ location_ramps_entry, /*!< The location refers to the entry ramps only, not the main carriageway. */
+ location_ramps_exit, /*!< The location refers to the exit ramps only, not the main carriageway. */
+};
+
+/**
+ * @brief Classes for supplementary information items.
+ */
+enum si_class {
+ si_class_invalid = 0, /*!< Invalid supplementary information item which should be ignored */
+ si_class_place, /*!< Qualifiers specifying the place(s) to which the event refers */
+ si_class_tendency, /*!< Traffic density development */
+ si_class_vehicle, /*!< Specifies categories of vehicles to which the event applies */
+};
+
+/**
+ * @brief Supplementary information types.
+ */
+enum si_type {
+ si_invalid = 0, /*!< Invalid supplementary information item which should be ignored */
+ si_place_bridge, /*!< On bridges */
+ si_place_ramp, /*!< On ramps (entry/exit) */
+ si_place_roadworks, /*!< In the roadworks area */
+ si_place_tunnel, /*!< In tunnels */
+ si_tendency_queue_decreasing, /*!< Traffic queue length decreasing (average rate in optional `q_speed`) */
+ si_tendency_queue_increasing, /*!< Traffic queue length increasing (average rate in optional `q_speed`) */
+ si_vehicle_all, /*!< For all vehicles */
+ si_vehicle_bus, /*!< For buses only (TODO currently supported for public buses only) */
+ si_vehicle_car, /*!< For cars only */
+ si_vehicle_car_with_caravan, /*!< For cars with caravans only (TODO currently not supported) */
+ si_vehicle_car_with_trailer, /*!< For cars with trailers only (TODO currently not supported) */
+ si_vehicle_hazmat, /*!< For hazardous loads only */
+ si_vehicle_hgv, /*!< For heavy trucks only */
+ si_vehicle_motor, /*!< For all motor vehicles */
+ si_vehicle_with_trailer, /*!< For vehicles with trailers only (TODO currently not supported) */
+};
+
+struct traffic_priv;
+struct traffic_location_priv;
+struct traffic_message_priv;
+
+/**
+ * @brief Holds all functions a traffic plugin has to implement to be usable
+ *
+ * This structure holds pointers to a traffic plugin's functions which navit's core will call
+ * to communicate with the plugin.
+ */
+struct traffic_methods {
+ struct traffic_message **(* get_messages)(struct traffic_priv * this_); /**< Retrieves new messages from the traffic plugin */
+};
+
+/**
+ * @brief A point on the road.
+ *
+ * This can either be a point location or an endpoint of a linear location. It specifies a coordinate
+ * pair and can optionally be supplemented with a junction name and/or number where applicable.
+ */
+struct traffic_point {
+ struct coord_geo coord; /*!< The coordinates of this point, as supplied by the source. These may
+ * deviate somewhat from the coordinates on the map. */
+ char * junction_name; /*!< The name of the motorway junction this point refers to. */
+ char * junction_ref; /*!< The reference number of the motorway junction this point refers to. */
+ char * tmc_id; /*!< The TMC identifier of the point, if the location was obtained via TMC.
+ * This can be an LCID (12345) or a combination of an LCID and an offset
+ * (12345+2, i.e. an offset of 2 points in positive direction from 12345).
+ * The offset is typically used with the secondary location in TMC. */
+};
+
+/**
+ * @brief Location data for a traffic message.
+ *
+ * Locations can be either point or linear locations.
+ *
+ * Linear locations are indicated by a pair of points and refer to a stretch of road. The entire
+ * location must be part of the same road, i.e. either the road name or the road reference must be the
+ * same for all affected segments, or all segments must be of the same type and be of a higher order
+ * than any road connecting to them directly.
+ *
+ * Point locations are indicated by a single point, as well as one or two auxiliary points to indicate
+ * direction. Auxiliary points can be omitted if `tmc_table`, `tmc_direction` and
+ * `at->tmc_id` are supplied. However, this will only work if the map has accurate TMC data for
+ * the location, thus it is recommended to supply an auxiliary point nonetheless.
+ *
+ * The order of points is as a driver would encounter them, i.e. first `from`, then `at`,
+ * finally `to`.
+ */
+struct traffic_location {
+ struct traffic_point * at; /*!< The point for a point location, NULL for linear locations. */
+ struct traffic_point * from; /*!< The start of a linear location, or a point before `at`. */
+ struct traffic_point * to; /*!< The end of a linear location, or a point after `at`. */
+ struct traffic_point * via; /*!< A point between `from` and `to`. Required on ring roads
+ * unless `not_via` is used; cannot be used together with `at`. */
+ struct traffic_point * not_via; /*!< A point NOT between `from` and `to`. Required on ring roads
+ * unless `via` is used; cannot be used together with `at`. */
+ char * destination; /*!< A destination, preferably the one given on road signs,
+ * indicating that the message applies only to traffic going in
+ * that direction. Do not use for bidirectional locations. */
+ char * direction; /*!< A compass direction indicating the direction of travel which
+ * this location refers to. Do not use where ambiguous. */
+ enum location_dir directionality; /*!< Indicates whether the message refers to one or both directions
+ * of travel. */
+ enum location_fuzziness fuzziness; /*!< Indicates how precisely the end points are known. */
+ enum location_ramps ramps; /*!< Any value other than `location_ramps_none` implies
+ * that only the specified ramps are affected while the main
+ * road is not. In that case, the `road*` fields refer to
+ * the main road served by the ramp, not the ramp itself. This
+ * is mainly intended for compatibility with TMC, where
+ * junctions with all their ramps are represented by a single
+ * point. Other sources should use coordinate pairs instead. */
+ enum item_type road_type; /*!< The importance of the road within the road network, must be a
+ * road item type. Use `line_unspecified` if not known or
+ * not consistent. */
+ char * road_name; /*!< A road name, if consistent throughout the location. */
+ char * road_ref; /*!< A road number, if consistent throughout the location. */
+ char * tmc_table; /*!< For messages received via TMC, the country identifier (CID)
+ * and location table number (LTN or TABCD) for the location
+ * table to be used for location lookup. The CID is the decimal
+ * number stored in the COUNTRIES and LOCATIONDATASETS tables,
+ * not the hexadecimal code from the PI (known as CCD in TMC). */
+ int tmc_direction; /*!< For messages received via TMC, the direction of the road to
+ * which this message applies (positive or negative). Ignored
+ * for bidirectional messages. */
+ struct traffic_location_priv * priv; /*!< Internal data, not exposed via the API */
+};
+
+/**
+ * @brief A quantifier, which can be used with events and supplementary information.
+ */
+/*
+ * For now, these are various integer types, but other types may be added in the future.
+ */
+struct quantifier {
+ union {
+ int q_duration; /*!< A duration in 1/10 of a second. */
+ int q_int; /*!< An integer. */
+ int q_speed; /*!< A speed in km/h. */
+ unsigned int q_time; /*!< A timestamp in epoch time (seconds elapsed since Jan 1, 1970, 00:00 UTC). */
+ } u;
+};
+
+/**
+ * @brief Extra information supplied with a traffic event.
+ */
+struct traffic_suppl_info {
+ enum si_class si_class; /*!< The supplementary information class (generic category). */
+ enum si_type type; /*!< The supplementary information type, which can be mapped to a
+ * string to be displayed to the user. */
+ struct quantifier * quantifier; /*!< Additional quantifier for supplementary information types
+ * allowing this. Data type and meaning depends on the event type. */
+};
+
+/**
+ * @brief A traffic event.
+ *
+ * An event refers to a condition, its cause or its effect.
+ */
+struct traffic_event {
+ enum event_class event_class; /*!< The event class (generic category). */
+ enum event_type type; /*!< The event type, which can be mapped to a string to be displayed
+ * to the user. */
+ int length; /*!< The length of the affected route in meters. */
+ int speed; /*!< The speed in km/h at which vehicles can expect to pass through the
+ * affected stretch of road (either a temporary speed limit or
+ * average speed in practice, whichever is less), `INT_MAX` if
+ * not set or unknown. */
+ struct quantifier * quantifier; /*!< Additional quantifier for events allowing this. Data type and
+ * meaning depends on the event type. */
+ int si_count; /*!< Number of supplementary information items in `si_count`. */
+ struct traffic_suppl_info ** si; /*!< Points to an array of pointers to supplementary information items. */
+};
+
+/**
+ * @brief A traffic message.
+ *
+ * A message is the atomic element of traffic information, referring to a particular condition at a
+ * given location.
+ *
+ * If no updates are received for a message, it should be discarded after both `expiration_time`
+ * and `end_time` (if specified) have elapsed.
+ */
+struct traffic_message {
+ char * id; /*!< An identifier, which remains stable over the entire lifecycle of the
+ * message. The colon (:) is a reserved character to separate different
+ * levels of source identifiers from each other and from the local
+ * message identifier. */
+ time_t receive_time; /*!< When the message was first received by the source, should be kept
+ * stable across all updates. */
+ time_t update_time; /*!< When the last update to this message was received by the source. */
+ time_t expiration_time; /*!< How long the message should be considered valid.*/
+ time_t start_time; /*!< When the condition is expected to begin (optional, 0 if not set). */
+ time_t end_time; /*!< How long the condition is expected to last (optional, 0 if not set). */
+ int is_cancellation; /*!< If true, this message is a cancellation message, indicating that
+ * existing messages with the same ID should be deleted or no longer
+ * considered current. All other attributes of a cancellation message
+ * should be ignored. */
+ int is_forecast; /*!< If false, the message describes a current situation. If true, it
+ * describes an expected situation in the future. */
+ int replaced_count; /*!< The number of entries in `replaces`. */
+ char ** replaces; /*!< Points to an array of identifiers of messages which the current
+ * message replaces. */
+ struct traffic_location * location; /*!< The location to which this message refers. */
+ int event_count; /*!< The number of events in `events`. */
+ struct traffic_event ** events; /*!< Points to an array of pointers to the events for this message. */
+ struct traffic_message_priv * priv; /*!< Internal data, not exposed via the API */
+};
+
+struct map;
+struct mapset;
+struct traffic;
+
+/**
+ * @brief Creates an event class from its string representation.
+ *
+ * @param string The string representation (case is ignored)
+ *
+ * @return The corresponding `enum event_class`, or `event_class_invalid` if `string` does not match a
+ * known identifier
+ */
+enum event_class event_class_new(char * string);
+
+/**
+ * @brief Translates an event class to its string representation.
+ *
+ * @return The string representation of the event class
+ */
+const char * event_class_to_string(enum event_class this_);
+
+/**
+ * @brief Creates an event type from its string representation.
+ *
+ * @param string The string representation (case is ignored)
+ *
+ * @return The corresponding `enum event_type`, or `event_invalid` if `string` does not match a known
+ * identifier
+ */
+enum event_type event_type_new(char * string);
+
+/**
+ * @brief Translates an event type to its string representation.
+ *
+ * @return The string representation of the event type
+ */
+const char * event_type_to_string(enum event_type this_);
+
+/**
+ * @brief Creates an item type from a road type.
+ *
+ * This is guaranteed to return either a routable type (i.e. `route_item_first <= type <= route_item_last`)
+ * or `type_line_unspecified`. The latter is also returned if `string` refers to a Navit item type which
+ * is not routable.
+ *
+ * @param string A TraFF road type or the string representation of a Navit item type
+ * @param is_urban Whether the road is in a built-up area (ignored if `string` is a Navit item type)
+ *
+ * @return The corresponding `enum item_type`, or `type_line_unspecified` if `string` does not match a
+ * known and routable identifier
+ */
+enum item_type item_type_from_road_type(char * string, int is_urban);
+
+/**
+ * @brief Creates a location directionality from its string representation.
+ *
+ * @param string The string representation (case is ignored)
+ *
+ * @return The corresponding `enum location_dir`, or `location_dir_both` if `string` does
+ * not match a known identifier
+ */
+enum location_dir location_dir_new(char * string);
+
+/**
+ * @brief Creates a location fuzziness from its string representation.
+ *
+ * @param string The string representation (case is ignored)
+ *
+ * @return The corresponding `enum location_fuzziness`, or `location_fuzziness_none` if `string` does
+ * not match a known identifier
+ */
+enum location_fuzziness location_fuzziness_new(char * string);
+
+/**
+ * @brief Translates location fuzziness to its string representation.
+ *
+ * @return The string representation of the location fuzziness, or NULL for `location_fuzziness_none`
+ */
+const char * location_fuzziness_to_string(enum location_fuzziness this_);
+
+/**
+ * @brief Creates an `enum location_ramps` from its string representation.
+ *
+ * @param string The string representation (case is ignored)
+ *
+ * @return The corresponding `enum location_ramps`, or `location_ramps_none` if `string` does
+ * not match a known identifier
+ */
+enum location_ramps location_ramps_new(char * string);
+
+/**
+ * @brief Translates an `enum location_ramps` to its string representation.
+ *
+ * @return The string representation
+ */
+const char * location_ramps_to_string(enum location_ramps this_);
+
+/**
+ * @brief Creates a supplementary information class from its string representation.
+ *
+ * @param string The string representation (case is ignored)
+ *
+ * @return The corresponding `enum si_class`, or `si_class_invalid` if `string` does not match a
+ * known identifier
+ */
+enum si_class si_class_new(char * string);
+
+/**
+ * @brief Translates a supplementary information class to its string representation.
+ *
+ * @return The string representation of the supplementary information class
+ */
+const char * si_class_to_string(enum si_class this_);
+
+/**
+ * @brief Creates a supplementary information type from its string representation.
+ *
+ * @param string The string representation (case is ignored)
+ *
+ * @return The corresponding `enum si_type`, or `si_invalid` if `string` does not match a known
+ * identifier
+ */
+enum si_type si_type_new(char * string);
+
+/**
+ * @brief Translates a supplementary information type to its string representation.
+ *
+ * @return The string representation of the supplementary information type
+ */
+const char * si_type_to_string(enum si_type this_);
+
+/**
+ * @brief Creates a new `traffic_point`.
+ *
+ * It is the responsibility of the caller to destroy all references passed to this function. This can be
+ * done immediately after the function returns.
+ *
+ * @param lon The longitude, as reported by the source, in GPS coordinates
+ * @param lat The latitude, as reported by the source, in GPS coordinates
+ * @param junction_name The name of the motorway junction this point refers to, NULL if not applicable
+ * @param junction_ref The reference number of the motorway junction this point refers to, NULL if not applicable
+ * @param tmc_id The TMC identifier of the point, if the location was obtained via TMC, or NULL if not applicable
+ */
+struct traffic_point * traffic_point_new(float lon, float lat, char * junction_name, char * junction_ref,
+ char * tmc_id);
+
+/**
+ * @brief Creates a new `traffic_point`.
+ *
+ * This is the short version of the constructor, which sets only mandatory members. Other members can be
+ * set after the instance is created.
+ *
+ * @param lon The longitude, as reported by the source, in GPS coordinates
+ * @param lat The latitude, as reported by the source, in GPS coordinates
+ */
+struct traffic_point * traffic_point_new_short(float lon, float lat);
+
+/**
+ * @brief Destroys a `traffic_point`.
+ *
+ * This will release the memory used by the `traffic_point` and all related data.
+ *
+ * A `traffic_point` is usually destroyed together with its parent `traffic_location`, thus
+ * it is usually not necessary to call this destructor directly.
+ *
+ * @param this_ The point
+ */
+void traffic_point_destroy(struct traffic_point * this_);
+
+/**
+ * @brief Creates a new `traffic_location`.
+ *
+ * The `traffic_point` instances are destroyed when the `traffic_location` is destroyed, and
+ * therefore cannot be shared between multiple `traffic_location` instances.
+ *
+ * It is the responsibility of the caller to destroy all other references passed to this function. This
+ * can be done immediately after the function returns.
+ *
+ * If `at` is non-NULL, the location is a point location, and `from` and `to` are
+ * interpreted as auxiliary locations.
+ *
+ * Of `from` and `to`, one is mandatory for a unidirectional point location; both are
+ * mandatory for a linear location.
+ *
+ * `ramps` is mainly intended for compatibility with TMC, where junctions with all their ramps are
+ * represented by a single point. Other sources should use coordinate pairs instead.
+ *
+ * @param at The coordinates for a point location, NULL for a linear location
+ * @param from The start of a linear location, or a point before `at`
+ * @param to The end of a linear location, or a point after `at`
+ * @param via A point between `from` and `to`, needed only on ring roads
+ * @param not_via A point not between `from` and `to`, needed only on ring roads
+ * @param destination A destination, preferably the one given on road signs, indicating that the message
+ * applies only to traffic going in that direction; can be NULL, do not use for bidirectional locations
+ * @param direction A compass direction indicating the direction of travel which this location refers to;
+ * can be NULL, do not use where ambiguous
+ * @param directionality Whether the location is unidirectional or bidirectional
+ * @param fuzziness A precision indicator for `from` and `to`
+ * @param ramps Whether the main carriageway or the ramps are affected
+ * @param road_type The importance of the road within the road network, must be a road item type,
+ * `type_line_unspecified` if not known or not consistent
+ * @param road_name A road name, if consistent throughout the location; NULL if not known or inconsistent
+ * @param road_ref A road number, if consistent throughout the location; NULL if not known or inconsistent
+ * @param tmc_table For messages received via TMC, the CID and LTN; NULL otherwise
+ * @param tmc_direction For messages received via TMC, the direction of the road; ignored for
+ * bidirectional or non-TMC messages
+ */
+// TODO split CID/LTN?
+struct traffic_location * traffic_location_new(struct traffic_point * at, struct traffic_point * from,
+ struct traffic_point * to, struct traffic_point * via, struct traffic_point * not_via,
+ char * destination, char * direction, enum location_dir directionality,
+ enum location_fuzziness fuzziness, enum location_ramps ramps, enum item_type road_type,
+ char * road_name, char * road_ref, char * tmc_table, int tmc_direction);
+
+/**
+ * @brief Creates a new `traffic_location`.
+ *
+ * This is the short version of the constructor, which sets only mandatory members. Other members can be
+ * set after the instance is created.
+ *
+ * The `traffic_point` instances are destroyed when the `traffic_location` is destroyed, and
+ * therefore cannot be shared between multiple `traffic_location` instances.
+ *
+ * If `at` is non-NULL, the location is a point location, and `from` and `to` are
+ * interpreted as auxiliary locations.
+ *
+ * Of `from` and `to`, one is mandatory for a unidirectional point location; both are
+ * mandatory for a linear location.
+ *
+ * @param at The coordinates for a point location, NULL for a linear location
+ * @param from The start of a linear location, or a point before `at`
+ * @param to The end of a linear location, or a point after `at`
+ * @param via A point between `from` and `to`, needed only on ring roads
+ * @param not_via A point not between `from` and `to`, needed only on ring roads
+ * @param directionality Whether the location is unidirectional or bidirectional
+ * @param fuzziness A precision indicator for `from` and `to`
+ */
+struct traffic_location * traffic_location_new_short(struct traffic_point * at, struct traffic_point * from,
+ struct traffic_point * to, struct traffic_point * via, struct traffic_point * not_via,
+ enum location_dir directionality, enum location_fuzziness fuzziness);
+
+/**
+ * @brief Destroys a `traffic_location`.
+ *
+ * This will release the memory used by the `traffic_location` and all related data.
+ *
+ * A `traffic_location` is usually destroyed together with its parent `traffic_message`, thus
+ * it is usually not necessary to call this destructor directly.
+ *
+ * @param this_ The location
+ */
+void traffic_location_destroy(struct traffic_location * this_);
+
+/**
+ * @brief Creates a new `traffic_suppl_info`.
+ *
+ * It is the responsibility of the caller to destroy all references passed to this function. This can be
+ * done immediately after the function returns.
+ *
+ * @param si_class The supplementary information class (generic category)
+ * @param type The supplementary information type, which can be mapped to a string to be displayed to
+ * the user
+ * @param quantifier Additional quantifier for supplementary information types allowing this, or NULL
+ */
+struct traffic_suppl_info * traffic_suppl_info_new(enum si_class si_class, enum si_type type,
+ struct quantifier * quantifier);
+
+/**
+ * @brief Destroys a `traffic_suppl_info`.
+ *
+ * This will release the memory used by the `traffic_suppl_info` and all related data.
+ *
+ * A `traffic_suppl_info` is usually destroyed together with its parent `traffic_event`, thus
+ * it is usually not necessary to call this destructor directly.
+ *
+ * @param this_ The supplementary information item
+ */
+void traffic_suppl_info_destroy(struct traffic_suppl_info * this_);
+
+/**
+ * @brief Creates a new `traffic_event`.
+ *
+ * The `traffic_suppl_info` instances are destroyed when the `traffic_event` is destroyed, and
+ * therefore cannot be shared between multiple `traffic_event` instances.
+ *
+ * It is the responsibility of the caller to destroy all other references passed to this function
+ * (including the `si` buffer but not the `traffic_suppl_info` instances). This can be done
+ * immediately after the function returns.
+ *
+ * @param event_class The event class (generic category)
+ * @param type The event type, which can be mapped to a string to be displayed to the user
+ * @param length The length of the affected route in meters, -1 if not known
+ * @param speed The speed in km/h at which vehicles can expect to pass through the affected stretch of
+ * road (either a temporary speed limit or average speed in practice, whichever is less); INT_MAX if unknown
+ * @param quantifier Additional quantifier for supplementary information types allowing this, or NULL
+ * @param si_count Number of supplementary information items in `si_count`
+ * @param si Points to an array of pointers to supplementary information items
+ */
+struct traffic_event * traffic_event_new(enum event_class event_class, enum event_type type,
+ int length, int speed, struct quantifier * quantifier, int si_count, struct traffic_suppl_info ** si);
+
+/**
+ * @brief Creates a new `traffic_event`.
+ *
+ * This is the short version of the constructor, which sets only mandatory members. Other members can be
+ * set after the instance is created.
+ *
+ * @param event_class The event class (generic category)
+ * @param type The event type, which can be mapped to a string to be displayed to the user
+ */
+struct traffic_event * traffic_event_new_short(enum event_class event_class, enum event_type type);
+
+/**
+ * @brief Destroys a `traffic_event`.
+ *
+ * This will release the memory used by the `traffic_event` and all related data.
+ *
+ * A `traffic_event` is usually destroyed together with its parent `traffic_message`, thus
+ * it is usually not necessary to call this destructor directly.
+ *
+ * @param this_ The event
+ */
+void traffic_event_destroy(struct traffic_event * this_);
+
+/**
+ * @brief Adds a supplementary information item to an event.
+ *
+ * The `traffic_suppl_info` instance is destroyed when the `traffic_event` is destroyed, and
+ * therefore cannot be shared between multiple `traffic_event` instances.
+ *
+ * @param this_ The event
+ * @param si The supplementary information item
+ */
+void traffic_event_add_suppl_info(struct traffic_event * this_, struct traffic_suppl_info * si);
+
+/**
+ * @brief Retrieves a supplementary information item associated with an event.
+ *
+ * @param this_ The event
+ * @param index The index of the supplementary information item, zero-based
+ * @return The supplementary information item at the specified position, or NULL if out of bounds
+ */
+struct traffic_suppl_info * traffic_event_get_suppl_info(struct traffic_event * this_, int index);
+
+/**
+ * @brief Creates a new `traffic_message`.
+ *
+ * The `traffic_event` and `traffic_location` instances are destroyed when the
+ * `traffic_message` is destroyed, and therefore cannot be shared between multiple
+ * `traffic_message` instances.
+ *
+ * It is the responsibility of the caller to destroy all other references passed to this function
+ * (including the `events` buffer but not the `traffic_event` instances). This can be done
+ * immediately after the function returns.
+ *
+ * @param id The message identifier; existing messages with the same identifier will be replaced by the
+ * new message
+ * @param receive_time When the message was first received by the source, should be kept stable across
+ * all updates
+ * @param update_time When the last update to this message was received by the source
+ * @param expiration_time How long the message should be considered valid
+ * @param start_time When the condition is expected to begin (optional, 0 if not set)
+ * @param end_time How long the condition is expected to last (optional, 0 if not set)
+ * @param isCancellation If true, create a cancellation message (existing messages with the same ID
+ * should be deleted or no longer considered current, and all other attributes ignored)
+ * @param isForecast If false, the message describes a current situation; if true, it describes an
+ * expected situation in the future
+ * @param replaced_count The number of entries in `replaces`
+ * @param replaces Points to an array of identifiers of messages which the current message replaces
+ * @param location The location to which this message refers
+ * @param event_count The number of events in `events`
+ * @param events Points to an array of pointers to the events for this message
+ */
+struct traffic_message * traffic_message_new(char * id, time_t receive_time, time_t update_time,
+ time_t expiration_time, time_t start_time, time_t end_time, int is_cancellation, int is_Forecast,
+ int replaced_count, char ** replaces, struct traffic_location * location, int event_count,
+ struct traffic_event ** events);
+
+/**
+ * @brief Creates a new `traffic_message`.
+ *
+ * This is the short version of the constructor, which sets only mandatory members. Other members can be
+ * set after the instance is created.
+ *
+ * The `traffic_event` and `traffic_location` instances are destroyed when the
+ * `traffic_message` is destroyed, and therefore cannot be shared between multiple
+ * `traffic_message` instances.
+ *
+ * It is the responsibility of the caller to destroy all other references passed to this function
+ * (including the `events` buffer but not the `traffic_event` instances). This can be done
+ * immediately after the function returns.
+ *
+ * @param id The message identifier; existing messages with the same identifier will be replaced by the
+ * new message
+ * @param receive_time When the message was first received by the source, should be kept stable across
+ * all updates
+ * @param update_time When the last update to this message was received by the source
+ * @param expiration_time How long the message should be considered valid
+ * @param is_forecast If false, the message describes a current situation; if true, it describes an
+ * expected situation in the future
+ * @param location The location to which this message refers
+ * @param event_count The number of events in `events`
+ * @param events Points to an array of pointers to the events for this message
+ */
+struct traffic_message * traffic_message_new_short(char * id, time_t receive_time, time_t update_time,
+ time_t expiration_time, int is_forecast, struct traffic_location * location,
+ int event_count, struct traffic_event ** events);
+
+/**
+ * @brief Creates a new single-event `traffic_message`.
+ *
+ * This is a convenience constructor, which sets only mandatory members. Other members can be
+ * set after the instance is created.
+ *
+ * The `traffic_location` instances are destroyed when the `traffic_message` is destroyed,
+ * and therefore cannot be shared between multiple `traffic_message` instances.
+ *
+ * It is the responsibility of the caller to destroy all other references passed to this function. This
+ * can be done immediately after the function returns.
+ *
+ * @param id The message identifier; existing messages with the same identifier will be replaced by the
+ * new message
+ * @param receive_time When the message was first received by the source, should be kept stable across
+ * all updates
+ * @param update_time When the last update to this message was received by the source
+ * @param expiration_time How long the message should be considered valid
+ * @param is_forecast If false, the message describes a current situation; if true, it describes an
+ * expected situation in the future
+ * @param location The location to which this message refers
+ * @param event_class The event class (generic category)
+ * @param type The event type, which can be mapped to a string to be displayed to the user
+ */
+struct traffic_message * traffic_message_new_single_event(char * id, time_t receive_time, time_t update_time,
+ time_t expiration_time, int is_forecast, struct traffic_location * location,
+ enum event_class event_class, enum event_type type);
+
+/**
+ * @brief Creates a new cancellation `traffic_message`.
+ *
+ * This is a convenience constructor, which creates a cancellation message, without the need to supply
+ * members which are not required for cancellation messages. Upon receiving a cancellation message,
+ * existing messages with the same ID should be deleted or no longer considered current, and all other
+ * attributes ignored.
+ *
+ * The `traffic_location` instances are destroyed when the `traffic_message` is destroyed,
+ * and therefore cannot be shared between multiple `traffic_message` instances.
+ *
+ * It is the responsibility of the caller to destroy all other references passed to this function. This
+ * can be done immediately after the function returns.
+ *
+ * @param id The message identifier; existing messages with the same identifier will be replaced by the
+ * new message
+ * @param receive_time When the message was first received by the source, should be kept stable across
+ * all updates
+ * @param update_time When the last update to this message was received by the source
+ * @param expiration_time How long the message should be considered valid
+ * @param location The location to which this message refers
+ */
+struct traffic_message * traffic_message_new_cancellation(char * id, time_t receive_time, time_t update_time,
+ time_t expiration_time, struct traffic_location * location);
+
+/**
+ * @brief Destroys a `traffic_message`.
+ *
+ * This will release the memory used by the `traffic_message` and all related data.
+ *
+ * A `traffic_message` is usually destroyed by the traffic plugin, thus it is usually not
+ * necessary to call this destructor directly.
+ *
+ * @param this_ The message
+ */
+void traffic_message_destroy(struct traffic_message * this_);
+
+/**
+ * @brief Adds an event to a message.
+ *
+ * The `traffic_event` instance is destroyed when the `traffic_message` is destroyed, and
+ * therefore cannot be shared between multiple `traffic_message` instances.
+ *
+ * @param this_ The message
+ * @param event The event to add to this message
+ */
+void traffic_message_add_event(struct traffic_message * this_, struct traffic_event * event);
+
+/**
+ * @brief Retrieves an event associated with a message.
+ *
+ * @param this_ The message
+ * @param index The index of the event, zero-based
+ * @return The event at the specified position, or NULL if out of bounds
+ */
+struct traffic_event * traffic_message_get_event(struct traffic_message * this_, int index);
+
+/**
+ * @brief Returns the items associated with a message.
+ *
+ * Note that no map rectangle is required to obtain traffic items. This behavior is particular to traffic items, which
+ * do not rely on a map rectangle. Items obtained from other maps may behave differently.
+ *
+ * @param this_ The message
+ *
+ * @return Items as a NULL-terminated array. The caller is responsible for freeing the array (not its elements) when it
+ * is no longer needed. This method will always return a valid pointer—if no items are associated with the message, an
+ * empty array (with just one single NULL element) will be returned. No particular order is guaranteed for the items.
+ */
+struct item ** traffic_message_get_items(struct traffic_message * this_);
+
+/**
+ * @brief Initializes the traffic plugin.
+ *
+ * This function is called once on startup.
+ */
+void traffic_init(void);
+
+/**
+ * @brief Reads previously stored traffic messages from an XML file.
+ *
+ * @param this_ The traffic instance
+ * @param filename The full path to the XML file to parse
+ *
+ * @return A `NULL`-terminated pointer array. Each element points to one `struct traffic_message`.
+ * `NULL` is returned (rather than an empty pointer array) if there are no messages to report.
+ */
+struct traffic_message ** traffic_get_messages_from_xml_file(struct traffic * this_, char * filename);
+
+/**
+ * @brief Reads traffic messages from an XML string.
+ *
+ * @param this_ The traffic instance
+ * @param filename The XML document to parse, as a string
+ *
+ * @return A `NULL`-terminated pointer array. Each element points to one `struct traffic_message`.
+ * `NULL` is returned (rather than an empty pointer array) if there are no messages to report.
+ */
+struct traffic_message ** traffic_get_messages_from_xml_string(struct traffic * this_, char * xml);
+
+/**
+ * @brief Returns the map for the traffic plugin.
+ *
+ * The map is created by the first traffic plugin loaded. If multiple traffic plugin instances are
+ * active at the same time, they share the map created by the first instance.
+ *
+ * @param this_ The traffic plugin instance
+ *
+ * @return The traffic map
+ */
+struct map * traffic_get_map(struct traffic *this_);
+
+/**
+ * @brief Returns currently active traffic messages.
+ *
+ * If multiple plugin instances are active, this will give the same result for any plugin, as traffic messages are
+ * shared between instances.
+ *
+ * @param this_ The traffic plugin instance
+ *
+ * @return A null-terminated array of traffic messages. The caller is responsible for freeing the array (not its
+ * elements) when it is no longer needed. This method will always return a valid pointer—if the message store is empty,
+ * an empty array (with just one single NULL element) will be returned.
+ */
+struct traffic_message ** traffic_get_stored_messages(struct traffic *this_);
+
+/**
+ * @brief Processes new traffic messages.
+ *
+ * Calling this method delivers new messages in a “push” manner (as opposed to the “pull” fashion of
+ * calling a plugin method).
+ *
+ * Messages which are past their expiration timestamp are skipped, and the flags in the return value
+ * are set only if at least one valid message is found.
+ *
+ * @param this_ The traffic instance
+ * @param messages The new messages
+ */
+void traffic_process_messages(struct traffic * this_, struct traffic_message ** messages);
+
+/**
+ * @brief Sets the mapset for the traffic plugin.
+ *
+ * This sets the mapset from which the segments affected by a traffic report will be retrieved.
+ *
+ * @param this_ The traffic plugin instance
+ * @param ms The mapset
+ */
+void traffic_set_mapset(struct traffic *this_, struct mapset *ms);
+
+/**
+ * @brief Sets the route for the traffic plugin.
+ *
+ * This sets the route which may get notified by the traffic plugin if traffic distortions change.
+ */
+void traffic_set_route(struct traffic *this_, struct route *rt);
+
+/* end of prototypes */
+#ifdef __cplusplus
+}
+#endif
+
+#endif