Add fuzzy matching for bearings and intersections list

This commit is contained in:
Patrick Niklaus 2016-05-18 21:41:52 +02:00
parent 95af72c70c
commit e3ce0c5887
No known key found for this signature in database
GPG Key ID: E426891B5F978B1B
3 changed files with 81 additions and 14 deletions

View File

@ -125,10 +125,10 @@ Feature: Intersections Data
| hd | |
When I route I should get
| waypoints | route | turns | intersections |
| e,f | ea,fb,fb | depart,abcda-exit-1,arrive | true:180;false:0 false:150 true:210,false:30 true:150 true:270;true:90 |
| e,g | ea,gc,gc | depart,abcda-exit-2,arrive | true:180;false:0 false:150 true:210,false:30 true:150 true:270,true:30 true:180 false:330;true:0 |
| waypoints | route | turns | intersections |
| e,f | ea,fb,fb | depart,abcda-exit-1,arrive | true:180;false:0 false:150 true:210,false:30 true:150 true:270;true:90 |
| e,g | ea,gc,gc | depart,abcda-exit-2,arrive | true:180;false:0 false:150 true:210,false:30 true:150 true:270,true:30 true:180 false:330;true:0|
| e,h | ea,hd,hd | depart,abcda-exit-3,arrive | true:180;false:0 false:150 true:210,false:30 true:150 true:270,true:30 true:180 false:330,true:90 false:210 true:330;true:270 |
| e,2 | ea,abcda,abcda | depart,abcda-exit-undefined,arrive | true:180;false:0 false:150 true:210,false:30 true:150 true:270;true:326 |
| 1,g | abcda,gc,gc | depart,abcda-exit-2,arrive | true:214;true:214,false:30 true:150 true:270,true:30 true:180 false:330;true:0 |
| 1,3 | abcda,abcda | depart,arrive | true:214,false:30 true:150 true:270,true:30 true:180 false:330;true:214 |
| e,2 | ea,abcda,abcda | depart,abcda-exit-undefined,arrive | true:180;false:0 false:150 true:210,false:30 true:150 true:270;true:327 +-1|
| 1,g | abcda,gc,gc | depart,abcda-exit-2,arrive | true:214;true:214,false:30 true:150 true:270,true:30 true:180 false:330;true:0|
| 1,3 | abcda,abcda | depart,arrive | true:214,false:30 true:150 true:270,true:30 true:180 false:330;true:214|

View File

@ -52,24 +52,91 @@ module.exports = {
match (got, want) {
var matchPercent = want.match(/(.*)\s+~(.+)%$/),
matchAbs = want.match(/(.*)\s+\+\-(.+)$/),
matchRe = want.match(/^\/(.*)\/$/);
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(':'))));
}
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;
} else if (matchPercent) { // percentage range: 100 ~ 5%
var target = parseFloat(matchPercent[1]),
percentage = parseFloat(matchPercent[2]);
if (target === 0) {
return true;
} else {
var ratio = Math.abs(1 - parseFloat(got) / target);
let ratio = Math.abs(1 - parseFloat(got) / target);
return 100 * ratio < percentage;
}
} else if (matchAbs) { // absolute range: 100 +-5
var margin = parseFloat(matchAbs[2]),
fromR = parseFloat(matchAbs[1]) - margin,
toR = parseFloat(matchAbs[1]) + margin;
return parseFloat(got) >= fromR && parseFloat(got) <= toR;
let margin = parseFloat(matchAbs[2]);
return inRange(margin, got, matchAbs[1]);
} else if (matchRe) { // regex: /a,b,.*/
return got.match(matchRe[1]);
} else {

View File

@ -35,10 +35,10 @@ Feature: Bearing parameter
When I route I should get
| from | to | bearings | route | bearing |
| 0 | c | 0 0 | | |
| 0 | c | 45 45 | bc,bc | 0->45,45->0|
| 0 | c | 45 45 | bc,bc | 0->44,44->0 +- 1|
| 0 | c | 85 85 | | |
| 0 | c | 95 95 | | |
| 0 | c | 135 135 | ac,ac | 0->136,136->0 |
| 0 | c | 135 135 | ac,ac | 0->135,135->0 +- 1|
| 0 | c | 180 180 | | |
Scenario: Testbot - Initial bearing on split way