Source code for routingtools.osrm

# -*- coding: utf-8 -*-
"""Interaction with the Open Source Routing Machine.

This module contains functions that send requests to the OSRM routing engine. A running
OSRM server is required.

.. _OSRM documentation:
  http://project-osrm.org/

"""

# External imports.
import logging
import os
import requests

# Internal imports.
from routingtools import _utils
from routingtools.exceptions import OSRMError

# Log settings.
logger = logging.getLogger(__name__)

# Server settings.
osrm_server = os.getenv("OSRM_SERVER_URL", "http://localhost:5000")

[docs]def get_cost_matrix(cost, coords): """ Retrieves a matrix from the OSRM routing engine, describing the travel cost between two locations, for each possible combination of locations. Args: cost (str): The type of travel cost to be used, either 'duration' or 'distance'. coords (list): List of coordinate pairs, where each coordinate pair describes a location in geographical space and is a list [a, b] with a and b being respectively the longitude and latitude coordinates of the location. Dummy locations, with a coordinate value of [None] instead of [a, b], will be ignored. Returns: list: A list in which each element is again a list. Each of those sub-lists is representing a single row of the cost matrix, and each of its elements is an integer describing the calculated travel cost between the two respective locations. """ # Compose request. # Only include real coordinates, i.e. a list of length 2 with longitude and latitude. # Coordinates of a dummy node (i.e. [None]) should not be included. url_type = osrm_server + "/table/v1/driving/" url_coords = ";".join([str(x[0]) + "," + str(x[1]) for x in coords if len(x) == 2]) url_cost = "?annotations=" + cost url = url_type + url_coords + url_cost logger.debug("Composed an OSRM matrix request: {}".format(url)) # Send request. raw_response = requests.get(url) response = raw_response.json() if not raw_response.ok: raise OSRMError("Failed to retrieve cost matrix: " + response["message"]) # Keep only the cost matrix, and not all its attributes. # Round the values to their nearest integer because Google OR Tools requires integers. matrix = _utils._convert_matrix_values_to_integers(response[cost + "s"]) logger.info("Retrieved a {} matrix from OSRM with {} nodes".format(cost, len(matrix))) return matrix
[docs]def get_route(coords): """ Retrieves the shortest route between multiple locations from the OSRM routing engine. The locations will be visited in the order they are provided. Args: coords (list): List of coordinate pairs, where each coordinate pair describes a location in geographical space and is a list [a, b] with a and b being respectively the longitude and latitude coordinates of the location. Dummy locations, with a coordinate value of [None] instead of [a, b], will be ignored. Returns: dict: An OSRM route result - http://project-osrm.org/docs/v5.5.1/api/#result-objects. """ # Compose request. # Only include real coordinates, i.e. a list of length 2 with longitude and latitude. # Coordinates of a dummy node (i.e. [None]) should not be included. url_type = osrm_server + "/route/v1/driving/" url_coords = ";".join([str(x[0]) + "," + str(x[1]) for x in coords if len(x) == 2]) url_options = "?overview=full&geometries=geojson" url = url_type + url_coords + url_options logger.debug("Composed an OSRM route request: {}".format(url)) # Send request. raw_response = requests.get(url) response = raw_response.json() if not raw_response.ok: raise OSRMError("Failed to retrieve cost matrix: " + response["message"]) # Keep only the routes object, and not all its attributes. routes = response["routes"] logger.info("Retrieved a route from OSRM with {} nodes".format(len(coords))) return routes