diff --git a/features/nearest/pick.feature b/features/nearest/pick.feature new file mode 100644 index 000000000..4c8284293 --- /dev/null +++ b/features/nearest/pick.feature @@ -0,0 +1,34 @@ +@nearest +Feature: Locating Nearest node on a Way - pick closest way + + Background: + Given the profile "testbot" + + @todo + Scenario: Nearest - two ways crossing + Given the node map + | | 0 | c | 1 | | + | 7 | | n | | 2 | + | a | k | x | m | b | + | 6 | | l | | 3 | + | | 5 | d | 4 | | + + And the ways + | nodes | + | axc | + | cxd | + + When I request nearest I should get + | in | out | + | 0 | c | + | 1 | c | + | 2 | b | + | 3 | b | + | 4 | d | + | 5 | d | + | 6 | a | + | 7 | a | + | k | k | + | l | l | + | m | m | + | n | n | diff --git a/features/nearest/projection.feature b/features/nearest/projection.feature new file mode 100644 index 000000000..f33a19f81 --- /dev/null +++ b/features/nearest/projection.feature @@ -0,0 +1,105 @@ +@nearest +Feature: Locating Nearest node on a Way - basic projection onto way + + Background: + Given the profile "testbot" + + Scenario: Nearest - easy-west way + Given the node map + | 0 | 1 | 2 | 3 | 4 | + | | a | x | b | | + | 5 | 6 | 7 | 8 | 9 | + + And the ways + | nodes | + | ab | + + When I request nearest I should get + | in | out | + | 0 | a | + | 1 | a | + | 2 | x | + | 3 | b | + | 4 | b | + | 5 | a | + | 6 | a | + | 7 | x | + | 8 | b | + | 9 | b | + + Scenario: Nearest - north-south way + Given the node map + | 0 | | 5 | + | 1 | a | 6 | + | 2 | x | 7 | + | 3 | b | 8 | + | 4 | | 9 | + + And the ways + | nodes | + | ab | + + When I request nearest I should get + | in | out | + | 0 | a | + | 1 | a | + | 2 | x | + | 3 | b | + | 4 | b | + | 5 | a | + | 6 | a | + | 7 | x | + | 8 | b | + | 9 | b | + + Scenario: Nearest - diagonal 1 + Given the node map + | 8 | | 4 | | | | + | | a | | 5 | | | + | 0 | | x | | 6 | | + | | 1 | | y | | 7 | + | | | 2 | | b | | + | | | | 3 | | 9 | + + And the ways + | nodes | + | ab | + + When I request nearest I should get + | in | out | + | 0 | a | + | 1 | x | + | 2 | y | + | 3 | b | + | 4 | a | + | 5 | x | + | 6 | y | + | 7 | b | + | 8 | a | + | 9 | b | + + Scenario: Nearest - diagonal 2 + Given the node map + | | | | 3 | | 9 | + | | | 2 | | b | | + | | 1 | | y | | 7 | + | 0 | | x | | 6 | | + | | a | | 5 | | | + | 8 | | 4 | | | | + + And the ways + | nodes | + | ab | + + When I request nearest I should get + | in | out | + | 0 | a | + | 1 | x | + | 2 | y | + | 3 | b | + | 4 | a | + | 5 | x | + | 6 | y | + | 7 | b | + | 8 | a | + | 9 | b | diff --git a/features/step_definitions/nearest.rb b/features/step_definitions/nearest.rb new file mode 100644 index 000000000..303788b47 --- /dev/null +++ b/features/step_definitions/nearest.rb @@ -0,0 +1,51 @@ +When /^I request nearest I should get$/ do |table| + reprocess + actual = [] + OSRMLauncher.new do + table.hashes.each_with_index do |row,ri| + in_node = @name_node_hash[ row['in'] ] + raise "*** unknown in-node '#{row['in']}" unless in_node + + out_node = @name_node_hash[ row['out'] ] + raise "*** unknown out-node '#{row['out']}" unless out_node + + response = request_nearest("#{in_node.lat},#{in_node.lon}") + if response.code == "200" && response.body.empty? == false + json = JSON.parse response.body + if json['status'] == 0 + coord = json['mapped_coordinate'] + end + end + + got = {'in' => row['in'], 'out' => coord } + + ok = true + row.keys.each do |key| + if key=='out' + if FuzzyMatch.match_location coord, out_node + got[key] = row[key] + else + row[key] = "#{row[key]} [#{out_node.lat},#{out_node.lon}]" + ok = false + end + end + end + + unless ok + failed = { :attempt => 'nearest', :query => @query, :response => response } + log_fail row,got,[failed] + end + + actual << got + end + end + table.routing_diff! actual +end + +When /^I route (\d+) times I should get$/ do |n,table| + ok = true + n.to_i.times do + ok = false unless step "I route I should get", table + end + ok +end \ No newline at end of file diff --git a/features/support/fuzzy.rb b/features/support/fuzzy.rb new file mode 100644 index 000000000..0876f9f66 --- /dev/null +++ b/features/support/fuzzy.rb @@ -0,0 +1,32 @@ + +class FuzzyMatch + + def self.match got, want + if got == want + return true + elsif want.match /(.*)\s+~(.+)%$/ #percentage range: 100 ~5% + margin = 1 - $2.to_f*0.01 + from = $1.to_f*margin + to = $1.to_f/margin + return got.to_f >= from && got.to_f <= to + elsif want.match /(.*)\s+\+\-(.+)$/ #absolute range: 100 +-5 + margin = $2.to_f + from = $1.to_f-margin + to = $1.to_f+margin + return got.to_f >= from && got.to_f <= to + elsif want =~ /^\/(.*)\/$/ #regex: /a,b,.*/ + return got =~ /#{$1}/ + else + return false + end + end + + def self.match_location got, want + match( got[0], "#{want.lat} ~0.002%" ) && + match( got[1], "#{want.lon} ~0.002%" ) + end + +end + + + diff --git a/features/support/nearest.rb b/features/support/nearest.rb new file mode 100644 index 000000000..e37130735 --- /dev/null +++ b/features/support/nearest.rb @@ -0,0 +1,17 @@ +require 'net/http' + +def request_nearest_url path + @query = path + uri = URI.parse "#{HOST}/#{path}" + Timeout.timeout(REQUEST_TIMEOUT) do + Net::HTTP.get_response uri + end +rescue Errno::ECONNREFUSED => e + raise "*** osrm-routed is not running." +rescue Timeout::Error + raise "*** osrm-routed did not respond." +end + +def request_nearest a + request_nearest_url "nearest?loc=#{a}" +end