// Copyright 2026 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.isochrones.v1;

import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/struct.proto";
import "google/type/latlng.proto";

option csharp_namespace = "Google.Maps.Isochrones.V1";
option go_package = "cloud.google.com/go/maps/isochrones/apiv1/isochronespb;isochronespb";
option java_multiple_files = true;
option java_outer_classname = "IsochronesServiceProto";
option java_package = "com.google.maps.isochrones.v1";
option objc_class_prefix = "GMPI";
option php_namespace = "Google\\Maps\\Isochrones\\V1";
option ruby_package = "Google::Maps::Isochrones::V1";
option (google.api.resource_definition) = {
  type: "places.googleapis.com/Place"
  pattern: "places/{place_id}"
};

// Service for calculating isochrones. An isochrone is an area of reachability
// from a given origin point within a specified travel time.
service IsochroneService {
  option (google.api.default_host) = "isochrones.googleapis.com";
  option (google.api.oauth_scopes) =
      "https://www.googleapis.com/auth/cloud-platform,"
      "https://www.googleapis.com/auth/maps-platform.isochrones";

  // Calculates and returns a single isochrone for a given set of parameters.
  rpc GenerateIsochrone(GenerateIsochroneRequest)
      returns (GenerateIsochroneResponse) {
    option (google.api.http) = {
      post: "/v1/isochrones:generate"
      body: "*"
    };
  }
}

// A request to generate a single isochrone.
message GenerateIsochroneRequest {
  // Defines the mode of transportation for isochrone calculation.
  enum TravelMode {
    // No travel mode specified.
    TRAVEL_MODE_UNSPECIFIED = 0;

    // Travel by passenger car.
    DRIVE = 1;

    // Travel by bicycle.
    BICYCLE = 2;

    // Travel by walking.
    WALK = 3;
  }

  // Specifies the direction of travel for the isochrone calculation.
  enum TravelDirection {
    // No travel direction specified.
    TRAVEL_DIRECTION_UNSPECIFIED = 0;

    // Calculates the area reachable *from* the origin point.
    // Example: "Where can I deliver to from my warehouse in 30 minutes?"
    FROM = 1;

    // Calculates the area from which you can travel *to* the origin point.
    // Example: "Where can my employees commute from to reach the office in 30
    // minutes?"
    TO = 2;
  }

  // Determines how traffic conditions are incorporated into the calculation.
  enum RoutingPreference {
    // No routing preference specified. The server will use its default,
    // which is TRAFFIC_UNAWARE.
    ROUTING_PREFERENCE_UNSPECIFIED = 0;

    // The calculation will not take traffic conditions into consideration.
    // The isochrone will be based on the road network and static travel times.
    // This is suitable for planning purposes where traffic is not a factor.
    TRAFFIC_UNAWARE = 1;

    // The calculation will factor in live traffic conditions.
    TRAFFIC_AWARE = 2;
  }

  // Controls the level of detail in the isochrone polygon.
  enum PolygonFidelity {
    // No polygon fidelity specified. The server will use its default, which
    // is based on the travel duration.
    POLYGON_FIDELITY_UNSPECIFIED = 0;

    // Low precision. Good for covering large areas with fewer vertices.
    LOW = 1;

    // Medium precision. A balance between detail and artifact size.
    MEDIUM = 2;

    // High precision. High fidelity edges, but may produce holes in the polygon
    // where the road network density is low.
    HIGH = 3;
  }

  // Required. The starting point for the isochrone calculation.
  oneof origin {
    // The origin as a latitude/longitude coordinate.
    google.type.LatLng location = 1;

    // The resource name of a place, in the `places/{place_id}` format.
    string place = 2 [
      (google.api.resource_reference) = { type: "places.googleapis.com/Place" }
    ];
  }

  // Required. The travel time for the isochrone calculation. The value must
  // be positive and is capped at 7200 seconds (120 minutes).
  // For DRIVE mode, the maximum allowed duration is 3600 seconds (60 minutes).
  google.protobuf.Duration travel_duration = 3
      [(google.api.field_behavior) = REQUIRED];

  // Required. The mode of transportation.
  TravelMode travel_mode = 4 [(google.api.field_behavior) = REQUIRED];

  // Required. The direction of travel.
  TravelDirection travel_direction = 5 [(google.api.field_behavior) = REQUIRED];

  // Optional. Specifies the preference for how to route. Defaults to
  // TRAFFIC_UNAWARE.
  RoutingPreference routing_preference = 6
      [(google.api.field_behavior) = OPTIONAL];

  // Optional. Specifies whether to smooth the edges of the resulting isochrone
  // polygons.
  bool enable_smoothing = 7 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Controls the precision of the generated polygon.
  // Defaults to POLYGON_FIDELITY_UNSPECIFIED.
  PolygonFidelity polygon_fidelity = 8 [(google.api.field_behavior) = OPTIONAL];
}

// A response containing the generated isochrone data.
message GenerateIsochroneResponse {
  // Output only. The generated isochrone.
  Isochrone isochrone = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// The result of an isochrone calculation, representing an area of reachability
// from an origin point within a specified travel time.
message Isochrone {
  // The geometric representation of the isochrone.
  oneof geometry {
    // Output only. The isochrone geometry in GeoJSON format, using the RFC 7946
    // format: https://datatracker.ietf.org/doc/html/rfc7946#section-3.1.6.
    google.protobuf.Struct geo_json = 1
        [(google.api.field_behavior) = OUTPUT_ONLY];
  }
}
