Coder Social home page Coder Social logo

giscience / openrouteservice-py Goto Github PK

View Code? Open in Web Editor NEW
373.0 14.0 52.0 1.68 MB

:snake: The Python API to consume openrouteservice(s) painlessly!

Home Page: https://openrouteservice.org

License: Apache License 2.0

Python 100.00%
python api directions-api routing-engine geocoding-api isochrones

openrouteservice-py's People

Contributors

isikl avatar jayaddison avatar jeromehoen avatar joker234 avatar koebi avatar michaelsjp avatar nilsnolde avatar ri0t avatar timmccauley avatar vlavorini avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

openrouteservice-py's Issues

feat: argument `options` in function `isochrones`

Here's what I did

import os
import openrouteservice as ors

ors_client = ors.client.Client(key=os.getenv("OPENROUTE"))  # valid token
params_iso = {'profile': 'cycling-regular', 
             'location_type': 'destination', 
             'range': [1200], 
             'options': {'avoid_features': ['ferries']}, 
             'locations': [(2.1426944999999997, 41.41344459999999)]
             }
ors_result = ors_client.isochrones(**params_iso, dry_run=True)

Here's what I got

Traceback:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In [1], line 11
      4 ors_client = ors.client.Client(key=os.getenv("OPENROUTE"))
      5 params_iso = {'profile': 'cycling-regular', 
      6              'location_type': 'destination', 
      7              'range': [1200], 
      8              'options': {'avoid_features': ['ferries']}, 
      9              'locations': [(2.1426944999999997, 41.41344459999999)]
     10              }
---> 11 ors_result = ors_client.isochrones(**params_iso, dry_run=True)

File ~/venv/lib/python3.10/site-packages/openrouteservice/client.py:299, in _make_api_method.<locals>.wrapper(*args, **kwargs)
    296 @functools.wraps(func)
    297 def wrapper(*args, **kwargs):
    298     args[0]._extra_params = kwargs.pop("extra_params", None)
--> 299     result = func(*args, **kwargs)
    300     try:
    301         del args[0]._extra_params

TypeError: isochrones() got an unexpected keyword argument 'options'

The error occurs because the function isochrones does not have a param options (See the code).


Here's what I was expecting

However, options is a valid param in the isochrones API v2. The following code works fine:

ors_result = ors_client.request("/v2/isochrones/" + params_iso["profile"] + "/geojson", 
                                      {}, 
                                      post_json=params_iso
                                      )

(code based on isochrones function.)

Once the code above is run, the variable ors_result contains the following (click to expand):

ors_result
{'type': 'FeatureCollection',
 'bbox': [2.09631, 41.370261, 2.198744, 41.4531],
 'features': [{'type': 'Feature',
   'properties': {'group_index': 0,
    'value': 1200.0,
    'center': [2.142878047909153, 41.413439681539124]},
   'geometry': {'coordinates': [[[2.09631, 41.405701],
      [2.099388, 41.397135],
      [2.098014, 41.387268],
      [2.097249, 41.383937],
      [2.097085, 41.382509],
      [2.097083, 41.382472],
      [2.09871, 41.380584],
      [2.099657, 41.380563],
      [2.109283, 41.380091],
      [2.117467, 41.377333],
      [2.12087, 41.374939],
      [2.120926, 41.374915],
      [2.123248, 41.37394],
      [2.133004, 41.371414],
      [2.134872, 41.370749],
      [2.138397, 41.370514],
      [2.140798, 41.370374],
      [2.145472, 41.370261],
      [2.151761, 41.370442],
      [2.160682, 41.370864],
      [2.163476, 41.371213],
      [2.17192, 41.371492],
      [2.177512, 41.3707],
      [2.177628, 41.3707],
      [2.179901, 41.371336],
      [2.179913, 41.371349],
      [2.181617, 41.375806],
      [2.190128, 41.383141],
      [2.190773, 41.383373],
      [2.195368, 41.387799],
      [2.196467, 41.395314],
      [2.198724, 41.404722],
      [2.198744, 41.41086],
      [2.198301, 41.420843],
      [2.198155, 41.423742],
      [2.194628, 41.430021],
      [2.193327, 41.43192],
      [2.185989, 41.440538],
      [2.18207, 41.44764],
      [2.181119, 41.448957],
      [2.175648, 41.45118],
      [2.175266, 41.451265],
      [2.175181, 41.451277],
      [2.174886, 41.451301],
      [2.174846, 41.451301],
      [2.163333, 41.45209],
      [2.162535, 41.45239],
      [2.162171, 41.452478],
      [2.15754, 41.4531],
      [2.148339, 41.448907],
      [2.148099, 41.448794],
      [2.144025, 41.446714],
      [2.132881, 41.442848],
      [2.127608, 41.441222],
      [2.127558, 41.441143],
      [2.125513, 41.436396],
      [2.115836, 41.434518],
      [2.114534, 41.435249],
      [2.112561, 41.434631],
      [2.107995, 41.430244],
      [2.10808, 41.430141],
      [2.109671, 41.42742],
      [2.103577, 41.418341],
      [2.100917, 41.418903],
      [2.100847, 41.418932],
      [2.098615, 41.417967],
      [2.09839, 41.417741],
      [2.096331, 41.409301],
      [2.09631, 41.405701]]],
    'type': 'Polygon'}}],
 'metadata': {'attribution': 'openrouteservice.org, OpenStreetMap contributors',
  'service': 'isochrones',
  'timestamp': 1676931765808,
  'query': {'profile': 'cycling-regular',
   'locations': [[2.1426944999999997, 41.41344459999999]],
   'location_type': 'destination',
   'range': [1200.0],
   'options': {'avoid_features': ['ferries']}},
  'engine': {'version': '6.8.0',
   'build_date': '2022-10-21T14:34:31Z',
   'graph_date': '2023-02-05T08:09:55Z'}}}

Here's what I think could be improved

I wonder if you consider including the param options in the function isochrones.
If so, I could work on the PR if needed.

Related to #44

optimization method hidden in development branch

I had used this code in version 2.3.0

now doing tests from branch development I find some problems

has changed api di ors-py? for optimixzation request?

import openrouteservice as ors

jobs = []
jobs.append(ors.optimization.Job(
        id = idx,
        location = cc,
        pickup = [1],
    ))
module 'openrouteservice' has no attribute 'optimization'

Missing options argument from API

Here's what I did

I have a working script to retrive ischrones. I want to avoid highways, so I added the option like this:
params_iso = {"locations":[[8.681495,49.41461],[8.686507,49.41943]],"range":[300,200],"options":{"avoid_features":["highways"]}}

The locations being added later

Here's what I got

TypeError: isochrones() got an unexpected keyword argument 'options'---

Here's what I was expecting

For the option parameter to work like the api


Here's what I think could be improved

Adding the options argument

JSONDecodeError when requesting directions in gpx format

Here's what I did

 [-0.0743414, 51.5015841],
 [-0.05273140000000039, 51.46430039999999],
 [-0.0531279, 51.4637547],
 [0.0320358, 51.3579627],
 [0.030053528946478628, 51.3510888399767],
 [0.0373899, 51.3508184],
 [0.05585272964791204, 51.33450105290082],
 [0.0528395, 51.3311335],
 [0.1014503, 51.246361],
 [0.14227140698558516, 51.18576100547525],
 [0.1458905, 51.1853518],
 [0.1459325, 51.1858536]]

gpx = directions.directions(clnt, coordinates_lon_lat, profile ='cycling-regular', 
                    format = 'gpx',preference = 'recommended' )

The same request is processed without any errors with format='json' or format='geojson' and the correct route is returned

dry_run output:

https://api.openrouteservice.org/v2/directions/driving-car/json?
Headers:
{
  "headers": {
    "User-Agent": "ORSClientPython.v2.3.0",
    "Content-type": "application/json",
    "Authorization": "5b3ce3597851110001cf62484bacb83d2107475198ea22650a25b872"
  },
  "timeout": 60,
  "json": {
    "coordinates": [
      [
        8.34234,
        48.23424
      ],
      [
        8.34423,
        48.26424
      ]
    ]
  }
}```
---
#### Here's what I got
<!-- we :heart: json outputs -->
```---------------------------------------------------------------------------
JSONDecodeError                           Traceback (most recent call last)
~/miniconda3/envs/ox/lib/python3.8/site-packages/openrouteservice/client.py in _get_body(response)
    228         try:
--> 229             body = response.json()
    230         except json.JSONDecodeError:

~/miniconda3/envs/ox/lib/python3.8/site-packages/requests/models.py in json(self, **kwargs)
    897                     pass
--> 898         return complexjson.loads(self.text, **kwargs)
    899 

~/miniconda3/envs/ox/lib/python3.8/json/__init__.py in loads(s, cls, object_hook, parse_float, parse_int, parse_constant, object_pairs_hook, **kw)
    356             parse_constant is None and object_pairs_hook is None and not kw):
--> 357         return _default_decoder.decode(s)
    358     if cls is None:

~/miniconda3/envs/ox/lib/python3.8/json/decoder.py in decode(self, s, _w)
    336         """
--> 337         obj, end = self.raw_decode(s, idx=_w(s, 0).end())
    338         end = _w(s, end).end()

~/miniconda3/envs/ox/lib/python3.8/json/decoder.py in raw_decode(self, s, idx)
    354         except StopIteration as err:
--> 355             raise JSONDecodeError("Expecting value", s, err.value) from None
    356         return obj, end

JSONDecodeError: Expecting value: line 1 column 1 (char 0)

During handling of the above exception, another exception occurred:

HTTPError                                 Traceback (most recent call last)
<ipython-input-129-0570940137d3> in <module>
----> 1 gpx = directions.directions(clnt, coordinates_lon_lat, profile ='cycling-regular', 
      2                     format = 'gpx',preference = 'recommended' )

~/miniconda3/envs/ox/lib/python3.8/site-packages/openrouteservice/directions.py in directions(client, coordinates, profile, format_out, format, preference, units, language, geometry, geometry_simplify, instructions, instructions_format, alternative_routes, roundabout_exits, attributes, maneuvers, radiuses, bearings, skip_segments, continue_straight, elevation, extra_info, suppress_warnings, optimized, optimize_waypoints, options, validate, dry_run)
    279         params['options'] = options
    280 
--> 281     return client.request("/v2/directions/" + profile + '/' + format, {}, post_json=params, dry_run=dry_run)
    282 
    283 

~/miniconda3/envs/ox/lib/python3.8/site-packages/openrouteservice/client.py in request(self, url, get_params, first_request_time, retry_counter, requests_kwargs, post_json, dry_run)
    202 
    203         try:
--> 204             result = self._get_body(response)
    205 
    206             return result

~/miniconda3/envs/ox/lib/python3.8/site-packages/openrouteservice/client.py in _get_body(response)
    229             body = response.json()
    230         except json.JSONDecodeError:
--> 231             raise exceptions.HTTPError(response.status_code)
    232 
    233         # error = body.get('error')

HTTPError: HTTP Error: 200

Here's what I was expecting

Same directions in GPX format

The same request generated as Python snippet from ORS API playground works correctly:


body = {"coordinates":[[-0.0858923,51.5050313],[-0.0743414,51.5015841],[-0.05273140000000039,51.46430039999999],[-0.0531279,51.4637547],[0.0320358,51.3579627],[0.030053528946478628,51.3510888399767],[0.0373899,51.3508184],[0.05585272964791204,51.33450105290082],[0.0528395,51.3311335],[0.1014503,51.246361],[0.14227140698558516,51.18576100547525],[0.1458905,51.1853518],[0.1459325,51.1858536]],"preference":"recommended"}

headers = {
    'Accept': 'application/json, application/geo+json, application/gpx+xml, img/png; charset=utf-8',
    'Authorization': '5b3ce3597851110001cf62484bacb83d2107475198ea22650a25b872',
    'Content-Type': 'application/json; charset=utf-8'
}
call = requests.post('https://api.openrouteservice.org/v2/directions/cycling-regular/gpx', json=body, headers=headers)

print(call.status_code, call.reason)
print(call.text)

Here's what I think could be improved

API response in GPX format should be correctly parsed or delivered as is

Distance_Matrix: 'Unable to find an appropriate routing profile.' - for all but 'driving-car'

Reported by @AvePazuzu

See GIScience/openrouteservice#299

I have been using the the function few weeks ago and it worked properly.

Since yesterday I get the titled error message for all profiles but 'driving-car'.

I have tried the examples but I always get the same result.

Here is my test code(py 3.6):

req_param = {'profile': 'driving-hgv', metrics' : ['duration', 'distance'], 'optimized': 'true', 'units': 'km', 'locations': [[9.970093,48.477473], [9.207916,49.153868]]}

dist_mat = clnt2.distance_matrix(**req_param)

And as response I get:

ApiError: 500 ({'error': {'code': 6099, 'message': 'Unable to find an appropriate routing profile.'}, 'info': {'engine': {'version': '4.5.0', 'build_date': '2018-09-23T13:46:49Z'}, 'timestamp': 1538421210721}})

Also, is there a lito find an mit for the number of elements of 25 now?

ApiError: 400 ({'error': {'code': 6004, 'message': "Parameter 'sources/destinations=36' is out of range. Maximum possible value is 25."}, 'info': {'engine': {'version': '4.5.0', 'build_date': '2018-09-23T13:47:22Z'}, 'timestamp': 1538421896753}})

Did I do something wrong here?

Many Thanks & bis dann.

priority field is not supported for optimization api?

hi
I would like to solve jobs that have a higher amount than the others before the others ..
I thought about adding the priority field to get this

my case study is it:

...vehicles...

jobs = []
for idx, cc in enumerate(job_locs):
    loc = list(reversed(cc))
    amount = random.randrange(1, 5) # random  value for testing..
    jobs.append(ors.optimization.Job(
        id = idx,
        location = cc,
        amount = [amount],
        priority = amount
    ))

clientVrp = ors.Client(base_url='http://myvroom/', key='')
optimized = clientVrp.optimization(
    vehicles = vehicles,
    jobs = jobs,
    geometry = True
)

I receive this error:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-94-5e80af05f327> in <module>
     41         #amount = [2] # Quantita' contenuto nel Bidone
     42         amount = [amount],
---> 43         priority = amount
     44     ))
     45     folium.Marker(loc, tooltip=folium.Tooltip(amount,permanent=True), icon=folium.Icon(icon='archive', prefix='fa', color='green')).add_to(m)

TypeError: __init__() got an unexpected keyword argument 'priority'

support true booleans

Very stupid design decision to use stringified booleans. Fix to support true booleans, keeping old behaviour for backwards compatibility.

allow support for additional kwargs

Currently, the library fails if anything is provided in the request parameters that isn't hard-coded as function parameters. It would be good if additional/new API parameters can be called without the need to hard-code them every time.

This would touch:
#75
#74
#62
#66

Distance_matrix not working with metrics parameter

Here's what I did

Used following code:

client_ors = openrouteservice.Client(key='<KEY>')
df_bus_stops_distances = client_ors.distance_matrix(llist_coords_bus_stops, metrics="distance")

and same without metrics parameter.

Tried on the API-Playground, it worked. Tried with the example code as python snippet from the API-Playground, that also worked.


Here's what I got

url:
https://api.openrouteservice.org/v2/matrix/driving-car/json?
Headers:
{
  "headers": {
    "User-Agent": "ORSClientPython.v2.2.2",
    "Content-type": "application/json",
    "Authorization": "<KEY>"
  },
  "timeout": 60,
  "json": {
    "locations": [
      [
        x,
        y
      ],
      [
        x,
        y
      ],
      [
        x,
        y
      ],
      [
        x,
        y
      ],
      [
        x,
        y
      ],
      [
        x,
        y
      ],
      [
        x,
        y
      ],
      [
        x,
        y
      ],
      [
        x,
        y
      ],
      [
        x,
        y
      ]
    ],
    "profile": "driving-car",
    "metrics": "distance"
  }
}

openrouteservice.exceptions.ApiError: 400 ({'error': {'code': 6003, 'message': "Parameter 'metrics' has incorrect value or format."}, 'info': {'engine': {'build_date': '2023-06-16T03:06:42Z', 'version': '7.1.0'}, 'timestamp': 1687986526446}})


Here's what I was expecting

Should get a working response, as using metrics-parameter works on normal REST-API calls (API-Playground/python example code)


Here's what I think could be improved

Looked at the code of this package, especially at the distance_matrix.py. Couldn't figure out the problem. I'm sorry.

Installation failed

Installtion with pip and conda don't work.

Installing collected packages: certifi, requests, openrouteservice
Found existing installation: certifi 2018.11.29
Cannot uninstall 'certifi'. It is a distutils installed project and thus we cannot accurately determine which files belong to it which would lead to only a partial uninstall.

For conda install the chanel nilsnolde cannot be found.

My setup:
win64
conda 4.5.12

Integrate best practices

  • Decent package manager: Poetry
  • Good testing eninge: tox
  • Code formatting/linting/pep8 check: pre-commit with addons.

fix crashing coveralls

Error message for coveralls:

Run coveralls
Submitting coverage to coveralls.io...
Could not submit coverage: 422 Client Error: Unprocessable Entity for url: coveralls.io/api/v1/jobs
Traceback (most recent call last):
  File "/opt/hostedtoolcache/Python/3.7.9/x64/lib/python3.7/site-packages/coveralls/api.py", line 252, in wear
    response.raise_for_status()
  File "/opt/hostedtoolcache/Python/3.7.9/x64/lib/python3.7/site-packages/requests/models.py", line 943, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 422 Client Error: Unprocessable Entity for url: coveralls.io/api/v1/jobs

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/opt/hostedtoolcache/Python/3.7.9/x64/lib/python3.7/site-packages/coveralls/cli.py", line 85, in main
    result = coverallz.wear()
  File "/opt/hostedtoolcache/Python/3.7.9/x64/lib/python3.7/site-packages/coveralls/api.py", line 255, in wear
    raise CoverallsException('Could not submit coverage: {}'.format(e))
coveralls.exception.CoverallsException: Could not submit coverage: 422 Client Error: Unprocessable Entity for url: coveralls.io/api/v1/jobs
resubmitting with id None-7239098140940868245

VROOM update for optimization

VROOM Api has new features, can these be added? Things like vehicle costs, description etc. The current API is missing this for optimizations.

decode_polyline does not support elevation

import openrouteservice

API_KEY = "123"
client = openrouteservice.Client(key = API_KEY, base_url = 'https://api.openrouteservice.org')

Handegg 6, Guttannen: 46.6122285, 8.3075423

Dorfstrasse, Innertkirchen: 46.70533443143516, 8.227912878765892

down = ((8.3075423,46.6122285 ),(8.227912878765892,46.70533443143516))
up = ((8.227912878765892,46.70533443143516),(8.3075423,46.6122285))

coords=up
geometry = client.directions(coords, profile='driving-car', preference='shortest',units='km',language='en', geometry='true', geometry_format='encodedpolyline', elevation='true', extra_info=['steepness'])
decoded = openrouteservice.convert.decode_polyline(geometry)
print(decoded)

$ py orstest.py
Traceback (most recent call last):
File "orstest.py", line 13, in
decoded = openrouteservice.convert.decode_polyline(geometry)
File "C:\Users\m50\AppData\Local\Programs\Python\Python36\lib\site-packages\openrouteservice\convert.py", line 150, in decode_polyline
b = ord(polyline[index]) - 63 - 1
KeyError: 0

Directions API, issue with parameters set to false

Hello!

There is an issue with boolean parameters that you convert to string. You only stringify them if they are True, for instance, see line 199 of the file directions.py:

if instructions:
    # not checked on backend, check here
    params["instructions"] = convert._convert_bool(instructions)

But as I want to set it to false, it doesn't get converted to string and the instructions are still in the response. Please consider reviewing all the boolean parameters that need a conversion.

PS: the hot fix is setting the parameters to "false" as a string.

various issues in examples

  • validate-parameter still present
  • polygons should be drawn in reverse order, otherwise you can't see/access the smaller (lower) one

Setting language=gr gives 400 error

As I say in the issue title, if i set parameter language=gr, then it gives me 400 error. I tried it with other values of the parameter and it works. Only gr doesn't work.

EDIT: Tried it with other values. Only en works.

Transit API

Is there any API in openrouteservice, which is equivalent to google transit API?

I am a new person to this area, so really appreciate your inputs on my question.

Remove old Python2 syntax

Here's what I did


Here's what I got


Here's what I was expecting


Here's what I think could be improved

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.