// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

syntax = "proto3";

package google.maps.routes.v1;

import "google/geo/type/viewport.proto";
import "google/maps/routes/v1/polyline.proto";
import "google/maps/routes/v1/waypoint.proto";
import "google/protobuf/duration.proto";
import "google/type/money.proto";

option cc_enable_arenas = true;
option csharp_namespace = "Google.Maps.Routes.V1";
option go_package = "cloud.google.com/go/maps/routes/apiv1/routespb;routespb";
option java_multiple_files = true;
option java_outer_classname = "RouteProto";
option java_package = "com.google.maps.routes.v1";
option objc_class_prefix = "GMRS";
option php_namespace = "Google\\Maps\\Routes\\V1";

// Encapsulates a route, which consists of a series of connected road segments
// that join beginning, ending, and intermediate waypoints.
message Route {
  // A collection of legs (path segments between waypoints) that make-up the
  // route. Each leg corresponds to the trip between two non-`via` Waypoints.
  // For example, a route with no intermediate waypoints has only one leg. A
  // route that includes one non-`via` intermediate waypoint has two legs. A
  // route that includes one `via` intermediate waypoint has one leg. The order
  // of the legs matches the order of Waypoints from `origin` to `intermediates`
  // to `destination`.
  repeated RouteLeg legs = 1;

  // The travel distance of the route, in meters.
  int32 distance_meters = 2;

  // The length of time needed to navigate the route. If you set the
  // `routing_preference` to `TRAFFIC_UNAWARE`, then this value is the same as
  // `static_duration`. If you set the `routing_preference` to either
  // `TRAFFIC_AWARE` or `TRAFFIC_AWARE_OPTIMAL`, then this value is calculated
  // taking traffic conditions into account.
  google.protobuf.Duration duration = 3;

  // The duration of traveling through the route without taking traffic
  // conditions into consideration.
  google.protobuf.Duration static_duration = 4;

  // The overall route polyline. This polyline will be the combined polyline of
  // all `legs`.
  Polyline polyline = 5;

  // A description of the route.
  string description = 6;

  // An array of warnings to show when displaying the route.
  repeated string warnings = 7;

  // The viewport bounding box of the polyline.
  google.geo.type.Viewport viewport = 8;

  // Additional information about the route.
  RouteTravelAdvisory travel_advisory = 9;

  // If ComputeRoutesRequest.optimize_waypoint_order is set to true, this field
  // contains the optimized ordering of intermediates waypoints.
  // otherwise, this field is empty.
  // For example, suppose the input is Origin: LA; Intermediates: Dallas,
  // Bangor, Phoenix;  Destination: New York; and the optimized intermediate
  // waypoint order is:  Phoenix, Dallas, Bangor. Then this field contains the
  // values [2, 0, 1]. The index starts with 0 for the first intermediate
  // waypoint.
  repeated int32 optimized_intermediate_waypoint_index = 10;
}

// Encapsulates the additional information that the user should be informed
// about, such as possible traffic zone restriction etc.
message RouteTravelAdvisory {
  // The traffic restriction that applies to the route. A vehicle that is
  // subject to the restriction is not allowed to travel on the route. As of
  // October 2019, only Jakarta, Indonesia takes into consideration.
  TrafficRestriction traffic_restriction = 1;

  // Encapsulates information about tolls on the Route.
  // This field is only populated if we expect there are tolls on the Route.
  // If this field is set but the estimated_price subfield is not populated,
  // we expect that road contains tolls but we do not know an estimated price.
  // If this field is not set, then we expect there is no toll on the Route.
  TollInfo toll_info = 2;

  // Speed reading intervals detailing traffic density. Applicable in case of
  // `TRAFFIC_AWARE` and `TRAFFIC_AWARE_OPTIMAL` routing preferences.
  // The intervals cover the entire polyline of the route without overlap.
  // The start point of a specified interval is the same as the end point of the
  // preceding interval.
  //
  // Example:
  //
  //     polyline: A ---- B ---- C ---- D ---- E ---- F ---- G
  //     speed_reading_intervals: [A,C), [C,D), [D,G).
  repeated SpeedReadingInterval speed_reading_intervals = 3;

  // Information related to the custom layer data that the customer specified
  // (e.g. time spent in a customer specified area).
  CustomLayerInfo custom_layer_info = 4;
}

// Encapsulates the additional information that the user should be informed
// about, such as possible traffic zone restriction etc. on a route leg.
message RouteLegTravelAdvisory {
  // Encapsulates information about tolls on the specific RouteLeg.
  // This field is only populated if we expect there are tolls on the RouteLeg.
  // If this field is set but the estimated_price subfield is not populated,
  // we expect that road contains tolls but we do not know an estimated price.
  // If this field does not exist, then there is no toll on the RouteLeg.
  TollInfo toll_info = 1;

  // Speed reading intervals detailing traffic density. Applicable in case of
  // `TRAFFIC_AWARE` and `TRAFFIC_AWARE_OPTIMAL` routing preferences.
  // The intervals cover the entire polyline of the RouteLg without overlap.
  // The start point of a specified interval is the same as the end point of the
  // preceding interval.
  //
  // Example:
  //
  //     polyline: A ---- B ---- C ---- D ---- E ---- F ---- G
  //     speed_reading_intervals: [A,C), [C,D), [D,G).
  repeated SpeedReadingInterval speed_reading_intervals = 2;

  // Information related to the custom layer data that the customer specified
  // (e.g. time spent in a customer specified area).
  CustomLayerInfo custom_layer_info = 3;
}

// Encapsulates the additional information that the user should be informed
// about, such as possible traffic zone restriction on a leg step.
message RouteLegStepTravelAdvisory {
  // Speed reading intervals detailing traffic density. Applicable in case of
  // `TRAFFIC_AWARE` and `TRAFFIC_AWARE_OPTIMAL` routing preferences.
  // The intervals cover the entire polyline of the RouteLegStep without
  // overlap. The start point of a specified interval is the same as the end
  // point of the preceding interval.
  //
  // Example:
  //
  //     polyline: A ---- B ---- C ---- D ---- E ---- F ---- G
  //     speed_reading_intervals: [A,C), [C,D), [D,G).
  repeated SpeedReadingInterval speed_reading_intervals = 1;
}

// Encapsulates the traffic restriction applied to the route. As of October
// 2019, only Jakarta, Indonesia takes into consideration.
message TrafficRestriction {
  // The restriction based on the vehicle's license plate last character. If
  // this field does not exist, then no restriction on route.
  LicensePlateLastCharacterRestriction
      license_plate_last_character_restriction = 1;
}

// Encapsulates the license plate last character restriction.
message LicensePlateLastCharacterRestriction {
  // The allowed last character of a license plate of a vehicle. Only vehicles
  // whose license plate's last characters match these are allowed to travel on
  // the route. If empty, no vehicle is allowed.
  repeated string allowed_last_characters = 1;
}

// Encapsulates a segment between non-`via` waypoints.
message RouteLeg {
  // The travel distance of the route leg, in meters.
  int32 distance_meters = 1;

  // The length of time needed to navigate the leg. If the `route_preference`
  // is set to `TRAFFIC_UNAWARE`, then this value is the same as
  // `static_duration`. If the `route_preference` is either `TRAFFIC_AWARE` or
  // `TRAFFIC_AWARE_OPTIMAL`, then this value is calculated taking traffic
  // conditions into account.
  google.protobuf.Duration duration = 2;

  // The duration of traveling through the leg, calculated without taking
  // traffic conditions into consideration.
  google.protobuf.Duration static_duration = 3;

  // The overall polyline for this leg. This includes that each `step`'s
  // polyline.
  Polyline polyline = 4;

  // The start location of this leg. This might be different from the provided
  // `origin`. For example, when the provided `origin` is not near a road, this
  // is a point on the road.
  Location start_location = 5;

  // The end location of this leg. This might be different from the provided
  // `destination`. For example, when the provided `destination` is not near a
  // road, this is a point on the road.
  Location end_location = 6;

  // An array of steps denoting segments within this leg. Each step represents
  // one navigation instruction.
  repeated RouteLegStep steps = 7;

  // Encapsulates the additional information that the user should be informed
  // about, such as possible traffic zone restriction etc. on a route leg.
  RouteLegTravelAdvisory travel_advisory = 8;
}

// Encapsulates toll information on a `Route` or on a `RouteLeg`.
message TollInfo {
  // The monetary amount of tolls for the corresponding Route or RouteLeg.
  // This list contains a money amount for each currency that is expected
  // to be charged by the toll stations. Typically this list will contain only
  // one item for routes with tolls in one currency. For international trips,
  // this list may contain multiple items to reflect tolls in different
  // currencies.
  repeated google.type.Money estimated_price = 1;
}

// Encapsulates a segment of a `RouteLeg`. A step corresponds to a single
// navigation instruction. Route legs are made up of steps.
message RouteLegStep {
  // The travel distance of this step, in meters. In some circumstances, this
  // field might not have a value.
  int32 distance_meters = 1;

  // The duration of travel through this step without taking traffic conditions
  // into consideration. In some circumstances, this field might not have a
  // value.
  google.protobuf.Duration static_duration = 2;

  // The polyline associated with this step.
  Polyline polyline = 3;

  // The start location of this step.
  Location start_location = 4;

  // The end location of this step.
  Location end_location = 5;

  // Navigation instructions.
  NavigationInstruction navigation_instruction = 6;

  // Encapsulates the additional information that the user should be informed
  // about, such as possible traffic zone restriction on a leg step.
  RouteLegStepTravelAdvisory travel_advisory = 7;
}

message NavigationInstruction {
  // Encapsulates the navigation instructions for the current step (e.g., turn
  // left, merge, straight, etc.). This field determines which icon to display.
  Maneuver maneuver = 1;

  // Instructions for navigating this step.
  string instructions = 2;
}

// A set of values that specify the navigation action to take for the current
// step (e.g., turn left, merge, straight, etc.).
enum Maneuver {
  // Not used.
  MANEUVER_UNSPECIFIED = 0;

  // Turn slightly to the left.
  TURN_SLIGHT_LEFT = 1;

  // Turn sharply to the left.
  TURN_SHARP_LEFT = 2;

  // Make a left u-turn.
  UTURN_LEFT = 3;

  // Turn left.
  TURN_LEFT = 4;

  // Turn slightly to the right.
  TURN_SLIGHT_RIGHT = 5;

  // Turn sharply to the right.
  TURN_SHARP_RIGHT = 6;

  // Make a right u-turn.
  UTURN_RIGHT = 7;

  // Turn right.
  TURN_RIGHT = 8;

  // Go straight.
  STRAIGHT = 9;

  // Take the left ramp.
  RAMP_LEFT = 10;

  // Take the right ramp.
  RAMP_RIGHT = 11;

  // Merge into traffic.
  MERGE = 12;

  // Take the left fork.
  FORK_LEFT = 13;

  // Take the right fork.
  FORK_RIGHT = 14;

  // Take the ferry.
  FERRY = 15;

  // Take the train leading onto the ferry.
  FERRY_TRAIN = 16;

  // Turn left at the roundabout.
  ROUNDABOUT_LEFT = 17;

  // Turn right at the roundabout.
  ROUNDABOUT_RIGHT = 18;
}

// Traffic density indicator on a contiguous segment of a polyline or path.
// Given a path with points P_0, P_1, ... , P_N (zero-based index), the
// SpeedReadingInterval defines an interval and describes its traffic using the
// following categories.
message SpeedReadingInterval {
  // The classification of polyline speed based on traffic data.
  enum Speed {
    // Default value. This value is unused.
    SPEED_UNSPECIFIED = 0;

    // Normal speed, no slowdown is detected.
    NORMAL = 1;

    // Slowdown detected, but no traffic jam formed.
    SLOW = 2;

    // Traffic jam detected.
    TRAFFIC_JAM = 3;
  }

  // The starting index of this interval in the polyline.
  // In JSON, when the index is 0, the field appears to be unpopulated.
  int32 start_polyline_point_index = 1;

  // The ending index of this interval in the polyline.
  // In JSON, when the index is 0, the field appears to be unpopulated.
  int32 end_polyline_point_index = 2;

  // Traffic speed in this interval.
  Speed speed = 3;
}

// Encapsulates statistics about the time spent and distance travelled in a
// custom area.
message CustomLayerInfo {
  // Encapsulates areas related information on a `Route` or on a `RouteLeg`.
  message AreaInfo {
    // ID of an area inside a customer provided dataset. An area represents a
    // collection of polygons on the map that are of concern to the customer.
    // For example, the customer may be interested in knowing whether a
    // returned route is traveling through multiple busy city blocks during
    // a predefined period of time. An area ID is unique within a single
    // dataset uploaded by a customer. That is, a (customer_id, dataset_id,
    // area_id) triplet should uniquely identify a set of polygons on the map
    // that "activates" following a common schedule.
    string area_id = 1;

    // Total distance traveled in the area (in meters).
    float distance_in_area_meters = 2;

    // Total time spent in the area.
    google.protobuf.Duration duration_in_area = 3;
  }

  // Encapsulates information about areas in the custom layer on the Route.
  // This field is only populated if a route travels through areas in the
  // custom layer.
  repeated AreaInfo area_info = 1;
}
