|
| 1 | +# -*- coding: utf-8 -*- |
| 2 | +# Copyright (C) 2018 HeiGIT, University of Heidelberg. |
| 3 | +# |
| 4 | +# |
| 5 | +# Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| 6 | +# use this file except in compliance with the License. You may obtain a copy of |
| 7 | +# the License at |
| 8 | +# |
| 9 | +# http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | +# |
| 11 | +# Unless required by applicable law or agreed to in writing, software |
| 12 | +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| 13 | +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| 14 | +# License for the specific language governing permissions and limitations under |
| 15 | +# the License. |
| 16 | +# |
| 17 | + |
| 18 | +"""Performs requests to the ORS optimization API.""" |
| 19 | + |
| 20 | + |
| 21 | +def optimization(client, |
| 22 | + jobs, |
| 23 | + vehicles, |
| 24 | + matrix=None, |
| 25 | + geometry=None, |
| 26 | + dry_run=None): |
| 27 | + """Optimize a fleet of vehicles on a number of jobs. |
| 28 | +
|
| 29 | + For more information, visit https://github.com/VROOM-Project/vroom/blob/master/docs/API.md. |
| 30 | +
|
| 31 | + Example: |
| 32 | +
|
| 33 | + >>> from openrouteservice import Client, optimization |
| 34 | + >>> coordinates = [[8.688641, 49.420577], [8.680916, 49.415776]] |
| 35 | + >>> jobs, vehicles = list(), list() |
| 36 | + >>> for idx, coord in enumerate(coordinates): |
| 37 | + jobs.append(optimization.Job(id=idx, location=coord)) |
| 38 | + vehicles.append(optimization.Vehicle(id=idx, location=coord)) |
| 39 | + >>> api = Client(key='somekey') |
| 40 | + >>> result = api.optimization(jobs=jobs, vehicles=vehicles) |
| 41 | +
|
| 42 | + :param jobs: The Job objects to fulfill. |
| 43 | + :type jobs: list of :class:`openrouteservice.optimization.Job` |
| 44 | +
|
| 45 | + :param vehicles: The vehicles to fulfill the :class:`openrouteservice.optimization.Job`'s. |
| 46 | + :type vehicles: list of :class:`openrouteservice.optimization.Vehicle` |
| 47 | +
|
| 48 | + :param matrix: Specify a custom cost matrix. If not specified, it will be calculated with |
| 49 | + the :meth:`openrouteservice.matrix.matrix` endpoint. |
| 50 | + :type matrix: list of lists of int |
| 51 | +
|
| 52 | + :param geometry: If the geometry of the resulting routes should be calculated. Default True. |
| 53 | + :type geometry: bool |
| 54 | +
|
| 55 | + :param dry_run: Print URL and parameters without sending the request. |
| 56 | + :param dry_run: boolean |
| 57 | +
|
| 58 | + :returns: Response of optimization endpoint. |
| 59 | + :rtype: dict |
| 60 | + """ |
| 61 | + |
| 62 | + assert all([isinstance(x, Job) for x in jobs]) |
| 63 | + assert all([isinstance(x, Vehicle) for x in vehicles]) |
| 64 | + |
| 65 | + params = {"jobs": [job.__dict__ for job in jobs], |
| 66 | + "vehicles": [vehicle.__dict__ for vehicle in vehicles]} |
| 67 | + |
| 68 | + if geometry is not None: |
| 69 | + params.update({"options": {"g": geometry}}) |
| 70 | + |
| 71 | + if matrix: |
| 72 | + params['matrix'] = matrix |
| 73 | + |
| 74 | + return client.request("/optimization", {}, post_json=params, dry_run=dry_run) |
| 75 | + |
| 76 | + |
| 77 | +class Job(object): |
| 78 | + """ |
| 79 | + Class to create a Job object for optimization endpoint. |
| 80 | +
|
| 81 | + Full documentation at https://github.com/VROOM-Project/vroom/blob/master/docs/API.md#jobs. |
| 82 | + """ |
| 83 | + def __init__(self, |
| 84 | + id, |
| 85 | + location=None, |
| 86 | + location_index=None, |
| 87 | + service=None, |
| 88 | + amount=None, |
| 89 | + skills=None, |
| 90 | + time_windows=None |
| 91 | + ): |
| 92 | + """ |
| 93 | + Create a job object for the optimization endpoint. |
| 94 | +
|
| 95 | + :param id: Integer used as unique identifier. |
| 96 | + :type id: int |
| 97 | +
|
| 98 | + :param location: Location of the job, as [lon, lat]. Optional if custom matrix is provided. |
| 99 | + :type location: tuple of float or list of float |
| 100 | +
|
| 101 | + :param location_index: Index of relevant row and column in custom matrix. Mandatory if custom |
| 102 | + matrix is provided. Irrelevant when no custom matrix is provided. |
| 103 | + :type location_index: int |
| 104 | +
|
| 105 | + :param service: Optional job service duration in seconds |
| 106 | + :type service: int |
| 107 | +
|
| 108 | + :param amount: An array of integers describing multidimensional quantities. |
| 109 | + :type amount: list of int or tuple of int |
| 110 | +
|
| 111 | + :param skills: An array of integers defining mandatory skills for this job. |
| 112 | + :type skills: list of int or tuple of int |
| 113 | +
|
| 114 | + :param time_windows: An array of time_window objects describing valid slots for job service start. |
| 115 | + :type time_windows: list of lists of int |
| 116 | + """ |
| 117 | + |
| 118 | + # if validate: |
| 119 | + # validator.validator(locals(), 'job') |
| 120 | + |
| 121 | + self.id = id |
| 122 | + |
| 123 | + if location is not None: |
| 124 | + self.location = location |
| 125 | + |
| 126 | + if location_index is not None: |
| 127 | + self.location_index = location_index |
| 128 | + |
| 129 | + if service is not None: |
| 130 | + self.service = service |
| 131 | + |
| 132 | + if amount is not None: |
| 133 | + self.amount = amount |
| 134 | + |
| 135 | + if skills is not None: |
| 136 | + self.skills = skills |
| 137 | + |
| 138 | + if time_windows is not None: |
| 139 | + self.time_windows = time_windows |
| 140 | + |
| 141 | + |
| 142 | +class Vehicle(object): |
| 143 | + """ |
| 144 | + Class to create a Vehicle object for optimization endpoint. |
| 145 | +
|
| 146 | + Full documentation at https://github.com/VROOM-Project/vroom/blob/master/docs/API.md#vehicles. |
| 147 | + """ |
| 148 | + |
| 149 | + def __init__(self, |
| 150 | + id, |
| 151 | + profile='driving-car', |
| 152 | + start=None, |
| 153 | + start_index=None, |
| 154 | + end=None, |
| 155 | + end_index=None, |
| 156 | + capacity=None, |
| 157 | + skills=None, |
| 158 | + time_window=None): |
| 159 | + """ |
| 160 | + Create a Vehicle object for the optimization endpoint. |
| 161 | +
|
| 162 | + :param id: Integer used as unique identifier. |
| 163 | + :param id: int |
| 164 | +
|
| 165 | + :param profile: Specifies the mode of transport to use when calculating |
| 166 | + directions. One of ["driving-car", "driving-hgv", "foot-walking", |
| 167 | + "foot-hiking", "cycling-regular", "cycling-road","cycling-mountain", |
| 168 | + "cycling-electric",]. Default "driving-car". |
| 169 | + :type profile: str |
| 170 | +
|
| 171 | + :param start: Coordinate for the vehicle to start from. If not specified, the start |
| 172 | + location will be the first visited job, determined by the optimization engine. |
| 173 | + :type start: list of float or tuple of float |
| 174 | +
|
| 175 | + :param start_index: Index of relevant row and column in custom matrix. Irrelevant |
| 176 | + if no custom matrix is provided. |
| 177 | + :type start_index: int |
| 178 | +
|
| 179 | + :param end: Coordinate for the vehicle to end at. If not specified, the end |
| 180 | + location will be the last visited job, determined by the optimization engine. |
| 181 | + :type end: list of float or tuple of float |
| 182 | +
|
| 183 | + :param end_index: Index of relevant row and column in custom matrix. Irrelevant |
| 184 | + if no custom matrix is provided. |
| 185 | + :type end_index: int |
| 186 | +
|
| 187 | + :param capacity: An array of integers describing multidimensional quantities. |
| 188 | + :type capacity: list of int or tuple of int |
| 189 | +
|
| 190 | + :param skills: An array of integers defining skills for this vehicle. |
| 191 | + :param skills: list of int or tuple of int |
| 192 | +
|
| 193 | + :param time_window: A time_window object describing working hours for this vehicle. |
| 194 | + :param time_window: list of int or tuple of int |
| 195 | + """ |
| 196 | + |
| 197 | + # if validate: |
| 198 | + # validator.validator(locals(), 'vehicle') |
| 199 | + |
| 200 | + self.id = id |
| 201 | + self.profile = profile |
| 202 | + |
| 203 | + if start is not None: |
| 204 | + self.start = start |
| 205 | + |
| 206 | + if start_index is not None: |
| 207 | + self.start_index = start_index |
| 208 | + |
| 209 | + if end is not None: |
| 210 | + self.end = end |
| 211 | + |
| 212 | + if end_index is not None: |
| 213 | + self.end_index = end_index |
| 214 | + |
| 215 | + if capacity is not None: |
| 216 | + self.capacity = capacity |
| 217 | + |
| 218 | + if skills is not None: |
| 219 | + self.skills = skills |
| 220 | + |
| 221 | + if time_window is not None: |
| 222 | + self.time_window = time_window |
0 commit comments