How to create a distance or travel time matrix when long/Lat are known

1,381 views
Skip to first unread message

Sampson

unread,
Sep 9, 2019, 1:05:57 AM9/9/19
to or-tools-discuss
Hi all,

I'm using Or-tools for VRP.

I need to get the distance matrix, upload it and get the routes. I have over 100 destinations, with their longitudes and latitudes.
 I have gone through the example here:
It is still quite confusing. This involves typing the destination coordinates manually.

Is there a more direct example please? Or how will I upload a csv file of the coordinates and return the distance matrix, please?

Thanks

Sam

blind.lin...@gmail.com

unread,
Sep 9, 2019, 1:51:23 PM9/9/19
to or-tools...@googlegroups.com
Obviously the answer is to write a program to hit the distance or
travel time matrix service, but I think your question is how to write
that program, correct?

The core of what I do relies on the python requests library
(https://2.python-requests.org/en/master/). There are others; you can
use whatever works for you, of course.

Personally, I never have the budget to hit the google maps service. I
use the Open Source Routing Machine (OSRM) backend project
https://github.com/Project-OSRM/osrm-backend. It is based on
OpenStreetMap, which means the quality of the data varies from place
to place, but you should find data for most places in the world.

OSRM has a demo server up, but they ask that you not use it for
production projects. So a while ago I wrote a small thing that sets
up a Docker image containing data for one (or a few) USA state. My
github repo for that is here:
https://github.com/jmarca/osrm_map_puller. As I recall the defaults
are set up for the state of Oregon, and different states can be
selected by changing environment variables. I haven't used it in over
a year, but it should be reasonably up to date.

OSRM has a web-based API
(https://github.com/Project-OSRM/osrm-backend/blob/master/docs/http.md)
that is similar to Google Maps' API. The basic idea is to hit the API
endpoint within a function, parse the reponse, and save it. In
python, here is a snippet of code that I use. If you want to stick
with Google Maps, you can probably adjust this code to match their URL
scheme.

```python
import requests
import json

class Spatial():
"""
A Class for handling spatial issues.
"""

def __init__(self,
proto="http",
host="osrm_routed", # assume using docker networking
port="5000",
prefix="route/v1/driving",
factor=1
):
self.factor = factor
self.apiurl="%s://%s:%s/%s" % ( proto,host,port,prefix )
return

... blah blah ...

def get_OSRM_route(self,lat1,lon1,lat2,lon2,readCache=True,writeCache=True):
"""
Make a call to the ORSM API to get the route(s) between (lat1,lon1) and (lat2,lon2).
Caches all results based upon the endpoint coords for future access.

Args:
lat1: Latitude of origin
lon1: Longitude of origin
lat2: Latitude of destination
lon2: Longitude of destination
readCache: True if attempt should be made to read route(s) from cache
writeCache: True if API-determined route should be written to cache
Returns:
dict: dictionary conversion of routes object returned from OSRM API
"""
if self.debug:
print ('latlon in getroute', lat1,lon1,lat2,lon2)

# form the URL fragment for Origin;Destination. can use as key in cache
k = "%f,%f;%f,%f" % (lat1,lon1,lat2,lon2)
action = ""
url = ("%s/%s?overview=false&alternatives=true&steps=true&hints=;" %
(self.apiurl,k))
if self.debug:
print(("URL %s" % url))
r = requests.get(url)
r = r.json()

# adjust travel time based on factor, because OSRM uses posted
# speed limits, not traffic-based travel times
if self.factor != 1:
r['routes'][0]['duration'] = r['routes'][0]['duration'] * self.factor
if self.debug:
print( "[%s]%s" % (k,action) )
print( r )
if r['code'] != 'Ok': raise NoRouteException("Couldn't find route for (%f,%f) -> (%f,%f): %s",lat1,lon1,lat2,lon2,r)
return r
```

Again, the fetching and parsing are handled by the requests library, with the lines

```
r = requests.get(url)
r = r.json()
```

The response from the OSRM service is in JSON by default. You might
need to set a flag for the google service.

Finally, for whatever service you use, I recommend caching data
locally. These calls are slow and the underlying data doesn't really
change very much.

Hope that helps,

James
> --
> You received this message because you are subscribed to the Google Groups "or-tools-discuss" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to or-tools-discu...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/or-tools-discuss/9c5db00d-89d6-478d-a192-f1ef744bd4e6%40googlegroups.com.


--

James E. Marca
signature.asc
Reply all
Reply to author
Forward
0 new messages