{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "cell_style": "center"
   },
   "outputs": [],
   "source": [
    "# Copyright 2026 Google LLC\n",
    "#\n",
    "# Licensed under the Apache License, Version 2.0 (the \"License\");\n",
    "# you may not use this file except in compliance with the License.\n",
    "# You may obtain a copy of the License at\n",
    "#\n",
    "#     https://www.apache.org/licenses/LICENSE-2.0\n",
    "#\n",
    "# Unless required by applicable law or agreed to in writing, software\n",
    "# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
    "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
    "# See the License for the specific language governing permissions and\n",
    "# limitations under the License.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# RMI Tutorial 02: Simple Route Setting\n",
    "\n",
    "Now that your project is set up and the API is enabled, let's register your first monitored road segment using the **Roads Selection API**.\n",
    "\n",
    "### Objectives:\n",
    "1. **Define** a monitoring segment (Origin/Destination).\n",
    "2. **Construct** an RMI-compliant JSON payload.\n",
    "3. **Register** the route via a REST API call.\n",
    "4. **Verify** the route status."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/googlemaps-samples/insights-samples/blob/main/roads_management_insights/tutorials/02_route_setting.ipynb) \n",
    "[![Open In Colab Enterprise](https://img.shields.io/badge/Open%20in-Colab%20Enterprise-blue?logo=google-cloud&logoColor=white)](https://console.cloud.google.com/vertex-ai/colab/import/https%3A%2F%2Fraw.githubusercontent.com%2Fgooglemaps-samples%2Finsights-samples%2Fmain%2Froads_management_insights%2Ftutorials%2F02_route_setting.ipynb) \n",
    "[![Open In BigQuery Notebooks](https://img.shields.io/badge/Open%20in-BigQuery%20Notebooks-blue?logo=google-cloud&logoColor=white)](https://console.cloud.google.com/bigquery/import?url=https%3A%2F%2Fraw.githubusercontent.com%2Fgooglemaps-samples%2Finsights-samples%2Fmain%2Froads_management_insights%2Ftutorials%2F02_route_setting.ipynb) \n",
    "[![View on GitHub](https://img.shields.io/badge/View%20on-GitHub-lightgrey?logo=github&logoColor=white)](https://github.com/googlemaps-samples/insights-samples/blob/main/roads_management_insights/tutorials/02_route_setting.ipynb)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Install necessary libraries\n",
    "!pip install --upgrade requests google-auth"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import requests\n",
    "import json\n",
    "import google.auth\n",
    "import google.auth.transport.requests\n",
    "from google.colab import auth\n",
    "\n",
    "auth.authenticate_user()\n",
    "\n",
    "PROJECT_ID = 'YOUR_PROJECT_ID' # @param {type:\"string\"}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "!gcloud config set project {PROJECT_ID}\n",
    "!gcloud config list"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. Define the Route\n",
    "We will define a simple **Origin/Destination (O/D)** dynamic route. \n",
    "\n",
    "### Why use O/D Only?\n",
    "The O/D-only strategy is the simplest way to define a monitoring segment. By providing only the start and end points, you allow RMI to automatically calculate the optimal path between them based on the underlying road network.\n",
    "\n",
    "**This strategy is best for:**\n",
    "- **Transit Monitoring**: Defining segments between consecutive bus stops or train stations.\n",
    "- **Standard Corridors**: Short road segments where the physical path is unambiguous.\n",
    "- **Rapid Prototyping**: Quickly setting up a large number of segments without needing precise waypoint traces.\n",
    "\n",
    "If you wish to influence the path selection (e.g., to bias the route toward specific segments), you would instead provide a list of **intermediate waypoints** (up to 25). Note that intermediates act as hints and do not strictly enforce a specific lane or microscopic path."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "ROUTE_ID = 'tutorial-route-001' # No underscores allowed!\n",
    "DISPLAY_NAME = 'Tutorial Prototype Route'\n",
    "\n",
    "# Example: Coordinates for a segment in Boston\n",
    "ORIGIN = {\"latitude\": 42.3601, \"longitude\": -71.0589}\n",
    "DESTINATION = {\"latitude\": 42.3611, \"longitude\": -71.0579}\n",
    "\n",
    "payload = {\n",
    "    \"displayName\": DISPLAY_NAME,\n",
    "    \"dynamicRoute\": {\n",
    "        \"origin\": ORIGIN,\n",
    "        \"destination\": DESTINATION,\n",
    "        \"intermediates\": []\n",
    "    },\n",
    "    \"routeAttributes\": {\n",
    "        \"use_case\": \"prototype\",\n",
    "        \"tutorial_id\": \"02\"\n",
    "    }\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. Register the Route\n",
    "We use an authenticated POST request to the Roads Selection API. For detailed specifications, refer to the [official guide on selecting roads](https://developers.google.com/maps/documentation/roads-management-insights/roads-selection/create) and the [REST API reference for route creation](https://developers.google.com/maps/documentation/roads-management-insights/reference/rest/v1/selection.v1.projects.selectedRoutes/create)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Get Access Token\n",
    "creds, _ = google.auth.default(scopes=['https://www.googleapis.com/auth/cloud-platform'])\n",
    "auth_req = google.auth.transport.requests.Request()\n",
    "creds.refresh(auth_req)\n",
    "\n",
    "ROADS_SELECTION_BASE_URL=\"https://roads.googleapis.com/selection/v1\"\n",
    "\n",
    "url = f\"{ROADS_SELECTION_BASE_URL}/projects/{PROJECT_ID}/selectedRoutes?selectedRouteId={ROUTE_ID}\"\n",
    "headers = {\n",
    "    \"Content-Type\": \"application/json\",\n",
    "    \"Authorization\": f\"Bearer {creds.token}\",\n",
    "    \"x-goog-user-project\": f\"{PROJECT_ID}\"\n",
    "}\n",
    "\n",
    "response = requests.post(url, headers=headers, json=payload)\n",
    "\n",
    "if response.status_code == 200:\n",
    "    print(\"Success! Route registered.\")\n",
    "    print(json.dumps(response.json(), indent=2))\n",
    "else:\n",
    "    print(f\"Error {response.status_code}: {response.text}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3. Monitor Route Status (Polling)\n",
    "Once registered, a route initially enters the `STATE_VALIDATING` phase. RMI performs internal geometry checks and verifies road usage. The cell below uses the [Get SelectedRoute REST method](https://developers.google.com/maps/documentation/roads-management-insights/reference/rest/v1/selection.v1.projects.selectedRoutes/get) to poll the API until the state changes to `STATE_RUNNING` or `STATE_INVALID`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import time\n",
    "\n",
    "get_url = f\"{ROADS_SELECTION_BASE_URL}/projects/{PROJECT_ID}/selectedRoutes/{ROUTE_ID}\"\n",
    "status = \"STATE_VALIDATING\"\n",
    "max_retries = 10\n",
    "retry_count = 0\n",
    "\n",
    "print(f\"Polling status for {ROUTE_ID}...\")\n",
    "\n",
    "while status == \"STATE_VALIDATING\" and retry_count < max_retries:\n",
    "    response = requests.get(get_url, headers=headers)\n",
    "    if response.status_code == 200:\n",
    "        data = response.json()\n",
    "        status = data.get('state', 'UNKNOWN')\n",
    "        validation_error = data.get('validationError', 'None')\n",
    "        \n",
    "        print(f\" - Current State: {status} (Validation Error: {validation_error})\")\n",
    "        \n",
    "        if status != \"STATE_VALIDATING\":\n",
    "            break\n",
    "    else:\n",
    "        print(f\"Error {response.status_code}: {response.text}\")\n",
    "        break\n",
    "    \n",
    "    retry_count += 1\n",
    "    time.sleep(30) # Poll every 30 seconds\n",
    "\n",
    "if status == \"STATE_RUNNING\":\n",
    "    print(\"\\nSuccess! Your route is now active and monitoring traffic.\")\n",
    "elif status == \"STATE_INVALID\":\n",
    "    print(f\"\\nRoute is INVALID. Reason: {validation_error}\")\n",
    "else:\n",
    "    print(\"\\nPolling timed out or encountered an error.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Summary & Next Steps\n",
    "You have successfully registered your first monitored route. RMI will now begin validating the geometry and traffic volumes.\n",
    "\n",
    "**Next**: In the next tutorial, we will verify how the data flows into BigQuery once the route is active."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "**For more advanced RMI query patterns, visit the official [RMI Sample Queries Repository](https://github.com/googlemaps-samples/insights-samples/tree/main/roads_management_insights/rmi_sample_queries).**"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "name": "python",
   "version": "3.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
