From 83d9ef4bd3a53b4a08e23d7baf4aee5371b24341 Mon Sep 17 00:00:00 2001 From: Enrico Davini Date: Sun, 8 Mar 2020 22:13:23 -0300 Subject: [PATCH 1/7] scopes on test fixtures --- tests/conftest.py | 3 ++- tests/func/test_route.py | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 84c31ee..871c75f 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -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 diff --git a/tests/func/test_route.py b/tests/func/test_route.py index 92a22ca..9b78931 100644 --- a/tests/func/test_route.py +++ b/tests/func/test_route.py @@ -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() From b05e7b9f8bc99b8b7d85c6c7f8139f4b4ff581ac Mon Sep 17 00:00:00 2001 From: Enrico Davini Date: Sun, 8 Mar 2020 22:17:24 -0300 Subject: [PATCH 2/7] fixed identation on pxd files --- src/boost.pxd | 8 +- src/osrm.pxd | 216 +++++++++++++++++++++++++------------------------- 2 files changed, 112 insertions(+), 112 deletions(-) diff --git a/src/boost.pxd b/src/boost.pxd index 39dcb9f..7703abc 100644 --- a/src/boost.pxd +++ b/src/boost.pxd @@ -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 diff --git a/src/osrm.pxd b/src/osrm.pxd index 11fe569..3c3f84a 100644 --- a/src/osrm.pxd +++ b/src/osrm.pxd @@ -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 ¶meters, ResultT &result) + cdef cppclass OSRM: + OSRM() except + + OSRM(EngineConfig &config) except + + Status Route(RouteParameters ¶meters, ResultT &result) From 78f053cb5efd8c01721751f440e4d4ee587c782d Mon Sep 17 00:00:00 2001 From: Enrico Davini Date: Sun, 8 Mar 2020 22:47:13 -0300 Subject: [PATCH 3/7] add changelog --- CHANGELOG.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..89580a5 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,19 @@ +# 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 +- Table api +- Trip api +- Nearest api + +## [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 From ce49644c1067d7ddf6d8e711ceb40fc4f4c7d8b3 Mon Sep 17 00:00:00 2001 From: Enrico Davini Date: Sun, 8 Mar 2020 23:13:05 -0300 Subject: [PATCH 4/7] add TestRouteExceptions --- tests/func/test_route.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/func/test_route.py b/tests/func/test_route.py index 9b78931..e3a9f16 100644 --- a/tests/func/test_route.py +++ b/tests/func/test_route.py @@ -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") From 6e9b864239dbf95724bcc2364ee64d8fdd25cf0c Mon Sep 17 00:00:00 2001 From: Enrico Davini Date: Sun, 8 Mar 2020 23:15:31 -0300 Subject: [PATCH 5/7] now path is optional and add validation for path or use_shared_memory initialization --- src/pyosrm/core.pyx | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/pyosrm/core.pyx b/src/pyosrm/core.pyx index b593c05..351fee9 100644 --- a/src/pyosrm/core.pyx +++ b/src/pyosrm/core.pyx @@ -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": From 0f40e5ba95f23b155a8b8005cef0795cf7aed978 Mon Sep 17 00:00:00 2001 From: Enrico Davini Date: Sun, 8 Mar 2020 23:59:35 -0300 Subject: [PATCH 6/7] version bump to 0.0.2 --- CHANGELOG.md | 9 +++++++++ setup.py | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 89580a5..31cd063 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,10 +6,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [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 diff --git a/setup.py b/setup.py index b18c304..37be23f 100644 --- a/setup.py +++ b/setup.py @@ -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, From db29b4f0bcfa4d358f8c18b28a63bcb965701469 Mon Sep 17 00:00:00 2001 From: Enrico Davini Date: Mon, 9 Mar 2020 00:01:14 -0300 Subject: [PATCH 7/7] Update readme --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ccec5a8..7434863 100644 --- a/README.md +++ b/README.md @@ -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). ```