Skip to content

Commit

Permalink
Merge pull request #3 from enricodvn/development
Browse files Browse the repository at this point in the history
release 0.0.2
  • Loading branch information
enricodvn authored Mar 9, 2020
2 parents 9b78f50 + db29b4f commit c005269
Show file tree
Hide file tree
Showing 8 changed files with 177 additions and 123 deletions.
28 changes: 28 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Changelog
All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
- CLI tools
- Windows and MacOS wheels
- Table api
- Trip api
- Nearest api

## [0.0.2] - 2020-03-08
### Changed
- Now path parameter is optional, and you can use either a valid path or
use_shared_memory=True to initialize a PyOSRM object

### Added
- path or use_shared_memory validation on PyOSRM object initialization

## [0.0.1] - 2020-03-03
### Added
- PyOSRM class with working route method
- RouterResult class
- Status enum
- Working examples on readme and tests
- test data unprocessed (raw) and preprocessed for CH and MLD
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,19 @@ python setup.py build_ext --inplace
```

## Usage
It is most likely you will need to install osrm-backend first to pre-process the data, since this package does not provide the cli tools to do it yet. Follow the instructions in the [project wiki](https://github.com/Project-OSRM/osrm-backend/wiki/Running-OSRM#quickstart) to pre-process the data using the desired algorithm (CH or MLD).
If you installed pyosrm using pip, you don't need to have osrm-backend installed, but it is most likely you will it first to pre-process the data, since this package does not provide the cli tools to do it yet. Follow the instructions in the [project wiki](https://github.com/Project-OSRM/osrm-backend/wiki/Running-OSRM#quickstart) to pre-process the data using the desired algorithm (CH or MLD).

To create a PyOSRM object, you need to pass the path to the pre-processed data, and the algorithm (default 'CH' or 'MLD').
```
import pyosrm
router = posrm.PyOSRM("tests/data/ch/monaco-latest.osrm")
```
For large datasets, it may be required [a lot of RAM](https://github.com/Project-OSRM/osrm-backend/wiki/Disk-and-Memory-Requirements) to run osrm. For this reason, if you have more than one python process instanciating a PyOSRM object, it is recommended to use shared memory instead.
```
import pyosrm
router = posrm.PyOSRM(use_shared_memory=True)
```
Refer to the [documentation](https://github.com/Project-OSRM/osrm-backend/wiki/Configuring-and-using-Shared-Memory) for more information about using shared memory with osrm.
### Route
To use the Route API, you just need to pass a list of coordinate pairs in format [lon, lat]. The easiest way to get the result is by using the RouteResult.json method, which formats the data in a easily serializable dictionary like the original API [result object](http://project-osrm.org/docs/v5.22.0/api/?language=cURL#result-objects).
```
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@

setup(
name='pyosrm',
version='0.0.1',
version='0.0.2',
license='MIT',
description='Cython wrapper of osrm-backend to be used in Python',
long_description=long_description,
Expand Down
8 changes: 4 additions & 4 deletions src/boost.pxd
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from libcpp.vector cimport vector

cdef extern from "filesystem.hpp" namespace "boost::filesystem":
cdef cppclass path:
pass
cdef cppclass path:
pass

cdef extern from "optional.hpp" namespace "boost::optional_ns":
cdef cppclass optional[T]:
pass
cdef cppclass optional[T]:
pass
216 changes: 108 additions & 108 deletions src/osrm.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -5,133 +5,133 @@ from libcpp.unordered_map cimport unordered_map
from boost cimport path, optional

cdef extern from "storage/storage_config.hpp" namespace "osrm::storage":
cdef cppclass IOConfig:
IOConfig (vector[path] required_input_files_,
vector[path] optional_input_files_,
vector[path] output_files_) except +
bool IsValid()
path GetPath(string& fileName)
path base_path

cdef cppclass StorageConfig(IOConfig):
StorageConfig(path& base)
StorageConfig(char* base)
cdef cppclass IOConfig:
IOConfig (vector[path] required_input_files_,
vector[path] optional_input_files_,
vector[path] output_files_) except +
bool IsValid()
path GetPath(string& fileName)
path base_path

cdef cppclass StorageConfig(IOConfig):
StorageConfig(path& base)
StorageConfig(char* base)

cdef extern from "engine_config.hpp" namespace "osrm":
ctypedef enum Algorithm:
CH "osrm::EngineConfig::Algorithm::CH"
MLD "osrm::EngineConfig::Algorithm::MLD"

struct EngineConfig:
bool IsValid()
StorageConfig storage_config
int max_locations_trip
int max_locations_viaroute
int max_locations_distance_table
int max_locations_map_matching
double max_radius_map_matching
int max_results_nearest
int max_alternatives
bool use_shared_memory
path memory_file
bool use_mmap
Algorithm algorithm
string verbosity
string dataset_name
ctypedef enum Algorithm:
CH "osrm::EngineConfig::Algorithm::CH"
MLD "osrm::EngineConfig::Algorithm::MLD"

struct EngineConfig:
bool IsValid()
StorageConfig storage_config
int max_locations_trip
int max_locations_viaroute
int max_locations_distance_table
int max_locations_map_matching
double max_radius_map_matching
int max_results_nearest
int max_alternatives
bool use_shared_memory
path memory_file
bool use_mmap
Algorithm algorithm
string verbosity
string dataset_name

cdef extern from "status.hpp" namespace "osrm::engine":
ctypedef enum Status:
Ok "osrm::engine::Status::Ok"
Error "osrm::engine::Status::Error"
ctypedef enum Status:
Ok "osrm::engine::Status::Ok"
Error "osrm::engine::Status::Error"

cdef extern from "bearing.hpp" namespace "osrm":
struct Bearing:
short bearing
short range
bool IsValid()
struct Bearing:
short bearing
short range
bool IsValid()

cdef extern from "approach.hpp" namespace "osrm":
cdef cppclass Approach:
pass
cdef cppclass Approach:
pass

cdef extern from "engine/hint.hpp" namespace "osrm::engine":
struct Hint:
pass
struct Hint:
pass

cdef extern from "util/coordinate.hpp" namespace "osrm::util":
cdef cppclass FixedLongitude:
pass
cdef cppclass FixedLatitude:
pass
cdef cppclass FloatLongitude:
# pass
FloatLongitude()
FloatLongitude(double)
double __value
cdef cppclass FloatLatitude:
# pass
FloatLatitude()
FloatLatitude(double)
double __value
cdef cppclass Coordinate:
FixedLongitude lon
FixedLatitude lat
Coordinate()
Coordinate(FixedLongitude lon_, FixedLatitude lat_)
Coordinate(FloatLongitude lon_, FloatLatitude lat_)
bool IsValid()
cdef cppclass FixedLongitude:
pass
cdef cppclass FixedLatitude:
pass
cdef cppclass FloatLongitude:
# pass
FloatLongitude()
FloatLongitude(double)
double __value
cdef cppclass FloatLatitude:
# pass
FloatLatitude()
FloatLatitude(double)
double __value
cdef cppclass Coordinate:
FixedLongitude lon
FixedLatitude lat
Coordinate()
Coordinate(FixedLongitude lon_, FixedLatitude lat_)
Coordinate(FloatLongitude lon_, FloatLatitude lat_)
bool IsValid()

cdef extern from "engine/api/base_parameters.hpp" namespace "osrm::engine::api":
cdef cppclass SnappingType:
pass
# Default "osrm::engine::api::BaseParameters::SnappingType::Default"
# Any "osrm::engine::api::BaseParameters::SnappingType::Any"

cdef cppclass OutputFormatType:
pass
# JSON "osrm::engine::api::BaseParameters::OutputFormatType::JSON"
# FLATBUFFERS "osrm::engine::api::BaseParameters::OutputFormatType::FLATBUFFERS"

cdef cppclass BaseParameters:
BaseParameters(vector[Coordinate] coordinates_, vector[optional[Hint]] hints_,
vector[optional[double]] radiuses_, vector[optional[Bearing]] bearings_,
vector[optional[Approach]] approaches_, bool generate_hints_,
vector[string] exclude, SnappingType snapping_)
vector[Coordinate] coordinates
vector[optional[Hint]] hints
vector[optional[double]] radiuses
vector[optional[Bearing]] bearings
vector[optional[Approach]] approaches
vector[string] exclude
optional[OutputFormatType] format
bool generate_hints
bool skip_waypoints
SnappingType snapping
cdef cppclass SnappingType:
pass
# Default "osrm::engine::api::BaseParameters::SnappingType::Default"
# Any "osrm::engine::api::BaseParameters::SnappingType::Any"

cdef cppclass OutputFormatType:
pass
# JSON "osrm::engine::api::BaseParameters::OutputFormatType::JSON"
# FLATBUFFERS "osrm::engine::api::BaseParameters::OutputFormatType::FLATBUFFERS"

cdef cppclass BaseParameters:
BaseParameters(vector[Coordinate] coordinates_, vector[optional[Hint]] hints_,
vector[optional[double]] radiuses_, vector[optional[Bearing]] bearings_,
vector[optional[Approach]] approaches_, bool generate_hints_,
vector[string] exclude, SnappingType snapping_)
vector[Coordinate] coordinates
vector[optional[Hint]] hints
vector[optional[double]] radiuses
vector[optional[Bearing]] bearings
vector[optional[Approach]] approaches
vector[string] exclude
optional[OutputFormatType] format
bool generate_hints
bool skip_waypoints
SnappingType snapping

cdef extern from "route_parameters.hpp" namespace "osrm":
cdef cppclass RouteParameters(BaseParameters):
pass
cdef cppclass RouteParameters(BaseParameters):
pass

cdef extern from "util/json_container.hpp" namespace "osrm::util::json":
cdef cppclass Value:
T get[T]()
cdef cppclass _JsonObject "osrm::util::json::Object":
unordered_map[string, Value] values
_JsonObject()
struct _Number "osrm::util::json::Number":
double value
struct _Array "osrm::util::json::Array":
vector[Value] values
struct _String "osrm::util::json::String":
string value
cdef cppclass Value:
T get[T]()
cdef cppclass _JsonObject "osrm::util::json::Object":
unordered_map[string, Value] values
_JsonObject()
struct _Number "osrm::util::json::Number":
double value
struct _Array "osrm::util::json::Array":
vector[Value] values
struct _String "osrm::util::json::String":
string value

cdef extern from "engine/api/base_result.hpp" namespace "osrm::engine::api":
cdef cppclass ResultT:
ResultT(_JsonObject value)
T get[T]()
cdef cppclass ResultT:
ResultT(_JsonObject value)
T get[T]()

cdef extern from "osrm.hpp" namespace "osrm":
cdef cppclass OSRM:
OSRM() except +
OSRM(EngineConfig &config) except +
Status Route(RouteParameters &parameters, ResultT &result)
cdef cppclass OSRM:
OSRM() except +
OSRM(EngineConfig &config) except +
Status Route(RouteParameters &parameters, ResultT &result)
17 changes: 11 additions & 6 deletions src/pyosrm/core.pyx
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
cimport osrm
from enum import Enum
import os

cdef class PyOSRM:
cdef:
osrm.OSRM* _thisptr

def __cinit__(self, path, algorithm="CH", use_shared_memory=False):
encoded_path = path.encode("UTF-8")
def __cinit__(self, path="", algorithm="CH", use_shared_memory=False):
cdef osrm.EngineConfig engine_config
cdef char* path_c = encoded_path
cdef osrm.StorageConfig *store_config = new osrm.StorageConfig(path_c)
engine_config.storage_config = store_config[0]
cdef char* path_c
cdef osrm.StorageConfig *store_config
if os.path.exists(path):
encoded_path = path.encode("UTF-8")
path_c = encoded_path
store_config = new osrm.StorageConfig(path_c)
engine_config.storage_config = store_config[0]
elif not use_shared_memory:
raise ValueError("You need either a valid path or use_shared_memory True")
engine_config.use_shared_memory = use_shared_memory

if algorithm=="CH":
engine_config.algorithm = osrm.Algorithm.CH
elif algorithm=="MLD":
Expand Down
3 changes: 2 additions & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
import pyosrm

@pytest.fixture(params=[{"algorithm": 'CH', "path": "tests/data/ch/monaco-latest.osrm"},
{"algorithm": 'MLD', "path": "tests/data/mld/monaco-latest.osrm"}])
{"algorithm": 'MLD', "path": "tests/data/mld/monaco-latest.osrm"}],
scope='session')
def initialized_router_instance(request):
router = pyosrm.PyOSRM(request.param["path"], algorithm=request.param["algorithm"])
return router
18 changes: 16 additions & 2 deletions tests/func/test_route.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@

valid_coords = ([[7.419758, 43.731142], [7.419505, 43.736825]], )

@pytest.fixture(params=valid_coords)
@pytest.fixture(params=valid_coords, scope='class')
def valid_route_result(request, initialized_router_instance):
return initialized_router_instance.route(request.param)

@pytest.fixture()
@pytest.fixture(scope='class')
def valid_result_dict(valid_route_result):
return valid_route_result.json()

Expand Down Expand Up @@ -81,3 +81,17 @@ def test_location_in_waypoint_dicts(self, valid_result_dict):

def test_code_in_result_dict(self, valid_result_dict):
assert "code" in valid_result_dict and valid_result_dict["code"] == "Ok"

class TestRouteExceptions:

def test_invalid_path_initialization(self):
with pytest.raises(ValueError):
pyosrm.PyOSRM("")

def test_no_parameters_initialization(self):
with pytest.raises(ValueError):
pyosrm.PyOSRM()

def test_invalid_algorithm_parameter(self):
with pytest.raises(ValueError):
pyosrm.PyOSRM("/", algorithm="dijkstra")

0 comments on commit c005269

Please sign in to comment.