/** * 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 Translates a Navit tile order to a minimum road class as used in TraFF. * * This can be used to translate a map selection into a TraFF filter. * * The tile order is the lowest tile level in which an object of a certain type can be placed (higher numbers * correspond to lower levels). Currently, 8 is the maximum order for `highway_city`, `highway_land` and * `street_n_lanes`, equivalent to `MOTORWAY` and `TRUNK`. 10 is the maximum order for `street_4_city` and * `street_4_land` (`SECONDARY`), 12 for `street_3_city` and `street_3_land` (`TERTIARY`). All others can * be placed in any tile level. * * This macro returns `PRIMARY`, `SECONDARY` and `TERTIARY` for the three bins above these cut-off orders, * corresponding to one level below the lowest road class we expect to find there. (Not considering that * low-level roads can be placed into higher-level tiles if they cross a tile boundary of the next lower * level.) Below the lowest cut-off order, the macro returns NULL. */ #define order_to_min_road_class(x) (x <= 8 ? "PRIMARY" : x <= 10 ? "SECONDARY" : x <= 12 ? "TERTIARY" : NULL) /** * @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; 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 */ void (*destroy)(struct traffic_priv * this_); /**< Destructor for 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); /** * @brief Destructor. */ void traffic_destroy(struct traffic *this_); /* end of prototypes */ #ifdef __cplusplus } #endif #endif