Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8250cd0f10 | |||
| 631c9f2360 | |||
| d8741a39e3 | |||
| d33ff6a897 |
+1
-1
@@ -365,7 +365,7 @@ install:
|
|||||||
script:
|
script:
|
||||||
- if [[ $TARGET_ARCH == armhf ]] ; then echo "Skip tests for $TARGET_ARCH" && exit 0 ; fi
|
- if [[ $TARGET_ARCH == armhf ]] ; then echo "Skip tests for $TARGET_ARCH" && exit 0 ; fi
|
||||||
- make -C test/data benchmark
|
- make -C test/data benchmark
|
||||||
# - ./example/build/osrm-example test/data/mld/monaco.osrm
|
- ./example/build/osrm-example test/data/mld/monaco.osrm
|
||||||
# All tests assume to be run from the build directory
|
# All tests assume to be run from the build directory
|
||||||
- pushd ${OSRM_BUILD_DIR}
|
- pushd ${OSRM_BUILD_DIR}
|
||||||
- ./unit_tests/library-tests
|
- ./unit_tests/library-tests
|
||||||
|
|||||||
+2
-7
@@ -1,16 +1,11 @@
|
|||||||
# UNRELEASED
|
# UNRELEASED
|
||||||
- Changes from 5.19.0:
|
|
||||||
- Features:
|
|
||||||
- ADDED: direct mmapping of datafiles is now supported via the `-mmap` switch. [#5242](https://github.com/Project-OSRM/osrm-backend/pull/5242)
|
|
||||||
- REMOVED: the previous `--memory_file` switch is now deprecated and will fallback to `--mmap` [#5242](https://github.com/Project-OSRM/osrm-backend/pull/5242)
|
|
||||||
|
|
||||||
# 5.19.0
|
|
||||||
- Changes from 5.18.0:
|
- Changes from 5.18.0:
|
||||||
- Optimizations:
|
- Optimizations:
|
||||||
|
- CHANGED: Map matching is now almost twice as fast. [#5060](https://github.com/Project-OSRM/osrm-backend/pull/5060)
|
||||||
- CHANGED: Use Grisu2 for serializing floating point numbers. [#5188](https://github.com/Project-OSRM/osrm-backend/pull/5188)
|
- CHANGED: Use Grisu2 for serializing floating point numbers. [#5188](https://github.com/Project-OSRM/osrm-backend/pull/5188)
|
||||||
- ADDED: Node bindings can return pre-rendered JSON buffer. [#5189](https://github.com/Project-OSRM/osrm-backend/pull/5189)
|
|
||||||
- Bugfixes:
|
- Bugfixes:
|
||||||
- FIXED: collapsing of ExitRoundabout instructions [#5114](https://github.com/Project-OSRM/osrm-backend/issues/5114)
|
- FIXED: collapsing of ExitRoundabout instructions [#5114](https://github.com/Project-OSRM/osrm-backend/issues/5114)
|
||||||
|
- FIXED: negative distances in table plugin annotation [#5106](https://github.com/Project-OSRM/osrm-backend/issues/5106)
|
||||||
- Misc:
|
- Misc:
|
||||||
- CHANGED: Support up to 512 named shared memory regions [#5185](https://github.com/Project-OSRM/osrm-backend/pull/5185)
|
- CHANGED: Support up to 512 named shared memory regions [#5185](https://github.com/Project-OSRM/osrm-backend/pull/5185)
|
||||||
|
|
||||||
|
|||||||
@@ -297,29 +297,6 @@ Returns **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refer
|
|||||||
2) `waypoint_index`: index of the point in the trip.
|
2) `waypoint_index`: index of the point in the trip.
|
||||||
**`trips`**: an array of [`Route`](#route) objects that assemble the trace.
|
**`trips`**: an array of [`Route`](#route) objects that assemble the trace.
|
||||||
|
|
||||||
## Plugin behaviour
|
|
||||||
|
|
||||||
All plugins support a second additional object that is available to configure some NodeJS specific behaviours.
|
|
||||||
|
|
||||||
- `plugin_config` **[Object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object)** Object literal containing parameters for the trip query.
|
|
||||||
- `plugin_config.format` **[String](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String)?** The format of the result object to various API calls. Valid options are `object` (default), which returns a standard Javascript object, as described above, and `json_buffer`, which will return a NodeJS **[Buffer](https://nodejs.org/api/buffer.html)** object, containing a JSON string. The latter has the advantage that it can be immediately serialized to disk/sent over the network, and the generation of the string is performed outside the main NodeJS event loop. This option is ignored by the `tile` plugin.
|
|
||||||
|
|
||||||
**Examples**
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
var osrm = new OSRM('network.osrm');
|
|
||||||
var options = {
|
|
||||||
coordinates: [
|
|
||||||
[13.36761474609375, 52.51663871100423],
|
|
||||||
[13.374481201171875, 52.506191342034576]
|
|
||||||
]
|
|
||||||
};
|
|
||||||
osrm.route(options, { format: "json_buffer" }, function(err, response) {
|
|
||||||
if (err) throw err;
|
|
||||||
console.log(response.toString("utf-8"));
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## Responses
|
## Responses
|
||||||
|
|
||||||
Responses
|
Responses
|
||||||
|
|||||||
@@ -84,47 +84,7 @@ class OSRMDirectLoader extends OSRMBaseLoader {
|
|||||||
throw new Error(util.format('osrm-routed %s: %s', errorReason(err), err.cmd));
|
throw new Error(util.format('osrm-routed %s: %s', errorReason(err), err.cmd));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
callback();
|
||||||
this.child.readyFunc = (data) => {
|
|
||||||
if (/running and waiting for requests/.test(data)) {
|
|
||||||
this.child.stdout.removeListener('data', this.child.readyFunc);
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
this.child.stdout.on('data',this.child.readyFunc);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class OSRMmmapLoader extends OSRMBaseLoader {
|
|
||||||
constructor (scope) {
|
|
||||||
super(scope);
|
|
||||||
}
|
|
||||||
|
|
||||||
load (inputFile, callback) {
|
|
||||||
this.inputFile = inputFile;
|
|
||||||
this.shutdown(() => {
|
|
||||||
this.launch(callback);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
osrmUp (callback) {
|
|
||||||
if (this.osrmIsRunning()) return callback(new Error("osrm-routed already running!"));
|
|
||||||
|
|
||||||
const command_arguments = util.format('%s -p %d -i %s -a %s --mmap', this.inputFile, this.scope.OSRM_PORT, this.scope.OSRM_IP, this.scope.ROUTING_ALGORITHM);
|
|
||||||
this.child = this.scope.runBin('osrm-routed', command_arguments, this.scope.environment, (err) => {
|
|
||||||
if (err && err.signal !== 'SIGINT') {
|
|
||||||
this.child = null;
|
|
||||||
throw new Error(util.format('osrm-routed %s: %s', errorReason(err), err.cmd));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.child.readyFunc = (data) => {
|
|
||||||
if (/running and waiting for requests/.test(data)) {
|
|
||||||
this.child.stdout.removeListener('data', this.child.readyFunc);
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
this.child.stdout.on('data',this.child.readyFunc);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -175,32 +135,22 @@ class OSRMLoader {
|
|||||||
this.scope = scope;
|
this.scope = scope;
|
||||||
this.sharedLoader = new OSRMDatastoreLoader(this.scope);
|
this.sharedLoader = new OSRMDatastoreLoader(this.scope);
|
||||||
this.directLoader = new OSRMDirectLoader(this.scope);
|
this.directLoader = new OSRMDirectLoader(this.scope);
|
||||||
this.mmapLoader = new OSRMmmapLoader(this.scope);
|
|
||||||
this.method = scope.DEFAULT_LOAD_METHOD;
|
this.method = scope.DEFAULT_LOAD_METHOD;
|
||||||
}
|
}
|
||||||
|
|
||||||
load (inputFile, callback) {
|
load (inputFile, callback) {
|
||||||
if (!this.loader) {
|
|
||||||
this.loader = {shutdown: (cb) => cb() };
|
|
||||||
}
|
|
||||||
if (this.method === 'datastore') {
|
if (this.method === 'datastore') {
|
||||||
this.loader.shutdown((err) => {
|
this.directLoader.shutdown((err) => {
|
||||||
if (err) return callback(err);
|
if (err) return callback(err);
|
||||||
this.loader = this.sharedLoader;
|
this.loader = this.sharedLoader;
|
||||||
this.sharedLoader.load(inputFile, callback);
|
this.sharedLoader.load(inputFile, callback);
|
||||||
});
|
});
|
||||||
} else if (this.method === 'directly') {
|
} else if (this.method === 'directly') {
|
||||||
this.loader.shutdown((err) => {
|
this.sharedLoader.shutdown((err) => {
|
||||||
if (err) return callback(err);
|
if (err) return callback(err);
|
||||||
this.loader = this.directLoader;
|
this.loader = this.directLoader;
|
||||||
this.directLoader.load(inputFile, callback);
|
this.directLoader.load(inputFile, callback);
|
||||||
});
|
});
|
||||||
} else if (this.method === 'mmap') {
|
|
||||||
this.loader.shutdown((err) => {
|
|
||||||
if (err) return callback(err);
|
|
||||||
this.loader = this.mmapLoader;
|
|
||||||
this.mmapLoader.load(inputFile, callback);
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
callback(new Error('*** Unknown load method ' + method));
|
callback(new Error('*** Unknown load method ' + method));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ module.exports = function () {
|
|||||||
this.DEFAULT_ENVIRONMENT = Object.assign({STXXLCFG: stxxl_config}, process.env);
|
this.DEFAULT_ENVIRONMENT = Object.assign({STXXLCFG: stxxl_config}, process.env);
|
||||||
this.DEFAULT_PROFILE = 'bicycle';
|
this.DEFAULT_PROFILE = 'bicycle';
|
||||||
this.DEFAULT_INPUT_FORMAT = 'osm';
|
this.DEFAULT_INPUT_FORMAT = 'osm';
|
||||||
this.DEFAULT_LOAD_METHOD = process.argv[process.argv.indexOf('-m') +1].match('mmap') ? 'mmap' : 'datastore';
|
this.DEFAULT_LOAD_METHOD = 'datastore';
|
||||||
this.DEFAULT_ORIGIN = [1,1];
|
this.DEFAULT_ORIGIN = [1,1];
|
||||||
this.OSM_USER = 'osrm';
|
this.OSM_USER = 'osrm';
|
||||||
this.OSM_UID = 1;
|
this.OSM_UID = 1;
|
||||||
|
|||||||
@@ -792,4 +792,4 @@ Feature: Basic Map Matching
|
|||||||
When I match I should get
|
When I match I should get
|
||||||
| trace | geometry | a:distance | a:duration | a:weight | duration |
|
| trace | geometry | a:distance | a:duration | a:weight | duration |
|
||||||
| 2345 | 1.00018,1,1.000315,1 | 15.013264 | 1.5 | 1.5 | 1.5 |
|
| 2345 | 1.00018,1,1.000315,1 | 15.013264 | 1.5 | 1.5 | 1.5 |
|
||||||
| 4321 | 1.00027,1,1.000135,1 | 15.013264 | 1.5 | 1.5 | 1.5 |
|
| 4321 | 1.00027,1,1.000135,1 | 15.013264 | 1.5 | 1.5 | 1.5 |
|
||||||
|
|||||||
@@ -10,7 +10,6 @@
|
|||||||
#include <boost/iostreams/device/mapped_file.hpp>
|
#include <boost/iostreams/device/mapped_file.hpp>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace osrm
|
namespace osrm
|
||||||
{
|
{
|
||||||
@@ -25,7 +24,8 @@ namespace datafacade
|
|||||||
class MMapMemoryAllocator : public ContiguousBlockAllocator
|
class MMapMemoryAllocator : public ContiguousBlockAllocator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit MMapMemoryAllocator(const storage::StorageConfig &config);
|
explicit MMapMemoryAllocator(const storage::StorageConfig &config,
|
||||||
|
const boost::filesystem::path &memory_file);
|
||||||
~MMapMemoryAllocator() override final;
|
~MMapMemoryAllocator() override final;
|
||||||
|
|
||||||
// interface to give access to the datafacades
|
// interface to give access to the datafacades
|
||||||
@@ -33,8 +33,8 @@ class MMapMemoryAllocator : public ContiguousBlockAllocator
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
storage::SharedDataIndex index;
|
storage::SharedDataIndex index;
|
||||||
std::vector<boost::iostreams::mapped_file> mapped_memory_files;
|
util::vector_view<char> mapped_memory;
|
||||||
std::string rtree_filename;
|
boost::iostreams::mapped_file mapped_memory_file;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace datafacade
|
} // namespace datafacade
|
||||||
|
|||||||
@@ -32,8 +32,9 @@ class ExternalProvider final : public DataFacadeProvider<AlgorithmT, FacadeT>
|
|||||||
public:
|
public:
|
||||||
using Facade = typename DataFacadeProvider<AlgorithmT, FacadeT>::Facade;
|
using Facade = typename DataFacadeProvider<AlgorithmT, FacadeT>::Facade;
|
||||||
|
|
||||||
ExternalProvider(const storage::StorageConfig &config)
|
ExternalProvider(const storage::StorageConfig &config,
|
||||||
: facade_factory(std::make_shared<datafacade::MMapMemoryAllocator>(config))
|
const boost::filesystem::path &memory_file)
|
||||||
|
: facade_factory(std::make_shared<datafacade::MMapMemoryAllocator>(config, memory_file))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,7 +94,7 @@ class WatchingProvider : public DataFacadeProvider<AlgorithmT, FacadeT>
|
|||||||
return watchdog.Get(params);
|
return watchdog.Get(params);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace detail
|
}
|
||||||
|
|
||||||
template <typename AlgorithmT>
|
template <typename AlgorithmT>
|
||||||
using DataFacadeProvider = detail::DataFacadeProvider<AlgorithmT, DataFacade>;
|
using DataFacadeProvider = detail::DataFacadeProvider<AlgorithmT, DataFacade>;
|
||||||
@@ -103,7 +104,7 @@ template <typename AlgorithmT>
|
|||||||
using ImmutableProvider = detail::ImmutableProvider<AlgorithmT, DataFacade>;
|
using ImmutableProvider = detail::ImmutableProvider<AlgorithmT, DataFacade>;
|
||||||
template <typename AlgorithmT>
|
template <typename AlgorithmT>
|
||||||
using ExternalProvider = detail::ExternalProvider<AlgorithmT, DataFacade>;
|
using ExternalProvider = detail::ExternalProvider<AlgorithmT, DataFacade>;
|
||||||
} // namespace engine
|
}
|
||||||
} // namespace osrm
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -63,16 +63,12 @@ template <typename Algorithm> class Engine final : public EngineInterface
|
|||||||
<< "\" with algorithm " << routing_algorithms::name<Algorithm>();
|
<< "\" with algorithm " << routing_algorithms::name<Algorithm>();
|
||||||
facade_provider = std::make_unique<WatchingProvider<Algorithm>>(config.dataset_name);
|
facade_provider = std::make_unique<WatchingProvider<Algorithm>>(config.dataset_name);
|
||||||
}
|
}
|
||||||
else if (!config.memory_file.empty() || config.use_mmap)
|
else if (!config.memory_file.empty())
|
||||||
{
|
{
|
||||||
if (!config.memory_file.empty())
|
util::Log(logDEBUG) << "Using memory mapped filed at " << config.memory_file
|
||||||
{
|
<< " with algorithm " << routing_algorithms::name<Algorithm>();
|
||||||
util::Log(logWARNING)
|
facade_provider = std::make_unique<ExternalProvider<Algorithm>>(config.storage_config,
|
||||||
<< "The 'memory_file' option is DEPRECATED - using direct mmaping instead";
|
config.memory_file);
|
||||||
}
|
|
||||||
util::Log(logDEBUG) << "Using direct memory mapping with algorithm "
|
|
||||||
<< routing_algorithms::name<Algorithm>();
|
|
||||||
facade_provider = std::make_unique<ExternalProvider<Algorithm>>(config.storage_config);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -138,7 +134,7 @@ template <typename Algorithm> class Engine final : public EngineInterface
|
|||||||
const plugins::MatchPlugin match_plugin;
|
const plugins::MatchPlugin match_plugin;
|
||||||
const plugins::TilePlugin tile_plugin;
|
const plugins::TilePlugin tile_plugin;
|
||||||
};
|
};
|
||||||
} // namespace engine
|
}
|
||||||
} // namespace osrm
|
}
|
||||||
|
|
||||||
#endif // OSRM_IMPL_HPP
|
#endif // OSRM_IMPL_HPP
|
||||||
|
|||||||
@@ -89,12 +89,11 @@ struct EngineConfig final
|
|||||||
int max_alternatives = 3; // set an arbitrary upper bound; can be adjusted by user
|
int max_alternatives = 3; // set an arbitrary upper bound; can be adjusted by user
|
||||||
bool use_shared_memory = true;
|
bool use_shared_memory = true;
|
||||||
boost::filesystem::path memory_file;
|
boost::filesystem::path memory_file;
|
||||||
bool use_mmap = true;
|
|
||||||
Algorithm algorithm = Algorithm::CH;
|
Algorithm algorithm = Algorithm::CH;
|
||||||
std::string verbosity;
|
std::string verbosity;
|
||||||
std::string dataset_name;
|
std::string dataset_name;
|
||||||
};
|
};
|
||||||
} // namespace engine
|
}
|
||||||
} // namespace osrm
|
}
|
||||||
|
|
||||||
#endif // SERVER_CONFIG_HPP
|
#endif // SERVER_CONFIG_HPP
|
||||||
|
|||||||
@@ -449,6 +449,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
const auto reverse_durations = datafacade.GetUncompressedReverseDurations(geometry_id);
|
const auto reverse_durations = datafacade.GetUncompressedReverseDurations(geometry_id);
|
||||||
|
|
||||||
const auto forward_geometry = datafacade.GetUncompressedForwardGeometry(geometry_id);
|
const auto forward_geometry = datafacade.GetUncompressedForwardGeometry(geometry_id);
|
||||||
|
const auto reverse_geometry = datafacade.GetUncompressedReverseGeometry(geometry_id);
|
||||||
|
|
||||||
const auto forward_weight_offset =
|
const auto forward_weight_offset =
|
||||||
std::accumulate(forward_weights.begin(),
|
std::accumulate(forward_weights.begin(),
|
||||||
@@ -479,19 +480,19 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
datafacade.GetCoordinateOfNode(forward_geometry(data.fwd_segment_position)),
|
datafacade.GetCoordinateOfNode(forward_geometry(data.fwd_segment_position)),
|
||||||
point_on_segment);
|
point_on_segment);
|
||||||
|
|
||||||
const auto reverse_weight_offset =
|
const auto rev_segment_position = reverse_weights.size() - data.fwd_segment_position - 1;
|
||||||
std::accumulate(reverse_weights.begin(),
|
|
||||||
reverse_weights.end() - data.fwd_segment_position - 1,
|
const auto reverse_weight_offset = std::accumulate(
|
||||||
EdgeWeight{0});
|
reverse_weights.begin(), reverse_weights.begin() + rev_segment_position, EdgeWeight{0});
|
||||||
|
|
||||||
const auto reverse_duration_offset =
|
const auto reverse_duration_offset =
|
||||||
std::accumulate(reverse_durations.begin(),
|
std::accumulate(reverse_durations.begin(),
|
||||||
reverse_durations.end() - data.fwd_segment_position - 1,
|
reverse_durations.begin() + rev_segment_position,
|
||||||
EdgeDuration{0});
|
EdgeDuration{0});
|
||||||
|
|
||||||
EdgeDistance reverse_distance_offset = 0;
|
EdgeDistance reverse_distance_offset = 0;
|
||||||
for (auto current = forward_geometry.begin();
|
for (auto current = reverse_geometry.begin();
|
||||||
current < forward_geometry.end() - data.fwd_segment_position - 2;
|
current < reverse_geometry.begin() + rev_segment_position;
|
||||||
++current)
|
++current)
|
||||||
{
|
{
|
||||||
reverse_distance_offset += util::coordinate_calculation::fccApproximateDistance(
|
reverse_distance_offset += util::coordinate_calculation::fccApproximateDistance(
|
||||||
@@ -499,13 +500,11 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
datafacade.GetCoordinateOfNode(*std::next(current)));
|
datafacade.GetCoordinateOfNode(*std::next(current)));
|
||||||
}
|
}
|
||||||
|
|
||||||
EdgeWeight reverse_weight =
|
EdgeWeight reverse_weight = reverse_weights[rev_segment_position];
|
||||||
reverse_weights[reverse_weights.size() - data.fwd_segment_position - 1];
|
EdgeDuration reverse_duration = reverse_durations[rev_segment_position];
|
||||||
EdgeDuration reverse_duration =
|
|
||||||
reverse_durations[reverse_durations.size() - data.fwd_segment_position - 1];
|
|
||||||
EdgeDistance reverse_distance = util::coordinate_calculation::fccApproximateDistance(
|
EdgeDistance reverse_distance = util::coordinate_calculation::fccApproximateDistance(
|
||||||
point_on_segment,
|
point_on_segment,
|
||||||
datafacade.GetCoordinateOfNode(forward_geometry(data.fwd_segment_position + 1)));
|
datafacade.GetCoordinateOfNode(reverse_geometry(rev_segment_position)));
|
||||||
|
|
||||||
ratio = std::min(1.0, std::max(0.0, ratio));
|
ratio = std::min(1.0, std::max(0.0, ratio));
|
||||||
if (data.forward_segment_id.id != SPECIAL_SEGMENTID)
|
if (data.forward_segment_id.id != SPECIAL_SEGMENTID)
|
||||||
@@ -693,7 +692,7 @@ template <typename RTreeT, typename DataFacadeT> class GeospatialQuery
|
|||||||
const CoordinateList &coordinates;
|
const CoordinateList &coordinates;
|
||||||
DataFacadeT &datafacade;
|
DataFacadeT &datafacade;
|
||||||
};
|
};
|
||||||
}
|
} // namespace engine
|
||||||
}
|
} // namespace osrm
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -46,14 +46,15 @@ namespace engine
|
|||||||
struct PhantomNode
|
struct PhantomNode
|
||||||
{
|
{
|
||||||
PhantomNode()
|
PhantomNode()
|
||||||
: forward_segment_id{SPECIAL_SEGMENTID, false},
|
: forward_segment_id{SPECIAL_SEGMENTID, false}, reverse_segment_id{SPECIAL_SEGMENTID,
|
||||||
reverse_segment_id{SPECIAL_SEGMENTID, false}, forward_weight(INVALID_EDGE_WEIGHT),
|
false},
|
||||||
reverse_weight(INVALID_EDGE_WEIGHT), forward_weight_offset(0), reverse_weight_offset(0),
|
forward_weight(INVALID_EDGE_WEIGHT), reverse_weight(INVALID_EDGE_WEIGHT),
|
||||||
|
forward_weight_offset(0), reverse_weight_offset(0),
|
||||||
forward_distance(INVALID_EDGE_DISTANCE), reverse_distance(INVALID_EDGE_DISTANCE),
|
forward_distance(INVALID_EDGE_DISTANCE), reverse_distance(INVALID_EDGE_DISTANCE),
|
||||||
forward_distance_offset(0), reverse_distance_offset(0),
|
forward_distance_offset(0), reverse_distance_offset(0),
|
||||||
forward_duration(MAXIMAL_EDGE_DURATION), reverse_duration(MAXIMAL_EDGE_DURATION),
|
forward_duration(MAXIMAL_EDGE_DURATION), reverse_duration(MAXIMAL_EDGE_DURATION),
|
||||||
forward_duration_offset(0), reverse_duration_offset(0), fwd_segment_position(0),
|
forward_duration_offset(0), reverse_duration_offset(0),
|
||||||
is_valid_forward_source{false}, is_valid_forward_target{false},
|
fwd_segment_position(0), is_valid_forward_source{false}, is_valid_forward_target{false},
|
||||||
is_valid_reverse_source{false}, is_valid_reverse_target{false}, bearing(0)
|
is_valid_reverse_source{false}, is_valid_reverse_target{false}, bearing(0)
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -111,8 +112,9 @@ struct PhantomNode
|
|||||||
|
|
||||||
bool IsValid(const unsigned number_of_nodes) const
|
bool IsValid(const unsigned number_of_nodes) const
|
||||||
{
|
{
|
||||||
return location.IsValid() && ((forward_segment_id.id < number_of_nodes) ||
|
return location.IsValid() &&
|
||||||
(reverse_segment_id.id < number_of_nodes)) &&
|
((forward_segment_id.id < number_of_nodes) ||
|
||||||
|
(reverse_segment_id.id < number_of_nodes)) &&
|
||||||
((forward_weight != INVALID_EDGE_WEIGHT) ||
|
((forward_weight != INVALID_EDGE_WEIGHT) ||
|
||||||
(reverse_weight != INVALID_EDGE_WEIGHT)) &&
|
(reverse_weight != INVALID_EDGE_WEIGHT)) &&
|
||||||
((forward_duration != MAXIMAL_EDGE_DURATION) ||
|
((forward_duration != MAXIMAL_EDGE_DURATION) ||
|
||||||
|
|||||||
@@ -44,44 +44,13 @@ bool needsLoopBackwards(const PhantomNode &source_phantom, const PhantomNode &ta
|
|||||||
bool needsLoopForward(const PhantomNodes &phantoms);
|
bool needsLoopForward(const PhantomNodes &phantoms);
|
||||||
bool needsLoopBackwards(const PhantomNodes &phantoms);
|
bool needsLoopBackwards(const PhantomNodes &phantoms);
|
||||||
|
|
||||||
template <typename Heap>
|
namespace detail
|
||||||
void insertNodesInHeaps(Heap &forward_heap, Heap &reverse_heap, const PhantomNodes &nodes)
|
|
||||||
{
|
{
|
||||||
const auto &source = nodes.source_phantom;
|
template <typename Algorithm>
|
||||||
if (source.IsValidForwardSource())
|
void insertSourceInHeap(typename SearchEngineData<Algorithm>::ManyToManyQueryHeap &heap,
|
||||||
{
|
const PhantomNode &phantom_node)
|
||||||
forward_heap.Insert(source.forward_segment_id.id,
|
|
||||||
-source.GetForwardWeightPlusOffset(),
|
|
||||||
source.forward_segment_id.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (source.IsValidReverseSource())
|
|
||||||
{
|
|
||||||
forward_heap.Insert(source.reverse_segment_id.id,
|
|
||||||
-source.GetReverseWeightPlusOffset(),
|
|
||||||
source.reverse_segment_id.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto &target = nodes.target_phantom;
|
|
||||||
if (target.IsValidForwardTarget())
|
|
||||||
{
|
|
||||||
reverse_heap.Insert(target.forward_segment_id.id,
|
|
||||||
target.GetForwardWeightPlusOffset(),
|
|
||||||
target.forward_segment_id.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target.IsValidReverseTarget())
|
|
||||||
{
|
|
||||||
reverse_heap.Insert(target.reverse_segment_id.id,
|
|
||||||
target.GetReverseWeightPlusOffset(),
|
|
||||||
target.reverse_segment_id.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ManyToManyQueryHeap>
|
|
||||||
void insertSourceInHeap(ManyToManyQueryHeap &heap, const PhantomNode &phantom_node)
|
|
||||||
{
|
{
|
||||||
if (phantom_node.IsValidForwardSource())
|
if (phantom_node.IsValidForwardTarget())
|
||||||
{
|
{
|
||||||
heap.Insert(phantom_node.forward_segment_id.id,
|
heap.Insert(phantom_node.forward_segment_id.id,
|
||||||
-phantom_node.GetForwardWeightPlusOffset(),
|
-phantom_node.GetForwardWeightPlusOffset(),
|
||||||
@@ -89,7 +58,7 @@ void insertSourceInHeap(ManyToManyQueryHeap &heap, const PhantomNode &phantom_no
|
|||||||
-phantom_node.GetForwardDuration(),
|
-phantom_node.GetForwardDuration(),
|
||||||
-phantom_node.GetForwardDistance()});
|
-phantom_node.GetForwardDistance()});
|
||||||
}
|
}
|
||||||
if (phantom_node.IsValidReverseSource())
|
if (phantom_node.IsValidReverseTarget())
|
||||||
{
|
{
|
||||||
heap.Insert(phantom_node.reverse_segment_id.id,
|
heap.Insert(phantom_node.reverse_segment_id.id,
|
||||||
-phantom_node.GetReverseWeightPlusOffset(),
|
-phantom_node.GetReverseWeightPlusOffset(),
|
||||||
@@ -99,8 +68,9 @@ void insertSourceInHeap(ManyToManyQueryHeap &heap, const PhantomNode &phantom_no
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ManyToManyQueryHeap>
|
template <typename Algorithm>
|
||||||
void insertTargetInHeap(ManyToManyQueryHeap &heap, const PhantomNode &phantom_node)
|
void insertTargetInHeap(typename SearchEngineData<Algorithm>::ManyToManyQueryHeap &heap,
|
||||||
|
const PhantomNode &phantom_node)
|
||||||
{
|
{
|
||||||
if (phantom_node.IsValidForwardTarget())
|
if (phantom_node.IsValidForwardTarget())
|
||||||
{
|
{
|
||||||
@@ -120,6 +90,109 @@ void insertTargetInHeap(ManyToManyQueryHeap &heap, const PhantomNode &phantom_no
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Algorithm>
|
||||||
|
void insertSourceInHeap(typename SearchEngineData<Algorithm>::QueryHeap &heap,
|
||||||
|
const PhantomNode &phantom_node)
|
||||||
|
{
|
||||||
|
if (phantom_node.IsValidForwardSource())
|
||||||
|
{
|
||||||
|
heap.Insert(phantom_node.forward_segment_id.id,
|
||||||
|
-phantom_node.GetForwardWeightPlusOffset(),
|
||||||
|
phantom_node.forward_segment_id.id);
|
||||||
|
}
|
||||||
|
if (phantom_node.IsValidReverseSource())
|
||||||
|
{
|
||||||
|
heap.Insert(phantom_node.reverse_segment_id.id,
|
||||||
|
-phantom_node.GetReverseWeightPlusOffset(),
|
||||||
|
phantom_node.reverse_segment_id.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Algorithm>
|
||||||
|
void insertTargetInHeap(typename SearchEngineData<Algorithm>::QueryHeap &heap,
|
||||||
|
const PhantomNode &phantom_node)
|
||||||
|
{
|
||||||
|
if (phantom_node.IsValidForwardTarget())
|
||||||
|
{
|
||||||
|
heap.Insert(phantom_node.forward_segment_id.id,
|
||||||
|
phantom_node.GetForwardWeightPlusOffset(),
|
||||||
|
phantom_node.forward_segment_id.id);
|
||||||
|
}
|
||||||
|
if (phantom_node.IsValidReverseTarget())
|
||||||
|
{
|
||||||
|
heap.Insert(phantom_node.reverse_segment_id.id,
|
||||||
|
phantom_node.GetReverseWeightPlusOffset(),
|
||||||
|
phantom_node.reverse_segment_id.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
inline void insertTargetInHeap(typename SearchEngineData<mld::Algorithm>::ManyToManyQueryHeap &heap,
|
||||||
|
const PhantomNode &phantom_node)
|
||||||
|
{
|
||||||
|
detail::insertTargetInHeap<mld::Algorithm>(heap, phantom_node);
|
||||||
|
}
|
||||||
|
inline void insertTargetInHeap(typename SearchEngineData<ch::Algorithm>::ManyToManyQueryHeap &heap,
|
||||||
|
const PhantomNode &phantom_node)
|
||||||
|
{
|
||||||
|
detail::insertTargetInHeap<ch::Algorithm>(heap, phantom_node);
|
||||||
|
}
|
||||||
|
inline void insertTargetInHeap(typename SearchEngineData<mld::Algorithm>::QueryHeap &heap,
|
||||||
|
const PhantomNode &phantom_node)
|
||||||
|
{
|
||||||
|
detail::insertTargetInHeap<mld::Algorithm>(heap, phantom_node);
|
||||||
|
}
|
||||||
|
inline void insertTargetInHeap(typename SearchEngineData<ch::Algorithm>::QueryHeap &heap,
|
||||||
|
const PhantomNode &phantom_node)
|
||||||
|
{
|
||||||
|
detail::insertTargetInHeap<ch::Algorithm>(heap, phantom_node);
|
||||||
|
}
|
||||||
|
inline void insertSourceInHeap(typename SearchEngineData<mld::Algorithm>::ManyToManyQueryHeap &heap,
|
||||||
|
const PhantomNode &phantom_node)
|
||||||
|
{
|
||||||
|
detail::insertSourceInHeap<mld::Algorithm>(heap, phantom_node);
|
||||||
|
}
|
||||||
|
inline void insertSourceInHeap(typename SearchEngineData<ch::Algorithm>::ManyToManyQueryHeap &heap,
|
||||||
|
const PhantomNode &phantom_node)
|
||||||
|
{
|
||||||
|
detail::insertSourceInHeap<ch::Algorithm>(heap, phantom_node);
|
||||||
|
}
|
||||||
|
inline void insertSourceInHeap(typename SearchEngineData<mld::Algorithm>::QueryHeap &heap,
|
||||||
|
const PhantomNode &phantom_node)
|
||||||
|
{
|
||||||
|
detail::insertSourceInHeap<mld::Algorithm>(heap, phantom_node);
|
||||||
|
}
|
||||||
|
inline void insertSourceInHeap(typename SearchEngineData<ch::Algorithm>::QueryHeap &heap,
|
||||||
|
const PhantomNode &phantom_node)
|
||||||
|
{
|
||||||
|
detail::insertSourceInHeap<ch::Algorithm>(heap, phantom_node);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Heap>
|
||||||
|
void insertNodesInHeaps(Heap &forward_heap, Heap &reverse_heap, const PhantomNodes &nodes)
|
||||||
|
{
|
||||||
|
insertSourceInHeap(forward_heap, nodes.source_phantom);
|
||||||
|
insertTargetInHeap(reverse_heap, nodes.target_phantom);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Algorithm>
|
||||||
|
void insertSourceInHeap(typename SearchEngineData<Algorithm>::ManyToManyQueryHeap &heap,
|
||||||
|
const PhantomNode &phantom_node)
|
||||||
|
{
|
||||||
|
if (phantom_node.IsValidForwardSource())
|
||||||
|
{
|
||||||
|
heap.Insert(phantom_node.forward_segment_id.id,
|
||||||
|
-phantom_node.GetForwardWeightPlusOffset(),
|
||||||
|
{phantom_node.forward_segment_id.id, -phantom_node.GetForwardDuration()});
|
||||||
|
}
|
||||||
|
if (phantom_node.IsValidReverseSource())
|
||||||
|
{
|
||||||
|
heap.Insert(phantom_node.reverse_segment_id.id,
|
||||||
|
-phantom_node.GetReverseWeightPlusOffset(),
|
||||||
|
{phantom_node.reverse_segment_id.id, -phantom_node.GetReverseDuration()});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <typename FacadeT>
|
template <typename FacadeT>
|
||||||
void annotatePath(const FacadeT &facade,
|
void annotatePath(const FacadeT &facade,
|
||||||
const PhantomNodes &phantom_node_pair,
|
const PhantomNodes &phantom_node_pair,
|
||||||
@@ -329,58 +402,10 @@ void annotatePath(const FacadeT &facade,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Algorithm>
|
EdgeDistance adjustPathDistanceToPhantomNodes(const std::vector<NodeID> &path,
|
||||||
double getPathDistance(const DataFacade<Algorithm> &facade,
|
const PhantomNode &source_phantom,
|
||||||
const std::vector<PathData> unpacked_path,
|
const PhantomNode &target_phantom,
|
||||||
const PhantomNode &source_phantom,
|
const EdgeDistance distance);
|
||||||
const PhantomNode &target_phantom)
|
|
||||||
{
|
|
||||||
using util::coordinate_calculation::detail::DEGREE_TO_RAD;
|
|
||||||
using util::coordinate_calculation::detail::EARTH_RADIUS;
|
|
||||||
|
|
||||||
double distance = 0;
|
|
||||||
double prev_lat =
|
|
||||||
static_cast<double>(util::toFloating(source_phantom.location.lat)) * DEGREE_TO_RAD;
|
|
||||||
double prev_lon =
|
|
||||||
static_cast<double>(util::toFloating(source_phantom.location.lon)) * DEGREE_TO_RAD;
|
|
||||||
double prev_cos = std::cos(prev_lat);
|
|
||||||
for (const auto &p : unpacked_path)
|
|
||||||
{
|
|
||||||
const auto current_coordinate = facade.GetCoordinateOfNode(p.turn_via_node);
|
|
||||||
|
|
||||||
const double current_lat =
|
|
||||||
static_cast<double>(util::toFloating(current_coordinate.lat)) * DEGREE_TO_RAD;
|
|
||||||
const double current_lon =
|
|
||||||
static_cast<double>(util::toFloating(current_coordinate.lon)) * DEGREE_TO_RAD;
|
|
||||||
const double current_cos = std::cos(current_lat);
|
|
||||||
|
|
||||||
const double sin_dlon = std::sin((prev_lon - current_lon) / 2.0);
|
|
||||||
const double sin_dlat = std::sin((prev_lat - current_lat) / 2.0);
|
|
||||||
|
|
||||||
const double aharv = sin_dlat * sin_dlat + prev_cos * current_cos * sin_dlon * sin_dlon;
|
|
||||||
const double charv = 2. * std::atan2(std::sqrt(aharv), std::sqrt(1.0 - aharv));
|
|
||||||
distance += EARTH_RADIUS * charv;
|
|
||||||
|
|
||||||
prev_lat = current_lat;
|
|
||||||
prev_lon = current_lon;
|
|
||||||
prev_cos = current_cos;
|
|
||||||
}
|
|
||||||
|
|
||||||
const double current_lat =
|
|
||||||
static_cast<double>(util::toFloating(target_phantom.location.lat)) * DEGREE_TO_RAD;
|
|
||||||
const double current_lon =
|
|
||||||
static_cast<double>(util::toFloating(target_phantom.location.lon)) * DEGREE_TO_RAD;
|
|
||||||
const double current_cos = std::cos(current_lat);
|
|
||||||
|
|
||||||
const double sin_dlon = std::sin((prev_lon - current_lon) / 2.0);
|
|
||||||
const double sin_dlat = std::sin((prev_lat - current_lat) / 2.0);
|
|
||||||
|
|
||||||
const double aharv = sin_dlat * sin_dlat + prev_cos * current_cos * sin_dlon * sin_dlon;
|
|
||||||
const double charv = 2. * std::atan2(std::sqrt(aharv), std::sqrt(1.0 - aharv));
|
|
||||||
distance += EARTH_RADIUS * charv;
|
|
||||||
|
|
||||||
return distance;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename AlgorithmT>
|
template <typename AlgorithmT>
|
||||||
InternalRouteResult extractRoute(const DataFacade<AlgorithmT> &facade,
|
InternalRouteResult extractRoute(const DataFacade<AlgorithmT> &facade,
|
||||||
|
|||||||
@@ -186,7 +186,7 @@ void routingStep(const DataFacade<Algorithm> &facade,
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <bool UseDuration>
|
template <bool UseDuration>
|
||||||
std::tuple<EdgeWeight, EdgeDistance> getLoopWeight(const DataFacade<Algorithm> &facade, NodeID node)
|
std::tuple<EdgeWeight,EdgeDistance> getLoopWeight(const DataFacade<Algorithm> &facade, NodeID node)
|
||||||
{
|
{
|
||||||
EdgeWeight loop_weight = UseDuration ? MAXIMAL_EDGE_DURATION : INVALID_EDGE_WEIGHT;
|
EdgeWeight loop_weight = UseDuration ? MAXIMAL_EDGE_DURATION : INVALID_EDGE_WEIGHT;
|
||||||
EdgeDistance loop_distance = MAXIMAL_EDGE_DISTANCE;
|
EdgeDistance loop_distance = MAXIMAL_EDGE_DISTANCE;
|
||||||
|
|||||||
@@ -97,7 +97,6 @@ inline LevelID getNodeQueryLevel(const MultiLevelPartition &partition,
|
|||||||
const std::vector<std::size_t> &phantom_indices)
|
const std::vector<std::size_t> &phantom_indices)
|
||||||
{
|
{
|
||||||
auto min_level = [&partition, node](const PhantomNode &phantom_node) {
|
auto min_level = [&partition, node](const PhantomNode &phantom_node) {
|
||||||
|
|
||||||
const auto &forward_segment = phantom_node.forward_segment_id;
|
const auto &forward_segment = phantom_node.forward_segment_id;
|
||||||
const auto forward_level =
|
const auto forward_level =
|
||||||
forward_segment.enabled ? partition.GetHighestDifferentLevel(node, forward_segment.id)
|
forward_segment.enabled ? partition.GetHighestDifferentLevel(node, forward_segment.id)
|
||||||
@@ -120,7 +119,7 @@ inline LevelID getNodeQueryLevel(const MultiLevelPartition &partition,
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
} // namespace
|
||||||
|
|
||||||
// Heaps only record for each node its predecessor ("parent") on the shortest path.
|
// Heaps only record for each node its predecessor ("parent") on the shortest path.
|
||||||
// For re-constructing the actual path we need to trace back all parent "pointers".
|
// For re-constructing the actual path we need to trace back all parent "pointers".
|
||||||
@@ -391,21 +390,27 @@ UnpackedPath search(SearchEngineData<Algorithm> &engine_working_data,
|
|||||||
EdgeWeight weight_upper_bound,
|
EdgeWeight weight_upper_bound,
|
||||||
Args... args)
|
Args... args)
|
||||||
{
|
{
|
||||||
if (forward_heap.Empty() || reverse_heap.Empty())
|
if (forward_heap.Empty() && reverse_heap.Empty())
|
||||||
{
|
{
|
||||||
return std::make_tuple(INVALID_EDGE_WEIGHT, std::vector<NodeID>(), std::vector<EdgeID>());
|
return std::make_tuple(INVALID_EDGE_WEIGHT, std::vector<NodeID>(), std::vector<EdgeID>());
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto &partition = facade.GetMultiLevelPartition();
|
const auto &partition = facade.GetMultiLevelPartition();
|
||||||
|
|
||||||
BOOST_ASSERT(!forward_heap.Empty() && forward_heap.MinKey() < INVALID_EDGE_WEIGHT);
|
BOOST_ASSERT(forward_heap.Empty() || forward_heap.MinKey() < INVALID_EDGE_WEIGHT);
|
||||||
BOOST_ASSERT(!reverse_heap.Empty() && reverse_heap.MinKey() < INVALID_EDGE_WEIGHT);
|
BOOST_ASSERT(reverse_heap.Empty() || reverse_heap.MinKey() < INVALID_EDGE_WEIGHT);
|
||||||
|
|
||||||
// run two-Target Dijkstra routing step.
|
// run two-Target Dijkstra routing step.
|
||||||
NodeID middle = SPECIAL_NODEID;
|
NodeID middle = SPECIAL_NODEID;
|
||||||
EdgeWeight weight = weight_upper_bound;
|
EdgeWeight weight = weight_upper_bound;
|
||||||
EdgeWeight forward_heap_min = forward_heap.MinKey();
|
|
||||||
EdgeWeight reverse_heap_min = reverse_heap.MinKey();
|
EdgeWeight forward_heap_min = 0;
|
||||||
|
if (!forward_heap.Empty())
|
||||||
|
forward_heap_min = forward_heap.MinKey();
|
||||||
|
EdgeWeight reverse_heap_min = 0;
|
||||||
|
if (!reverse_heap.Empty())
|
||||||
|
reverse_heap_min = reverse_heap.MinKey();
|
||||||
|
|
||||||
while (forward_heap.Size() + reverse_heap.Size() > 0 &&
|
while (forward_heap.Size() + reverse_heap.Size() > 0 &&
|
||||||
forward_heap_min + reverse_heap_min < weight)
|
forward_heap_min + reverse_heap_min < weight)
|
||||||
{
|
{
|
||||||
@@ -657,11 +662,7 @@ double getNetworkDistance(SearchEngineData<Algorithm> &engine_working_data,
|
|||||||
const PhantomNode &target_phantom,
|
const PhantomNode &target_phantom,
|
||||||
EdgeWeight weight_upper_bound = INVALID_EDGE_WEIGHT)
|
EdgeWeight weight_upper_bound = INVALID_EDGE_WEIGHT)
|
||||||
{
|
{
|
||||||
forward_heap.Clear();
|
|
||||||
reverse_heap.Clear();
|
|
||||||
|
|
||||||
const PhantomNodes phantom_nodes{source_phantom, target_phantom};
|
const PhantomNodes phantom_nodes{source_phantom, target_phantom};
|
||||||
insertNodesInHeaps(forward_heap, reverse_heap, phantom_nodes);
|
|
||||||
|
|
||||||
EdgeWeight weight = INVALID_EDGE_WEIGHT;
|
EdgeWeight weight = INVALID_EDGE_WEIGHT;
|
||||||
std::vector<NodeID> unpacked_nodes;
|
std::vector<NodeID> unpacked_nodes;
|
||||||
@@ -680,11 +681,22 @@ double getNetworkDistance(SearchEngineData<Algorithm> &engine_working_data,
|
|||||||
return std::numeric_limits<double>::max();
|
return std::numeric_limits<double>::max();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<PathData> unpacked_path;
|
EdgeDistance distance = 0;
|
||||||
|
|
||||||
annotatePath(facade, phantom_nodes, unpacked_nodes, unpacked_edges, unpacked_path);
|
if (!unpacked_nodes.empty())
|
||||||
|
{
|
||||||
|
distance = std::accumulate(unpacked_nodes.begin(),
|
||||||
|
std::prev(unpacked_nodes.end()),
|
||||||
|
EdgeDistance{0},
|
||||||
|
[&](const EdgeDistance distance, const auto node_id) {
|
||||||
|
return distance + computeEdgeDistance(facade, node_id);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return getPathDistance(facade, unpacked_path, source_phantom, target_phantom);
|
distance = adjustPathDistanceToPhantomNodes(
|
||||||
|
unpacked_nodes, phantom_nodes.source_phantom, phantom_nodes.target_phantom, distance);
|
||||||
|
|
||||||
|
return distance;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace mld
|
} // namespace mld
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
#define OSRM_BINDINGS_NODE_SUPPORT_HPP
|
#define OSRM_BINDINGS_NODE_SUPPORT_HPP
|
||||||
|
|
||||||
#include "nodejs/json_v8_renderer.hpp"
|
#include "nodejs/json_v8_renderer.hpp"
|
||||||
#include "util/json_renderer.hpp"
|
|
||||||
|
|
||||||
#include "osrm/approach.hpp"
|
#include "osrm/approach.hpp"
|
||||||
#include "osrm/bearing.hpp"
|
#include "osrm/bearing.hpp"
|
||||||
@@ -25,7 +24,6 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <sstream>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -44,13 +42,6 @@ using match_parameters_ptr = std::unique_ptr<osrm::MatchParameters>;
|
|||||||
using nearest_parameters_ptr = std::unique_ptr<osrm::NearestParameters>;
|
using nearest_parameters_ptr = std::unique_ptr<osrm::NearestParameters>;
|
||||||
using table_parameters_ptr = std::unique_ptr<osrm::TableParameters>;
|
using table_parameters_ptr = std::unique_ptr<osrm::TableParameters>;
|
||||||
|
|
||||||
struct PluginParameters
|
|
||||||
{
|
|
||||||
bool renderJSONToBuffer = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
using ObjectOrString = typename mapbox::util::variant<osrm::json::Object, std::string>;
|
|
||||||
|
|
||||||
template <typename ResultT> inline v8::Local<v8::Value> render(const ResultT &result);
|
template <typename ResultT> inline v8::Local<v8::Value> render(const ResultT &result);
|
||||||
|
|
||||||
template <> v8::Local<v8::Value> inline render(const std::string &result)
|
template <> v8::Local<v8::Value> inline render(const std::string &result)
|
||||||
@@ -58,21 +49,11 @@ template <> v8::Local<v8::Value> inline render(const std::string &result)
|
|||||||
return Nan::CopyBuffer(result.data(), result.size()).ToLocalChecked();
|
return Nan::CopyBuffer(result.data(), result.size()).ToLocalChecked();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <> v8::Local<v8::Value> inline render(const ObjectOrString &result)
|
template <> v8::Local<v8::Value> inline render(const osrm::json::Object &result)
|
||||||
{
|
{
|
||||||
if (result.is<osrm::json::Object>())
|
v8::Local<v8::Value> value;
|
||||||
{
|
renderToV8(value, result);
|
||||||
// Convert osrm::json object tree into matching v8 object tree
|
return value;
|
||||||
v8::Local<v8::Value> value;
|
|
||||||
renderToV8(value, result.get<osrm::json::Object>());
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Return the string object as a node Buffer
|
|
||||||
return Nan::CopyBuffer(result.get<std::string>().data(), result.get<std::string>().size())
|
|
||||||
.ToLocalChecked();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void ParseResult(const osrm::Status &result_status, osrm::json::Object &result)
|
inline void ParseResult(const osrm::Status &result_status, osrm::json::Object &result)
|
||||||
@@ -142,10 +123,6 @@ inline engine_config_ptr argumentsToEngineConfig(const Nan::FunctionCallbackInfo
|
|||||||
if (shared_memory.IsEmpty())
|
if (shared_memory.IsEmpty())
|
||||||
return engine_config_ptr();
|
return engine_config_ptr();
|
||||||
|
|
||||||
auto mmap_memory = params->Get(Nan::New("mmap_memory").ToLocalChecked());
|
|
||||||
if (mmap_memory.IsEmpty())
|
|
||||||
return engine_config_ptr();
|
|
||||||
|
|
||||||
if (!memory_file->IsUndefined())
|
if (!memory_file->IsUndefined())
|
||||||
{
|
{
|
||||||
if (path->IsUndefined())
|
if (path->IsUndefined())
|
||||||
@@ -194,18 +171,6 @@ inline engine_config_ptr argumentsToEngineConfig(const Nan::FunctionCallbackInfo
|
|||||||
return engine_config_ptr();
|
return engine_config_ptr();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!mmap_memory->IsUndefined())
|
|
||||||
{
|
|
||||||
if (mmap_memory->IsBoolean())
|
|
||||||
{
|
|
||||||
engine_config->use_mmap = Nan::To<bool>(mmap_memory).FromJust();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Nan::ThrowError("mmap_memory option must be a boolean");
|
|
||||||
return engine_config_ptr();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (path->IsUndefined() && !engine_config->use_shared_memory)
|
if (path->IsUndefined() && !engine_config->use_shared_memory)
|
||||||
{
|
{
|
||||||
@@ -849,50 +814,6 @@ inline bool parseCommonParameters(const v8::Local<v8::Object> &obj, ParamType &p
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline PluginParameters
|
|
||||||
argumentsToPluginParameters(const Nan::FunctionCallbackInfo<v8::Value> &args)
|
|
||||||
{
|
|
||||||
if (args.Length() < 3 || !args[1]->IsObject())
|
|
||||||
{
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
v8::Local<v8::Object> obj = Nan::To<v8::Object>(args[1]).ToLocalChecked();
|
|
||||||
if (obj->Has(Nan::New("format").ToLocalChecked()))
|
|
||||||
{
|
|
||||||
|
|
||||||
v8::Local<v8::Value> format = obj->Get(Nan::New("format").ToLocalChecked());
|
|
||||||
if (format.IsEmpty())
|
|
||||||
{
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!format->IsString())
|
|
||||||
{
|
|
||||||
Nan::ThrowError("format must be a string: \"object\" or \"json_buffer\"");
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
const Nan::Utf8String format_utf8str(format);
|
|
||||||
std::string format_str{*format_utf8str, *format_utf8str + format_utf8str.length()};
|
|
||||||
|
|
||||||
if (format_str == "object")
|
|
||||||
{
|
|
||||||
return {false};
|
|
||||||
}
|
|
||||||
else if (format_str == "json_buffer")
|
|
||||||
{
|
|
||||||
return {true};
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Nan::ThrowError("format must be a string: \"object\" or \"json_buffer\"");
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
inline route_parameters_ptr
|
inline route_parameters_ptr
|
||||||
argumentsToRouteParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
|
argumentsToRouteParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
|
||||||
bool requires_multiple_coordinates)
|
bool requires_multiple_coordinates)
|
||||||
@@ -1436,6 +1357,6 @@ argumentsToMatchParameter(const Nan::FunctionCallbackInfo<v8::Value> &args,
|
|||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace node_osrm
|
} // ns node_osrm
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -16,15 +16,10 @@ struct Block
|
|||||||
{
|
{
|
||||||
std::uint64_t num_entries;
|
std::uint64_t num_entries;
|
||||||
std::uint64_t byte_size;
|
std::uint64_t byte_size;
|
||||||
std::uint64_t offset;
|
|
||||||
|
|
||||||
Block() : num_entries(0), byte_size(0), offset(0) {}
|
Block() : num_entries(0), byte_size(0) {}
|
||||||
Block(std::uint64_t num_entries, std::uint64_t byte_size, std::uint64_t offset)
|
|
||||||
: num_entries(num_entries), byte_size(byte_size), offset(offset)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
Block(std::uint64_t num_entries, std::uint64_t byte_size)
|
Block(std::uint64_t num_entries, std::uint64_t byte_size)
|
||||||
: num_entries(num_entries), byte_size(byte_size), offset(0)
|
: num_entries(num_entries), byte_size(byte_size)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -34,7 +29,7 @@ using NamedBlock = std::tuple<std::string, Block>;
|
|||||||
template <typename T> Block make_block(uint64_t num_entries)
|
template <typename T> Block make_block(uint64_t num_entries)
|
||||||
{
|
{
|
||||||
static_assert(sizeof(T) % alignof(T) == 0, "aligned T* can't be used as an array pointer");
|
static_assert(sizeof(T) % alignof(T) == 0, "aligned T* can't be used as an array pointer");
|
||||||
return Block{num_entries, sizeof(T) * num_entries, 0};
|
return Block{num_entries, sizeof(T) * num_entries};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,29 +30,22 @@ namespace serialization
|
|||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
template <typename T, typename BlockT = unsigned char>
|
template <typename T, typename BlockT = unsigned char>
|
||||||
inline BlockT packBits(const T &data, std::size_t base_index, const std::size_t count)
|
inline BlockT packBits(const T &data, std::size_t index, std::size_t count)
|
||||||
{
|
{
|
||||||
static_assert(std::is_same<typename T::value_type, bool>::value, "value_type is not bool");
|
static_assert(std::is_same<typename T::value_type, bool>::value, "value_type is not bool");
|
||||||
|
|
||||||
// Note: if this packing is changed, be sure to update vector_view<bool>
|
|
||||||
// as well, so that on-disk and in-memory layouts match.
|
|
||||||
BlockT value = 0;
|
BlockT value = 0;
|
||||||
for (std::size_t bit = 0; bit < count; ++bit)
|
for (std::size_t bit = 0; bit < count; ++bit, ++index)
|
||||||
{
|
value = (value << 1) | data[index];
|
||||||
value |= (data[base_index + bit] ? BlockT{1} : BlockT{0}) << bit;
|
|
||||||
}
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename BlockT = unsigned char>
|
template <typename T, typename BlockT = unsigned char>
|
||||||
inline void
|
inline void unpackBits(T &data, std::size_t index, std::size_t count, BlockT value)
|
||||||
unpackBits(T &data, const std::size_t base_index, const std::size_t count, const BlockT value)
|
|
||||||
{
|
{
|
||||||
static_assert(std::is_same<typename T::value_type, bool>::value, "value_type is not bool");
|
static_assert(std::is_same<typename T::value_type, bool>::value, "value_type is not bool");
|
||||||
for (std::size_t bit = 0; bit < count; ++bit)
|
const BlockT mask = BlockT{1} << (count - 1);
|
||||||
{
|
for (std::size_t bit = 0; bit < count; value <<= 1, ++bit, ++index)
|
||||||
data[base_index + bit] = value & (BlockT{1} << bit);
|
data[index] = value & mask;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename VectorT>
|
template <typename VectorT>
|
||||||
@@ -97,7 +90,7 @@ void writeBoolVector(tar::FileWriter &writer, const std::string &name, const Vec
|
|||||||
boost::make_function_input_iterator(encode_function, boost::infinite()),
|
boost::make_function_input_iterator(encode_function, boost::infinite()),
|
||||||
number_of_blocks);
|
number_of_blocks);
|
||||||
}
|
}
|
||||||
} // namespace detail
|
}
|
||||||
|
|
||||||
/* All vector formats here use the same on-disk format.
|
/* All vector formats here use the same on-disk format.
|
||||||
* This is important because we want to be able to write from a vector
|
* This is important because we want to be able to write from a vector
|
||||||
@@ -273,17 +266,14 @@ template <typename K, typename V> void write(io::BufferWriter &writer, const std
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void read(io::BufferReader &reader, std::unique_ptr<BaseDataLayout> &layout)
|
inline void read(io::BufferReader &reader, DataLayout &layout) { read(reader, layout.blocks); }
|
||||||
{
|
|
||||||
read(reader, layout->blocks);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void write(io::BufferWriter &writer, const std::unique_ptr<BaseDataLayout> &layout)
|
inline void write(io::BufferWriter &writer, const DataLayout &layout)
|
||||||
{
|
{
|
||||||
write(writer, layout->blocks);
|
write(writer, layout.blocks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} // namespace serialization
|
|
||||||
} // namespace storage
|
|
||||||
} // namespace osrm
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ class SharedDataIndex
|
|||||||
struct AllocatedRegion
|
struct AllocatedRegion
|
||||||
{
|
{
|
||||||
char *memory_ptr;
|
char *memory_ptr;
|
||||||
std::unique_ptr<BaseDataLayout> layout;
|
DataLayout layout;
|
||||||
};
|
};
|
||||||
|
|
||||||
SharedDataIndex() = default;
|
SharedDataIndex() = default;
|
||||||
@@ -29,10 +29,10 @@ class SharedDataIndex
|
|||||||
// Build mapping from block name to region
|
// Build mapping from block name to region
|
||||||
for (auto index : util::irange<std::uint32_t>(0, regions.size()))
|
for (auto index : util::irange<std::uint32_t>(0, regions.size()))
|
||||||
{
|
{
|
||||||
regions[index].layout->List("",
|
regions[index].layout.List("",
|
||||||
boost::make_function_output_iterator([&](const auto &name) {
|
boost::make_function_output_iterator([&](const auto &name) {
|
||||||
block_to_region[name] = index;
|
block_to_region[name] = index;
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,32 +40,32 @@ class SharedDataIndex
|
|||||||
{
|
{
|
||||||
for (const auto ®ion : regions)
|
for (const auto ®ion : regions)
|
||||||
{
|
{
|
||||||
region.layout->List(name_prefix, out);
|
region.layout.List(name_prefix, out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> auto GetBlockPtr(const std::string &name) const
|
template <typename T> auto GetBlockPtr(const std::string &name) const
|
||||||
{
|
{
|
||||||
const auto ®ion = GetBlockRegion(name);
|
const auto ®ion = GetBlockRegion(name);
|
||||||
return reinterpret_cast<T *>(region.layout->GetBlockPtr(region.memory_ptr, name));
|
return region.layout.GetBlockPtr<T>(region.memory_ptr, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> auto GetBlockPtr(const std::string &name)
|
template <typename T> auto GetBlockPtr(const std::string &name)
|
||||||
{
|
{
|
||||||
const auto ®ion = GetBlockRegion(name);
|
const auto ®ion = GetBlockRegion(name);
|
||||||
return reinterpret_cast<T *>(region.layout->GetBlockPtr(region.memory_ptr, name));
|
return region.layout.GetBlockPtr<T>(region.memory_ptr, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t GetBlockEntries(const std::string &name) const
|
std::size_t GetBlockEntries(const std::string &name) const
|
||||||
{
|
{
|
||||||
const auto ®ion = GetBlockRegion(name);
|
const auto ®ion = GetBlockRegion(name);
|
||||||
return region.layout->GetBlockEntries(name);
|
return region.layout.GetBlockEntries(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t GetBlockSize(const std::string &name) const
|
std::size_t GetBlockSize(const std::string &name) const
|
||||||
{
|
{
|
||||||
const auto ®ion = GetBlockRegion(name);
|
const auto ®ion = GetBlockRegion(name);
|
||||||
return region.layout->GetBlockSize(name);
|
return region.layout.GetBlockSize(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -20,12 +20,12 @@ namespace osrm
|
|||||||
namespace storage
|
namespace storage
|
||||||
{
|
{
|
||||||
|
|
||||||
class BaseDataLayout;
|
class DataLayout;
|
||||||
namespace serialization
|
namespace serialization
|
||||||
{
|
{
|
||||||
inline void read(io::BufferReader &reader, std::unique_ptr<BaseDataLayout> &layout);
|
inline void read(io::BufferReader &reader, DataLayout &layout);
|
||||||
|
|
||||||
inline void write(io::BufferWriter &writer, const std::unique_ptr<BaseDataLayout> &layout);
|
inline void write(io::BufferWriter &writer, const DataLayout &layout);
|
||||||
} // namespace serialization
|
} // namespace serialization
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
@@ -54,20 +54,43 @@ inline std::string trimName(const std::string &name_prefix, const std::string &n
|
|||||||
}
|
}
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
class BaseDataLayout
|
class DataLayout
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~BaseDataLayout() = default;
|
DataLayout() : blocks{} {}
|
||||||
|
|
||||||
virtual inline void SetBlock(const std::string &name, Block block) = 0;
|
inline void SetBlock(const std::string &name, Block block) { blocks[name] = std::move(block); }
|
||||||
|
|
||||||
virtual inline uint64_t GetBlockEntries(const std::string &name) const = 0;
|
inline uint64_t GetBlockEntries(const std::string &name) const
|
||||||
|
{
|
||||||
|
return GetBlock(name).num_entries;
|
||||||
|
}
|
||||||
|
|
||||||
virtual inline uint64_t GetBlockSize(const std::string &name) const = 0;
|
inline uint64_t GetBlockSize(const std::string &name) const { return GetBlock(name).byte_size; }
|
||||||
|
|
||||||
virtual inline bool HasBlock(const std::string &name) const = 0;
|
inline bool HasBlock(const std::string &name) const
|
||||||
|
{
|
||||||
|
return blocks.find(name) != blocks.end();
|
||||||
|
}
|
||||||
|
|
||||||
virtual inline uint64_t GetSizeOfLayout() const = 0;
|
inline uint64_t GetSizeOfLayout() const
|
||||||
|
{
|
||||||
|
uint64_t result = 0;
|
||||||
|
for (const auto &name_and_block : blocks)
|
||||||
|
{
|
||||||
|
result += GetBlockSize(name_and_block.first) + BLOCK_ALIGNMENT;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> inline T *GetBlockPtr(char *shared_memory, const std::string &name) const
|
||||||
|
{
|
||||||
|
static_assert(BLOCK_ALIGNMENT % std::alignment_of<T>::value == 0,
|
||||||
|
"Datatype does not fit alignment constraints.");
|
||||||
|
|
||||||
|
char *ptr = (char *)GetAlignedBlockPtr(shared_memory, name);
|
||||||
|
return (T *)ptr;
|
||||||
|
}
|
||||||
|
|
||||||
// Depending on the name prefix this function either lists all blocks with the same prefix
|
// Depending on the name prefix this function either lists all blocks with the same prefix
|
||||||
// or all entries in the sub-directory.
|
// or all entries in the sub-directory.
|
||||||
@@ -92,59 +115,9 @@ class BaseDataLayout
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual inline void *GetBlockPtr(char *shared_memory, const std::string &name) const = 0;
|
|
||||||
|
|
||||||
std::map<std::string, Block> blocks;
|
|
||||||
};
|
|
||||||
|
|
||||||
class DataLayout final : public BaseDataLayout
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
inline void SetBlock(const std::string &name, Block block) override final
|
|
||||||
{
|
|
||||||
blocks[name] = std::move(block);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint64_t GetBlockEntries(const std::string &name) const override final
|
|
||||||
{
|
|
||||||
return GetBlock(name).num_entries;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint64_t GetBlockSize(const std::string &name) const override final
|
|
||||||
{
|
|
||||||
return GetBlock(name).byte_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool HasBlock(const std::string &name) const override final
|
|
||||||
{
|
|
||||||
return blocks.find(name) != blocks.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint64_t GetSizeOfLayout() const override final
|
|
||||||
{
|
|
||||||
uint64_t result = 0;
|
|
||||||
for (const auto &name_and_block : blocks)
|
|
||||||
{
|
|
||||||
result += GetBlockSize(name_and_block.first) + BLOCK_ALIGNMENT;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void *GetBlockPtr(char *shared_memory, const std::string &name) const override final
|
|
||||||
{
|
|
||||||
// TODO: re-enable this alignment checking somehow
|
|
||||||
// static_assert(BLOCK_ALIGNMENT % std::alignment_of<T>::value == 0,
|
|
||||||
// "Datatype does not fit alignment constraints.");
|
|
||||||
|
|
||||||
char *ptr = (char *)GetAlignedBlockPtr(shared_memory, name);
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend void serialization::read(io::BufferReader &reader,
|
friend void serialization::read(io::BufferReader &reader, DataLayout &layout);
|
||||||
std::unique_ptr<BaseDataLayout> &layout);
|
friend void serialization::write(io::BufferWriter &writer, const DataLayout &layout);
|
||||||
friend void serialization::write(io::BufferWriter &writer,
|
|
||||||
const std::unique_ptr<BaseDataLayout> &layout);
|
|
||||||
|
|
||||||
const Block &GetBlock(const std::string &name) const
|
const Block &GetBlock(const std::string &name) const
|
||||||
{
|
{
|
||||||
@@ -184,64 +157,7 @@ class DataLayout final : public BaseDataLayout
|
|||||||
}
|
}
|
||||||
|
|
||||||
static constexpr std::size_t BLOCK_ALIGNMENT = 64;
|
static constexpr std::size_t BLOCK_ALIGNMENT = 64;
|
||||||
};
|
std::map<std::string, Block> blocks;
|
||||||
|
|
||||||
class TarDataLayout final : public BaseDataLayout
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
inline void SetBlock(const std::string &name, Block block) override final
|
|
||||||
{
|
|
||||||
blocks[name] = std::move(block);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint64_t GetBlockEntries(const std::string &name) const override final
|
|
||||||
{
|
|
||||||
return GetBlock(name).num_entries;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint64_t GetBlockSize(const std::string &name) const override final
|
|
||||||
{
|
|
||||||
return GetBlock(name).byte_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool HasBlock(const std::string &name) const override final
|
|
||||||
{
|
|
||||||
return blocks.find(name) != blocks.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint64_t GetSizeOfLayout() const override final
|
|
||||||
{
|
|
||||||
uint64_t result = 0;
|
|
||||||
for (const auto &name_and_block : blocks)
|
|
||||||
{
|
|
||||||
result += GetBlockSize(name_and_block.first);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void *GetBlockPtr(char *memory_ptr, const std::string &name) const override final
|
|
||||||
{
|
|
||||||
auto offset = GetBlock(name).offset;
|
|
||||||
const auto offset_memory = memory_ptr + offset;
|
|
||||||
return offset_memory;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend void serialization::read(io::BufferReader &reader,
|
|
||||||
std::unique_ptr<BaseDataLayout> &layout);
|
|
||||||
friend void serialization::write(io::BufferWriter &writer,
|
|
||||||
const std::unique_ptr<BaseDataLayout> &layout);
|
|
||||||
|
|
||||||
const Block &GetBlock(const std::string &name) const
|
|
||||||
{
|
|
||||||
auto iter = blocks.find(name);
|
|
||||||
if (iter == blocks.end())
|
|
||||||
{
|
|
||||||
throw util::exception("Could not find block " + name);
|
|
||||||
}
|
|
||||||
|
|
||||||
return iter->second;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SharedRegion
|
struct SharedRegion
|
||||||
|
|||||||
@@ -46,15 +46,11 @@ class Storage
|
|||||||
Storage(StorageConfig config);
|
Storage(StorageConfig config);
|
||||||
|
|
||||||
int Run(int max_wait, const std::string &name, bool only_metric);
|
int Run(int max_wait, const std::string &name, bool only_metric);
|
||||||
|
|
||||||
|
void PopulateStaticLayout(DataLayout &layout);
|
||||||
|
void PopulateUpdatableLayout(DataLayout &layout);
|
||||||
void PopulateStaticData(const SharedDataIndex &index);
|
void PopulateStaticData(const SharedDataIndex &index);
|
||||||
void PopulateUpdatableData(const SharedDataIndex &index);
|
void PopulateUpdatableData(const SharedDataIndex &index);
|
||||||
void PopulateLayout(std::unique_ptr<storage::BaseDataLayout> &layout,
|
|
||||||
std::vector<std::pair<bool, boost::filesystem::path>> files);
|
|
||||||
std::string PopulateLayoutWithRTree(std::unique_ptr<storage::BaseDataLayout> &layout);
|
|
||||||
void readBlocks(const boost::filesystem::path &path,
|
|
||||||
std::unique_ptr<storage::BaseDataLayout> &layout);
|
|
||||||
std::vector<std::pair<bool, boost::filesystem::path>> GetUpdatableFiles();
|
|
||||||
std::vector<std::pair<bool, boost::filesystem::path>> GetStaticFiles();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
StorageConfig config;
|
StorageConfig config;
|
||||||
|
|||||||
@@ -23,9 +23,6 @@ namespace detail
|
|||||||
{
|
{
|
||||||
const constexpr double DEGREE_TO_RAD = 0.017453292519943295769236907684886;
|
const constexpr double DEGREE_TO_RAD = 0.017453292519943295769236907684886;
|
||||||
const constexpr double RAD_TO_DEGREE = 1. / DEGREE_TO_RAD;
|
const constexpr double RAD_TO_DEGREE = 1. / DEGREE_TO_RAD;
|
||||||
// earth radius varies between 6,356.750-6,378.135 km (3,949.901-3,963.189mi)
|
|
||||||
// The IUGG value for the equatorial radius is 6378.137 km (3963.19 miles)
|
|
||||||
const constexpr long double EARTH_RADIUS = 6372797.560856;
|
|
||||||
|
|
||||||
inline double degToRad(const double degree)
|
inline double degToRad(const double degree)
|
||||||
{
|
{
|
||||||
|
|||||||
+16
-17
@@ -15,14 +15,14 @@ namespace util
|
|||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
template <typename T, typename MmapContainerT>
|
template <typename T, typename RegionT>
|
||||||
util::vector_view<T> mmapFile(const boost::filesystem::path &file, MmapContainerT &mmap_container)
|
util::vector_view<T> mmapFile(const boost::filesystem::path &file, RegionT ®ion)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
mmap_container.open(file);
|
region.open(file);
|
||||||
std::size_t num_objects = mmap_container.size() / sizeof(T);
|
std::size_t num_objects = region.size() / sizeof(T);
|
||||||
auto data_ptr = mmap_container.data();
|
auto data_ptr = region.data();
|
||||||
BOOST_ASSERT(reinterpret_cast<uintptr_t>(data_ptr) % alignof(T) == 0);
|
BOOST_ASSERT(reinterpret_cast<uintptr_t>(data_ptr) % alignof(T) == 0);
|
||||||
return util::vector_view<T>(reinterpret_cast<T *>(data_ptr), num_objects);
|
return util::vector_view<T>(reinterpret_cast<T *>(data_ptr), num_objects);
|
||||||
}
|
}
|
||||||
@@ -34,10 +34,9 @@ util::vector_view<T> mmapFile(const boost::filesystem::path &file, MmapContainer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T, typename MmapContainerT>
|
template <typename T, typename RegionT>
|
||||||
util::vector_view<T> mmapFile(const boost::filesystem::path &file,
|
util::vector_view<T>
|
||||||
MmapContainerT &mmap_container,
|
mmapFile(const boost::filesystem::path &file, RegionT ®ion, const std::size_t size)
|
||||||
const std::size_t size)
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -46,10 +45,10 @@ util::vector_view<T> mmapFile(const boost::filesystem::path &file,
|
|||||||
params.path = file.string();
|
params.path = file.string();
|
||||||
params.flags = boost::iostreams::mapped_file::readwrite;
|
params.flags = boost::iostreams::mapped_file::readwrite;
|
||||||
params.new_file_size = size;
|
params.new_file_size = size;
|
||||||
mmap_container.open(params);
|
region.open(params);
|
||||||
|
|
||||||
std::size_t num_objects = size / sizeof(T);
|
std::size_t num_objects = size / sizeof(T);
|
||||||
auto data_ptr = mmap_container.data();
|
auto data_ptr = region.data();
|
||||||
BOOST_ASSERT(reinterpret_cast<uintptr_t>(data_ptr) % alignof(T) == 0);
|
BOOST_ASSERT(reinterpret_cast<uintptr_t>(data_ptr) % alignof(T) == 0);
|
||||||
return util::vector_view<T>(reinterpret_cast<T *>(data_ptr), num_objects);
|
return util::vector_view<T>(reinterpret_cast<T *>(data_ptr), num_objects);
|
||||||
}
|
}
|
||||||
@@ -64,24 +63,24 @@ util::vector_view<T> mmapFile(const boost::filesystem::path &file,
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
util::vector_view<const T> mmapFile(const boost::filesystem::path &file,
|
util::vector_view<const T> mmapFile(const boost::filesystem::path &file,
|
||||||
boost::iostreams::mapped_file_source &mmap_container)
|
boost::iostreams::mapped_file_source ®ion)
|
||||||
{
|
{
|
||||||
return detail::mmapFile<const T>(file, mmap_container);
|
return detail::mmapFile<const T>(file, region);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
util::vector_view<T> mmapFile(const boost::filesystem::path &file,
|
util::vector_view<T> mmapFile(const boost::filesystem::path &file,
|
||||||
boost::iostreams::mapped_file &mmap_container)
|
boost::iostreams::mapped_file ®ion)
|
||||||
{
|
{
|
||||||
return detail::mmapFile<T>(file, mmap_container);
|
return detail::mmapFile<T>(file, region);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
util::vector_view<T> mmapFile(const boost::filesystem::path &file,
|
util::vector_view<T> mmapFile(const boost::filesystem::path &file,
|
||||||
boost::iostreams::mapped_file &mmap_container,
|
boost::iostreams::mapped_file ®ion,
|
||||||
std::size_t size)
|
std::size_t size)
|
||||||
{
|
{
|
||||||
return detail::mmapFile<T>(file, mmap_container, size);
|
return detail::mmapFile<T>(file, region, size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
|
|
||||||
#include <tbb/parallel_sort.h>
|
#include <tbb/parallel_sort.h>
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
@@ -88,13 +87,9 @@ NodeBasedDynamicGraphFromEdges(NodeID number_of_nodes,
|
|||||||
output_edge.data.flags = input_edge.flags;
|
output_edge.data.flags = input_edge.flags;
|
||||||
output_edge.data.annotation_data = input_edge.annotation_data;
|
output_edge.data.annotation_data = input_edge.annotation_data;
|
||||||
|
|
||||||
BOOST_ASSERT(output_edge.data.weight >= 0);
|
BOOST_ASSERT(output_edge.data.weight > 0);
|
||||||
BOOST_ASSERT(output_edge.data.duration >= 0);
|
BOOST_ASSERT(output_edge.data.duration > 0);
|
||||||
if (output_edge.data.distance <= 0)
|
BOOST_ASSERT(output_edge.data.distance > 0);
|
||||||
{
|
|
||||||
std::cout << "output_edge.data.distance " << output_edge.data.distance << std::endl;
|
|
||||||
}
|
|
||||||
BOOST_ASSERT(output_edge.data.distance >= 0);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
tbb::parallel_sort(edges_list.begin(), edges_list.end());
|
tbb::parallel_sort(edges_list.begin(), edges_list.end());
|
||||||
|
|||||||
@@ -195,8 +195,6 @@ template <> class vector_view<bool>
|
|||||||
{
|
{
|
||||||
BOOST_ASSERT_MSG(index < m_size, "invalid size");
|
BOOST_ASSERT_MSG(index < m_size, "invalid size");
|
||||||
const std::size_t bucket = index / WORD_BITS;
|
const std::size_t bucket = index / WORD_BITS;
|
||||||
// Note: ordering of bits here should match packBits in storage/serialization.hpp
|
|
||||||
// so that directly mmap-ing data is possible
|
|
||||||
const auto offset = index % WORD_BITS;
|
const auto offset = index % WORD_BITS;
|
||||||
return m_ptr[bucket] & (static_cast<Word>(1) << offset);
|
return m_ptr[bucket] & (static_cast<Word>(1) << offset);
|
||||||
}
|
}
|
||||||
@@ -226,22 +224,11 @@ template <> class vector_view<bool>
|
|||||||
{
|
{
|
||||||
BOOST_ASSERT(index < m_size);
|
BOOST_ASSERT(index < m_size);
|
||||||
const auto bucket = index / WORD_BITS;
|
const auto bucket = index / WORD_BITS;
|
||||||
// Note: ordering of bits here should match packBits in storage/serialization.hpp
|
|
||||||
// so that directly mmap-ing data is possible
|
|
||||||
const auto offset = index % WORD_BITS;
|
const auto offset = index % WORD_BITS;
|
||||||
return reference{m_ptr + bucket, static_cast<Word>(1) << offset};
|
return reference{m_ptr + bucket, static_cast<Word>(1) << offset};
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> friend void swap(vector_view<T> &, vector_view<T> &) noexcept;
|
template <typename T> friend void swap(vector_view<T> &, vector_view<T> &) noexcept;
|
||||||
|
|
||||||
friend std::ostream &operator<<(std::ostream &os, const vector_view<bool> &rhs)
|
|
||||||
{
|
|
||||||
for (std::size_t i = 0; i < rhs.size(); ++i)
|
|
||||||
{
|
|
||||||
os << (i > 0 ? " " : "") << rhs.at(i);
|
|
||||||
}
|
|
||||||
return os;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Both vector_view<T> and the vector_view<bool> specializations share this impl.
|
// Both vector_view<T> and the vector_view<bool> specializations share this impl.
|
||||||
|
|||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "osrm",
|
"name": "osrm",
|
||||||
"version": "5.20.0-alpha.3",
|
"version": "5.20.0-alpha.1",
|
||||||
"private": false,
|
"private": false,
|
||||||
"description": "The Open Source Routing Machine is a high performance routing engine written in C++14 designed to run on OpenStreetMap data.",
|
"description": "The Open Source Routing Machine is a high performance routing engine written in C++14 designed to run on OpenStreetMap data.",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"lint": "node ./node_modules/eslint/bin/eslint.js -c ./.eslintrc features/step_definitions/ features/support/",
|
"lint": "node ./node_modules/eslint/bin/eslint.js -c ./.eslintrc features/step_definitions/ features/support/",
|
||||||
"test": "npm run lint && node ./node_modules/cucumber/bin/cucumber.js features/ -p verify && node ./node_modules/cucumber/bin/cucumber.js features/ -p verify -m mmap && node ./node_modules/cucumber/bin/cucumber.js features/ -p mld && node ./node_modules/cucumber/bin/cucumber.js features/ -p mld -m mmap",
|
"test": "npm run lint && node ./node_modules/cucumber/bin/cucumber.js features/ -p verify && node ./node_modules/cucumber/bin/cucumber.js features/ -p mld",
|
||||||
"clean": "rm -rf test/cache",
|
"clean": "rm -rf test/cache",
|
||||||
"docs": "./scripts/build_api_docs.sh",
|
"docs": "./scripts/build_api_docs.sh",
|
||||||
"install": "node-pre-gyp install --fallback-to-build=false || ./scripts/node_install.sh",
|
"install": "node-pre-gyp install --fallback-to-build=false || ./scripts/node_install.sh",
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
#include "engine/datafacade/mmap_memory_allocator.hpp"
|
#include "engine/datafacade/mmap_memory_allocator.hpp"
|
||||||
|
|
||||||
#include "storage/block.hpp"
|
|
||||||
#include "storage/io.hpp"
|
#include "storage/io.hpp"
|
||||||
#include "storage/serialization.hpp"
|
#include "storage/serialization.hpp"
|
||||||
#include "storage/storage.hpp"
|
#include "storage/storage.hpp"
|
||||||
@@ -17,52 +16,47 @@ namespace engine
|
|||||||
namespace datafacade
|
namespace datafacade
|
||||||
{
|
{
|
||||||
|
|
||||||
MMapMemoryAllocator::MMapMemoryAllocator(const storage::StorageConfig &config)
|
MMapMemoryAllocator::MMapMemoryAllocator(const storage::StorageConfig &config,
|
||||||
|
const boost::filesystem::path &memory_file)
|
||||||
{
|
{
|
||||||
storage::Storage storage(config);
|
storage::Storage storage(config);
|
||||||
std::vector<storage::SharedDataIndex::AllocatedRegion> allocated_regions;
|
|
||||||
|
|
||||||
|
if (!boost::filesystem::exists(memory_file))
|
||||||
{
|
{
|
||||||
std::unique_ptr<storage::BaseDataLayout> fake_layout =
|
storage::DataLayout initial_layout;
|
||||||
std::make_unique<storage::TarDataLayout>();
|
storage.PopulateStaticLayout(initial_layout);
|
||||||
|
storage.PopulateUpdatableLayout(initial_layout);
|
||||||
|
|
||||||
// Convert the boost::filesystem::path object into a plain string
|
auto data_size = initial_layout.GetSizeOfLayout();
|
||||||
// that's stored as a member of this allocator object
|
|
||||||
rtree_filename = storage.PopulateLayoutWithRTree(fake_layout);
|
|
||||||
|
|
||||||
// Now, we add one more AllocatedRegion, with it's start address as the start
|
storage::io::BufferWriter writer;
|
||||||
// of the rtree_filename string we've saved. In the fake_layout, we've
|
storage::serialization::write(writer, initial_layout);
|
||||||
// stated that the data is at offset 0, which is where the string starts
|
auto encoded_layout = writer.GetBuffer();
|
||||||
// at it's own memory address.
|
|
||||||
// The syntax &(rtree_filename[0]) gets the memory address of the first char.
|
auto total_size = data_size + encoded_layout.size();
|
||||||
// We can't use the convenient `.data()` or `.c_str()` methods, because
|
|
||||||
// prior to C++17 (which we're not using), those return a `const char *`,
|
mapped_memory = util::mmapFile<char>(memory_file, mapped_memory_file, total_size);
|
||||||
// which isn't compatible with the `char *` that AllocatedRegion expects
|
|
||||||
// for it's memory_ptr
|
std::copy(encoded_layout.begin(), encoded_layout.end(), mapped_memory.data());
|
||||||
allocated_regions.push_back({&(rtree_filename[0]), std::move(fake_layout)});
|
|
||||||
|
index = storage::SharedDataIndex(
|
||||||
|
{{mapped_memory.data() + encoded_layout.size(), std::move(initial_layout)}});
|
||||||
|
|
||||||
|
storage.PopulateStaticData(index);
|
||||||
|
storage.PopulateUpdatableData(index);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
std::vector<std::pair<bool, boost::filesystem::path>> files = storage.GetStaticFiles();
|
|
||||||
std::vector<std::pair<bool, boost::filesystem::path>> updatable_files =
|
|
||||||
storage.GetUpdatableFiles();
|
|
||||||
files.insert(files.end(), updatable_files.begin(), updatable_files.end());
|
|
||||||
|
|
||||||
for (const auto &file : files)
|
|
||||||
{
|
{
|
||||||
if (boost::filesystem::exists(file.second))
|
mapped_memory = util::mmapFile<char>(memory_file, mapped_memory_file);
|
||||||
{
|
|
||||||
std::unique_ptr<storage::BaseDataLayout> layout =
|
|
||||||
std::make_unique<storage::TarDataLayout>();
|
|
||||||
boost::iostreams::mapped_file mapped_memory_file;
|
|
||||||
util::mmapFile<char>(file.second, mapped_memory_file);
|
|
||||||
mapped_memory_files.push_back(std::move(mapped_memory_file));
|
|
||||||
storage.readBlocks(file.second, layout);
|
|
||||||
allocated_regions.push_back({mapped_memory_file.data(), std::move(layout)});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
index = storage::SharedDataIndex{std::move(allocated_regions)};
|
storage::DataLayout layout;
|
||||||
} // namespace datafacade
|
storage::io::BufferReader reader(mapped_memory.data(), mapped_memory.size());
|
||||||
|
storage::serialization::read(reader, layout);
|
||||||
|
auto layout_size = reader.GetPosition();
|
||||||
|
|
||||||
|
index = storage::SharedDataIndex({{mapped_memory.data() + layout_size, std::move(layout)}});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MMapMemoryAllocator::~MMapMemoryAllocator() {}
|
MMapMemoryAllocator::~MMapMemoryAllocator() {}
|
||||||
|
|
||||||
|
|||||||
@@ -15,26 +15,20 @@ ProcessMemoryAllocator::ProcessMemoryAllocator(const storage::StorageConfig &con
|
|||||||
storage::Storage storage(config);
|
storage::Storage storage(config);
|
||||||
|
|
||||||
// Calculate the layout/size of the memory block
|
// Calculate the layout/size of the memory block
|
||||||
std::vector<std::pair<bool, boost::filesystem::path>> static_files = storage.GetStaticFiles();
|
storage::DataLayout layout;
|
||||||
std::vector<std::pair<bool, boost::filesystem::path>> updatable_files =
|
storage.PopulateStaticLayout(layout);
|
||||||
storage.GetUpdatableFiles();
|
storage.PopulateUpdatableLayout(layout);
|
||||||
std::unique_ptr<storage::BaseDataLayout> layout = std::make_unique<storage::DataLayout>();
|
|
||||||
storage.PopulateLayoutWithRTree(layout);
|
|
||||||
storage.PopulateLayout(layout, static_files);
|
|
||||||
storage.PopulateLayout(layout, updatable_files);
|
|
||||||
|
|
||||||
// Allocate the memory block, then load data from files into it
|
// Allocate the memory block, then load data from files into it
|
||||||
internal_memory = std::make_unique<char[]>(layout->GetSizeOfLayout());
|
internal_memory = std::make_unique<char[]>(layout.GetSizeOfLayout());
|
||||||
|
|
||||||
std::vector<storage::SharedDataIndex::AllocatedRegion> regions;
|
index = storage::SharedDataIndex({{internal_memory.get(), std::move(layout)}});
|
||||||
regions.push_back({internal_memory.get(), std::move(layout)});
|
|
||||||
index = {std::move(regions)};
|
|
||||||
|
|
||||||
storage.PopulateStaticData(index);
|
storage.PopulateStaticData(index);
|
||||||
storage.PopulateUpdatableData(index);
|
storage.PopulateUpdatableData(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessMemoryAllocator::~ProcessMemoryAllocator() { /* free(internal_memory) */}
|
ProcessMemoryAllocator::~ProcessMemoryAllocator() {}
|
||||||
|
|
||||||
const storage::SharedDataIndex &ProcessMemoryAllocator::GetIndex() { return index; }
|
const storage::SharedDataIndex &ProcessMemoryAllocator::GetIndex() { return index; }
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ SharedMemoryAllocator::SharedMemoryAllocator(
|
|||||||
auto mem = storage::makeSharedMemory(shm_key);
|
auto mem = storage::makeSharedMemory(shm_key);
|
||||||
|
|
||||||
storage::io::BufferReader reader(reinterpret_cast<char *>(mem->Ptr()), mem->Size());
|
storage::io::BufferReader reader(reinterpret_cast<char *>(mem->Ptr()), mem->Size());
|
||||||
std::unique_ptr<storage::BaseDataLayout> layout = std::make_unique<storage::DataLayout>();
|
storage::DataLayout layout;
|
||||||
storage::serialization::read(reader, layout);
|
storage::serialization::read(reader, layout);
|
||||||
auto layout_size = reader.GetPosition();
|
auto layout_size = reader.GetPosition();
|
||||||
|
|
||||||
|
|||||||
@@ -23,9 +23,7 @@ bool EngineConfig::IsValid() const
|
|||||||
unlimited_or_more_than(max_results_nearest, 0) &&
|
unlimited_or_more_than(max_results_nearest, 0) &&
|
||||||
max_alternatives >= 0;
|
max_alternatives >= 0;
|
||||||
|
|
||||||
return ((use_shared_memory && all_path_are_empty) || (use_mmap && storage_config.IsValid()) ||
|
return ((use_shared_memory && all_path_are_empty) || storage_config.IsValid()) && limits_valid;
|
||||||
storage_config.IsValid()) &&
|
}
|
||||||
limits_valid;
|
}
|
||||||
}
|
}
|
||||||
} // namespace engine
|
|
||||||
} // namespace osrm
|
|
||||||
|
|||||||
@@ -254,74 +254,12 @@ void calculateDistances(typename SearchEngineData<ch::Algorithm>::ManyToManyQuer
|
|||||||
}
|
}
|
||||||
if (!packed_leg.empty())
|
if (!packed_leg.empty())
|
||||||
{
|
{
|
||||||
auto annotation =
|
EdgeDistance annotation =
|
||||||
ch::calculateEBGNodeAnnotations(facade, packed_leg.begin(), packed_leg.end());
|
ch::calculateEBGNodeAnnotations(facade, packed_leg.begin(), packed_leg.end());
|
||||||
|
annotation = adjustPathDistanceToPhantomNodes(
|
||||||
|
packed_leg, source_phantom, target_phantom, annotation);
|
||||||
|
|
||||||
distances_table[row_index * number_of_targets + column_index] = annotation;
|
distances_table[row_index * number_of_targets + column_index] = annotation;
|
||||||
|
|
||||||
// check the direction of travel to figure out how to calculate the offset to/from
|
|
||||||
// the source/target
|
|
||||||
if (source_phantom.forward_segment_id.id == packed_leg.front())
|
|
||||||
{
|
|
||||||
// ............ <-- calculateEGBAnnotation returns distance from 0 to 3
|
|
||||||
// -->s <-- subtract offset to start at source
|
|
||||||
// ......... <-- want this distance as result
|
|
||||||
// entry 0---1---2---3--- <-- 3 is exit node
|
|
||||||
EdgeDistance offset = source_phantom.GetForwardDistance();
|
|
||||||
distances_table[row_index * number_of_targets + column_index] -= offset;
|
|
||||||
}
|
|
||||||
else if (source_phantom.reverse_segment_id.id == packed_leg.front())
|
|
||||||
{
|
|
||||||
// ............ <-- calculateEGBAnnotation returns distance from 0 to 3
|
|
||||||
// s<------- <-- subtract offset to start at source
|
|
||||||
// ... <-- want this distance
|
|
||||||
// entry 0---1---2---3 <-- 3 is exit node
|
|
||||||
EdgeDistance offset = source_phantom.GetReverseDistance();
|
|
||||||
distances_table[row_index * number_of_targets + column_index] -= offset;
|
|
||||||
}
|
|
||||||
if (target_phantom.forward_segment_id.id == packed_leg.back())
|
|
||||||
{
|
|
||||||
// ............ <-- calculateEGBAnnotation returns distance from 0 to 3
|
|
||||||
// ++>t <-- add offset to get to target
|
|
||||||
// ................ <-- want this distance as result
|
|
||||||
// entry 0---1---2---3--- <-- 3 is exit node
|
|
||||||
EdgeDistance offset = target_phantom.GetForwardDistance();
|
|
||||||
distances_table[row_index * number_of_targets + column_index] += offset;
|
|
||||||
}
|
|
||||||
else if (target_phantom.reverse_segment_id.id == packed_leg.back())
|
|
||||||
{
|
|
||||||
// ............ <-- calculateEGBAnnotation returns distance from 0 to 3
|
|
||||||
// <++t <-- add offset to get from target
|
|
||||||
// ................ <-- want this distance as result
|
|
||||||
// entry 0---1---2---3--- <-- 3 is exit node
|
|
||||||
EdgeDistance offset = target_phantom.GetReverseDistance();
|
|
||||||
distances_table[row_index * number_of_targets + column_index] += offset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// there is no shortcut to unpack. source and target are on the same EBG Node.
|
|
||||||
// if the offset of the target is greater than the offset of the source, subtract it
|
|
||||||
if (target_phantom.GetForwardDistance() > source_phantom.GetForwardDistance())
|
|
||||||
{
|
|
||||||
// --------->t <-- offsets
|
|
||||||
// ->s <-- subtract source offset from target offset
|
|
||||||
// ......... <-- want this distance as result
|
|
||||||
// entry 0---1---2---3--- <-- 3 is exit node
|
|
||||||
EdgeDistance offset =
|
|
||||||
target_phantom.GetForwardDistance() - source_phantom.GetForwardDistance();
|
|
||||||
distances_table[row_index * number_of_targets + column_index] = offset;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// s<--- <-- offsets
|
|
||||||
// t<--------- <-- subtract source offset from target offset
|
|
||||||
// ...... <-- want this distance as result
|
|
||||||
// entry 0---1---2---3--- <-- 3 is exit node
|
|
||||||
EdgeDistance offset =
|
|
||||||
target_phantom.GetReverseDistance() - source_phantom.GetReverseDistance();
|
|
||||||
distances_table[row_index * number_of_targets + column_index] = offset;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
packed_leg.clear();
|
packed_leg.clear();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -227,6 +227,9 @@ SubMatchingList mapMatching(SearchEngineData<Algorithm> &engine_working_data,
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
forward_heap.Clear();
|
||||||
|
const auto &source_phantom = prev_unbroken_timestamps_list[s].phantom_node;
|
||||||
|
insertSourceInHeap(forward_heap, source_phantom);
|
||||||
|
|
||||||
for (const auto s_prime : util::irange<std::size_t>(0UL, current_viterbi.size()))
|
for (const auto s_prime : util::irange<std::size_t>(0UL, current_viterbi.size()))
|
||||||
{
|
{
|
||||||
@@ -237,14 +240,19 @@ SubMatchingList mapMatching(SearchEngineData<Algorithm> &engine_working_data,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
double network_distance =
|
reverse_heap.Clear();
|
||||||
getNetworkDistance(engine_working_data,
|
const auto &target_phantom = current_timestamps_list[s_prime].phantom_node;
|
||||||
facade,
|
insertTargetInHeap(reverse_heap, target_phantom);
|
||||||
forward_heap,
|
|
||||||
reverse_heap,
|
double network_distance = getNetworkDistance(engine_working_data,
|
||||||
prev_unbroken_timestamps_list[s].phantom_node,
|
facade,
|
||||||
current_timestamps_list[s_prime].phantom_node,
|
forward_heap,
|
||||||
weight_upper_bound);
|
reverse_heap,
|
||||||
|
source_phantom,
|
||||||
|
target_phantom,
|
||||||
|
weight_upper_bound);
|
||||||
|
|
||||||
|
network_distance = std::round(network_distance * 10) / 10;
|
||||||
|
|
||||||
// get distance diff between loc1/2 and locs/s_prime
|
// get distance diff between loc1/2 and locs/s_prime
|
||||||
const auto d_t = std::abs(network_distance - haversine_distance);
|
const auto d_t = std::abs(network_distance - haversine_distance);
|
||||||
|
|||||||
@@ -33,6 +33,79 @@ bool needsLoopBackwards(const PhantomNodes &phantoms)
|
|||||||
return needsLoopBackwards(phantoms.source_phantom, phantoms.target_phantom);
|
return needsLoopBackwards(phantoms.source_phantom, phantoms.target_phantom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EdgeDistance adjustPathDistanceToPhantomNodes(const std::vector<NodeID> &path,
|
||||||
|
const PhantomNode &source_phantom,
|
||||||
|
const PhantomNode &target_phantom,
|
||||||
|
const EdgeDistance uncorrected_distance)
|
||||||
|
{
|
||||||
|
EdgeDistance distance = uncorrected_distance;
|
||||||
|
if (!path.empty())
|
||||||
|
{
|
||||||
|
|
||||||
|
// check the direction of travel to figure out how to calculate the offset to/from
|
||||||
|
// the source/target
|
||||||
|
if (source_phantom.forward_segment_id.id == path.front())
|
||||||
|
{
|
||||||
|
// ............ <-- calculateEGBAnnotation returns distance from 0 to 3
|
||||||
|
// -->s <-- subtract offset to start at source
|
||||||
|
// ......... <-- want this distance as result
|
||||||
|
// entry 0---1---2---3--- <-- 3 is exit node
|
||||||
|
distance -= source_phantom.GetForwardDistance();
|
||||||
|
}
|
||||||
|
else if (source_phantom.reverse_segment_id.id == path.front())
|
||||||
|
{
|
||||||
|
// ............ <-- calculateEGBAnnotation returns distance from 0 to 3
|
||||||
|
// s<------- <-- subtract offset to start at source
|
||||||
|
// ... <-- want this distance
|
||||||
|
// entry 0---1---2---3 <-- 3 is exit node
|
||||||
|
distance -= source_phantom.GetReverseDistance();
|
||||||
|
}
|
||||||
|
if (target_phantom.forward_segment_id.id == path.back())
|
||||||
|
{
|
||||||
|
// ............ <-- calculateEGBAnnotation returns distance from 0 to 3
|
||||||
|
// ++>t <-- add offset to get to target
|
||||||
|
// ................ <-- want this distance as result
|
||||||
|
// entry 0---1---2---3--- <-- 3 is exit node
|
||||||
|
distance += target_phantom.GetForwardDistance();
|
||||||
|
}
|
||||||
|
else if (target_phantom.reverse_segment_id.id == path.back())
|
||||||
|
{
|
||||||
|
// ............ <-- calculateEGBAnnotation returns distance from 0 to 3
|
||||||
|
// <++t <-- add offset to get from target
|
||||||
|
// ................ <-- want this distance as result
|
||||||
|
// entry 0---1---2---3--- <-- 3 is exit node
|
||||||
|
distance += target_phantom.GetReverseDistance();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// there is no shortcut to unpack. source and target are on the same EBG Node.
|
||||||
|
// if the offset of the target is greater than the offset of the source, subtract it
|
||||||
|
if (target_phantom.GetForwardDistance() > source_phantom.GetForwardDistance())
|
||||||
|
{
|
||||||
|
// --------->t <-- offsets
|
||||||
|
// ->s <-- subtract source offset from target offset
|
||||||
|
// ......... <-- want this distance as result
|
||||||
|
// entry 0---1---2---3--- <-- 3 is exit node
|
||||||
|
distance = target_phantom.GetForwardDistance() - source_phantom.GetForwardDistance();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// s<--- <-- offsets
|
||||||
|
// t<--------- <-- subtract source offset from target offset
|
||||||
|
// ...... <-- want this distance as result
|
||||||
|
// entry 0---1---2---3--- <-- 3 is exit node
|
||||||
|
distance = target_phantom.GetReverseDistance() - source_phantom.GetReverseDistance();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_ASSERT_MSG(distance >= 0 || distance > -1.0f,
|
||||||
|
"Distance correction generated negative number");
|
||||||
|
// guard against underflow errors caused by rounding
|
||||||
|
distance = std::max(EdgeDistance{0}, distance);
|
||||||
|
return distance;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace routing_algorithms
|
} // namespace routing_algorithms
|
||||||
} // namespace engine
|
} // namespace engine
|
||||||
} // namespace osrm
|
} // namespace osrm
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ void search(SearchEngineData<Algorithm> & /*engine_working_data*/,
|
|||||||
const PhantomNodes & /*phantom_nodes*/,
|
const PhantomNodes & /*phantom_nodes*/,
|
||||||
const EdgeWeight weight_upper_bound)
|
const EdgeWeight weight_upper_bound)
|
||||||
{
|
{
|
||||||
if (forward_heap.Empty() || reverse_heap.Empty())
|
if (forward_heap.Empty() && reverse_heap.Empty())
|
||||||
{
|
{
|
||||||
weight = INVALID_EDGE_WEIGHT;
|
weight = INVALID_EDGE_WEIGHT;
|
||||||
return;
|
return;
|
||||||
@@ -110,10 +110,14 @@ void search(SearchEngineData<Algorithm> & /*engine_working_data*/,
|
|||||||
weight = weight_upper_bound;
|
weight = weight_upper_bound;
|
||||||
|
|
||||||
// get offset to account for offsets on phantom nodes on compressed edges
|
// get offset to account for offsets on phantom nodes on compressed edges
|
||||||
const auto min_edge_offset = std::min(0, forward_heap.MinKey());
|
EdgeWeight min_edge_offset = 0;
|
||||||
BOOST_ASSERT(min_edge_offset <= 0);
|
if (forward_heap.Size() > 0)
|
||||||
|
{
|
||||||
|
min_edge_offset = std::min(min_edge_offset, forward_heap.MinKey());
|
||||||
|
BOOST_ASSERT(min_edge_offset <= 0);
|
||||||
|
}
|
||||||
// we only every insert negative offsets for nodes in the forward heap
|
// we only every insert negative offsets for nodes in the forward heap
|
||||||
BOOST_ASSERT(reverse_heap.MinKey() >= 0);
|
BOOST_ASSERT(reverse_heap.Empty() || reverse_heap.MinKey() >= 0);
|
||||||
|
|
||||||
// run two-Target Dijkstra routing step.
|
// run two-Target Dijkstra routing step.
|
||||||
while (0 < (forward_heap.Size() + reverse_heap.Size()))
|
while (0 < (forward_heap.Size() + reverse_heap.Size()))
|
||||||
@@ -176,11 +180,6 @@ double getNetworkDistance(SearchEngineData<Algorithm> &engine_working_data,
|
|||||||
const PhantomNode &target_phantom,
|
const PhantomNode &target_phantom,
|
||||||
EdgeWeight weight_upper_bound)
|
EdgeWeight weight_upper_bound)
|
||||||
{
|
{
|
||||||
forward_heap.Clear();
|
|
||||||
reverse_heap.Clear();
|
|
||||||
|
|
||||||
insertNodesInHeaps(forward_heap, reverse_heap, {source_phantom, target_phantom});
|
|
||||||
|
|
||||||
EdgeWeight weight = INVALID_EDGE_WEIGHT;
|
EdgeWeight weight = INVALID_EDGE_WEIGHT;
|
||||||
std::vector<NodeID> packed_path;
|
std::vector<NodeID> packed_path;
|
||||||
search(engine_working_data,
|
search(engine_working_data,
|
||||||
@@ -199,14 +198,31 @@ double getNetworkDistance(SearchEngineData<Algorithm> &engine_working_data,
|
|||||||
return std::numeric_limits<double>::max();
|
return std::numeric_limits<double>::max();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<PathData> unpacked_path;
|
EdgeDistance distance = 0;
|
||||||
unpackPath(facade,
|
|
||||||
packed_path.begin(),
|
|
||||||
packed_path.end(),
|
|
||||||
{source_phantom, target_phantom},
|
|
||||||
unpacked_path);
|
|
||||||
|
|
||||||
return getPathDistance(facade, unpacked_path, source_phantom, target_phantom);
|
std::vector<NodeID> unpacked_nodes;
|
||||||
|
unpacked_nodes.reserve(packed_path.size());
|
||||||
|
if (!packed_path.empty())
|
||||||
|
{
|
||||||
|
unpacked_nodes.push_back(packed_path.front());
|
||||||
|
unpackPath(
|
||||||
|
facade, packed_path.begin(), packed_path.end(), [&](const auto &edge, const auto &) {
|
||||||
|
BOOST_ASSERT(edge.first == unpacked_nodes.back());
|
||||||
|
unpacked_nodes.push_back(edge.second);
|
||||||
|
});
|
||||||
|
|
||||||
|
distance = std::accumulate(unpacked_nodes.begin(),
|
||||||
|
std::prev(unpacked_nodes.end()),
|
||||||
|
EdgeDistance{0},
|
||||||
|
[&](const EdgeDistance distance, const auto node_id) {
|
||||||
|
return distance + computeEdgeDistance(facade, node_id);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
distance =
|
||||||
|
adjustPathDistanceToPhantomNodes(unpacked_nodes, source_phantom, target_phantom, distance);
|
||||||
|
|
||||||
|
return distance;
|
||||||
}
|
}
|
||||||
} // namespace ch
|
} // namespace ch
|
||||||
|
|
||||||
|
|||||||
@@ -555,21 +555,21 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
|||||||
&scripting_environment,
|
&scripting_environment,
|
||||||
weight_multiplier,
|
weight_multiplier,
|
||||||
&conditional_restriction_map](
|
&conditional_restriction_map](
|
||||||
// what nodes will be used? In most cases this will be the id
|
// what nodes will be used? In most cases this will be the id
|
||||||
// stored in the edge_data. In case of duplicated nodes (e.g.
|
// stored in the edge_data. In case of duplicated nodes (e.g.
|
||||||
// due to via-way restrictions), one/both of these might
|
// due to via-way restrictions), one/both of these might
|
||||||
// refer to a newly added edge based node
|
// refer to a newly added edge based node
|
||||||
const auto edge_based_node_from,
|
const auto edge_based_node_from,
|
||||||
const auto edge_based_node_to,
|
const auto edge_based_node_to,
|
||||||
// the situation of the turn
|
// the situation of the turn
|
||||||
const auto node_along_road_entering,
|
const auto node_along_road_entering,
|
||||||
const auto node_based_edge_from,
|
const auto node_based_edge_from,
|
||||||
const auto intersection_node,
|
const auto intersection_node,
|
||||||
const auto node_based_edge_to,
|
const auto node_based_edge_to,
|
||||||
const auto &turn_angle,
|
const auto &turn_angle,
|
||||||
const auto &road_legs_on_the_right,
|
const auto &road_legs_on_the_right,
|
||||||
const auto &road_legs_on_the_left,
|
const auto &road_legs_on_the_left,
|
||||||
const auto &edge_geometries) {
|
const auto &edge_geometries) {
|
||||||
const auto node_restricted =
|
const auto node_restricted =
|
||||||
isRestricted(node_along_road_entering,
|
isRestricted(node_along_road_entering,
|
||||||
intersection_node,
|
intersection_node,
|
||||||
@@ -890,7 +890,7 @@ void EdgeBasedGraphFactory::GenerateEdgeExpandedEdges(
|
|||||||
// TODO: this loop is not optimized - once we have a few
|
// TODO: this loop is not optimized - once we have a few
|
||||||
// overrides available, we should index this for faster
|
// overrides available, we should index this for faster
|
||||||
// lookups
|
// lookups
|
||||||
for (auto & override : unresolved_maneuver_overrides)
|
for (auto &override : unresolved_maneuver_overrides)
|
||||||
{
|
{
|
||||||
for (auto &turn : override.turn_sequence)
|
for (auto &turn : override.turn_sequence)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -277,8 +277,8 @@ void ExtractionContainers::PrepareEdges(ScriptingEnvironment &scripting_environm
|
|||||||
{
|
{
|
||||||
if (edge_iterator->result.osm_source_id < node_iterator->node_id)
|
if (edge_iterator->result.osm_source_id < node_iterator->node_id)
|
||||||
{
|
{
|
||||||
util::Log(logDEBUG) << "Found invalid node reference "
|
util::Log(logDEBUG)
|
||||||
<< edge_iterator->result.source;
|
<< "Found invalid node reference " << edge_iterator->result.source;
|
||||||
edge_iterator->result.source = SPECIAL_NODEID;
|
edge_iterator->result.source = SPECIAL_NODEID;
|
||||||
++edge_iterator;
|
++edge_iterator;
|
||||||
continue;
|
continue;
|
||||||
@@ -1038,8 +1038,9 @@ void ExtractionContainers::PrepareRestrictions()
|
|||||||
// translate the turn from one segment onto another into a node restriction (the ways can
|
// translate the turn from one segment onto another into a node restriction (the ways can
|
||||||
// only
|
// only
|
||||||
// be connected at a single location)
|
// be connected at a single location)
|
||||||
auto const get_node_restriction_from_OSM_ids = [&](
|
auto const get_node_restriction_from_OSM_ids = [&](auto const from_id,
|
||||||
auto const from_id, auto const to_id, const OSMNodeID via_node) {
|
auto const to_id,
|
||||||
|
const OSMNodeID via_node) {
|
||||||
auto const from_segment_itr = referenced_ways.find(from_id);
|
auto const from_segment_itr = referenced_ways.find(from_id);
|
||||||
if (from_segment_itr->second.way_id != from_id)
|
if (from_segment_itr->second.way_id != from_id)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ void ExtractorCallbacks::ProcessRestriction(const InputConditionalTurnRestrictio
|
|||||||
// util::Log() << restriction.toString();
|
// util::Log() << restriction.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExtractorCallbacks::ProcessManeuverOverride(const InputManeuverOverride & override)
|
void ExtractorCallbacks::ProcessManeuverOverride(const InputManeuverOverride &override)
|
||||||
{
|
{
|
||||||
external_memory.external_maneuver_overrides_list.push_back(override);
|
external_memory.external_maneuver_overrides_list.push_back(override);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -185,17 +185,18 @@ void GraphCompressor::Compress(
|
|||||||
* just
|
* just
|
||||||
* like a barrier.
|
* like a barrier.
|
||||||
*/
|
*/
|
||||||
const auto selectAnnotation = [&node_data_container](
|
const auto selectAnnotation =
|
||||||
const AnnotationID front_annotation, const AnnotationID back_annotation) {
|
[&node_data_container](const AnnotationID front_annotation,
|
||||||
// A lane has tags: u - (front) - v - (back) - w
|
const AnnotationID back_annotation) {
|
||||||
// During contraction, we keep only one of the tags. Usually the one closer
|
// A lane has tags: u - (front) - v - (back) - w
|
||||||
// to the intersection is preferred. If its empty, however, we keep the
|
// During contraction, we keep only one of the tags. Usually the one closer
|
||||||
// non-empty one
|
// to the intersection is preferred. If its empty, however, we keep the
|
||||||
if (node_data_container[back_annotation].lane_description_id ==
|
// non-empty one
|
||||||
INVALID_LANE_DESCRIPTIONID)
|
if (node_data_container[back_annotation].lane_description_id ==
|
||||||
return front_annotation;
|
INVALID_LANE_DESCRIPTIONID)
|
||||||
return back_annotation;
|
return front_annotation;
|
||||||
};
|
return back_annotation;
|
||||||
|
};
|
||||||
|
|
||||||
graph.GetEdgeData(forward_e1).annotation_data = selectAnnotation(
|
graph.GetEdgeData(forward_e1).annotation_data = selectAnnotation(
|
||||||
fwd_edge_data1.annotation_data, fwd_edge_data2.annotation_data);
|
fwd_edge_data1.annotation_data, fwd_edge_data2.annotation_data);
|
||||||
|
|||||||
+11
-92
@@ -9,15 +9,12 @@
|
|||||||
#include "osrm/trip_parameters.hpp"
|
#include "osrm/trip_parameters.hpp"
|
||||||
|
|
||||||
#include <exception>
|
#include <exception>
|
||||||
#include <sstream>
|
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "nodejs/node_osrm.hpp"
|
#include "nodejs/node_osrm.hpp"
|
||||||
#include "nodejs/node_osrm_support.hpp"
|
#include "nodejs/node_osrm_support.hpp"
|
||||||
|
|
||||||
#include "util/json_renderer.hpp"
|
|
||||||
|
|
||||||
namespace node_osrm
|
namespace node_osrm
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -125,8 +122,6 @@ inline void async(const Nan::FunctionCallbackInfo<v8::Value> &info,
|
|||||||
if (!params)
|
if (!params)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto pluginParams = argumentsToPluginParameters(info);
|
|
||||||
|
|
||||||
BOOST_ASSERT(params->IsValid());
|
BOOST_ASSERT(params->IsValid());
|
||||||
|
|
||||||
if (!info[info.Length() - 1]->IsFunction())
|
if (!info[info.Length() - 1]->IsFunction())
|
||||||
@@ -142,89 +137,9 @@ inline void async(const Nan::FunctionCallbackInfo<v8::Value> &info,
|
|||||||
Worker(std::shared_ptr<osrm::OSRM> osrm_,
|
Worker(std::shared_ptr<osrm::OSRM> osrm_,
|
||||||
ParamPtr params_,
|
ParamPtr params_,
|
||||||
ServiceMemFn service,
|
ServiceMemFn service,
|
||||||
Nan::Callback *callback,
|
Nan::Callback *callback)
|
||||||
PluginParameters pluginParams_)
|
|
||||||
: Base(callback), osrm{std::move(osrm_)}, service{std::move(service)},
|
: Base(callback), osrm{std::move(osrm_)}, service{std::move(service)},
|
||||||
params{std::move(params_)}, pluginParams{std::move(pluginParams_)}
|
params{std::move(params_)}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void Execute() override try
|
|
||||||
{
|
|
||||||
osrm::json::Object r;
|
|
||||||
const auto status = ((*osrm).*(service))(*params, r);
|
|
||||||
ParseResult(status, r);
|
|
||||||
if (pluginParams.renderJSONToBuffer)
|
|
||||||
{
|
|
||||||
std::ostringstream buf;
|
|
||||||
osrm::util::json::render(buf, r);
|
|
||||||
result = buf.str();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
result = r;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (const std::exception &e)
|
|
||||||
{
|
|
||||||
SetErrorMessage(e.what());
|
|
||||||
}
|
|
||||||
|
|
||||||
void HandleOKCallback() override
|
|
||||||
{
|
|
||||||
Nan::HandleScope scope;
|
|
||||||
|
|
||||||
const constexpr auto argc = 2u;
|
|
||||||
v8::Local<v8::Value> argv[argc] = {Nan::Null(), render(result)};
|
|
||||||
|
|
||||||
callback->Call(argc, argv);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Keeps the OSRM object alive even after shutdown until we're done with callback
|
|
||||||
std::shared_ptr<osrm::OSRM> osrm;
|
|
||||||
ServiceMemFn service;
|
|
||||||
const ParamPtr params;
|
|
||||||
const PluginParameters pluginParams;
|
|
||||||
|
|
||||||
ObjectOrString result;
|
|
||||||
};
|
|
||||||
|
|
||||||
auto *callback = new Nan::Callback{info[info.Length() - 1].As<v8::Function>()};
|
|
||||||
Nan::AsyncQueueWorker(
|
|
||||||
new Worker{self->this_, std::move(params), service, callback, std::move(pluginParams)});
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename ParameterParser, typename ServiceMemFn>
|
|
||||||
inline void asyncForTiles(const Nan::FunctionCallbackInfo<v8::Value> &info,
|
|
||||||
ParameterParser argsToParams,
|
|
||||||
ServiceMemFn service,
|
|
||||||
bool requires_multiple_coordinates)
|
|
||||||
{
|
|
||||||
auto params = argsToParams(info, requires_multiple_coordinates);
|
|
||||||
if (!params)
|
|
||||||
return;
|
|
||||||
|
|
||||||
auto pluginParams = argumentsToPluginParameters(info);
|
|
||||||
|
|
||||||
BOOST_ASSERT(params->IsValid());
|
|
||||||
|
|
||||||
if (!info[info.Length() - 1]->IsFunction())
|
|
||||||
return Nan::ThrowTypeError("last argument must be a callback function");
|
|
||||||
|
|
||||||
auto *const self = Nan::ObjectWrap::Unwrap<Engine>(info.Holder());
|
|
||||||
using ParamPtr = decltype(params);
|
|
||||||
|
|
||||||
struct Worker final : Nan::AsyncWorker
|
|
||||||
{
|
|
||||||
using Base = Nan::AsyncWorker;
|
|
||||||
|
|
||||||
Worker(std::shared_ptr<osrm::OSRM> osrm_,
|
|
||||||
ParamPtr params_,
|
|
||||||
ServiceMemFn service,
|
|
||||||
Nan::Callback *callback,
|
|
||||||
PluginParameters pluginParams_)
|
|
||||||
: Base(callback), osrm{std::move(osrm_)}, service{std::move(service)},
|
|
||||||
params{std::move(params_)}, pluginParams{std::move(pluginParams_)}
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -252,14 +167,18 @@ inline void asyncForTiles(const Nan::FunctionCallbackInfo<v8::Value> &info,
|
|||||||
std::shared_ptr<osrm::OSRM> osrm;
|
std::shared_ptr<osrm::OSRM> osrm;
|
||||||
ServiceMemFn service;
|
ServiceMemFn service;
|
||||||
const ParamPtr params;
|
const ParamPtr params;
|
||||||
const PluginParameters pluginParams;
|
|
||||||
|
|
||||||
std::string result;
|
// All services return json::Object .. except for Tile!
|
||||||
|
using ObjectOrString =
|
||||||
|
typename std::conditional<std::is_same<ParamPtr, tile_parameters_ptr>::value,
|
||||||
|
std::string,
|
||||||
|
osrm::json::Object>::type;
|
||||||
|
|
||||||
|
ObjectOrString result;
|
||||||
};
|
};
|
||||||
|
|
||||||
auto *callback = new Nan::Callback{info[info.Length() - 1].As<v8::Function>()};
|
auto *callback = new Nan::Callback{info[info.Length() - 1].As<v8::Function>()};
|
||||||
Nan::AsyncQueueWorker(
|
Nan::AsyncQueueWorker(new Worker{self->this_, std::move(params), service, callback});
|
||||||
new Worker{self->this_, std::move(params), service, callback, std::move(pluginParams)});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
@@ -422,7 +341,7 @@ NAN_METHOD(Engine::table) //
|
|||||||
// clang-format on
|
// clang-format on
|
||||||
NAN_METHOD(Engine::tile)
|
NAN_METHOD(Engine::tile)
|
||||||
{
|
{
|
||||||
asyncForTiles(info, &argumentsToTileParameters, &osrm::OSRM::Tile, {/*unused*/});
|
async(info, &argumentsToTileParameters, &osrm::OSRM::Tile, {/*unused*/});
|
||||||
}
|
}
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
|
|||||||
+73
-90
@@ -44,6 +44,24 @@ namespace
|
|||||||
{
|
{
|
||||||
using Monitor = SharedMonitor<SharedRegionRegister>;
|
using Monitor = SharedMonitor<SharedRegionRegister>;
|
||||||
|
|
||||||
|
void readBlocks(const boost::filesystem::path &path, DataLayout &layout)
|
||||||
|
{
|
||||||
|
tar::FileReader reader(path, tar::FileReader::VerifyFingerprint);
|
||||||
|
|
||||||
|
std::vector<tar::FileReader::FileEntry> entries;
|
||||||
|
reader.List(std::back_inserter(entries));
|
||||||
|
|
||||||
|
for (const auto &entry : entries)
|
||||||
|
{
|
||||||
|
const auto name_end = entry.name.rfind(".meta");
|
||||||
|
if (name_end == std::string::npos)
|
||||||
|
{
|
||||||
|
auto number_of_elements = reader.ReadElementCount64(entry.name);
|
||||||
|
layout.SetBlock(entry.name, Block{number_of_elements, entry.size});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct RegionHandle
|
struct RegionHandle
|
||||||
{
|
{
|
||||||
std::unique_ptr<SharedMemory> memory;
|
std::unique_ptr<SharedMemory> memory;
|
||||||
@@ -51,8 +69,7 @@ struct RegionHandle
|
|||||||
std::uint16_t shm_key;
|
std::uint16_t shm_key;
|
||||||
};
|
};
|
||||||
|
|
||||||
auto setupRegion(SharedRegionRegister &shared_register,
|
auto setupRegion(SharedRegionRegister &shared_register, const DataLayout &layout)
|
||||||
const std::unique_ptr<storage::BaseDataLayout> &layout)
|
|
||||||
{
|
{
|
||||||
// This is safe because we have an exclusive lock for all osrm-datastore processes.
|
// This is safe because we have an exclusive lock for all osrm-datastore processes.
|
||||||
auto shm_key = shared_register.ReserveKey();
|
auto shm_key = shared_register.ReserveKey();
|
||||||
@@ -73,7 +90,7 @@ auto setupRegion(SharedRegionRegister &shared_register,
|
|||||||
auto encoded_static_layout = writer.GetBuffer();
|
auto encoded_static_layout = writer.GetBuffer();
|
||||||
|
|
||||||
// Allocate shared memory block
|
// Allocate shared memory block
|
||||||
auto regions_size = encoded_static_layout.size() + layout->GetSizeOfLayout();
|
auto regions_size = encoded_static_layout.size() + layout.GetSizeOfLayout();
|
||||||
util::Log() << "Data layout has a size of " << encoded_static_layout.size() << " bytes";
|
util::Log() << "Data layout has a size of " << encoded_static_layout.size() << " bytes";
|
||||||
util::Log() << "Allocating shared memory of " << regions_size << " bytes";
|
util::Log() << "Allocating shared memory of " << regions_size << " bytes";
|
||||||
auto memory = makeSharedMemory(shm_key, regions_size);
|
auto memory = makeSharedMemory(shm_key, regions_size);
|
||||||
@@ -165,29 +182,10 @@ bool swapData(Monitor &monitor,
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} // namespace
|
}
|
||||||
|
|
||||||
Storage::Storage(StorageConfig config_) : config(std::move(config_)) {}
|
Storage::Storage(StorageConfig config_) : config(std::move(config_)) {}
|
||||||
|
|
||||||
void Storage::readBlocks(const boost::filesystem::path &path,
|
|
||||||
std::unique_ptr<storage::BaseDataLayout> &layout)
|
|
||||||
{
|
|
||||||
tar::FileReader reader(path, tar::FileReader::VerifyFingerprint);
|
|
||||||
|
|
||||||
std::vector<tar::FileReader::FileEntry> entries;
|
|
||||||
reader.List(std::back_inserter(entries));
|
|
||||||
|
|
||||||
for (const auto &entry : entries)
|
|
||||||
{
|
|
||||||
const auto name_end = entry.name.rfind(".meta");
|
|
||||||
if (name_end == std::string::npos)
|
|
||||||
{
|
|
||||||
auto number_of_elements = reader.ReadElementCount64(entry.name);
|
|
||||||
layout->SetBlock(entry.name, Block{number_of_elements, entry.size, entry.offset});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int Storage::Run(int max_wait, const std::string &dataset_name, bool only_metric)
|
int Storage::Run(int max_wait, const std::string &dataset_name, bool only_metric)
|
||||||
{
|
{
|
||||||
BOOST_ASSERT_MSG(config.IsValid(), "Invalid storage config");
|
BOOST_ASSERT_MSG(config.IsValid(), "Invalid storage config");
|
||||||
@@ -245,35 +243,29 @@ int Storage::Run(int max_wait, const std::string &dataset_name, bool only_metric
|
|||||||
auto static_region = shared_register.GetRegion(region_id);
|
auto static_region = shared_register.GetRegion(region_id);
|
||||||
auto static_memory = makeSharedMemory(static_region.shm_key);
|
auto static_memory = makeSharedMemory(static_region.shm_key);
|
||||||
|
|
||||||
std::unique_ptr<storage::BaseDataLayout> static_layout =
|
DataLayout static_layout;
|
||||||
std::make_unique<storage::DataLayout>();
|
|
||||||
io::BufferReader reader(reinterpret_cast<char *>(static_memory->Ptr()),
|
io::BufferReader reader(reinterpret_cast<char *>(static_memory->Ptr()),
|
||||||
static_memory->Size());
|
static_memory->Size());
|
||||||
serialization::read(reader, static_layout);
|
serialization::read(reader, static_layout);
|
||||||
auto layout_size = reader.GetPosition();
|
auto layout_size = reader.GetPosition();
|
||||||
auto *data_ptr = reinterpret_cast<char *>(static_memory->Ptr()) + layout_size;
|
auto *data_ptr = reinterpret_cast<char *>(static_memory->Ptr()) + layout_size;
|
||||||
|
|
||||||
regions.push_back({data_ptr, std::move(static_layout)});
|
regions.push_back({data_ptr, static_layout});
|
||||||
readonly_handles.push_back({std::move(static_memory), data_ptr, static_region.shm_key});
|
readonly_handles.push_back({std::move(static_memory), data_ptr, static_region.shm_key});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::unique_ptr<storage::BaseDataLayout> static_layout =
|
DataLayout static_layout;
|
||||||
std::make_unique<storage::DataLayout>();
|
PopulateStaticLayout(static_layout);
|
||||||
Storage::PopulateLayoutWithRTree(static_layout);
|
|
||||||
std::vector<std::pair<bool, boost::filesystem::path>> files = Storage::GetStaticFiles();
|
|
||||||
Storage::PopulateLayout(static_layout, files);
|
|
||||||
auto static_handle = setupRegion(shared_register, static_layout);
|
auto static_handle = setupRegion(shared_register, static_layout);
|
||||||
regions.push_back({static_handle.data_ptr, std::move(static_layout)});
|
regions.push_back({static_handle.data_ptr, static_layout});
|
||||||
handles[dataset_name + "/static"] = std::move(static_handle);
|
handles[dataset_name + "/static"] = std::move(static_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<storage::BaseDataLayout> updatable_layout =
|
DataLayout updatable_layout;
|
||||||
std::make_unique<storage::DataLayout>();
|
PopulateUpdatableLayout(updatable_layout);
|
||||||
std::vector<std::pair<bool, boost::filesystem::path>> files = Storage::GetUpdatableFiles();
|
|
||||||
Storage::PopulateLayout(updatable_layout, files);
|
|
||||||
auto updatable_handle = setupRegion(shared_register, updatable_layout);
|
auto updatable_handle = setupRegion(shared_register, updatable_layout);
|
||||||
regions.push_back({updatable_handle.data_ptr, std::move(updatable_layout)});
|
regions.push_back({updatable_handle.data_ptr, updatable_layout});
|
||||||
handles[dataset_name + "/updatable"] = std::move(updatable_handle);
|
handles[dataset_name + "/updatable"] = std::move(updatable_handle);
|
||||||
|
|
||||||
SharedDataIndex index{std::move(regions)};
|
SharedDataIndex index{std::move(regions)};
|
||||||
@@ -289,12 +281,24 @@ int Storage::Run(int max_wait, const std::string &dataset_name, bool only_metric
|
|||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::pair<bool, boost::filesystem::path>> Storage::GetStaticFiles()
|
/**
|
||||||
|
* This function examines all our data files and figures out how much
|
||||||
|
* memory needs to be allocated, and the position of each data structure
|
||||||
|
* in that big block. It updates the fields in the DataLayout parameter.
|
||||||
|
*/
|
||||||
|
void Storage::PopulateStaticLayout(DataLayout &static_layout)
|
||||||
{
|
{
|
||||||
|
{
|
||||||
|
auto absolute_file_index_path =
|
||||||
|
boost::filesystem::absolute(config.GetPath(".osrm.fileIndex"));
|
||||||
|
|
||||||
|
static_layout.SetBlock("/common/rtree/file_index_path",
|
||||||
|
make_block<char>(absolute_file_index_path.string().length() + 1));
|
||||||
|
}
|
||||||
|
|
||||||
constexpr bool REQUIRED = true;
|
constexpr bool REQUIRED = true;
|
||||||
constexpr bool OPTIONAL = false;
|
constexpr bool OPTIONAL = false;
|
||||||
|
std::vector<std::pair<bool, boost::filesystem::path>> tar_files = {
|
||||||
std::vector<std::pair<bool, boost::filesystem::path>> files = {
|
|
||||||
{OPTIONAL, config.GetPath(".osrm.cells")},
|
{OPTIONAL, config.GetPath(".osrm.cells")},
|
||||||
{OPTIONAL, config.GetPath(".osrm.partition")},
|
{OPTIONAL, config.GetPath(".osrm.partition")},
|
||||||
{REQUIRED, config.GetPath(".osrm.icd")},
|
{REQUIRED, config.GetPath(".osrm.icd")},
|
||||||
@@ -306,74 +310,53 @@ std::vector<std::pair<bool, boost::filesystem::path>> Storage::GetStaticFiles()
|
|||||||
{REQUIRED, config.GetPath(".osrm.maneuver_overrides")},
|
{REQUIRED, config.GetPath(".osrm.maneuver_overrides")},
|
||||||
{REQUIRED, config.GetPath(".osrm.edges")},
|
{REQUIRED, config.GetPath(".osrm.edges")},
|
||||||
{REQUIRED, config.GetPath(".osrm.names")},
|
{REQUIRED, config.GetPath(".osrm.names")},
|
||||||
{REQUIRED, config.GetPath(".osrm.ramIndex")}};
|
{REQUIRED, config.GetPath(".osrm.ramIndex")},
|
||||||
|
};
|
||||||
|
|
||||||
for (const auto &file : files)
|
for (const auto &file : tar_files)
|
||||||
{
|
{
|
||||||
if (file.first == REQUIRED && !boost::filesystem::exists(file.second))
|
if (boost::filesystem::exists(file.second))
|
||||||
{
|
{
|
||||||
throw util::exception("Could not find required filed: " + std::get<1>(file).string());
|
readBlocks(file.second, static_layout);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (file.first == REQUIRED)
|
||||||
|
{
|
||||||
|
throw util::exception("Could not find required filed: " +
|
||||||
|
std::get<1>(file).string());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return files;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::pair<bool, boost::filesystem::path>> Storage::GetUpdatableFiles()
|
void Storage::PopulateUpdatableLayout(DataLayout &updatable_layout)
|
||||||
{
|
{
|
||||||
constexpr bool REQUIRED = true;
|
constexpr bool REQUIRED = true;
|
||||||
constexpr bool OPTIONAL = false;
|
constexpr bool OPTIONAL = false;
|
||||||
|
std::vector<std::pair<bool, boost::filesystem::path>> tar_files = {
|
||||||
std::vector<std::pair<bool, boost::filesystem::path>> files = {
|
|
||||||
{OPTIONAL, config.GetPath(".osrm.mldgr")},
|
{OPTIONAL, config.GetPath(".osrm.mldgr")},
|
||||||
{OPTIONAL, config.GetPath(".osrm.cell_metrics")},
|
{OPTIONAL, config.GetPath(".osrm.cell_metrics")},
|
||||||
{OPTIONAL, config.GetPath(".osrm.hsgr")},
|
{OPTIONAL, config.GetPath(".osrm.hsgr")},
|
||||||
{REQUIRED, config.GetPath(".osrm.datasource_names")},
|
{REQUIRED, config.GetPath(".osrm.datasource_names")},
|
||||||
{REQUIRED, config.GetPath(".osrm.geometry")},
|
{REQUIRED, config.GetPath(".osrm.geometry")},
|
||||||
{REQUIRED, config.GetPath(".osrm.turn_weight_penalties")},
|
{REQUIRED, config.GetPath(".osrm.turn_weight_penalties")},
|
||||||
{REQUIRED, config.GetPath(".osrm.turn_duration_penalties")}};
|
{REQUIRED, config.GetPath(".osrm.turn_duration_penalties")},
|
||||||
|
};
|
||||||
|
|
||||||
for (const auto &file : files)
|
for (const auto &file : tar_files)
|
||||||
{
|
|
||||||
if (file.first == REQUIRED && !boost::filesystem::exists(file.second))
|
|
||||||
{
|
|
||||||
throw util::exception("Could not find required filed: " + std::get<1>(file).string());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return files;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Storage::PopulateLayoutWithRTree(std::unique_ptr<storage::BaseDataLayout> &layout)
|
|
||||||
{
|
|
||||||
// Figure out the path to the rtree file (it's not a tar file)
|
|
||||||
auto absolute_file_index_path = boost::filesystem::absolute(config.GetPath(".osrm.fileIndex"));
|
|
||||||
|
|
||||||
// Convert the boost::filesystem::path object into a plain string
|
|
||||||
// that can then be stored as a member of an allocator object
|
|
||||||
std::string rtree_filename = absolute_file_index_path.string();
|
|
||||||
|
|
||||||
// Here, we hardcode the special file_index_path block name.
|
|
||||||
// The important bit here is that the "offset" is set to zero
|
|
||||||
layout->SetBlock("/common/rtree/file_index_path",
|
|
||||||
make_block<char>(rtree_filename.length() + 1));
|
|
||||||
|
|
||||||
return rtree_filename;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This function examines all our data files and figures out how much
|
|
||||||
* memory needs to be allocated, and the position of each data structure
|
|
||||||
* in that big block. It updates the fields in the std::unique_ptr<BaseDataLayout> parameter.
|
|
||||||
*/
|
|
||||||
void Storage::PopulateLayout(std::unique_ptr<storage::BaseDataLayout> &layout,
|
|
||||||
std::vector<std::pair<bool, boost::filesystem::path>> files)
|
|
||||||
{
|
|
||||||
for (const auto &file : files)
|
|
||||||
{
|
{
|
||||||
if (boost::filesystem::exists(file.second))
|
if (boost::filesystem::exists(file.second))
|
||||||
{
|
{
|
||||||
readBlocks(file.second, layout);
|
readBlocks(file.second, updatable_layout);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (file.first == REQUIRED)
|
||||||
|
{
|
||||||
|
throw util::exception("Could not find required filed: " +
|
||||||
|
std::get<1>(file).string());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -586,5 +569,5 @@ void Storage::PopulateUpdatableData(const SharedDataIndex &index)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // namespace storage
|
}
|
||||||
} // namespace osrm
|
}
|
||||||
|
|||||||
@@ -81,10 +81,7 @@ return_code parseArguments(int argc,
|
|||||||
"time-zone-file",
|
"time-zone-file",
|
||||||
boost::program_options::value<std::string>(&contractor_config.updater_config.tz_file_path),
|
boost::program_options::value<std::string>(&contractor_config.updater_config.tz_file_path),
|
||||||
"Required for conditional turn restriction parsing, provide a geojson file containing "
|
"Required for conditional turn restriction parsing, provide a geojson file containing "
|
||||||
"time zone boundaries")(
|
"time zone boundaries")("cache-distances",boost::program_options::bool_switch(&contractor_config.cache_distances)->default_value(false),
|
||||||
"cache-distances",
|
|
||||||
boost::program_options::bool_switch(&contractor_config.cache_distances)
|
|
||||||
->default_value(false),
|
|
||||||
"Store distances for CH edges, avoiding the need for query-time re-calculation.");
|
"Store distances for CH edges, avoiding the need for query-time re-calculation.");
|
||||||
|
|
||||||
// hidden options, will be allowed on command line, but will not be shown to the user
|
// hidden options, will be allowed on command line, but will not be shown to the user
|
||||||
|
|||||||
+14
-13
@@ -70,8 +70,8 @@ std::istream &operator>>(std::istream &in, EngineConfig::Algorithm &algorithm)
|
|||||||
throw util::RuntimeError(token, ErrorCode::UnknownAlgorithm, SOURCE_REF);
|
throw util::RuntimeError(token, ErrorCode::UnknownAlgorithm, SOURCE_REF);
|
||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
} // namespace engine
|
}
|
||||||
} // namespace osrm
|
}
|
||||||
|
|
||||||
// generate boost::program_options object for the routing part
|
// generate boost::program_options object for the routing part
|
||||||
inline unsigned generateServerProgramOptions(const int argc,
|
inline unsigned generateServerProgramOptions(const int argc,
|
||||||
@@ -119,10 +119,7 @@ inline unsigned generateServerProgramOptions(const int argc,
|
|||||||
"Load data from shared memory") //
|
"Load data from shared memory") //
|
||||||
("memory_file",
|
("memory_file",
|
||||||
value<boost::filesystem::path>(&config.memory_file),
|
value<boost::filesystem::path>(&config.memory_file),
|
||||||
"DEPRECATED: Will behave the same as --mmap.")(
|
"Store data in a memory mapped file rather than in process memory.") //
|
||||||
"mmap,m",
|
|
||||||
value<bool>(&config.use_mmap)->implicit_value(true)->default_value(false),
|
|
||||||
"Map datafiles directly, do not use any additional memory.") //
|
|
||||||
("dataset-name",
|
("dataset-name",
|
||||||
value<std::string>(&config.dataset_name),
|
value<std::string>(&config.dataset_name),
|
||||||
"Name of the shared memory dataset to connect to.") //
|
"Name of the shared memory dataset to connect to.") //
|
||||||
@@ -276,12 +273,10 @@ int main(int argc, const char *argv[]) try
|
|||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
int sig = 0;
|
int sig = 0;
|
||||||
sigset_t wait_mask;
|
sigset_t new_mask;
|
||||||
sigemptyset(&wait_mask);
|
sigset_t old_mask;
|
||||||
sigaddset(&wait_mask, SIGINT);
|
sigfillset(&new_mask);
|
||||||
sigaddset(&wait_mask, SIGQUIT);
|
pthread_sigmask(SIG_BLOCK, &new_mask, &old_mask);
|
||||||
sigaddset(&wait_mask, SIGTERM);
|
|
||||||
pthread_sigmask(SIG_BLOCK, &wait_mask, nullptr); // only block necessary signals
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
auto service_handler = std::make_unique<server::ServiceHandler>(config);
|
auto service_handler = std::make_unique<server::ServiceHandler>(config);
|
||||||
@@ -303,13 +298,19 @@ int main(int argc, const char *argv[]) try
|
|||||||
std::thread server_thread(std::move(server_task));
|
std::thread server_thread(std::move(server_task));
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
|
sigset_t wait_mask;
|
||||||
|
pthread_sigmask(SIG_SETMASK, &old_mask, nullptr);
|
||||||
|
sigemptyset(&wait_mask);
|
||||||
|
sigaddset(&wait_mask, SIGINT);
|
||||||
|
sigaddset(&wait_mask, SIGQUIT);
|
||||||
|
sigaddset(&wait_mask, SIGTERM);
|
||||||
|
pthread_sigmask(SIG_BLOCK, &wait_mask, nullptr);
|
||||||
util::Log() << "running and waiting for requests";
|
util::Log() << "running and waiting for requests";
|
||||||
if (std::getenv("SIGNAL_PARENT_WHEN_READY"))
|
if (std::getenv("SIGNAL_PARENT_WHEN_READY"))
|
||||||
{
|
{
|
||||||
kill(getppid(), SIGUSR1);
|
kill(getppid(), SIGUSR1);
|
||||||
}
|
}
|
||||||
sigwait(&wait_mask, &sig);
|
sigwait(&wait_mask, &sig);
|
||||||
util::Log() << "received signal " << sig;
|
|
||||||
#else
|
#else
|
||||||
// Set console control handler to allow server to be stopped.
|
// Set console control handler to allow server to be stopped.
|
||||||
console_ctrl_function = std::bind(&server::Server::Stop, routing_server);
|
console_ctrl_function = std::bind(&server::Server::Stop, routing_server);
|
||||||
|
|||||||
+3
-3
@@ -52,14 +52,14 @@ void listRegions(bool show_blocks)
|
|||||||
auto memory = makeSharedMemory(region.shm_key);
|
auto memory = makeSharedMemory(region.shm_key);
|
||||||
io::BufferReader reader(reinterpret_cast<char *>(memory->Ptr()), memory->Size());
|
io::BufferReader reader(reinterpret_cast<char *>(memory->Ptr()), memory->Size());
|
||||||
|
|
||||||
std::unique_ptr<BaseDataLayout> layout = std::make_unique<DataLayout>();
|
DataLayout layout;
|
||||||
serialization::read(reader, layout);
|
serialization::read(reader, layout);
|
||||||
|
|
||||||
std::vector<std::string> block_names;
|
std::vector<std::string> block_names;
|
||||||
layout->List("", std::back_inserter(block_names));
|
layout.List("", std::back_inserter(block_names));
|
||||||
for (auto &name : block_names)
|
for (auto &name : block_names)
|
||||||
{
|
{
|
||||||
osrm::util::Log() << " " << name << " " << layout->GetBlockSize(name);
|
osrm::util::Log() << " " << name << " " << layout.GetBlockSize(name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,11 @@ namespace coordinate_calculation
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// earth radius varies between 6,356.750-6,378.135 km (3,949.901-3,963.189mi)
|
||||||
|
// The IUGG value for the equatorial radius is 6378.137 km (3963.19 miles)
|
||||||
|
const constexpr double EARTH_RADIUS = 6372797.560856;
|
||||||
|
|
||||||
class CheapRulerContainer
|
class CheapRulerContainer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -112,7 +117,7 @@ double haversineDistance(const Coordinate coordinate_1, const Coordinate coordin
|
|||||||
const double aharv = std::pow(std::sin(dlat / 2.0), 2.0) +
|
const double aharv = std::pow(std::sin(dlat / 2.0), 2.0) +
|
||||||
std::cos(dlat1) * std::cos(dlat2) * std::pow(std::sin(dlong / 2.), 2);
|
std::cos(dlat1) * std::cos(dlat2) * std::pow(std::sin(dlong / 2.), 2);
|
||||||
const double charv = 2. * std::atan2(std::sqrt(aharv), std::sqrt(1.0 - aharv));
|
const double charv = 2. * std::atan2(std::sqrt(aharv), std::sqrt(1.0 - aharv));
|
||||||
return detail::EARTH_RADIUS * charv;
|
return EARTH_RADIUS * charv;
|
||||||
}
|
}
|
||||||
|
|
||||||
double greatCircleDistance(const Coordinate coordinate_1, const Coordinate coordinate_2)
|
double greatCircleDistance(const Coordinate coordinate_1, const Coordinate coordinate_2)
|
||||||
@@ -133,7 +138,7 @@ double greatCircleDistance(const Coordinate coordinate_1, const Coordinate coord
|
|||||||
|
|
||||||
const double x_value = (float_lon2 - float_lon1) * std::cos((float_lat1 + float_lat2) / 2.0);
|
const double x_value = (float_lon2 - float_lon1) * std::cos((float_lat1 + float_lat2) / 2.0);
|
||||||
const double y_value = float_lat2 - float_lat1;
|
const double y_value = float_lat2 - float_lat1;
|
||||||
return std::hypot(x_value, y_value) * detail::EARTH_RADIUS;
|
return std::hypot(x_value, y_value) * EARTH_RADIUS;
|
||||||
}
|
}
|
||||||
|
|
||||||
double perpendicularDistance(const Coordinate segment_source,
|
double perpendicularDistance(const Coordinate segment_source,
|
||||||
|
|||||||
+5
-5
@@ -74,11 +74,11 @@ benchmark: data $(DATA_NAME).requests
|
|||||||
$(TIMER) "queries\tCoreCH" "cat $(DATA_NAME).requests | xargs curl &> /dev/null"
|
$(TIMER) "queries\tCoreCH" "cat $(DATA_NAME).requests | xargs curl &> /dev/null"
|
||||||
@cat osrm-routed.pid | xargs kill
|
@cat osrm-routed.pid | xargs kill
|
||||||
@rm osrm-routed.pid
|
@rm osrm-routed.pid
|
||||||
# @/bin/sh -c '$(OSRM_ROUTED) --algorithm=MLD mld/$(DATA_NAME).osrm > /dev/null & echo "$$!" > osrm-routed.pid'
|
@/bin/sh -c '$(OSRM_ROUTED) --algorithm=MLD mld/$(DATA_NAME).osrm > /dev/null & echo "$$!" > osrm-routed.pid'
|
||||||
# @sleep 1
|
@sleep 1
|
||||||
# $(TIMER) "queries\tMLD" "cat $(DATA_NAME).requests | xargs curl &> /dev/null"
|
$(TIMER) "queries\tMLD" "cat $(DATA_NAME).requests | xargs curl &> /dev/null"
|
||||||
# @cat osrm-routed.pid | xargs kill
|
@cat osrm-routed.pid | xargs kill
|
||||||
# @rm osrm-routed.pid
|
@rm osrm-routed.pid
|
||||||
@echo "**** timings ***"
|
@echo "**** timings ***"
|
||||||
@cat /tmp/osrm.timings
|
@cat /tmp/osrm.timings
|
||||||
@echo "****************"
|
@echo "****************"
|
||||||
|
|||||||
+8
-40
@@ -25,28 +25,6 @@ test('match: match in Monaco', function(assert) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('match: match in Monaco returning a buffer', function(assert) {
|
|
||||||
assert.plan(6);
|
|
||||||
var osrm = new OSRM(data_path);
|
|
||||||
var options = {
|
|
||||||
coordinates: three_test_coordinates,
|
|
||||||
timestamps: [1424684612, 1424684616, 1424684620]
|
|
||||||
};
|
|
||||||
osrm.match(options, { format: 'json_buffer' }, function(err, response) {
|
|
||||||
assert.ifError(err);
|
|
||||||
assert.ok(response instanceof Buffer);
|
|
||||||
response = JSON.parse(response);
|
|
||||||
assert.equal(response.matchings.length, 1);
|
|
||||||
assert.ok(response.matchings.every(function(m) {
|
|
||||||
return !!m.distance && !!m.duration && Array.isArray(m.legs) && !!m.geometry && m.confidence > 0;
|
|
||||||
}))
|
|
||||||
assert.equal(response.tracepoints.length, 3);
|
|
||||||
assert.ok(response.tracepoints.every(function(t) {
|
|
||||||
return !!t.hint && !isNaN(t.matchings_index) && !isNaN(t.waypoint_index) && !!t.name;
|
|
||||||
}));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
test('match: match in Monaco without timestamps', function(assert) {
|
test('match: match in Monaco without timestamps', function(assert) {
|
||||||
assert.plan(3);
|
assert.plan(3);
|
||||||
var osrm = new OSRM(data_path);
|
var osrm = new OSRM(data_path);
|
||||||
@@ -247,30 +225,20 @@ test('match: throws on invalid tidy param', function(assert) {
|
|||||||
/tidy must be of type Boolean/);
|
/tidy must be of type Boolean/);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('match: throws on invalid config param', function(assert) {
|
test('match: match in Monaco without motorways', function(assert) {
|
||||||
assert.plan(1);
|
assert.plan(3);
|
||||||
var osrm = new OSRM({path: mld_data_path, algorithm: 'MLD'});
|
var osrm = new OSRM({path: mld_data_path, algorithm: 'MLD'});
|
||||||
var options = {
|
var options = {
|
||||||
coordinates: three_test_coordinates,
|
coordinates: three_test_coordinates,
|
||||||
|
exclude: ['motorway']
|
||||||
};
|
};
|
||||||
assert.throws(function() { osrm.match(options, { format: 'invalid' }, function(err, response) {}) },
|
osrm.match(options, function(err, response) {
|
||||||
/format must be a string:/);
|
assert.ifError(err);
|
||||||
|
assert.equal(response.tracepoints.length, 3);
|
||||||
|
assert.equal(response.matchings.length, 1);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// test('match: match in Monaco without motorways', function(assert) {
|
|
||||||
// assert.plan(3);
|
|
||||||
// var osrm = new OSRM({path: mld_data_path, algorithm: 'MLD'});
|
|
||||||
// var options = {
|
|
||||||
// coordinates: three_test_coordinates,
|
|
||||||
// exclude: ['motorway']
|
|
||||||
// };
|
|
||||||
// osrm.match(options, function(err, response) {
|
|
||||||
// assert.ifError(err);
|
|
||||||
// assert.equal(response.tracepoints.length, 3);
|
|
||||||
// assert.equal(response.matchings.length, 1);
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
|
|
||||||
test('match: throws on invalid waypoints values needs at least two', function(assert) {
|
test('match: throws on invalid waypoints values needs at least two', function(assert) {
|
||||||
assert.plan(1);
|
assert.plan(1);
|
||||||
var osrm = new OSRM(data_path);
|
var osrm = new OSRM(data_path);
|
||||||
|
|||||||
+13
-32
@@ -19,21 +19,6 @@ test('nearest', function(assert) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('nearest', function(assert) {
|
|
||||||
assert.plan(5);
|
|
||||||
var osrm = new OSRM(data_path);
|
|
||||||
osrm.nearest({
|
|
||||||
coordinates: [three_test_coordinates[0]]
|
|
||||||
}, { format: 'json_buffer' }, function(err, result) {
|
|
||||||
assert.ifError(err);
|
|
||||||
assert.ok(result instanceof Buffer);
|
|
||||||
result = JSON.parse(result);
|
|
||||||
assert.equal(result.waypoints.length, 1);
|
|
||||||
assert.equal(result.waypoints[0].location.length, 2);
|
|
||||||
assert.ok(result.waypoints[0].hasOwnProperty('name'));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
test('nearest: can ask for multiple nearest pts', function(assert) {
|
test('nearest: can ask for multiple nearest pts', function(assert) {
|
||||||
assert.plan(2);
|
assert.plan(2);
|
||||||
var osrm = new OSRM(data_path);
|
var osrm = new OSRM(data_path);
|
||||||
@@ -47,7 +32,7 @@ test('nearest: can ask for multiple nearest pts', function(assert) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('nearest: throws on invalid args', function(assert) {
|
test('nearest: throws on invalid args', function(assert) {
|
||||||
assert.plan(7);
|
assert.plan(6);
|
||||||
var osrm = new OSRM(data_path);
|
var osrm = new OSRM(data_path);
|
||||||
var options = {};
|
var options = {};
|
||||||
assert.throws(function() { osrm.nearest(options); },
|
assert.throws(function() { osrm.nearest(options); },
|
||||||
@@ -67,21 +52,17 @@ test('nearest: throws on invalid args', function(assert) {
|
|||||||
options.number = 0;
|
options.number = 0;
|
||||||
assert.throws(function() { osrm.nearest(options, function(err, res) {}); },
|
assert.throws(function() { osrm.nearest(options, function(err, res) {}); },
|
||||||
/Number must be an integer greater than or equal to 1/);
|
/Number must be an integer greater than or equal to 1/);
|
||||||
|
|
||||||
options.number = 1;
|
|
||||||
assert.throws(function() { osrm.nearest(options, { format: 'invalid' }, function(err, res) {}); },
|
|
||||||
/format must be a string:/);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// test('nearest: nearest in Monaco without motorways', function(assert) {
|
test('nearest: nearest in Monaco without motorways', function(assert) {
|
||||||
// assert.plan(2);
|
assert.plan(2);
|
||||||
// var osrm = new OSRM({path: mld_data_path, algorithm: 'MLD'});
|
var osrm = new OSRM({path: mld_data_path, algorithm: 'MLD'});
|
||||||
// var options = {
|
var options = {
|
||||||
// coordinates: [two_test_coordinates[0]],
|
coordinates: [two_test_coordinates[0]],
|
||||||
// exclude: ['motorway']
|
exclude: ['motorway']
|
||||||
// };
|
};
|
||||||
// osrm.nearest(options, function(err, response) {
|
osrm.nearest(options, function(err, response) {
|
||||||
// assert.ifError(err);
|
assert.ifError(err);
|
||||||
// assert.equal(response.waypoints.length, 1);
|
assert.equal(response.waypoints.length, 1);
|
||||||
// });
|
});
|
||||||
// });
|
});
|
||||||
|
|||||||
+14
-30
@@ -43,22 +43,8 @@ test('route: routes Monaco on CoreCH', function(assert) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('route: routes Monaco and returns a JSON buffer', function(assert) {
|
|
||||||
assert.plan(6);
|
|
||||||
var osrm = new OSRM({path: monaco_corech_path, algorithm: 'CoreCH'});
|
|
||||||
osrm.route({coordinates: [[13.43864,52.51993],[13.415852,52.513191]]}, { format: 'json_buffer'}, function(err, result) {
|
|
||||||
assert.ifError(err);
|
|
||||||
assert.ok(result instanceof Buffer);
|
|
||||||
const route = JSON.parse(result);
|
|
||||||
assert.ok(route.waypoints);
|
|
||||||
assert.ok(route.routes);
|
|
||||||
assert.ok(route.routes.length);
|
|
||||||
assert.ok(route.routes[0].geometry);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
test('route: throws with too few or invalid args', function(assert) {
|
test('route: throws with too few or invalid args', function(assert) {
|
||||||
assert.plan(4);
|
assert.plan(3);
|
||||||
var osrm = new OSRM(monaco_path);
|
var osrm = new OSRM(monaco_path);
|
||||||
assert.throws(function() { osrm.route({coordinates: two_test_coordinates}) },
|
assert.throws(function() { osrm.route({coordinates: two_test_coordinates}) },
|
||||||
/Two arguments required/);
|
/Two arguments required/);
|
||||||
@@ -66,8 +52,6 @@ test('route: throws with too few or invalid args', function(assert) {
|
|||||||
/First arg must be an object/);
|
/First arg must be an object/);
|
||||||
assert.throws(function() { osrm.route({coordinates: two_test_coordinates}, true)},
|
assert.throws(function() { osrm.route({coordinates: two_test_coordinates}, true)},
|
||||||
/last argument must be a callback function/);
|
/last argument must be a callback function/);
|
||||||
assert.throws(function() { osrm.route({coordinates: two_test_coordinates}, { format: 'invalid' }, function(err, route) {})},
|
|
||||||
/format must be a string:/);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('route: provides no alternatives by default, but when requested it may (not guaranteed)', function(assert) {
|
test('route: provides no alternatives by default, but when requested it may (not guaranteed)', function(assert) {
|
||||||
@@ -592,17 +576,17 @@ test('route: in Monaco with custom limits on MLD', function(assert) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// test('route: route in Monaco without motorways', function(assert) {
|
test('route: route in Monaco without motorways', function(assert) {
|
||||||
// assert.plan(3);
|
assert.plan(3);
|
||||||
// var osrm = new OSRM({path: monaco_mld_path, algorithm: 'MLD'});
|
var osrm = new OSRM({path: monaco_mld_path, algorithm: 'MLD'});
|
||||||
// var options = {
|
var options = {
|
||||||
// coordinates: two_test_coordinates,
|
coordinates: two_test_coordinates,
|
||||||
// exclude: ['motorway']
|
exclude: ['motorway']
|
||||||
// };
|
};
|
||||||
// osrm.route(options, function(err, response) {
|
osrm.route(options, function(err, response) {
|
||||||
// assert.ifError(err);
|
assert.ifError(err);
|
||||||
// assert.equal(response.waypoints.length, 2);
|
assert.equal(response.waypoints.length, 2);
|
||||||
// assert.equal(response.routes.length, 1);
|
assert.equal(response.routes.length, 1);
|
||||||
// });
|
});
|
||||||
// });
|
});
|
||||||
|
|
||||||
|
|||||||
+13
-30
@@ -48,20 +48,6 @@ test('table: test annotations paramater combination', function(assert) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('table: returns buffer', function(assert) {
|
|
||||||
assert.plan(3);
|
|
||||||
var osrm = new OSRM(data_path);
|
|
||||||
var options = {
|
|
||||||
coordinates: [three_test_coordinates[0], three_test_coordinates[1]],
|
|
||||||
};
|
|
||||||
osrm.table(options, { format: 'json_buffer' }, function(err, table) {
|
|
||||||
assert.ifError(err);
|
|
||||||
assert.ok(table instanceof Buffer);
|
|
||||||
table = JSON.parse(table);
|
|
||||||
assert.ok(table['durations'], 'distances table result should exist');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
var tables = ['distances', 'durations'];
|
var tables = ['distances', 'durations'];
|
||||||
|
|
||||||
tables.forEach(function(annotation) {
|
tables.forEach(function(annotation) {
|
||||||
@@ -130,7 +116,7 @@ tables.forEach(function(annotation) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('table: ' + annotation + ' throws on invalid arguments', function(assert) {
|
test('table: ' + annotation + ' throws on invalid arguments', function(assert) {
|
||||||
assert.plan(15);
|
assert.plan(14);
|
||||||
var osrm = new OSRM(data_path);
|
var osrm = new OSRM(data_path);
|
||||||
var options = {annotations: [annotation.slice(0,-1)]};
|
var options = {annotations: [annotation.slice(0,-1)]};
|
||||||
assert.throws(function() { osrm.table(options); },
|
assert.throws(function() { osrm.table(options); },
|
||||||
@@ -149,9 +135,6 @@ tables.forEach(function(annotation) {
|
|||||||
/Coordinates must be an array of \(lon\/lat\) pairs/);
|
/Coordinates must be an array of \(lon\/lat\) pairs/);
|
||||||
|
|
||||||
options.coordinates = two_test_coordinates;
|
options.coordinates = two_test_coordinates;
|
||||||
assert.throws(function() { osrm.table(options, { format: 'invalid' }, function(err, response) {}) },
|
|
||||||
/format must be a string:/);
|
|
||||||
|
|
||||||
options.sources = true;
|
options.sources = true;
|
||||||
assert.throws(function() { osrm.table(options, function(err, response) {}) },
|
assert.throws(function() { osrm.table(options, function(err, response) {}) },
|
||||||
/Sources must be an array of indices \(or undefined\)/);
|
/Sources must be an array of indices \(or undefined\)/);
|
||||||
@@ -233,17 +216,17 @@ tables.forEach(function(annotation) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// test('table: ' + annotation + ' table in Monaco without motorways', function(assert) {
|
test('table: ' + annotation + ' table in Monaco without motorways', function(assert) {
|
||||||
// assert.plan(1);
|
assert.plan(1);
|
||||||
// var osrm = new OSRM({path: mld_data_path, algorithm: 'MLD'});
|
var osrm = new OSRM({path: mld_data_path, algorithm: 'MLD'});
|
||||||
// var options = {
|
var options = {
|
||||||
// coordinates: two_test_coordinates,
|
coordinates: two_test_coordinates,
|
||||||
// exclude: ['motorway'],
|
exclude: ['motorway'],
|
||||||
// annotations: [annotation.slice(0,-1)]
|
annotations: [annotation.slice(0,-1)]
|
||||||
// };
|
};
|
||||||
// osrm.table(options, function(err, response) {
|
osrm.table(options, function(err, response) {
|
||||||
// assert.equal(response[annotation].length, 2);
|
assert.equal(response[annotation].length, 2);
|
||||||
// });
|
});
|
||||||
// });
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
+14
-29
@@ -17,19 +17,6 @@ test('trip: trip in Monaco', function(assert) {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('trip: trip in Monaco as a buffer', function(assert) {
|
|
||||||
assert.plan(3);
|
|
||||||
var osrm = new OSRM(data_path);
|
|
||||||
osrm.trip({coordinates: two_test_coordinates}, { format: 'json_buffer' }, function(err, trip) {
|
|
||||||
assert.ifError(err);
|
|
||||||
assert.ok(trip instanceof Buffer);
|
|
||||||
trip = JSON.parse(trip);
|
|
||||||
for (t = 0; t < trip.trips.length; t++) {
|
|
||||||
assert.ok(trip.trips[t].geometry);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
test('trip: trip with many locations in Monaco', function(assert) {
|
test('trip: trip with many locations in Monaco', function(assert) {
|
||||||
assert.plan(2);
|
assert.plan(2);
|
||||||
|
|
||||||
@@ -46,14 +33,12 @@ test('trip: trip with many locations in Monaco', function(assert) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('trip: throws with too few or invalid args', function(assert) {
|
test('trip: throws with too few or invalid args', function(assert) {
|
||||||
assert.plan(3);
|
assert.plan(2);
|
||||||
var osrm = new OSRM(data_path);
|
var osrm = new OSRM(data_path);
|
||||||
assert.throws(function() { osrm.trip({coordinates: two_test_coordinates}) },
|
assert.throws(function() { osrm.trip({coordinates: two_test_coordinates}) },
|
||||||
/Two arguments required/);
|
/Two arguments required/);
|
||||||
assert.throws(function() { osrm.trip(null, function(err, trip) {}) },
|
assert.throws(function() { osrm.trip(null, function(err, trip) {}) },
|
||||||
/First arg must be an object/);
|
/First arg must be an object/);
|
||||||
assert.throws(function() { osrm.trip({coordinates: two_test_coordinates}, { format: 'invalid' }, function(err, trip) {}) },
|
|
||||||
/format must be a string:/);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('trip: throws with bad params', function(assert) {
|
test('trip: throws with bad params', function(assert) {
|
||||||
@@ -342,17 +327,17 @@ test('trip: fixed start and end combinations', function(assert) {
|
|||||||
assert.end();
|
assert.end();
|
||||||
});
|
});
|
||||||
|
|
||||||
// test('trip: trip in Monaco without motorways', function(assert) {
|
test('trip: trip in Monaco without motorways', function(assert) {
|
||||||
// assert.plan(3);
|
assert.plan(3);
|
||||||
// var osrm = new OSRM({path: mld_data_path, algorithm: 'MLD'});
|
var osrm = new OSRM({path: mld_data_path, algorithm: 'MLD'});
|
||||||
// var options = {
|
var options = {
|
||||||
// coordinates: two_test_coordinates,
|
coordinates: two_test_coordinates,
|
||||||
// exclude: ['motorway']
|
exclude: ['motorway']
|
||||||
// };
|
};
|
||||||
// osrm.trip(options, function(err, response) {
|
osrm.trip(options, function(err, response) {
|
||||||
// assert.ifError(err);
|
assert.ifError(err);
|
||||||
// assert.equal(response.waypoints.length, 2);
|
assert.equal(response.waypoints.length, 2);
|
||||||
// assert.equal(response.trips.length, 1);
|
assert.equal(response.trips.length, 1);
|
||||||
// });
|
});
|
||||||
// });
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -31,79 +31,79 @@ std::ostream &operator<<(std::ostream &out, const QueryEdge &edge)
|
|||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE(contracted_edge_container)
|
BOOST_AUTO_TEST_SUITE(contracted_edge_container)
|
||||||
|
|
||||||
// BOOST_AUTO_TEST_CASE(merge_edge_of_multiple_graph)
|
BOOST_AUTO_TEST_CASE(merge_edge_of_multiple_graph)
|
||||||
// {
|
{
|
||||||
// ContractedEdgeContainer container;
|
ContractedEdgeContainer container;
|
||||||
|
|
||||||
// std::vector<QueryEdge> edges;
|
std::vector<QueryEdge> edges;
|
||||||
// edges.push_back(QueryEdge{0, 1, {1, false, 3, 6, true, false}});
|
edges.push_back(QueryEdge{0, 1, {1, false, 3, 6, true, false}});
|
||||||
// edges.push_back(QueryEdge{1, 2, {2, false, 3, 6, true, false}});
|
edges.push_back(QueryEdge{1, 2, {2, false, 3, 6, true, false}});
|
||||||
// edges.push_back(QueryEdge{2, 0, {3, false, 3, 6, false, true}});
|
edges.push_back(QueryEdge{2, 0, {3, false, 3, 6, false, true}});
|
||||||
// edges.push_back(QueryEdge{2, 1, {4, false, 3, 6, false, true}});
|
edges.push_back(QueryEdge{2, 1, {4, false, 3, 6, false, true}});
|
||||||
// container.Insert(edges);
|
container.Insert(edges);
|
||||||
|
|
||||||
// edges.clear();
|
edges.clear();
|
||||||
// edges.push_back(QueryEdge{0, 1, {1, false, 3, 6, true, false}});
|
edges.push_back(QueryEdge{0, 1, {1, false, 3, 6, true, false}});
|
||||||
// edges.push_back(QueryEdge{1, 2, {2, false, 3, 6, true, false}});
|
edges.push_back(QueryEdge{1, 2, {2, false, 3, 6, true, false}});
|
||||||
// edges.push_back(QueryEdge{2, 0, {3, false, 12, 24, false, true}});
|
edges.push_back(QueryEdge{2, 0, {3, false, 12, 24, false, true}});
|
||||||
// edges.push_back(QueryEdge{2, 1, {4, false, 12, 24, false, true}});
|
edges.push_back(QueryEdge{2, 1, {4, false, 12, 24, false, true}});
|
||||||
// container.Merge(edges);
|
container.Merge(edges);
|
||||||
|
|
||||||
// edges.clear();
|
edges.clear();
|
||||||
// edges.push_back(QueryEdge{1, 4, {5, false, 3, 6, true, false}});
|
edges.push_back(QueryEdge{1, 4, {5, false, 3, 6, true, false}});
|
||||||
// container.Merge(edges);
|
container.Merge(edges);
|
||||||
|
|
||||||
// std::vector<QueryEdge> reference_edges;
|
std::vector<QueryEdge> reference_edges;
|
||||||
// reference_edges.push_back(QueryEdge{0, 1, {1, false, 3, 6, true, false}});
|
reference_edges.push_back(QueryEdge{0, 1, {1, false, 3, 6, true, false}});
|
||||||
// reference_edges.push_back(QueryEdge{1, 2, {2, false, 3, 6, true, false}});
|
reference_edges.push_back(QueryEdge{1, 2, {2, false, 3, 6, true, false}});
|
||||||
// reference_edges.push_back(QueryEdge{1, 4, {5, false, 3, 6, true, false}});
|
reference_edges.push_back(QueryEdge{1, 4, {5, false, 3, 6, true, false}});
|
||||||
// reference_edges.push_back(QueryEdge{2, 0, {3, false, 3, 6, false, true}});
|
reference_edges.push_back(QueryEdge{2, 0, {3, false, 3, 6, false, true}});
|
||||||
// reference_edges.push_back(QueryEdge{2, 0, {3, false, 12, 24, false, true}});
|
reference_edges.push_back(QueryEdge{2, 0, {3, false, 12, 24, false, true}});
|
||||||
// reference_edges.push_back(QueryEdge{2, 1, {4, false, 3, 6, false, true}});
|
reference_edges.push_back(QueryEdge{2, 1, {4, false, 3, 6, false, true}});
|
||||||
// reference_edges.push_back(QueryEdge{2, 1, {4, false, 12, 24, false, true}});
|
reference_edges.push_back(QueryEdge{2, 1, {4, false, 12, 24, false, true}});
|
||||||
// CHECK_EQUAL_COLLECTIONS(container.edges, reference_edges);
|
CHECK_EQUAL_COLLECTIONS(container.edges, reference_edges);
|
||||||
|
|
||||||
// auto filters = container.MakeEdgeFilters();
|
auto filters = container.MakeEdgeFilters();
|
||||||
// BOOST_CHECK_EQUAL(filters.size(), 2);
|
BOOST_CHECK_EQUAL(filters.size(), 2);
|
||||||
|
|
||||||
// REQUIRE_SIZE_RANGE(filters[0], 7);
|
REQUIRE_SIZE_RANGE(filters[0], 7);
|
||||||
// CHECK_EQUAL_RANGE(filters[0], true, true, false, true, true, true, true);
|
CHECK_EQUAL_RANGE(filters[0], true, true, false, true, true, true, true);
|
||||||
|
|
||||||
// REQUIRE_SIZE_RANGE(filters[1], 7);
|
REQUIRE_SIZE_RANGE(filters[1], 7);
|
||||||
// CHECK_EQUAL_RANGE(filters[1], true, true, true, true, false, true, false);
|
CHECK_EQUAL_RANGE(filters[1], true, true, true, true, false, true, false);
|
||||||
// }
|
}
|
||||||
|
|
||||||
// BOOST_AUTO_TEST_CASE(merge_edge_of_multiple_disjoint_graph)
|
BOOST_AUTO_TEST_CASE(merge_edge_of_multiple_disjoint_graph)
|
||||||
// {
|
{
|
||||||
// ContractedEdgeContainer container;
|
ContractedEdgeContainer container;
|
||||||
|
|
||||||
// std::vector<QueryEdge> edges;
|
std::vector<QueryEdge> edges;
|
||||||
// edges.push_back(QueryEdge{0, 1, {1, false, 3, 6, true, false}});
|
edges.push_back(QueryEdge{0, 1, {1, false, 3, 6, true, false}});
|
||||||
// edges.push_back(QueryEdge{1, 2, {2, false, 3, 6, true, false}});
|
edges.push_back(QueryEdge{1, 2, {2, false, 3, 6, true, false}});
|
||||||
// edges.push_back(QueryEdge{2, 0, {3, false, 12, 24, false, true}});
|
edges.push_back(QueryEdge{2, 0, {3, false, 12, 24, false, true}});
|
||||||
// edges.push_back(QueryEdge{2, 1, {4, false, 12, 24, false, true}});
|
edges.push_back(QueryEdge{2, 1, {4, false, 12, 24, false, true}});
|
||||||
// container.Merge(edges);
|
container.Merge(edges);
|
||||||
|
|
||||||
// edges.clear();
|
edges.clear();
|
||||||
// edges.push_back(QueryEdge{1, 4, {5, false, 3, 6, true, false}});
|
edges.push_back(QueryEdge{1, 4, {5, false, 3, 6, true, false}});
|
||||||
// container.Merge(edges);
|
container.Merge(edges);
|
||||||
|
|
||||||
// std::vector<QueryEdge> reference_edges;
|
std::vector<QueryEdge> reference_edges;
|
||||||
// reference_edges.push_back(QueryEdge{0, 1, {1, false, 3, 6, true, false}});
|
reference_edges.push_back(QueryEdge{0, 1, {1, false, 3, 6, true, false}});
|
||||||
// reference_edges.push_back(QueryEdge{1, 2, {2, false, 3, 6, true, false}});
|
reference_edges.push_back(QueryEdge{1, 2, {2, false, 3, 6, true, false}});
|
||||||
// reference_edges.push_back(QueryEdge{1, 4, {5, false, 3, 6, true, false}});
|
reference_edges.push_back(QueryEdge{1, 4, {5, false, 3, 6, true, false}});
|
||||||
// reference_edges.push_back(QueryEdge{2, 0, {3, false, 12, 24, false, true}});
|
reference_edges.push_back(QueryEdge{2, 0, {3, false, 12, 24, false, true}});
|
||||||
// reference_edges.push_back(QueryEdge{2, 1, {4, false, 12, 24, false, true}});
|
reference_edges.push_back(QueryEdge{2, 1, {4, false, 12, 24, false, true}});
|
||||||
// CHECK_EQUAL_COLLECTIONS(container.edges, reference_edges);
|
CHECK_EQUAL_COLLECTIONS(container.edges, reference_edges);
|
||||||
|
|
||||||
// auto filters = container.MakeEdgeFilters();
|
auto filters = container.MakeEdgeFilters();
|
||||||
// BOOST_CHECK_EQUAL(filters.size(), 2);
|
BOOST_CHECK_EQUAL(filters.size(), 2);
|
||||||
|
|
||||||
// REQUIRE_SIZE_RANGE(filters[0], 5);
|
REQUIRE_SIZE_RANGE(filters[0], 5);
|
||||||
// CHECK_EQUAL_RANGE(filters[0], true, true, false, true, true);
|
CHECK_EQUAL_RANGE(filters[0], true, true, false, true, true);
|
||||||
|
|
||||||
// REQUIRE_SIZE_RANGE(filters[1], 5);
|
REQUIRE_SIZE_RANGE(filters[1], 5);
|
||||||
// CHECK_EQUAL_RANGE(filters[1], false, false, true, false, false);
|
CHECK_EQUAL_RANGE(filters[1], false, false, true, false, false);
|
||||||
// }
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|||||||
@@ -14,122 +14,122 @@ using namespace osrm::unit_test;
|
|||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE(graph_contractor)
|
BOOST_AUTO_TEST_SUITE(graph_contractor)
|
||||||
|
|
||||||
// BOOST_AUTO_TEST_CASE(contract_graph)
|
BOOST_AUTO_TEST_CASE(contract_graph)
|
||||||
// {
|
{
|
||||||
// tbb::task_scheduler_init scheduler(1);
|
tbb::task_scheduler_init scheduler(1);
|
||||||
// /*
|
/*
|
||||||
// * <--1--<
|
* <--1--<
|
||||||
// * (0) >--3--> (1) >--3--> (3)
|
* (0) >--3--> (1) >--3--> (3)
|
||||||
// * v ^ v ^
|
* v ^ v ^
|
||||||
// * \ / \ |
|
* \ / \ |
|
||||||
// * 1 1 1 1
|
* 1 1 1 1
|
||||||
// * \ ^ \ /
|
* \ ^ \ /
|
||||||
// * >(5) > (4) >
|
* >(5) > (4) >
|
||||||
// */
|
*/
|
||||||
// std::vector<TestEdge> edges = {TestEdge{0, 1, 3},
|
std::vector<TestEdge> edges = {TestEdge{0, 1, 3},
|
||||||
// TestEdge{0, 5, 1},
|
TestEdge{0, 5, 1},
|
||||||
// TestEdge{1, 3, 3},
|
TestEdge{1, 3, 3},
|
||||||
// TestEdge{1, 4, 1},
|
TestEdge{1, 4, 1},
|
||||||
// TestEdge{3, 1, 1},
|
TestEdge{3, 1, 1},
|
||||||
// TestEdge{4, 3, 1},
|
TestEdge{4, 3, 1},
|
||||||
// TestEdge{5, 1, 1}};
|
TestEdge{5, 1, 1}};
|
||||||
// auto reference_graph = makeGraph(edges);
|
auto reference_graph = makeGraph(edges);
|
||||||
|
|
||||||
// auto contracted_graph = reference_graph;
|
auto contracted_graph = reference_graph;
|
||||||
// std::vector<bool> core = contractGraph(contracted_graph, {1, 1, 1, 1, 1, 1});
|
std::vector<bool> core = contractGraph(contracted_graph, {1, 1, 1, 1, 1, 1});
|
||||||
|
|
||||||
// // This contraction order is dependent on the priority caculation in the contractor
|
// This contraction order is dependent on the priority caculation in the contractor
|
||||||
// // but deterministic for the same graph.
|
// but deterministic for the same graph.
|
||||||
// CHECK_EQUAL_RANGE(core, false, false, false, false, false, false);
|
CHECK_EQUAL_RANGE(core, false, false, false, false, false, false);
|
||||||
|
|
||||||
// /* After contracting 0 and 2:
|
/* After contracting 0 and 2:
|
||||||
// *
|
*
|
||||||
// * Deltes edges 5 -> 0, 1 -> 0
|
* Deltes edges 5 -> 0, 1 -> 0
|
||||||
// *
|
*
|
||||||
// * <--1--<
|
* <--1--<
|
||||||
// * (0) ---3--> (1) >--3--> (3)
|
* (0) ---3--> (1) >--3--> (3)
|
||||||
// * \ ^ v ^
|
* \ ^ v ^
|
||||||
// * \ / \ |
|
* \ / \ |
|
||||||
// * 1 1 1 1
|
* 1 1 1 1
|
||||||
// * \ ^ \ /
|
* \ ^ \ /
|
||||||
// * >(5) > (4) >
|
* >(5) > (4) >
|
||||||
// */
|
*/
|
||||||
// reference_graph.DeleteEdgesTo(5, 0);
|
reference_graph.DeleteEdgesTo(5, 0);
|
||||||
// reference_graph.DeleteEdgesTo(1, 0);
|
reference_graph.DeleteEdgesTo(1, 0);
|
||||||
|
|
||||||
// /* After contracting 5:
|
/* After contracting 5:
|
||||||
// *
|
*
|
||||||
// * Deletes edges 1 -> 5
|
* Deletes edges 1 -> 5
|
||||||
// *
|
*
|
||||||
// * <--1--<
|
* <--1--<
|
||||||
// * (0) ---3--> (1) >--3--> (3)
|
* (0) ---3--> (1) >--3--> (3)
|
||||||
// * \ ^ v ^
|
* \ ^ v ^
|
||||||
// * \ / \ |
|
* \ / \ |
|
||||||
// * 1 1 1 1
|
* 1 1 1 1
|
||||||
// * \ / \ /
|
* \ / \ /
|
||||||
// * >(5) > (4) >
|
* >(5) > (4) >
|
||||||
// */
|
*/
|
||||||
// reference_graph.DeleteEdgesTo(5, 0);
|
reference_graph.DeleteEdgesTo(5, 0);
|
||||||
// reference_graph.DeleteEdgesTo(1, 0);
|
reference_graph.DeleteEdgesTo(1, 0);
|
||||||
|
|
||||||
// After contracting 3:
|
/* After contracting 3:
|
||||||
// *
|
*
|
||||||
// * Deletes edges 1 -> 3
|
* Deletes edges 1 -> 3
|
||||||
// * Deletes edges 4 -> 3
|
* Deletes edges 4 -> 3
|
||||||
// * Insert edge 4 -> 1
|
* Insert edge 4 -> 1
|
||||||
// *
|
*
|
||||||
// * <--1---
|
* <--1---
|
||||||
// * (0) ---3--> (1) >--3--- (3)
|
* (0) ---3--> (1) >--3--- (3)
|
||||||
// * \ ^ v ^ |
|
* \ ^ v ^ |
|
||||||
// * \ / \ \ |
|
* \ / \ \ |
|
||||||
// * 1 1 1 2 1
|
* 1 1 1 2 1
|
||||||
// * \ / \ \ /
|
* \ / \ \ /
|
||||||
// * >(5) > (4) >
|
* >(5) > (4) >
|
||||||
|
*/
|
||||||
|
reference_graph.DeleteEdgesTo(1, 3);
|
||||||
|
reference_graph.DeleteEdgesTo(4, 3);
|
||||||
|
// Insert shortcut
|
||||||
|
reference_graph.InsertEdge(4, 1, {2, 4, 3, 0, true, true, false});
|
||||||
|
|
||||||
// reference_graph.DeleteEdgesTo(1, 3);
|
/* After contracting 4:
|
||||||
// reference_graph.DeleteEdgesTo(4, 3);
|
*
|
||||||
// // Insert shortcut
|
* Delete edges 1 -> 4
|
||||||
// reference_graph.InsertEdge(4, 1, {2, 4, 3, 0, true, true, false});
|
*
|
||||||
|
* <--1---
|
||||||
|
* (0) ---3--> (1) >--3--- (3)
|
||||||
|
* \ ^ v ^ |
|
||||||
|
* \ / \ \ |
|
||||||
|
* 1 1 1 2 1
|
||||||
|
* \ / \ \ /
|
||||||
|
* >(5) \ (4) >
|
||||||
|
*/
|
||||||
|
reference_graph.DeleteEdgesTo(1, 4);
|
||||||
|
|
||||||
// /* After contracting 4:
|
/* After contracting 1:
|
||||||
// *
|
*
|
||||||
// * Delete edges 1 -> 4
|
* Delete no edges.
|
||||||
// *
|
*
|
||||||
// * <--1---
|
* <--1---
|
||||||
// * (0) ---3--> (1) >--3--- (3)
|
* (0) ---3--> (1) >--3--- (3)
|
||||||
// * \ ^ v ^ |
|
* \ ^ v ^ |
|
||||||
// * \ / \ \ |
|
* \ / \ \ |
|
||||||
// * 1 1 1 2 1
|
* 1 1 1 2 1
|
||||||
// * \ / \ \ /
|
* \ / \ \ /
|
||||||
// * >(5) \ (4) >
|
* >(5) \ (4) >
|
||||||
// */
|
*/
|
||||||
// reference_graph.DeleteEdgesTo(1, 4);
|
|
||||||
|
|
||||||
// /* After contracting 1:
|
REQUIRE_SIZE_RANGE(contracted_graph.GetAdjacentEdgeRange(0), 2);
|
||||||
// *
|
BOOST_CHECK(contracted_graph.FindEdge(0, 1) != SPECIAL_EDGEID);
|
||||||
// * Delete no edges.
|
BOOST_CHECK(contracted_graph.FindEdge(0, 5) != SPECIAL_EDGEID);
|
||||||
// *
|
REQUIRE_SIZE_RANGE(contracted_graph.GetAdjacentEdgeRange(1), 0);
|
||||||
// * <--1---
|
REQUIRE_SIZE_RANGE(contracted_graph.GetAdjacentEdgeRange(2), 0);
|
||||||
// * (0) ---3--> (1) >--3--- (3)
|
REQUIRE_SIZE_RANGE(contracted_graph.GetAdjacentEdgeRange(3), 3);
|
||||||
// * \ ^ v ^ |
|
BOOST_CHECK(contracted_graph.FindEdge(3, 1) != SPECIAL_EDGEID);
|
||||||
// * \ / \ \ |
|
BOOST_CHECK(contracted_graph.FindEdge(3, 4) != SPECIAL_EDGEID);
|
||||||
// * 1 1 1 2 1
|
REQUIRE_SIZE_RANGE(contracted_graph.GetAdjacentEdgeRange(4), 2);
|
||||||
// * \ / \ \ /
|
BOOST_CHECK(contracted_graph.FindEdge(4, 1) != SPECIAL_EDGEID);
|
||||||
// * >(5) \ (4) >
|
REQUIRE_SIZE_RANGE(contracted_graph.GetAdjacentEdgeRange(5), 1);
|
||||||
// */
|
BOOST_CHECK(contracted_graph.FindEdge(5, 1) != SPECIAL_EDGEID);
|
||||||
|
}
|
||||||
// REQUIRE_SIZE_RANGE(contracted_graph.GetAdjacentEdgeRange(0), 2);
|
|
||||||
// BOOST_CHECK(contracted_graph.FindEdge(0, 1) != SPECIAL_EDGEID);
|
|
||||||
// BOOST_CHECK(contracted_graph.FindEdge(0, 5) != SPECIAL_EDGEID);
|
|
||||||
// REQUIRE_SIZE_RANGE(contracted_graph.GetAdjacentEdgeRange(1), 0);
|
|
||||||
// REQUIRE_SIZE_RANGE(contracted_graph.GetAdjacentEdgeRange(2), 0);
|
|
||||||
// REQUIRE_SIZE_RANGE(contracted_graph.GetAdjacentEdgeRange(3), 3);
|
|
||||||
// BOOST_CHECK(contracted_graph.FindEdge(3, 1) != SPECIAL_EDGEID);
|
|
||||||
// BOOST_CHECK(contracted_graph.FindEdge(3, 4) != SPECIAL_EDGEID);
|
|
||||||
// REQUIRE_SIZE_RANGE(contracted_graph.GetAdjacentEdgeRange(4), 2);
|
|
||||||
// BOOST_CHECK(contracted_graph.FindEdge(4, 1) != SPECIAL_EDGEID);
|
|
||||||
// REQUIRE_SIZE_RANGE(contracted_graph.GetAdjacentEdgeRange(5), 1);
|
|
||||||
// BOOST_CHECK(contracted_graph.FindEdge(5, 1) != SPECIAL_EDGEID);
|
|
||||||
// }
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|||||||
@@ -24,11 +24,11 @@ inline contractor::ContractorGraph makeGraph(const std::vector<TestEdge> &edges)
|
|||||||
input_edges.push_back(contractor::ContractorEdge{
|
input_edges.push_back(contractor::ContractorEdge{
|
||||||
start,
|
start,
|
||||||
target,
|
target,
|
||||||
contractor::ContractorEdgeData{weight, weight * 2, 1.0, id++, 0, false, true, false}});
|
contractor::ContractorEdgeData{weight, weight * 2, id++, 0, false, true, false}});
|
||||||
input_edges.push_back(contractor::ContractorEdge{
|
input_edges.push_back(contractor::ContractorEdge{
|
||||||
target,
|
target,
|
||||||
start,
|
start,
|
||||||
contractor::ContractorEdgeData{weight, weight * 2, 1.0, id++, 0, false, false, true}});
|
contractor::ContractorEdgeData{weight, weight * 2, id++, 0, false, false, true}});
|
||||||
}
|
}
|
||||||
std::sort(input_edges.begin(), input_edges.end());
|
std::sort(input_edges.begin(), input_edges.end());
|
||||||
|
|
||||||
|
|||||||
@@ -1,296 +1,295 @@
|
|||||||
// #include "extractor/graph_compressor.hpp"
|
#include "extractor/graph_compressor.hpp"
|
||||||
// #include "extractor/compressed_edge_container.hpp"
|
#include "extractor/compressed_edge_container.hpp"
|
||||||
// #include "extractor/maneuver_override.hpp"
|
#include "extractor/maneuver_override.hpp"
|
||||||
// #include "extractor/restriction.hpp"
|
#include "extractor/restriction.hpp"
|
||||||
// #include "util/node_based_graph.hpp"
|
#include "util/node_based_graph.hpp"
|
||||||
// #include "util/typedefs.hpp"
|
#include "util/typedefs.hpp"
|
||||||
|
|
||||||
// #include "../unit_tests/mocks/mock_scripting_environment.hpp"
|
#include "../unit_tests/mocks/mock_scripting_environment.hpp"
|
||||||
|
|
||||||
// #include <boost/test/test_case_template.hpp>
|
#include <boost/test/test_case_template.hpp>
|
||||||
// #include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
// #include <iostream>
|
#include <iostream>
|
||||||
// #include <unordered_set>
|
#include <unordered_set>
|
||||||
// #include <vector>
|
#include <vector>
|
||||||
|
|
||||||
// BOOST_AUTO_TEST_SUITE(graph_compressor)
|
BOOST_AUTO_TEST_SUITE(graph_compressor)
|
||||||
|
|
||||||
// using namespace osrm;
|
using namespace osrm;
|
||||||
// using namespace osrm::extractor;
|
using namespace osrm::extractor;
|
||||||
// using InputEdge = util::NodeBasedDynamicGraph::InputEdge;
|
using InputEdge = util::NodeBasedDynamicGraph::InputEdge;
|
||||||
// using Graph = util::NodeBasedDynamicGraph;
|
using Graph = util::NodeBasedDynamicGraph;
|
||||||
|
|
||||||
// namespace
|
namespace
|
||||||
// {
|
{
|
||||||
|
|
||||||
// // creates a default edge of unit weight
|
// creates a default edge of unit weight
|
||||||
// inline InputEdge MakeUnitEdge(const NodeID from, const NodeID to)
|
inline InputEdge MakeUnitEdge(const NodeID from, const NodeID to)
|
||||||
// {
|
{
|
||||||
// return {from, // source
|
return {from, // source
|
||||||
// to, // target
|
to, // target
|
||||||
// 1, // weight
|
1, // weight
|
||||||
// 1, // duration
|
1, // duration
|
||||||
// GeometryID{0, false}, // geometry_id
|
GeometryID{0, false}, // geometry_id
|
||||||
// false, // reversed
|
false, // reversed
|
||||||
// NodeBasedEdgeClassification(), // default flags
|
NodeBasedEdgeClassification(), // default flags
|
||||||
// 0}; // AnnotationID
|
0}; // AnnotationID
|
||||||
// }
|
}
|
||||||
|
|
||||||
// bool compatible(Graph const &graph,
|
bool compatible(Graph const &graph,
|
||||||
// const std::vector<NodeBasedEdgeAnnotation> &node_data_container,
|
const std::vector<NodeBasedEdgeAnnotation> &node_data_container,
|
||||||
// EdgeID const first,
|
EdgeID const first,
|
||||||
// EdgeID second)
|
EdgeID second)
|
||||||
// {
|
{
|
||||||
// auto const &first_flags = graph.GetEdgeData(first).flags;
|
auto const &first_flags = graph.GetEdgeData(first).flags;
|
||||||
// auto const &second_flags = graph.GetEdgeData(second).flags;
|
auto const &second_flags = graph.GetEdgeData(second).flags;
|
||||||
// if (!(first_flags == second_flags))
|
if (!(first_flags == second_flags))
|
||||||
// return false;
|
return false;
|
||||||
|
|
||||||
// if (graph.GetEdgeData(first).reversed != graph.GetEdgeData(second).reversed)
|
if (graph.GetEdgeData(first).reversed != graph.GetEdgeData(second).reversed)
|
||||||
// return false;
|
return false;
|
||||||
|
|
||||||
// auto const &first_annotation = node_data_container[graph.GetEdgeData(first).annotation_data];
|
auto const &first_annotation = node_data_container[graph.GetEdgeData(first).annotation_data];
|
||||||
// auto const &second_annotation =
|
auto const &second_annotation = node_data_container[graph.GetEdgeData(second).annotation_data];
|
||||||
// node_data_container[graph.GetEdgeData(second).annotation_data];
|
|
||||||
|
|
||||||
// return first_annotation.CanCombineWith(second_annotation);
|
return first_annotation.CanCombineWith(second_annotation);
|
||||||
// }
|
}
|
||||||
|
|
||||||
// } // namespace
|
} // namespace
|
||||||
|
|
||||||
// BOOST_AUTO_TEST_CASE(long_road_test)
|
BOOST_AUTO_TEST_CASE(long_road_test)
|
||||||
// {
|
{
|
||||||
// //
|
//
|
||||||
// // 0---1---2---3---4
|
// 0---1---2---3---4
|
||||||
// //
|
//
|
||||||
// GraphCompressor compressor;
|
GraphCompressor compressor;
|
||||||
|
|
||||||
// std::unordered_set<NodeID> barrier_nodes;
|
std::unordered_set<NodeID> barrier_nodes;
|
||||||
// std::unordered_set<NodeID> traffic_lights;
|
std::unordered_set<NodeID> traffic_lights;
|
||||||
// std::vector<TurnRestriction> restrictions;
|
std::vector<TurnRestriction> restrictions;
|
||||||
// std::vector<ConditionalTurnRestriction> conditional_restrictions;
|
std::vector<ConditionalTurnRestriction> conditional_restrictions;
|
||||||
// std::vector<NodeBasedEdgeAnnotation> annotations(1);
|
std::vector<NodeBasedEdgeAnnotation> annotations(1);
|
||||||
// CompressedEdgeContainer container;
|
CompressedEdgeContainer container;
|
||||||
// test::MockScriptingEnvironment scripting_environment;
|
test::MockScriptingEnvironment scripting_environment;
|
||||||
// std::vector<UnresolvedManeuverOverride> maneuver_overrides;
|
std::vector<UnresolvedManeuverOverride> maneuver_overrides;
|
||||||
|
|
||||||
// std::vector<InputEdge> edges = {MakeUnitEdge(0, 1),
|
std::vector<InputEdge> edges = {MakeUnitEdge(0, 1),
|
||||||
// MakeUnitEdge(1, 0),
|
MakeUnitEdge(1, 0),
|
||||||
// MakeUnitEdge(1, 2),
|
MakeUnitEdge(1, 2),
|
||||||
// MakeUnitEdge(2, 1),
|
MakeUnitEdge(2, 1),
|
||||||
// MakeUnitEdge(2, 3),
|
MakeUnitEdge(2, 3),
|
||||||
// MakeUnitEdge(3, 2),
|
MakeUnitEdge(3, 2),
|
||||||
// MakeUnitEdge(3, 4),
|
MakeUnitEdge(3, 4),
|
||||||
// MakeUnitEdge(4, 3)};
|
MakeUnitEdge(4, 3)};
|
||||||
|
|
||||||
// Graph graph(5, edges);
|
Graph graph(5, edges);
|
||||||
// BOOST_CHECK(compatible(graph, annotations, 0, 2));
|
BOOST_CHECK(compatible(graph, annotations, 0, 2));
|
||||||
// BOOST_CHECK(compatible(graph, annotations, 2, 4));
|
BOOST_CHECK(compatible(graph, annotations, 2, 4));
|
||||||
// BOOST_CHECK(compatible(graph, annotations, 4, 6));
|
BOOST_CHECK(compatible(graph, annotations, 4, 6));
|
||||||
|
|
||||||
// compressor.Compress(barrier_nodes,
|
compressor.Compress(barrier_nodes,
|
||||||
// traffic_lights,
|
traffic_lights,
|
||||||
// scripting_environment,
|
scripting_environment,
|
||||||
// restrictions,
|
restrictions,
|
||||||
// conditional_restrictions,
|
conditional_restrictions,
|
||||||
// maneuver_overrides,
|
maneuver_overrides,
|
||||||
// graph,
|
graph,
|
||||||
// annotations,
|
annotations,
|
||||||
// container);
|
container);
|
||||||
// BOOST_CHECK_EQUAL(graph.FindEdge(0, 1), SPECIAL_EDGEID);
|
BOOST_CHECK_EQUAL(graph.FindEdge(0, 1), SPECIAL_EDGEID);
|
||||||
// BOOST_CHECK_EQUAL(graph.FindEdge(1, 2), SPECIAL_EDGEID);
|
BOOST_CHECK_EQUAL(graph.FindEdge(1, 2), SPECIAL_EDGEID);
|
||||||
// BOOST_CHECK_EQUAL(graph.FindEdge(2, 3), SPECIAL_EDGEID);
|
BOOST_CHECK_EQUAL(graph.FindEdge(2, 3), SPECIAL_EDGEID);
|
||||||
// BOOST_CHECK_EQUAL(graph.FindEdge(3, 4), SPECIAL_EDGEID);
|
BOOST_CHECK_EQUAL(graph.FindEdge(3, 4), SPECIAL_EDGEID);
|
||||||
// BOOST_CHECK(graph.FindEdge(0, 4) != SPECIAL_EDGEID);
|
BOOST_CHECK(graph.FindEdge(0, 4) != SPECIAL_EDGEID);
|
||||||
// }
|
}
|
||||||
|
|
||||||
// BOOST_AUTO_TEST_CASE(loop_test)
|
BOOST_AUTO_TEST_CASE(loop_test)
|
||||||
// {
|
{
|
||||||
// //
|
//
|
||||||
// // 0---1---2
|
// 0---1---2
|
||||||
// // | |
|
// | |
|
||||||
// // 5---4---3
|
// 5---4---3
|
||||||
// //
|
//
|
||||||
// GraphCompressor compressor;
|
GraphCompressor compressor;
|
||||||
|
|
||||||
// std::unordered_set<NodeID> barrier_nodes;
|
std::unordered_set<NodeID> barrier_nodes;
|
||||||
// std::unordered_set<NodeID> traffic_lights;
|
std::unordered_set<NodeID> traffic_lights;
|
||||||
// std::vector<TurnRestriction> restrictions;
|
std::vector<TurnRestriction> restrictions;
|
||||||
// std::vector<ConditionalTurnRestriction> conditional_restrictions;
|
std::vector<ConditionalTurnRestriction> conditional_restrictions;
|
||||||
// CompressedEdgeContainer container;
|
CompressedEdgeContainer container;
|
||||||
// std::vector<NodeBasedEdgeAnnotation> annotations(1);
|
std::vector<NodeBasedEdgeAnnotation> annotations(1);
|
||||||
// test::MockScriptingEnvironment scripting_environment;
|
test::MockScriptingEnvironment scripting_environment;
|
||||||
// std::vector<UnresolvedManeuverOverride> maneuver_overrides;
|
std::vector<UnresolvedManeuverOverride> maneuver_overrides;
|
||||||
|
|
||||||
// std::vector<InputEdge> edges = {MakeUnitEdge(0, 1),
|
std::vector<InputEdge> edges = {MakeUnitEdge(0, 1),
|
||||||
// MakeUnitEdge(0, 5),
|
MakeUnitEdge(0, 5),
|
||||||
// MakeUnitEdge(1, 0),
|
MakeUnitEdge(1, 0),
|
||||||
// MakeUnitEdge(1, 2),
|
MakeUnitEdge(1, 2),
|
||||||
// MakeUnitEdge(2, 1),
|
MakeUnitEdge(2, 1),
|
||||||
// MakeUnitEdge(2, 3),
|
MakeUnitEdge(2, 3),
|
||||||
// MakeUnitEdge(3, 2),
|
MakeUnitEdge(3, 2),
|
||||||
// MakeUnitEdge(3, 4),
|
MakeUnitEdge(3, 4),
|
||||||
// MakeUnitEdge(4, 3),
|
MakeUnitEdge(4, 3),
|
||||||
// MakeUnitEdge(4, 5),
|
MakeUnitEdge(4, 5),
|
||||||
// MakeUnitEdge(5, 0),
|
MakeUnitEdge(5, 0),
|
||||||
// MakeUnitEdge(5, 4)};
|
MakeUnitEdge(5, 4)};
|
||||||
|
|
||||||
// Graph graph(6, edges);
|
Graph graph(6, edges);
|
||||||
// BOOST_CHECK(edges.size() == 12);
|
BOOST_CHECK(edges.size() == 12);
|
||||||
// BOOST_CHECK(compatible(graph, annotations, 0, 1));
|
BOOST_CHECK(compatible(graph, annotations, 0, 1));
|
||||||
// BOOST_CHECK(compatible(graph, annotations, 1, 2));
|
BOOST_CHECK(compatible(graph, annotations, 1, 2));
|
||||||
// BOOST_CHECK(compatible(graph, annotations, 2, 3));
|
BOOST_CHECK(compatible(graph, annotations, 2, 3));
|
||||||
// BOOST_CHECK(compatible(graph, annotations, 3, 4));
|
BOOST_CHECK(compatible(graph, annotations, 3, 4));
|
||||||
// BOOST_CHECK(compatible(graph, annotations, 4, 5));
|
BOOST_CHECK(compatible(graph, annotations, 4, 5));
|
||||||
// BOOST_CHECK(compatible(graph, annotations, 5, 6));
|
BOOST_CHECK(compatible(graph, annotations, 5, 6));
|
||||||
// BOOST_CHECK(compatible(graph, annotations, 6, 7));
|
BOOST_CHECK(compatible(graph, annotations, 6, 7));
|
||||||
// BOOST_CHECK(compatible(graph, annotations, 7, 8));
|
BOOST_CHECK(compatible(graph, annotations, 7, 8));
|
||||||
// BOOST_CHECK(compatible(graph, annotations, 8, 9));
|
BOOST_CHECK(compatible(graph, annotations, 8, 9));
|
||||||
// BOOST_CHECK(compatible(graph, annotations, 9, 10));
|
BOOST_CHECK(compatible(graph, annotations, 9, 10));
|
||||||
// BOOST_CHECK(compatible(graph, annotations, 10, 11));
|
BOOST_CHECK(compatible(graph, annotations, 10, 11));
|
||||||
// BOOST_CHECK(compatible(graph, annotations, 11, 0));
|
BOOST_CHECK(compatible(graph, annotations, 11, 0));
|
||||||
|
|
||||||
// compressor.Compress(barrier_nodes,
|
compressor.Compress(barrier_nodes,
|
||||||
// traffic_lights,
|
traffic_lights,
|
||||||
// scripting_environment,
|
scripting_environment,
|
||||||
// restrictions,
|
restrictions,
|
||||||
// conditional_restrictions,
|
conditional_restrictions,
|
||||||
// maneuver_overrides,
|
maneuver_overrides,
|
||||||
// graph,
|
graph,
|
||||||
// annotations,
|
annotations,
|
||||||
// container);
|
container);
|
||||||
|
|
||||||
// BOOST_CHECK_EQUAL(graph.FindEdge(5, 0), SPECIAL_EDGEID);
|
BOOST_CHECK_EQUAL(graph.FindEdge(5, 0), SPECIAL_EDGEID);
|
||||||
// BOOST_CHECK_EQUAL(graph.FindEdge(0, 1), SPECIAL_EDGEID);
|
BOOST_CHECK_EQUAL(graph.FindEdge(0, 1), SPECIAL_EDGEID);
|
||||||
// BOOST_CHECK_EQUAL(graph.FindEdge(1, 2), SPECIAL_EDGEID);
|
BOOST_CHECK_EQUAL(graph.FindEdge(1, 2), SPECIAL_EDGEID);
|
||||||
// BOOST_CHECK_EQUAL(graph.FindEdge(2, 3), SPECIAL_EDGEID);
|
BOOST_CHECK_EQUAL(graph.FindEdge(2, 3), SPECIAL_EDGEID);
|
||||||
// BOOST_CHECK(graph.FindEdge(5, 3) != SPECIAL_EDGEID);
|
BOOST_CHECK(graph.FindEdge(5, 3) != SPECIAL_EDGEID);
|
||||||
// BOOST_CHECK(graph.FindEdge(3, 4) != SPECIAL_EDGEID);
|
BOOST_CHECK(graph.FindEdge(3, 4) != SPECIAL_EDGEID);
|
||||||
// BOOST_CHECK(graph.FindEdge(4, 5) != SPECIAL_EDGEID);
|
BOOST_CHECK(graph.FindEdge(4, 5) != SPECIAL_EDGEID);
|
||||||
// }
|
}
|
||||||
|
|
||||||
// BOOST_AUTO_TEST_CASE(t_intersection)
|
BOOST_AUTO_TEST_CASE(t_intersection)
|
||||||
// {
|
{
|
||||||
// //
|
//
|
||||||
// // 0---1---2
|
// 0---1---2
|
||||||
// // |
|
// |
|
||||||
// // 3
|
// 3
|
||||||
// //
|
//
|
||||||
// GraphCompressor compressor;
|
GraphCompressor compressor;
|
||||||
|
|
||||||
// std::unordered_set<NodeID> barrier_nodes;
|
std::unordered_set<NodeID> barrier_nodes;
|
||||||
// std::unordered_set<NodeID> traffic_lights;
|
std::unordered_set<NodeID> traffic_lights;
|
||||||
// std::vector<NodeBasedEdgeAnnotation> annotations(1);
|
std::vector<NodeBasedEdgeAnnotation> annotations(1);
|
||||||
// std::vector<TurnRestriction> restrictions;
|
std::vector<TurnRestriction> restrictions;
|
||||||
// std::vector<ConditionalTurnRestriction> conditional_restrictions;
|
std::vector<ConditionalTurnRestriction> conditional_restrictions;
|
||||||
// CompressedEdgeContainer container;
|
CompressedEdgeContainer container;
|
||||||
// test::MockScriptingEnvironment scripting_environment;
|
test::MockScriptingEnvironment scripting_environment;
|
||||||
// std::vector<UnresolvedManeuverOverride> maneuver_overrides;
|
std::vector<UnresolvedManeuverOverride> maneuver_overrides;
|
||||||
|
|
||||||
// std::vector<InputEdge> edges = {MakeUnitEdge(0, 1),
|
std::vector<InputEdge> edges = {MakeUnitEdge(0, 1),
|
||||||
// MakeUnitEdge(1, 0),
|
MakeUnitEdge(1, 0),
|
||||||
// MakeUnitEdge(1, 2),
|
MakeUnitEdge(1, 2),
|
||||||
// MakeUnitEdge(1, 3),
|
MakeUnitEdge(1, 3),
|
||||||
// MakeUnitEdge(2, 1),
|
MakeUnitEdge(2, 1),
|
||||||
// MakeUnitEdge(3, 1)};
|
MakeUnitEdge(3, 1)};
|
||||||
|
|
||||||
// Graph graph(4, edges);
|
Graph graph(4, edges);
|
||||||
// BOOST_CHECK(compatible(graph, annotations, 0, 1));
|
BOOST_CHECK(compatible(graph, annotations, 0, 1));
|
||||||
// BOOST_CHECK(compatible(graph, annotations, 1, 2));
|
BOOST_CHECK(compatible(graph, annotations, 1, 2));
|
||||||
// BOOST_CHECK(compatible(graph, annotations, 2, 3));
|
BOOST_CHECK(compatible(graph, annotations, 2, 3));
|
||||||
// BOOST_CHECK(compatible(graph, annotations, 3, 4));
|
BOOST_CHECK(compatible(graph, annotations, 3, 4));
|
||||||
// BOOST_CHECK(compatible(graph, annotations, 4, 5));
|
BOOST_CHECK(compatible(graph, annotations, 4, 5));
|
||||||
|
|
||||||
// compressor.Compress(barrier_nodes,
|
compressor.Compress(barrier_nodes,
|
||||||
// traffic_lights,
|
traffic_lights,
|
||||||
// scripting_environment,
|
scripting_environment,
|
||||||
// restrictions,
|
restrictions,
|
||||||
// conditional_restrictions,
|
conditional_restrictions,
|
||||||
// maneuver_overrides,
|
maneuver_overrides,
|
||||||
// graph,
|
graph,
|
||||||
// annotations,
|
annotations,
|
||||||
// container);
|
container);
|
||||||
|
|
||||||
// BOOST_CHECK(graph.FindEdge(0, 1) != SPECIAL_EDGEID);
|
BOOST_CHECK(graph.FindEdge(0, 1) != SPECIAL_EDGEID);
|
||||||
// BOOST_CHECK(graph.FindEdge(1, 2) != SPECIAL_EDGEID);
|
BOOST_CHECK(graph.FindEdge(1, 2) != SPECIAL_EDGEID);
|
||||||
// BOOST_CHECK(graph.FindEdge(1, 3) != SPECIAL_EDGEID);
|
BOOST_CHECK(graph.FindEdge(1, 3) != SPECIAL_EDGEID);
|
||||||
// }
|
}
|
||||||
|
|
||||||
// BOOST_AUTO_TEST_CASE(street_name_changes)
|
BOOST_AUTO_TEST_CASE(street_name_changes)
|
||||||
// {
|
{
|
||||||
// //
|
//
|
||||||
// // 0---1---2
|
// 0---1---2
|
||||||
// //
|
//
|
||||||
// GraphCompressor compressor;
|
GraphCompressor compressor;
|
||||||
|
|
||||||
// std::unordered_set<NodeID> barrier_nodes;
|
std::unordered_set<NodeID> barrier_nodes;
|
||||||
// std::unordered_set<NodeID> traffic_lights;
|
std::unordered_set<NodeID> traffic_lights;
|
||||||
// std::vector<NodeBasedEdgeAnnotation> annotations(2);
|
std::vector<NodeBasedEdgeAnnotation> annotations(2);
|
||||||
// std::vector<TurnRestriction> restrictions;
|
std::vector<TurnRestriction> restrictions;
|
||||||
// std::vector<ConditionalTurnRestriction> conditional_restrictions;
|
std::vector<ConditionalTurnRestriction> conditional_restrictions;
|
||||||
// CompressedEdgeContainer container;
|
CompressedEdgeContainer container;
|
||||||
// test::MockScriptingEnvironment scripting_environment;
|
test::MockScriptingEnvironment scripting_environment;
|
||||||
// std::vector<UnresolvedManeuverOverride> maneuver_overrides;
|
std::vector<UnresolvedManeuverOverride> maneuver_overrides;
|
||||||
|
|
||||||
// std::vector<InputEdge> edges = {
|
std::vector<InputEdge> edges = {
|
||||||
// MakeUnitEdge(0, 1), MakeUnitEdge(1, 0), MakeUnitEdge(1, 2), MakeUnitEdge(2, 1)};
|
MakeUnitEdge(0, 1), MakeUnitEdge(1, 0), MakeUnitEdge(1, 2), MakeUnitEdge(2, 1)};
|
||||||
|
|
||||||
// annotations[1].name_id = 1;
|
annotations[1].name_id = 1;
|
||||||
// edges[2].data.annotation_data = edges[3].data.annotation_data = 1;
|
edges[2].data.annotation_data = edges[3].data.annotation_data = 1;
|
||||||
|
|
||||||
// Graph graph(5, edges);
|
Graph graph(5, edges);
|
||||||
// BOOST_CHECK(compatible(graph, annotations, 0, 1));
|
BOOST_CHECK(compatible(graph, annotations, 0, 1));
|
||||||
// BOOST_CHECK(compatible(graph, annotations, 2, 3));
|
BOOST_CHECK(compatible(graph, annotations, 2, 3));
|
||||||
|
|
||||||
// compressor.Compress(barrier_nodes,
|
compressor.Compress(barrier_nodes,
|
||||||
// traffic_lights,
|
traffic_lights,
|
||||||
// scripting_environment,
|
scripting_environment,
|
||||||
// restrictions,
|
restrictions,
|
||||||
// conditional_restrictions,
|
conditional_restrictions,
|
||||||
// maneuver_overrides,
|
maneuver_overrides,
|
||||||
// graph,
|
graph,
|
||||||
// annotations,
|
annotations,
|
||||||
// container);
|
container);
|
||||||
|
|
||||||
// BOOST_CHECK(graph.FindEdge(0, 1) != SPECIAL_EDGEID);
|
BOOST_CHECK(graph.FindEdge(0, 1) != SPECIAL_EDGEID);
|
||||||
// BOOST_CHECK(graph.FindEdge(1, 2) != SPECIAL_EDGEID);
|
BOOST_CHECK(graph.FindEdge(1, 2) != SPECIAL_EDGEID);
|
||||||
// }
|
}
|
||||||
|
|
||||||
// BOOST_AUTO_TEST_CASE(direction_changes)
|
BOOST_AUTO_TEST_CASE(direction_changes)
|
||||||
// {
|
{
|
||||||
// //
|
//
|
||||||
// // 0-->1---2
|
// 0-->1---2
|
||||||
// //
|
//
|
||||||
// GraphCompressor compressor;
|
GraphCompressor compressor;
|
||||||
|
|
||||||
// std::unordered_set<NodeID> barrier_nodes;
|
std::unordered_set<NodeID> barrier_nodes;
|
||||||
// std::unordered_set<NodeID> traffic_lights;
|
std::unordered_set<NodeID> traffic_lights;
|
||||||
// std::vector<NodeBasedEdgeAnnotation> annotations(1);
|
std::vector<NodeBasedEdgeAnnotation> annotations(1);
|
||||||
// std::vector<TurnRestriction> restrictions;
|
std::vector<TurnRestriction> restrictions;
|
||||||
// std::vector<ConditionalTurnRestriction> conditional_restrictions;
|
std::vector<ConditionalTurnRestriction> conditional_restrictions;
|
||||||
// CompressedEdgeContainer container;
|
CompressedEdgeContainer container;
|
||||||
// test::MockScriptingEnvironment scripting_environment;
|
test::MockScriptingEnvironment scripting_environment;
|
||||||
// std::vector<UnresolvedManeuverOverride> maneuver_overrides;
|
std::vector<UnresolvedManeuverOverride> maneuver_overrides;
|
||||||
|
|
||||||
// std::vector<InputEdge> edges = {
|
std::vector<InputEdge> edges = {
|
||||||
// MakeUnitEdge(0, 1), MakeUnitEdge(1, 0), MakeUnitEdge(1, 2), MakeUnitEdge(2, 1)};
|
MakeUnitEdge(0, 1), MakeUnitEdge(1, 0), MakeUnitEdge(1, 2), MakeUnitEdge(2, 1)};
|
||||||
// // make first edge point forward
|
// make first edge point forward
|
||||||
// edges[1].data.reversed = true;
|
edges[1].data.reversed = true;
|
||||||
|
|
||||||
// Graph graph(5, edges);
|
Graph graph(5, edges);
|
||||||
// compressor.Compress(barrier_nodes,
|
compressor.Compress(barrier_nodes,
|
||||||
// traffic_lights,
|
traffic_lights,
|
||||||
// scripting_environment,
|
scripting_environment,
|
||||||
// restrictions,
|
restrictions,
|
||||||
// conditional_restrictions,
|
conditional_restrictions,
|
||||||
// maneuver_overrides,
|
maneuver_overrides,
|
||||||
// graph,
|
graph,
|
||||||
// annotations,
|
annotations,
|
||||||
// container);
|
container);
|
||||||
|
|
||||||
// BOOST_CHECK(graph.FindEdge(0, 1) != SPECIAL_EDGEID);
|
BOOST_CHECK(graph.FindEdge(0, 1) != SPECIAL_EDGEID);
|
||||||
// BOOST_CHECK(graph.FindEdge(1, 2) != SPECIAL_EDGEID);
|
BOOST_CHECK(graph.FindEdge(1, 2) != SPECIAL_EDGEID);
|
||||||
// }
|
}
|
||||||
|
|
||||||
// BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// #include "extractor/intersection/intersection_analysis.hpp"
|
#include "extractor/intersection/intersection_analysis.hpp"
|
||||||
|
|
||||||
#include "extractor/graph_compressor.hpp"
|
#include "extractor/graph_compressor.hpp"
|
||||||
|
|
||||||
@@ -17,306 +17,305 @@ using namespace osrm::extractor::intersection;
|
|||||||
using InputEdge = util::NodeBasedDynamicGraph::InputEdge;
|
using InputEdge = util::NodeBasedDynamicGraph::InputEdge;
|
||||||
using Graph = util::NodeBasedDynamicGraph;
|
using Graph = util::NodeBasedDynamicGraph;
|
||||||
|
|
||||||
// BOOST_AUTO_TEST_CASE(simple_intersection_connectivity)
|
BOOST_AUTO_TEST_CASE(simple_intersection_connectivity)
|
||||||
// {
|
{
|
||||||
// std::unordered_set<NodeID> barrier_nodes{6};
|
std::unordered_set<NodeID> barrier_nodes{6};
|
||||||
// std::unordered_set<NodeID> traffic_lights;
|
std::unordered_set<NodeID> traffic_lights;
|
||||||
// std::vector<NodeBasedEdgeAnnotation> annotations{
|
std::vector<NodeBasedEdgeAnnotation> annotations{
|
||||||
// {EMPTY_NAMEID, 0, INAVLID_CLASS_DATA, TRAVEL_MODE_DRIVING, false},
|
{EMPTY_NAMEID, 0, INAVLID_CLASS_DATA, TRAVEL_MODE_DRIVING, false},
|
||||||
// {EMPTY_NAMEID, 1, INAVLID_CLASS_DATA, TRAVEL_MODE_DRIVING, false}};
|
{EMPTY_NAMEID, 1, INAVLID_CLASS_DATA, TRAVEL_MODE_DRIVING, false}};
|
||||||
// std::vector<TurnRestriction> restrictions{TurnRestriction{NodeRestriction{0, 2, 1}, false}};
|
std::vector<TurnRestriction> restrictions{TurnRestriction{NodeRestriction{0, 2, 1}, false}};
|
||||||
// std::vector<ConditionalTurnRestriction> conditional_restrictions;
|
std::vector<ConditionalTurnRestriction> conditional_restrictions;
|
||||||
// CompressedEdgeContainer container;
|
CompressedEdgeContainer container;
|
||||||
// test::MockScriptingEnvironment scripting_environment;
|
test::MockScriptingEnvironment scripting_environment;
|
||||||
// std::vector<UnresolvedManeuverOverride> maneuver_overrides;
|
std::vector<UnresolvedManeuverOverride> maneuver_overrides;
|
||||||
|
|
||||||
// TurnLanesIndexedArray turn_lanes_data{{0, 0, 3},
|
TurnLanesIndexedArray turn_lanes_data{{0, 0, 3},
|
||||||
// {TurnLaneType::uturn | TurnLaneType::left,
|
{TurnLaneType::uturn | TurnLaneType::left,
|
||||||
// TurnLaneType::straight,
|
TurnLaneType::straight,
|
||||||
// TurnLaneType::straight | TurnLaneType::right}};
|
TurnLaneType::straight | TurnLaneType::right}};
|
||||||
|
|
||||||
// // Graph with an additional turn restriction 0→2→1 and bollard at 6
|
// Graph with an additional turn restriction 0→2→1 and bollard at 6
|
||||||
// // 0→5↔6↔7
|
// 0→5↔6↔7
|
||||||
// // ↕
|
// ↕
|
||||||
// // 1↔2←3
|
// 1↔2←3
|
||||||
// // ↓
|
// ↓
|
||||||
// // 4
|
// 4
|
||||||
// const auto unit_edge =
|
const auto unit_edge =
|
||||||
// [](const NodeID from, const NodeID to, bool allowed, AnnotationID annotation) {
|
[](const NodeID from, const NodeID to, bool allowed, AnnotationID annotation) {
|
||||||
// return InputEdge{from,
|
return InputEdge{from,
|
||||||
// to,
|
to,
|
||||||
// 1,
|
1,
|
||||||
// 1,
|
1,
|
||||||
// GeometryID{0, false},
|
GeometryID{0, false},
|
||||||
// !allowed,
|
!allowed,
|
||||||
// NodeBasedEdgeClassification(),
|
NodeBasedEdgeClassification(),
|
||||||
// annotation};
|
annotation};
|
||||||
// };
|
};
|
||||||
|
|
||||||
// std::vector<InputEdge> edges = {unit_edge(0, 2, true, 1),
|
std::vector<InputEdge> edges = {unit_edge(0, 2, true, 1),
|
||||||
// unit_edge(0, 5, true, 0),
|
unit_edge(0, 5, true, 0),
|
||||||
// unit_edge(1, 2, true, 0),
|
unit_edge(1, 2, true, 0),
|
||||||
// unit_edge(2, 0, true, 0),
|
unit_edge(2, 0, true, 0),
|
||||||
// unit_edge(2, 1, true, 0),
|
unit_edge(2, 1, true, 0),
|
||||||
// unit_edge(2, 3, false, 0),
|
unit_edge(2, 3, false, 0),
|
||||||
// unit_edge(2, 4, true, 0),
|
unit_edge(2, 4, true, 0),
|
||||||
// unit_edge(3, 2, true, 0),
|
unit_edge(3, 2, true, 0),
|
||||||
// unit_edge(4, 2, false, 0),
|
unit_edge(4, 2, false, 0),
|
||||||
// unit_edge(5, 0, false, 0),
|
unit_edge(5, 0, false, 0),
|
||||||
// unit_edge(5, 6, true, 0),
|
unit_edge(5, 6, true, 0),
|
||||||
// unit_edge(6, 5, true, 0),
|
unit_edge(6, 5, true, 0),
|
||||||
// unit_edge(6, 7, true, 0),
|
unit_edge(6, 7, true, 0),
|
||||||
// unit_edge(7, 6, true, 0)};
|
unit_edge(7, 6, true, 0)};
|
||||||
// IntersectionEdgeGeometries edge_geometries{
|
IntersectionEdgeGeometries edge_geometries{
|
||||||
// {0, 180, 180, 10.}, // 0→2
|
{0, 180, 180, 10.}, // 0→2
|
||||||
// {1, 90, 90, 10.}, // 0→5
|
{1, 90, 90, 10.}, // 0→5
|
||||||
// {2, 90, 90, 10.}, // 1→2
|
{2, 90, 90, 10.}, // 1→2
|
||||||
// {3, 0, 0, 10.}, // 2→0
|
{3, 0, 0, 10.}, // 2→0
|
||||||
// {4, 270, 270, 10.}, // 2→1
|
{4, 270, 270, 10.}, // 2→1
|
||||||
// {5, 90, 90, 10.}, // 2→3
|
{5, 90, 90, 10.}, // 2→3
|
||||||
// {6, 180, 180, 10.}, // 2→4
|
{6, 180, 180, 10.}, // 2→4
|
||||||
// {7, 270, 270, 10.}, // 3→2
|
{7, 270, 270, 10.}, // 3→2
|
||||||
// {8, 0, 0, 10.}, // 4→2
|
{8, 0, 0, 10.}, // 4→2
|
||||||
// {9, 270, 270, 10.}, // 5→0
|
{9, 270, 270, 10.}, // 5→0
|
||||||
// {10, 90, 90, 10.}, // 5→6
|
{10, 90, 90, 10.}, // 5→6
|
||||||
// {11, 270, 270, 10.}, // 6→5
|
{11, 270, 270, 10.}, // 6→5
|
||||||
// {12, 90, 90, 10.}, // 6→7
|
{12, 90, 90, 10.}, // 6→7
|
||||||
// {13, 270, 270, 10.} // 7→6
|
{13, 270, 270, 10.} // 7→6
|
||||||
// };
|
};
|
||||||
|
|
||||||
// Graph graph(8, edges);
|
Graph graph(8, edges);
|
||||||
|
|
||||||
// GraphCompressor().Compress(barrier_nodes,
|
GraphCompressor().Compress(barrier_nodes,
|
||||||
// traffic_lights,
|
traffic_lights,
|
||||||
// scripting_environment,
|
scripting_environment,
|
||||||
// restrictions,
|
restrictions,
|
||||||
// conditional_restrictions,
|
conditional_restrictions,
|
||||||
// maneuver_overrides,
|
maneuver_overrides,
|
||||||
// graph,
|
graph,
|
||||||
// annotations,
|
annotations,
|
||||||
// container);
|
container);
|
||||||
|
|
||||||
// REQUIRE_SIZE_RANGE(getIncomingEdges(graph, 2), 3);
|
REQUIRE_SIZE_RANGE(getIncomingEdges(graph, 2), 3);
|
||||||
// REQUIRE_SIZE_RANGE(getOutgoingEdges(graph, 2), 4);
|
REQUIRE_SIZE_RANGE(getOutgoingEdges(graph, 2), 4);
|
||||||
|
|
||||||
// EdgeBasedNodeDataContainer node_data_container(
|
EdgeBasedNodeDataContainer node_data_container(
|
||||||
// std::vector<EdgeBasedNode>(graph.GetNumberOfEdges()), annotations);
|
std::vector<EdgeBasedNode>(graph.GetNumberOfEdges()), annotations);
|
||||||
// RestrictionMap restriction_map(restrictions, IndexNodeByFromAndVia());
|
RestrictionMap restriction_map(restrictions, IndexNodeByFromAndVia());
|
||||||
|
|
||||||
// const auto connectivity_matrix = [&](NodeID node) {
|
const auto connectivity_matrix = [&](NodeID node) {
|
||||||
// std::vector<bool> result;
|
std::vector<bool> result;
|
||||||
// const auto incoming_edges = getIncomingEdges(graph, node);
|
const auto incoming_edges = getIncomingEdges(graph, node);
|
||||||
// const auto outgoing_edges = getOutgoingEdges(graph, node);
|
const auto outgoing_edges = getOutgoingEdges(graph, node);
|
||||||
// for (const auto incoming_edge : incoming_edges)
|
for (const auto incoming_edge : incoming_edges)
|
||||||
// {
|
{
|
||||||
// for (const auto outgoing_edge : outgoing_edges)
|
for (const auto outgoing_edge : outgoing_edges)
|
||||||
// {
|
{
|
||||||
// result.push_back(isTurnAllowed(graph,
|
result.push_back(isTurnAllowed(graph,
|
||||||
// node_data_container,
|
node_data_container,
|
||||||
// restriction_map,
|
restriction_map,
|
||||||
// barrier_nodes,
|
barrier_nodes,
|
||||||
// edge_geometries,
|
edge_geometries,
|
||||||
// turn_lanes_data,
|
turn_lanes_data,
|
||||||
// incoming_edge,
|
incoming_edge,
|
||||||
// outgoing_edge));
|
outgoing_edge));
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// return result;
|
return result;
|
||||||
// };
|
};
|
||||||
|
|
||||||
// CHECK_EQUAL_RANGE(connectivity_matrix(0), 1, 1); // from node 2 allowed U-turn and to node 5
|
CHECK_EQUAL_RANGE(connectivity_matrix(0), 1, 1); // from node 2 allowed U-turn and to node 5
|
||||||
// CHECK_EQUAL_RANGE(connectivity_matrix(1), 1); // from node 2 allowed U-turn
|
CHECK_EQUAL_RANGE(connectivity_matrix(1), 1); // from node 2 allowed U-turn
|
||||||
// CHECK_EQUAL_RANGE(connectivity_matrix(2),
|
CHECK_EQUAL_RANGE(connectivity_matrix(2),
|
||||||
// // clang-format off
|
// clang-format off
|
||||||
// 1, 0, 0, 1, // from node 0 to node 4 and a U-turn at 2
|
1, 0, 0, 1, // from node 0 to node 4 and a U-turn at 2
|
||||||
// 1, 0, 0, 1, // from node 1 to nodes 0 and 4
|
1, 0, 0, 1, // from node 1 to nodes 0 and 4
|
||||||
// 1, 1, 0, 1 // from node 3 to nodes 0, 1 and 4
|
1, 1, 0, 1 // from node 3 to nodes 0, 1 and 4
|
||||||
// // clang-format on
|
// clang-format on
|
||||||
// );
|
);
|
||||||
// REQUIRE_SIZE_RANGE(connectivity_matrix(3), 0); // no incoming edges, empty matrix
|
REQUIRE_SIZE_RANGE(connectivity_matrix(3), 0); // no incoming edges, empty matrix
|
||||||
// CHECK_EQUAL_RANGE(connectivity_matrix(4), 0); // from node 2 not allowed U-turn
|
CHECK_EQUAL_RANGE(connectivity_matrix(4), 0); // from node 2 not allowed U-turn
|
||||||
// CHECK_EQUAL_RANGE(connectivity_matrix(5),
|
CHECK_EQUAL_RANGE(connectivity_matrix(5),
|
||||||
// // clang-format off
|
// clang-format off
|
||||||
// 0, 1, // from node 0 to node 6
|
0, 1, // from node 0 to node 6
|
||||||
// 0, 1, // from node 6 a U-turn to node 6
|
0, 1, // from node 6 a U-turn to node 6
|
||||||
// // clang-format on
|
// clang-format on
|
||||||
// );
|
);
|
||||||
|
|
||||||
// CHECK_EQUAL_RANGE(connectivity_matrix(6),
|
CHECK_EQUAL_RANGE(connectivity_matrix(6),
|
||||||
// // clang-format off
|
// clang-format off
|
||||||
// 1, 0, // from node 5 a U-turn to node 5
|
1, 0, // from node 5 a U-turn to node 5
|
||||||
// 0, 1, // from node 7 a U-turn to node 7
|
0, 1, // from node 7 a U-turn to node 7
|
||||||
// // clang-format on
|
// clang-format on
|
||||||
// );
|
);
|
||||||
// }
|
}
|
||||||
|
|
||||||
// BOOST_AUTO_TEST_CASE(roundabout_intersection_connectivity)
|
BOOST_AUTO_TEST_CASE(roundabout_intersection_connectivity)
|
||||||
// {
|
{
|
||||||
// std::unordered_set<NodeID> barrier_nodes;
|
std::unordered_set<NodeID> barrier_nodes;
|
||||||
// std::unordered_set<NodeID> traffic_lights;
|
std::unordered_set<NodeID> traffic_lights;
|
||||||
// std::vector<NodeBasedEdgeAnnotation> annotations;
|
std::vector<NodeBasedEdgeAnnotation> annotations;
|
||||||
// std::vector<TurnRestriction> restrictions;
|
std::vector<TurnRestriction> restrictions;
|
||||||
// std::vector<ConditionalTurnRestriction> conditional_restrictions;
|
std::vector<ConditionalTurnRestriction> conditional_restrictions;
|
||||||
// CompressedEdgeContainer container;
|
CompressedEdgeContainer container;
|
||||||
// test::MockScriptingEnvironment scripting_environment;
|
test::MockScriptingEnvironment scripting_environment;
|
||||||
// std::vector<UnresolvedManeuverOverride> maneuver_overrides;
|
std::vector<UnresolvedManeuverOverride> maneuver_overrides;
|
||||||
|
|
||||||
// TurnLanesIndexedArray turn_lanes_data;
|
TurnLanesIndexedArray turn_lanes_data;
|
||||||
|
|
||||||
// // Graph with roundabout edges 5→0→2
|
// Graph with roundabout edges 5→0→2
|
||||||
// // 1 2 3
|
// 1 2 3
|
||||||
// // ↘ ↑ ↙
|
// ↘ ↑ ↙
|
||||||
// // 0
|
// 0
|
||||||
// // ↙ ↑ ↘
|
// ↙ ↑ ↘
|
||||||
// // 4 5 6
|
// 4 5 6
|
||||||
// const auto unit_edge = [](const NodeID from, const NodeID to, bool allowed, bool roundabout)
|
const auto unit_edge = [](const NodeID from, const NodeID to, bool allowed, bool roundabout) {
|
||||||
// {
|
return InputEdge{from,
|
||||||
// return InputEdge{from,
|
to,
|
||||||
// to,
|
1,
|
||||||
// 1,
|
1,
|
||||||
// 1,
|
GeometryID{0, false},
|
||||||
// GeometryID{0, false},
|
!allowed,
|
||||||
// !allowed,
|
NodeBasedEdgeClassification{
|
||||||
// NodeBasedEdgeClassification{
|
true, false, false, roundabout, false, false, false, {}, 0, 0},
|
||||||
// true, false, false, roundabout, false, false, false, {}, 0, 0},
|
0};
|
||||||
// 0};
|
};
|
||||||
// };
|
std::vector<InputEdge> edges = {unit_edge(0, 1, false, false),
|
||||||
// std::vector<InputEdge> edges = {unit_edge(0, 1, false, false),
|
unit_edge(0, 2, true, true),
|
||||||
// unit_edge(0, 2, true, true),
|
unit_edge(0, 3, false, false),
|
||||||
// unit_edge(0, 3, false, false),
|
unit_edge(0, 4, true, false),
|
||||||
// unit_edge(0, 4, true, false),
|
unit_edge(0, 5, false, true),
|
||||||
// unit_edge(0, 5, false, true),
|
unit_edge(0, 6, true, false),
|
||||||
// unit_edge(0, 6, true, false),
|
unit_edge(1, 0, true, false),
|
||||||
// unit_edge(1, 0, true, false),
|
unit_edge(2, 0, false, true),
|
||||||
// unit_edge(2, 0, false, true),
|
unit_edge(3, 0, true, false),
|
||||||
// unit_edge(3, 0, true, false),
|
unit_edge(4, 0, false, false),
|
||||||
// unit_edge(4, 0, false, false),
|
unit_edge(5, 0, true, true),
|
||||||
// unit_edge(5, 0, true, true),
|
unit_edge(6, 0, false, false)};
|
||||||
// unit_edge(6, 0, false, false)};
|
IntersectionEdgeGeometries edge_geometries{
|
||||||
// IntersectionEdgeGeometries edge_geometries{
|
{0, 315, 315, 10}, // 0→1
|
||||||
// {0, 315, 315, 10}, // 0→1
|
{1, 0, 0, 10}, // 0→2
|
||||||
// {1, 0, 0, 10}, // 0→2
|
{2, 45, 45, 10}, // 0→3
|
||||||
// {2, 45, 45, 10}, // 0→3
|
{3, 225, 225, 10}, // 0→4
|
||||||
// {3, 225, 225, 10}, // 0→4
|
{4, 180, 180, 10}, // 0→5
|
||||||
// {4, 180, 180, 10}, // 0→5
|
{5, 135, 135, 10}, // 0→6
|
||||||
// {5, 135, 135, 10}, // 0→6
|
{6, 135, 135, 10}, // 1→0
|
||||||
// {6, 135, 135, 10}, // 1→0
|
{7, 180, 180, 10}, // 2→0
|
||||||
// {7, 180, 180, 10}, // 2→0
|
{8, 225, 225, 10}, // 3→0
|
||||||
// {8, 225, 225, 10}, // 3→0
|
{9, 45, 45, 10}, // 4→0
|
||||||
// {9, 45, 45, 10}, // 4→0
|
{10, 0, 0, 10}, // 5→0
|
||||||
// {10, 0, 0, 10}, // 5→0
|
{11, 315, 315, 10} // 6→0
|
||||||
// {11, 315, 315, 10} // 6→0
|
};
|
||||||
// };
|
|
||||||
|
|
||||||
// Graph graph(7, edges);
|
Graph graph(7, edges);
|
||||||
|
|
||||||
// GraphCompressor().Compress(barrier_nodes,
|
GraphCompressor().Compress(barrier_nodes,
|
||||||
// traffic_lights,
|
traffic_lights,
|
||||||
// scripting_environment,
|
scripting_environment,
|
||||||
// restrictions,
|
restrictions,
|
||||||
// conditional_restrictions,
|
conditional_restrictions,
|
||||||
// maneuver_overrides,
|
maneuver_overrides,
|
||||||
// graph,
|
graph,
|
||||||
// annotations,
|
annotations,
|
||||||
// container);
|
container);
|
||||||
|
|
||||||
// REQUIRE_SIZE_RANGE(getIncomingEdges(graph, 0), 3);
|
REQUIRE_SIZE_RANGE(getIncomingEdges(graph, 0), 3);
|
||||||
// REQUIRE_SIZE_RANGE(getOutgoingEdges(graph, 0), 6);
|
REQUIRE_SIZE_RANGE(getOutgoingEdges(graph, 0), 6);
|
||||||
|
|
||||||
// EdgeBasedNodeDataContainer node_data_container(
|
EdgeBasedNodeDataContainer node_data_container(
|
||||||
// std::vector<EdgeBasedNode>(graph.GetNumberOfEdges()), annotations);
|
std::vector<EdgeBasedNode>(graph.GetNumberOfEdges()), annotations);
|
||||||
// RestrictionMap restriction_map(restrictions, IndexNodeByFromAndVia());
|
RestrictionMap restriction_map(restrictions, IndexNodeByFromAndVia());
|
||||||
|
|
||||||
// const auto connectivity_matrix = [&](NodeID node) {
|
const auto connectivity_matrix = [&](NodeID node) {
|
||||||
// std::vector<bool> result;
|
std::vector<bool> result;
|
||||||
// const auto incoming_edges = getIncomingEdges(graph, node);
|
const auto incoming_edges = getIncomingEdges(graph, node);
|
||||||
// const auto outgoing_edges = getOutgoingEdges(graph, node);
|
const auto outgoing_edges = getOutgoingEdges(graph, node);
|
||||||
// for (const auto incoming_edge : incoming_edges)
|
for (const auto incoming_edge : incoming_edges)
|
||||||
// {
|
{
|
||||||
// for (const auto outgoing_edge : outgoing_edges)
|
for (const auto outgoing_edge : outgoing_edges)
|
||||||
// {
|
{
|
||||||
// result.push_back(isTurnAllowed(graph,
|
result.push_back(isTurnAllowed(graph,
|
||||||
// node_data_container,
|
node_data_container,
|
||||||
// restriction_map,
|
restriction_map,
|
||||||
// barrier_nodes,
|
barrier_nodes,
|
||||||
// edge_geometries,
|
edge_geometries,
|
||||||
// turn_lanes_data,
|
turn_lanes_data,
|
||||||
// incoming_edge,
|
incoming_edge,
|
||||||
// outgoing_edge));
|
outgoing_edge));
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// return result;
|
return result;
|
||||||
// };
|
};
|
||||||
|
|
||||||
// CHECK_EQUAL_RANGE(connectivity_matrix(0),
|
CHECK_EQUAL_RANGE(connectivity_matrix(0),
|
||||||
// // clang-format off
|
// clang-format off
|
||||||
// 0, 1, 0, 0, 0, 1, // from node 1 to nodes 2 and 6
|
0, 1, 0, 0, 0, 1, // from node 1 to nodes 2 and 6
|
||||||
// 0, 1, 0, 1, 0, 0, // from node 3 to nodes 2 and 4
|
0, 1, 0, 1, 0, 0, // from node 3 to nodes 2 and 4
|
||||||
// 0, 1, 0, 1, 0, 1 // from node 5 to nodes 2, 4 and 6
|
0, 1, 0, 1, 0, 1 // from node 5 to nodes 2, 4 and 6
|
||||||
// // clang-format on
|
// clang-format on
|
||||||
// );
|
);
|
||||||
// }
|
}
|
||||||
|
|
||||||
// BOOST_AUTO_TEST_CASE(skip_degree_two_nodes)
|
BOOST_AUTO_TEST_CASE(skip_degree_two_nodes)
|
||||||
// {
|
{
|
||||||
// std::unordered_set<NodeID> barrier_nodes{1};
|
std::unordered_set<NodeID> barrier_nodes{1};
|
||||||
// std::unordered_set<NodeID> traffic_lights{2};
|
std::unordered_set<NodeID> traffic_lights{2};
|
||||||
// std::vector<NodeBasedEdgeAnnotation> annotations(1);
|
std::vector<NodeBasedEdgeAnnotation> annotations(1);
|
||||||
// std::vector<TurnRestriction> restrictions;
|
std::vector<TurnRestriction> restrictions;
|
||||||
// std::vector<ConditionalTurnRestriction> conditional_restrictions;
|
std::vector<ConditionalTurnRestriction> conditional_restrictions;
|
||||||
// CompressedEdgeContainer container;
|
CompressedEdgeContainer container;
|
||||||
// test::MockScriptingEnvironment scripting_environment;
|
test::MockScriptingEnvironment scripting_environment;
|
||||||
// std::vector<UnresolvedManeuverOverride> maneuver_overrides;
|
std::vector<UnresolvedManeuverOverride> maneuver_overrides;
|
||||||
|
|
||||||
// TurnLanesIndexedArray turn_lanes_data;
|
TurnLanesIndexedArray turn_lanes_data;
|
||||||
|
|
||||||
// // Graph
|
// Graph
|
||||||
// //
|
//
|
||||||
// // 0↔1→2↔3↔4→5 7
|
// 0↔1→2↔3↔4→5 7
|
||||||
// // ↑ ↕ ↕
|
// ↑ ↕ ↕
|
||||||
// // 6 8 ↔ 9
|
// 6 8 ↔ 9
|
||||||
// //
|
//
|
||||||
// const auto unit_edge = [](const NodeID from, const NodeID to, bool allowed) {
|
const auto unit_edge = [](const NodeID from, const NodeID to, bool allowed) {
|
||||||
// return InputEdge{
|
return InputEdge{
|
||||||
// from, to, 1, 1, GeometryID{0, false}, !allowed, NodeBasedEdgeClassification{}, 0};
|
from, to, 1, 1, GeometryID{0, false}, !allowed, NodeBasedEdgeClassification{}, 0};
|
||||||
// };
|
};
|
||||||
// std::vector<InputEdge> edges = {unit_edge(0, 1, true), // 0
|
std::vector<InputEdge> edges = {unit_edge(0, 1, true), // 0
|
||||||
// unit_edge(1, 0, true),
|
unit_edge(1, 0, true),
|
||||||
// unit_edge(1, 2, true),
|
unit_edge(1, 2, true),
|
||||||
// unit_edge(2, 1, false),
|
unit_edge(2, 1, false),
|
||||||
// unit_edge(2, 3, true),
|
unit_edge(2, 3, true),
|
||||||
// unit_edge(3, 2, true), // 5
|
unit_edge(3, 2, true), // 5
|
||||||
// unit_edge(3, 4, true),
|
unit_edge(3, 4, true),
|
||||||
// unit_edge(4, 3, true),
|
unit_edge(4, 3, true),
|
||||||
// unit_edge(4, 5, true),
|
unit_edge(4, 5, true),
|
||||||
// unit_edge(4, 6, false),
|
unit_edge(4, 6, false),
|
||||||
// unit_edge(5, 4, false), // 10
|
unit_edge(5, 4, false), // 10
|
||||||
// unit_edge(6, 4, true),
|
unit_edge(6, 4, true),
|
||||||
// // Circle
|
// Circle
|
||||||
// unit_edge(7, 8, true), // 12
|
unit_edge(7, 8, true), // 12
|
||||||
// unit_edge(7, 9, true),
|
unit_edge(7, 9, true),
|
||||||
// unit_edge(8, 7, true),
|
unit_edge(8, 7, true),
|
||||||
// unit_edge(8, 9, true),
|
unit_edge(8, 9, true),
|
||||||
// unit_edge(9, 7, true),
|
unit_edge(9, 7, true),
|
||||||
// unit_edge(9, 8, true)};
|
unit_edge(9, 8, true)};
|
||||||
|
|
||||||
// Graph graph(10, edges);
|
Graph graph(10, edges);
|
||||||
|
|
||||||
// GraphCompressor().Compress(barrier_nodes,
|
GraphCompressor().Compress(barrier_nodes,
|
||||||
// traffic_lights,
|
traffic_lights,
|
||||||
// scripting_environment,
|
scripting_environment,
|
||||||
// restrictions,
|
restrictions,
|
||||||
// conditional_restrictions,
|
conditional_restrictions,
|
||||||
// maneuver_overrides,
|
maneuver_overrides,
|
||||||
// graph,
|
graph,
|
||||||
// annotations,
|
annotations,
|
||||||
// container);
|
container);
|
||||||
|
|
||||||
// BOOST_CHECK_EQUAL(graph.GetTarget(skipDegreeTwoNodes(graph, {0, 0}).edge), 4);
|
BOOST_CHECK_EQUAL(graph.GetTarget(skipDegreeTwoNodes(graph, {0, 0}).edge), 4);
|
||||||
// BOOST_CHECK_EQUAL(graph.GetTarget(skipDegreeTwoNodes(graph, {4, 7}).edge), 0);
|
BOOST_CHECK_EQUAL(graph.GetTarget(skipDegreeTwoNodes(graph, {4, 7}).edge), 0);
|
||||||
// BOOST_CHECK_EQUAL(graph.GetTarget(skipDegreeTwoNodes(graph, {5, 10}).edge), 4);
|
BOOST_CHECK_EQUAL(graph.GetTarget(skipDegreeTwoNodes(graph, {5, 10}).edge), 4);
|
||||||
// BOOST_CHECK_EQUAL(graph.GetTarget(skipDegreeTwoNodes(graph, {6, 11}).edge), 4);
|
BOOST_CHECK_EQUAL(graph.GetTarget(skipDegreeTwoNodes(graph, {6, 11}).edge), 4);
|
||||||
// BOOST_CHECK_EQUAL(graph.GetTarget(skipDegreeTwoNodes(graph, {7, 12}).edge), 7);
|
BOOST_CHECK_EQUAL(graph.GetTarget(skipDegreeTwoNodes(graph, {7, 12}).edge), 7);
|
||||||
// }
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|||||||
@@ -16,13 +16,13 @@ BOOST_AUTO_TEST_CASE(test_extract_with_invalid_config)
|
|||||||
std::exception); // including osrm::util::exception, osmium::io_error, etc.
|
std::exception); // including osrm::util::exception, osmium::io_error, etc.
|
||||||
}
|
}
|
||||||
|
|
||||||
// BOOST_AUTO_TEST_CASE(test_extract_with_valid_config)
|
BOOST_AUTO_TEST_CASE(test_extract_with_valid_config)
|
||||||
// {
|
{
|
||||||
// osrm::ExtractorConfig config;
|
osrm::ExtractorConfig config;
|
||||||
// config.input_path = OSRM_TEST_DATA_DIR "/monaco.osm.pbf";
|
config.input_path = OSRM_TEST_DATA_DIR "/monaco.osm.pbf";
|
||||||
// config.UseDefaultOutputNames(OSRM_TEST_DATA_DIR "/monaco.osm.pbf");
|
config.UseDefaultOutputNames(OSRM_TEST_DATA_DIR "/monaco.osm.pbf");
|
||||||
// config.requested_num_threads = tbb::task_scheduler_init::default_num_threads();
|
config.requested_num_threads = tbb::task_scheduler_init::default_num_threads();
|
||||||
// BOOST_CHECK_NO_THROW(osrm::extract(config));
|
BOOST_CHECK_NO_THROW(osrm::extract(config));
|
||||||
// }
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|||||||
@@ -32,9 +32,9 @@ auto makeGraph(const std::vector<MockEdge> &mock_edges)
|
|||||||
max_id = std::max<std::size_t>(max_id, std::max(m.start, m.target));
|
max_id = std::max<std::size_t>(max_id, std::max(m.start, m.target));
|
||||||
|
|
||||||
edges.push_back(InputEdge{
|
edges.push_back(InputEdge{
|
||||||
m.start, m.target, EdgeBasedGraphEdgeData{SPECIAL_NODEID, 1, 1, 1, true, false}});
|
m.start, m.target, EdgeBasedGraphEdgeData{SPECIAL_NODEID, 1, 1, true, false}});
|
||||||
edges.push_back(InputEdge{
|
edges.push_back(InputEdge{
|
||||||
m.target, m.start, EdgeBasedGraphEdgeData{SPECIAL_NODEID, 1, 1, 1, false, true}});
|
m.target, m.start, EdgeBasedGraphEdgeData{SPECIAL_NODEID, 1, 1, false, true}});
|
||||||
}
|
}
|
||||||
std::sort(edges.begin(), edges.end());
|
std::sort(edges.begin(), edges.end());
|
||||||
return DynamicEdgeBasedGraph(max_id + 1, edges);
|
return DynamicEdgeBasedGraph(max_id + 1, edges);
|
||||||
|
|||||||
@@ -15,89 +15,86 @@ using namespace osrm::storage;
|
|||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(layout_write_test)
|
BOOST_AUTO_TEST_CASE(layout_write_test)
|
||||||
{
|
{
|
||||||
std::unique_ptr<BaseDataLayout> layout = std::make_unique<DataLayout>();
|
DataLayout layout;
|
||||||
|
|
||||||
Block block_1{20, 8 * 20};
|
Block block_1{20, 8 * 20};
|
||||||
Block block_2{1, 4 * 1};
|
Block block_2{1, 4 * 1};
|
||||||
Block block_3{100, static_cast<std::uint64_t>(std::ceil(100 / 64.))};
|
Block block_3{100, static_cast<std::uint64_t>(std::ceil(100 / 64.))};
|
||||||
|
|
||||||
layout->SetBlock("block1", block_1);
|
layout.SetBlock("block1", block_1);
|
||||||
layout->SetBlock("block2", block_2);
|
layout.SetBlock("block2", block_2);
|
||||||
layout->SetBlock("block3", block_3);
|
layout.SetBlock("block3", block_3);
|
||||||
|
|
||||||
// Canary and alignment change layout size
|
// Canary and alignment change layout size
|
||||||
BOOST_CHECK_GT(layout->GetSizeOfLayout(),
|
BOOST_CHECK_GT(layout.GetSizeOfLayout(),
|
||||||
block_1.byte_size + block_2.byte_size + block_3.byte_size);
|
block_1.byte_size + block_2.byte_size + block_3.byte_size);
|
||||||
|
|
||||||
BOOST_CHECK_EQUAL(layout->GetBlockSize("block1"), block_1.byte_size);
|
BOOST_CHECK_EQUAL(layout.GetBlockSize("block1"), block_1.byte_size);
|
||||||
BOOST_CHECK_EQUAL(layout->GetBlockSize("block2"), block_2.byte_size);
|
BOOST_CHECK_EQUAL(layout.GetBlockSize("block2"), block_2.byte_size);
|
||||||
BOOST_CHECK_EQUAL(layout->GetBlockSize("block3"), block_3.byte_size);
|
BOOST_CHECK_EQUAL(layout.GetBlockSize("block3"), block_3.byte_size);
|
||||||
|
|
||||||
std::vector<char> buffer(layout->GetSizeOfLayout());
|
std::vector<char> buffer(layout.GetSizeOfLayout());
|
||||||
auto smallest_addr = buffer.data();
|
auto smallest_addr = buffer.data();
|
||||||
auto biggest_addr = buffer.data() + buffer.size();
|
auto biggest_addr = buffer.data() + buffer.size();
|
||||||
|
|
||||||
{
|
{
|
||||||
auto block_1_ptr =
|
auto block_1_ptr = layout.GetBlockPtr<std::uint64_t>(buffer.data(), "block1");
|
||||||
reinterpret_cast<std::uint64_t *>(layout->GetBlockPtr(buffer.data(), "block1"));
|
auto block_2_ptr = layout.GetBlockPtr<std::uint32_t>(buffer.data(), "block2");
|
||||||
auto block_2_ptr =
|
auto block_3_ptr = layout.GetBlockPtr<std::uint64_t>(buffer.data(), "block3");
|
||||||
reinterpret_cast<std::uint32_t *>(layout->GetBlockPtr(buffer.data(), "block2"));
|
|
||||||
auto block_3_ptr =
|
|
||||||
reinterpret_cast<std::uint64_t *>(layout->GetBlockPtr(buffer.data(), "block3"));
|
|
||||||
|
|
||||||
BOOST_CHECK_LE(reinterpret_cast<std::size_t>(smallest_addr),
|
BOOST_CHECK_LT(reinterpret_cast<std::size_t>(smallest_addr),
|
||||||
reinterpret_cast<std::size_t>(block_1_ptr));
|
reinterpret_cast<std::size_t>(block_1_ptr));
|
||||||
BOOST_CHECK_GT(
|
BOOST_CHECK_GT(
|
||||||
reinterpret_cast<std::size_t>(biggest_addr),
|
reinterpret_cast<std::size_t>(biggest_addr),
|
||||||
reinterpret_cast<std::size_t>(block_1_ptr + layout->GetBlockEntries("block1")));
|
reinterpret_cast<std::size_t>(block_1_ptr + layout.GetBlockEntries("block1")));
|
||||||
|
|
||||||
BOOST_CHECK_LT(reinterpret_cast<std::size_t>(smallest_addr),
|
BOOST_CHECK_LT(reinterpret_cast<std::size_t>(smallest_addr),
|
||||||
reinterpret_cast<std::size_t>(block_2_ptr));
|
reinterpret_cast<std::size_t>(block_2_ptr));
|
||||||
BOOST_CHECK_GT(
|
BOOST_CHECK_GT(
|
||||||
reinterpret_cast<std::size_t>(biggest_addr),
|
reinterpret_cast<std::size_t>(biggest_addr),
|
||||||
reinterpret_cast<std::size_t>(block_2_ptr + layout->GetBlockEntries("block2")));
|
reinterpret_cast<std::size_t>(block_2_ptr + layout.GetBlockEntries("block2")));
|
||||||
|
|
||||||
BOOST_CHECK_LT(reinterpret_cast<std::size_t>(smallest_addr),
|
BOOST_CHECK_LT(reinterpret_cast<std::size_t>(smallest_addr),
|
||||||
reinterpret_cast<std::size_t>(block_3_ptr));
|
reinterpret_cast<std::size_t>(block_3_ptr));
|
||||||
BOOST_CHECK_GT(reinterpret_cast<std::size_t>(biggest_addr),
|
BOOST_CHECK_GT(reinterpret_cast<std::size_t>(biggest_addr),
|
||||||
reinterpret_cast<std::size_t>(
|
reinterpret_cast<std::size_t>(
|
||||||
block_3_ptr + static_cast<std::size_t>(
|
block_3_ptr + static_cast<std::size_t>(
|
||||||
std::ceil(layout->GetBlockEntries("block3") / 64))));
|
std::ceil(layout.GetBlockEntries("block3") / 64))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(layout_list_test)
|
BOOST_AUTO_TEST_CASE(layout_list_test)
|
||||||
{
|
{
|
||||||
std::unique_ptr<BaseDataLayout> layout = std::make_unique<DataLayout>();
|
DataLayout layout;
|
||||||
|
|
||||||
Block block_1{20, 8 * 20};
|
Block block_1{20, 8 * 20};
|
||||||
Block block_2{1, 4 * 1};
|
Block block_2{1, 4 * 1};
|
||||||
Block block_3{100, static_cast<std::uint64_t>(std::ceil(100 / 64.))};
|
Block block_3{100, static_cast<std::uint64_t>(std::ceil(100 / 64.))};
|
||||||
|
|
||||||
layout->SetBlock("/ch/edge_filter/block1", block_1);
|
layout.SetBlock("/ch/edge_filter/block1", block_1);
|
||||||
layout->SetBlock("/ch/edge_filter/block2", block_2);
|
layout.SetBlock("/ch/edge_filter/block2", block_2);
|
||||||
layout->SetBlock("/ch/edge_filter/block3", block_3);
|
layout.SetBlock("/ch/edge_filter/block3", block_3);
|
||||||
layout->SetBlock("/mld/metrics/0/durations", block_2);
|
layout.SetBlock("/mld/metrics/0/durations", block_2);
|
||||||
layout->SetBlock("/mld/metrics/0/weights", block_3);
|
layout.SetBlock("/mld/metrics/0/weights", block_3);
|
||||||
layout->SetBlock("/mld/metrics/1/durations", block_2);
|
layout.SetBlock("/mld/metrics/1/durations", block_2);
|
||||||
layout->SetBlock("/mld/metrics/1/weights", block_3);
|
layout.SetBlock("/mld/metrics/1/weights", block_3);
|
||||||
|
|
||||||
std::vector<std::string> results_1;
|
std::vector<std::string> results_1;
|
||||||
std::vector<std::string> results_2;
|
std::vector<std::string> results_2;
|
||||||
std::vector<std::string> results_3;
|
std::vector<std::string> results_3;
|
||||||
layout->List("/ch/edge_filter", std::back_inserter(results_1));
|
layout.List("/ch/edge_filter", std::back_inserter(results_1));
|
||||||
layout->List("/ch/edge_filter/", std::back_inserter(results_2));
|
layout.List("/ch/edge_filter/", std::back_inserter(results_2));
|
||||||
layout->List("/ch/", std::back_inserter(results_3));
|
layout.List("/ch/", std::back_inserter(results_3));
|
||||||
|
|
||||||
std::vector<std::string> results_4;
|
std::vector<std::string> results_4;
|
||||||
std::vector<std::string> results_5;
|
std::vector<std::string> results_5;
|
||||||
std::vector<std::string> results_6;
|
std::vector<std::string> results_6;
|
||||||
layout->List("/mld/metrics", std::back_inserter(results_4));
|
layout.List("/mld/metrics", std::back_inserter(results_4));
|
||||||
layout->List("/mld/metrics/", std::back_inserter(results_5));
|
layout.List("/mld/metrics/", std::back_inserter(results_5));
|
||||||
layout->List("/mld/", std::back_inserter(results_6));
|
layout.List("/mld/", std::back_inserter(results_6));
|
||||||
|
|
||||||
std::vector<std::string> results_7;
|
std::vector<std::string> results_7;
|
||||||
layout->List("", std::back_inserter(results_7));
|
layout.List("", std::back_inserter(results_7));
|
||||||
BOOST_CHECK_EQUAL(results_7.size(), 7);
|
BOOST_CHECK_EQUAL(results_7.size(), 7);
|
||||||
|
|
||||||
CHECK_EQUAL_RANGE(
|
CHECK_EQUAL_RANGE(
|
||||||
|
|||||||
@@ -12,50 +12,46 @@ using namespace osrm::updater;
|
|||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(timezoner_test)
|
BOOST_AUTO_TEST_CASE(timezoner_test)
|
||||||
{
|
{
|
||||||
// const char json[] =
|
const char json[] =
|
||||||
// "{ \"type\" : \"FeatureCollection\", \"features\": ["
|
"{ \"type\" : \"FeatureCollection\", \"features\": ["
|
||||||
// "{ \"type\" : \"Feature\","
|
"{ \"type\" : \"Feature\","
|
||||||
// "\"properties\" : { \"TZID\" : \"Europe/Berlin\"}, \"geometry\" : { \"type\":
|
"\"properties\" : { \"TZID\" : \"Europe/Berlin\"}, \"geometry\" : { \"type\": \"polygon\", "
|
||||||
// \"polygon\", "
|
"\"coordinates\": [[[8.28369,48.88277], [8.57757, "
|
||||||
// "\"coordinates\": [[[8.28369,48.88277], [8.57757, "
|
"48.88277], [8.57757, 49.07206], [8.28369, "
|
||||||
// "48.88277], [8.57757, 49.07206], [8.28369, "
|
"49.07206], [8.28369, 48.88277]]] }} ]}";
|
||||||
// "49.07206], [8.28369, 48.88277]]] }} ]}";
|
std::time_t now = time(0);
|
||||||
// std::time_t now = time(0);
|
BOOST_CHECK_NO_THROW(Timezoner tz(json, now));
|
||||||
// BOOST_CHECK_NO_THROW(Timezoner tz(json, now));
|
|
||||||
|
|
||||||
// boost::filesystem::path test_path(TEST_DATA_DIR "/test.geojson");
|
boost::filesystem::path test_path(TEST_DATA_DIR "/test.geojson");
|
||||||
// BOOST_CHECK_NO_THROW(Timezoner tz(test_path, now));
|
BOOST_CHECK_NO_THROW(Timezoner tz(test_path, now));
|
||||||
|
|
||||||
// missing opening bracket
|
// missing opening bracket
|
||||||
// const char bad[] =
|
const char bad[] =
|
||||||
// "\"type\" : \"FeatureCollection\", \"features\": ["
|
"\"type\" : \"FeatureCollection\", \"features\": ["
|
||||||
// "{ \"type\" : \"Feature\","
|
"{ \"type\" : \"Feature\","
|
||||||
// "\"properties\" : { \"TZID\" : \"Europe/Berlin\"}, \"geometry\" : { \"type\":
|
"\"properties\" : { \"TZID\" : \"Europe/Berlin\"}, \"geometry\" : { \"type\": \"polygon\", "
|
||||||
// \"polygon\", "
|
"\"coordinates\": [[[8.28369,48.88277], [8.57757, "
|
||||||
// "\"coordinates\": [[[8.28369,48.88277], [8.57757, "
|
"48.88277], [8.57757, 49.07206], [8.28369, "
|
||||||
// "48.88277], [8.57757, 49.07206], [8.28369, "
|
"49.07206], [8.28369, 48.88277]]] }} ]}";
|
||||||
// "49.07206], [8.28369, 48.88277]]] }} ]}";
|
BOOST_CHECK_THROW(Timezoner tz(bad, now), util::exception);
|
||||||
// BOOST_CHECK_THROW(Timezoner tz(bad, now), util::exception);
|
|
||||||
|
|
||||||
// missing/malformed FeatureCollection type field
|
// missing/malformed FeatureCollection type field
|
||||||
// const char missing_type[] =
|
const char missing_type[] =
|
||||||
// "{ \"FeatureCollection\", \"features\": ["
|
"{ \"FeatureCollection\", \"features\": ["
|
||||||
// "{ \"type\" : \"Feature\","
|
"{ \"type\" : \"Feature\","
|
||||||
// "\"properties\" : { \"TZID\" : \"Europe/Berlin\"}, \"geometry\" : { \"type\":
|
"\"properties\" : { \"TZID\" : \"Europe/Berlin\"}, \"geometry\" : { \"type\": \"polygon\", "
|
||||||
// \"polygon\", "
|
"\"coordinates\": [[[8.28369,48.88277], [8.57757, "
|
||||||
// "\"coordinates\": [[[8.28369,48.88277], [8.57757, "
|
"48.88277], [8.57757, 49.07206], [8.28369, "
|
||||||
// "48.88277], [8.57757, 49.07206], [8.28369, "
|
"49.07206], [8.28369, 48.88277]]] }} ]}";
|
||||||
// "49.07206], [8.28369, 48.88277]]] }} ]}";
|
BOOST_CHECK_THROW(Timezoner tz(missing_type, now), util::exception);
|
||||||
// BOOST_CHECK_THROW(Timezoner tz(missing_type, now), util::exception);
|
|
||||||
|
|
||||||
// const char missing_featc[] =
|
const char missing_featc[] =
|
||||||
// "{ \"type\" : \"Collection\", \"features\": ["
|
"{ \"type\" : \"Collection\", \"features\": ["
|
||||||
// "{ \"type\" : \"Feature\","
|
"{ \"type\" : \"Feature\","
|
||||||
// "\"properties\" : { \"TZID\" : \"Europe/Berlin\"}, \"geometry\" : { \"type\":
|
"\"properties\" : { \"TZID\" : \"Europe/Berlin\"}, \"geometry\" : { \"type\": \"polygon\", "
|
||||||
// \"polygon\", "
|
"\"coordinates\": [[[8.28369,48.88277], [8.57757, "
|
||||||
// "\"coordinates\": [[[8.28369,48.88277], [8.57757, "
|
"48.88277], [8.57757, 49.07206], [8.28369, "
|
||||||
// "48.88277], [8.57757, 49.07206], [8.28369, "
|
"49.07206], [8.28369, 48.88277]]] }} ]}";
|
||||||
// "49.07206], [8.28369, 48.88277]]] }} ]}";
|
BOOST_CHECK_THROW(Timezoner tz(missing_featc, now), util::exception);
|
||||||
// BOOST_CHECK_THROW(Timezoner tz(missing_featc, now), util::exception);
|
|
||||||
}
|
}
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|||||||
@@ -71,74 +71,68 @@ BOOST_AUTO_TEST_CASE(timezone_validation_test)
|
|||||||
"48.88277], [8.57757, 49.07206], [8.28369, "
|
"48.88277], [8.57757, 49.07206], [8.28369, "
|
||||||
"49.07206], [8.28369, 48.88277]]] }}";
|
"49.07206], [8.28369, 48.88277]]] }}";
|
||||||
doc.Parse(missing_tzid);
|
doc.Parse(missing_tzid);
|
||||||
// BOOST_CHECK_THROW(util::validateFeature(doc), util::exception);
|
BOOST_CHECK_THROW(util::validateFeature(doc), util::exception);
|
||||||
|
|
||||||
// char tzid_err[] = "{ \"type\" : \"Feature\","
|
char tzid_err[] = "{ \"type\" : \"Feature\","
|
||||||
// "\"properties\" : { \"TZID\" : []}, \"geometry\" : { \"type\": \"polygon\",
|
"\"properties\" : { \"TZID\" : []}, \"geometry\" : { \"type\": \"polygon\", "
|
||||||
// "
|
"\"coordinates\": [[[8.28369,48.88277], [8.57757, "
|
||||||
// "\"coordinates\": [[[8.28369,48.88277], [8.57757, "
|
"48.88277], [8.57757, 49.07206], [8.28369, "
|
||||||
// "48.88277], [8.57757, 49.07206], [8.28369, "
|
"49.07206], [8.28369, 48.88277]]] }}";
|
||||||
// "49.07206], [8.28369, 48.88277]]] }}";
|
doc.Parse(tzid_err);
|
||||||
// doc.Parse(tzid_err);
|
BOOST_CHECK_THROW(util::validateFeature(doc), util::exception);
|
||||||
// BOOST_CHECK_THROW(util::validateFeature(doc), util::exception);
|
|
||||||
|
|
||||||
// char missing_geom[] = "{ \"type\" : \"Feature\","
|
char missing_geom[] = "{ \"type\" : \"Feature\","
|
||||||
// "\"properties\" : { \"TZID\" : \"Europe/Berlin\"}, \"geometries\" : { "
|
"\"properties\" : { \"TZID\" : \"Europe/Berlin\"}, \"geometries\" : { "
|
||||||
// "\"type\": \"polygon\", "
|
"\"type\": \"polygon\", "
|
||||||
// "\"coordinates\": [[[8.28369,48.88277], [8.57757, "
|
"\"coordinates\": [[[8.28369,48.88277], [8.57757, "
|
||||||
// "48.88277], [8.57757, 49.07206], [8.28369, "
|
"48.88277], [8.57757, 49.07206], [8.28369, "
|
||||||
// "49.07206], [8.28369, 48.88277]]] }}";
|
"49.07206], [8.28369, 48.88277]]] }}";
|
||||||
// doc.Parse(missing_geom);
|
doc.Parse(missing_geom);
|
||||||
// BOOST_CHECK_THROW(util::validateFeature(doc), util::exception);
|
BOOST_CHECK_THROW(util::validateFeature(doc), util::exception);
|
||||||
|
|
||||||
// char nonobj_geom[] =
|
char nonobj_geom[] =
|
||||||
// "{ \"type\" : \"Feature\","
|
"{ \"type\" : \"Feature\","
|
||||||
// "\"properties\" : { \"TZID\" : \"Europe/Berlin\"}, \"geometry\" : [ \"type\",
|
"\"properties\" : { \"TZID\" : \"Europe/Berlin\"}, \"geometry\" : [ \"type\", \"polygon\", "
|
||||||
// \"polygon\", "
|
"\"coordinates\", [[[8.28369,48.88277], [8.57757, "
|
||||||
// "\"coordinates\", [[[8.28369,48.88277], [8.57757, "
|
"48.88277], [8.57757, 49.07206], [8.28369, "
|
||||||
// "48.88277], [8.57757, 49.07206], [8.28369, "
|
"49.07206], [8.28369, 48.88277]]] ]}";
|
||||||
// "49.07206], [8.28369, 48.88277]]] ]}";
|
doc.Parse(nonobj_geom);
|
||||||
// doc.Parse(nonobj_geom);
|
BOOST_CHECK_THROW(util::validateFeature(doc), util::exception);
|
||||||
// BOOST_CHECK_THROW(util::validateFeature(doc), util::exception);
|
|
||||||
|
|
||||||
// char missing_geom_type[] = "{ \"type\" : \"Feature\","
|
char missing_geom_type[] = "{ \"type\" : \"Feature\","
|
||||||
// "\"properties\" : { \"TZID\" : \"Europe/Berlin\"}, \"geometry\" :
|
"\"properties\" : { \"TZID\" : \"Europe/Berlin\"}, \"geometry\" : { "
|
||||||
// { "
|
"\"no_type\": \"polygon\", "
|
||||||
// "\"no_type\": \"polygon\", "
|
"\"coordinates\": [[[8.28369,48.88277], [8.57757, "
|
||||||
// "\"coordinates\": [[[8.28369,48.88277], [8.57757, "
|
"48.88277], [8.57757, 49.07206], [8.28369, "
|
||||||
// "48.88277], [8.57757, 49.07206], [8.28369, "
|
"49.07206], [8.28369, 48.88277]]] }}";
|
||||||
// "49.07206], [8.28369, 48.88277]]] }}";
|
doc.Parse(missing_geom_type);
|
||||||
// doc.Parse(missing_geom_type);
|
BOOST_CHECK_THROW(util::validateFeature(doc), util::exception);
|
||||||
// BOOST_CHECK_THROW(util::validateFeature(doc), util::exception);
|
|
||||||
|
|
||||||
// char nonstring_geom_type[] = "{ \"type\" : \"Feature\","
|
char nonstring_geom_type[] = "{ \"type\" : \"Feature\","
|
||||||
// "\"properties\" : { \"TZID\" : \"Europe/Berlin\"}, \"geometry\"
|
"\"properties\" : { \"TZID\" : \"Europe/Berlin\"}, \"geometry\" : "
|
||||||
// : "
|
"{ \"type\": [\"polygon\"], "
|
||||||
// "{ \"type\": [\"polygon\"], "
|
"\"coordinates\": [[[8.28369,48.88277], [8.57757, "
|
||||||
// "\"coordinates\": [[[8.28369,48.88277], [8.57757, "
|
"48.88277], [8.57757, 49.07206], [8.28369, "
|
||||||
// "48.88277], [8.57757, 49.07206], [8.28369, "
|
"49.07206], [8.28369, 48.88277]]] }}";
|
||||||
// "49.07206], [8.28369, 48.88277]]] }}";
|
doc.Parse(nonstring_geom_type);
|
||||||
// doc.Parse(nonstring_geom_type);
|
BOOST_CHECK_THROW(util::validateFeature(doc), util::exception);
|
||||||
// BOOST_CHECK_THROW(util::validateFeature(doc), util::exception);
|
|
||||||
|
|
||||||
// char missing_coords[] =
|
char missing_coords[] =
|
||||||
// "{ \"type\" : \"Feature\","
|
"{ \"type\" : \"Feature\","
|
||||||
// "\"properties\" : { \"TZID\" : \"Europe/Berlin\"}, \"geometry\" : { \"type\":
|
"\"properties\" : { \"TZID\" : \"Europe/Berlin\"}, \"geometry\" : { \"type\": \"polygon\", "
|
||||||
// \"polygon\", "
|
"\"coords\": [[[8.28369,48.88277], [8.57757, "
|
||||||
// "\"coords\": [[[8.28369,48.88277], [8.57757, "
|
"48.88277], [8.57757, 49.07206], [8.28369, "
|
||||||
// "48.88277], [8.57757, 49.07206], [8.28369, "
|
"49.07206], [8.28369, 48.88277]]] }}";
|
||||||
// "49.07206], [8.28369, 48.88277]]] }}";
|
doc.Parse(missing_coords);
|
||||||
// doc.Parse(missing_coords);
|
BOOST_CHECK_THROW(util::validateFeature(doc), util::exception);
|
||||||
// BOOST_CHECK_THROW(util::validateFeature(doc), util::exception);
|
|
||||||
|
|
||||||
// char missing_outerring[] =
|
char missing_outerring[] =
|
||||||
// "{ \"type\" : \"Feature\","
|
"{ \"type\" : \"Feature\","
|
||||||
// "\"properties\" : { \"TZID\" : \"Europe/Berlin\"}, \"geometry\" : { \"type\":
|
"\"properties\" : { \"TZID\" : \"Europe/Berlin\"}, \"geometry\" : { \"type\": \"polygon\", "
|
||||||
// \"polygon\", "
|
"\"coordinates\": [[8.28369,48.88277], [8.57757, "
|
||||||
// "\"coordinates\": [[8.28369,48.88277], [8.57757, "
|
"48.88277], [8.57757, 49.07206], [8.28369, "
|
||||||
// "48.88277], [8.57757, 49.07206], [8.28369, "
|
"49.07206], [8.28369, 48.88277]] }}";
|
||||||
// "49.07206], [8.28369, 48.88277]] }}";
|
doc.Parse(missing_outerring);
|
||||||
// doc.Parse(missing_outerring);
|
BOOST_CHECK_THROW(util::validateFeature(doc), util::exception);
|
||||||
// BOOST_CHECK_THROW(util::validateFeature(doc), util::exception);
|
|
||||||
}
|
}
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|||||||
Reference in New Issue
Block a user