osrm-backend/features/support/data_classes.js

127 lines
5.7 KiB
JavaScript
Raw Normal View History

2016-03-04 15:11:05 -05:00
'use strict';
const util = require('util');
2016-03-04 15:11:05 -05:00
module.exports = {
Location: class {
constructor (lon, lat) {
this.lon = lon;
this.lat = lat;
}
},
FuzzyMatch: class {
match (got, want) {
// don't fail if bearings input and extected string is empty and actual result is undefined
if (want === '' && (got === '' || got === undefined))
return true;
2016-03-04 15:11:05 -05:00
var matchPercent = want.match(/(.*)\s+~(.+)%$/),
matchAbs = want.match(/(.*)\s+\+\-(.+)$/),
matchRe = want.match(/^\/(.*)\/$/),
// we use this for matching before/after bearing
matchBearingListAbs = want.match(/^((\d+)->(\d+))(,(\d+)->(\d+))*\s+\+\-(.+)$/),
matchIntersectionListAbs = want.match(/^(((((true|false):\d+)\s{0,1})+,{0,1})+;{0,1})+\s+\+\-(.+)$/);
function inRange(margin, got, want) {
var fromR = parseFloat(want) - margin,
toR = parseFloat(want) + margin;
return parseFloat(got) >= fromR && parseFloat(got) <= toR;
}
function parseIntersectionString(str) {
return str.split(';')
.map((turn_intersections) => turn_intersections
.split(',')
.map((intersection) => intersection
.split(' ')
.map((entry_bearing_pair) => entry_bearing_pair
.split(':'))));
}
2016-03-04 15:11:05 -05:00
if (got === want) {
return true;
} else if (matchBearingListAbs) {
let want_and_margin = want.split('+-'),
margin = parseFloat(want_and_margin[1].trim()),
want_pairs = want_and_margin[0].trim().split(',').map((pair) => pair.split('->')),
got_pairs = got.split(',').map((pair) => pair.split('->'));
if (want_pairs.length != got_pairs.length)
{
return false;
}
for (var i = 0; i < want_pairs.length; ++i)
{
if (!inRange(margin, got_pairs[i][0], want_pairs[i][0]) ||
!inRange(margin, got_pairs[i][1], want_pairs[i][1]))
{
return false;
}
}
return true;
} else if (matchIntersectionListAbs) {
let margin = parseFloat(want.split('+-')[1]),
want_intersections = parseIntersectionString(want.split('+-')[0].trim()),
got_intersections = parseIntersectionString(got);
if (want_intersections.length != got_intersections.length)
{
return false;
}
for (let step_idx = 0; step_idx < want_intersections.length; ++step_idx)
{
if (want_intersections[step_idx].length != got_intersections[step_idx].length)
{
return false;
}
for (let intersection_idx = 0; intersection_idx < want_intersections[step_idx].length; ++intersection_idx)
{
if (want_intersections[step_idx][intersection_idx].length != got_intersections[step_idx][intersection_idx].length)
{
return false;
}
for (let pair_idx = 0; pair_idx < want_intersections[step_idx][intersection_idx].length; ++pair_idx)
{
let want_pair = want_intersections[step_idx][intersection_idx][pair_idx],
got_pair = got_intersections[step_idx][intersection_idx][pair_idx];
if (got_pair[0] != want_pair[0] ||
!inRange(margin, got_pair[1], want_pair[1]))
{
return false;
}
}
}
}
return true;
2016-03-04 15:11:05 -05:00
} else if (matchPercent) { // percentage range: 100 ~ 5%
var target = parseFloat(matchPercent[1]),
percentage = parseFloat(matchPercent[2]);
if (target === 0) {
return true;
} else {
let ratio = Math.abs(1 - parseFloat(got) / target);
2016-03-04 15:11:05 -05:00
return 100 * ratio < percentage;
}
} else if (matchAbs) { // absolute range: 100 +-5
let margin = parseFloat(matchAbs[2]);
return inRange(margin, got, matchAbs[1]);
2016-03-04 15:11:05 -05:00
} else if (matchRe) { // regex: /a,b,.*/
return got.match(matchRe[1]);
} else {
return false;
}
}
matchLocation (got, want) {
if (got == null || want == null) return false;
2016-03-30 15:23:57 -04:00
return this.match(got[0], util.format('%d ~0.0025%', want.lon)) &&
this.match(got[1], util.format('%d ~0.0025%', want.lat));
2016-03-04 15:11:05 -05:00
}
matchCoordinate (got, want, zoom) {
if (got == null || want == null) return false;
return this.match(got.lon, util.format('%d +- %d', want.lon, 0.25*zoom)) &&
this.match(got.lat, util.format('%d +- %d', want.lat, 0.25*zoom));
}
2016-03-04 15:11:05 -05:00
}
};