diff --git a/.gitignore b/.gitignore index bbdd03c1fbb..2647c65ba72 100644 --- a/.gitignore +++ b/.gitignore @@ -94,3 +94,6 @@ node_modules /server.ini *.swp + +# local lua debugging file +debug.lua \ No newline at end of file diff --git a/profiles/debug.lua b/profiles/debug.lua deleted file mode 100644 index aed80b7f5a0..00000000000 --- a/profiles/debug.lua +++ /dev/null @@ -1,150 +0,0 @@ --- Enable calling our lua profile code directly from the lua command line, --- which makes it easier to debug. --- We simulate the normal C++ environment by defining the required globals and functions. - --- Usage: --- > cd profiles --- > lua5.1 debug.lua - - --- for more convenient printing of tables -local pprint = require('lib/pprint') - --- globals that are normally set from C++ - --- profiles code modifies this table -properties = {} - --- should match values defined in include/extractor/guidance/road_classification.hpp -road_priority_class = { - motorway = 0, - trunk = 2, - primary = 4, - secondary = 6, - tertiary = 8, - main_residential = 10, - side_residential = 11, - link_road = 14, - bike_path = 16, - foot_path = 18, - connectivity = 31, -} - --- should match values defined in include/extractor/travel_mode.hpp -mode = { - inaccessible = 0, - driving = 1, - cycling = 2, - walking = 3, - ferry = 4, - train = 5, - pushing_bike = 6, -} - --- input tags, normally extracted from OSM data -local way = { - --highway = 'footway', - amenity = 'parking', - name = 'Hyper Drive', - --foot = 'yes', - --oneway = 'yes', - --access = 'no' - --["access:forward"] = 'no' - --width = '3', - --maxspeed = '30', - --['maxspeed:advisory'] = '25', - --service = 'alley', - --['oneway:bicycle'] = 'yes', - --junction = 'roundabout', - --['name:pronunciation'] = 'fuerloong', - --route = 'ferry', - --duration = '00:01:00', - --hov = 'designated', - --hov:lanes:forward"] = 'designated', - --destination = 'Berlin', - --["destination:ref"] = 'Nuremberg', - --["destination:ref:forward"] = 'Hamburg;Dresden', -} --- tag function normally provided via C++ -function way:get_value_by_key(k) - if not self['_debug'] then - self['_debug'] = { - _counts = {} - } - end - - if self['_debug']['_total'] then - self['_debug']['_total'] = self['_debug']['_total'] + 1 - else - self['_debug']['_total'] = 1 - end - - if self['_debug']['_counts'][k] then - self['_debug']['_counts'][k] = self['_debug']['_counts'][k] + 1 - else - self['_debug']['_counts'][k] = 1 - end - - return self[k] -end - --- Mock C++ helper functions which are called from LUA. --- FIXME --- Debugging LUA code that uses these will not work correctly --- unless we reimplement themethods in LUA. - -function durationIsValid(str) - return true -end - -function parseDuration(str) - return 1 -end - -function canonicalizeStringList(str) - return str -end - --- helpers for sorting associative array -function get_keys_sorted_by_value(tbl, sortFunction) - local keys = {} - for key in pairs(tbl) do - table.insert(keys, key) - end - - table.sort(keys, function(a, b) - return sortFunction(tbl[a], tbl[b]) - end) - - return keys -end - --- helper for printing sorted array -function print_sorted(sorted,associative) - for _, key in ipairs(sorted) do - print(associative[key], key) - end -end - --- start state of result table, normally set form C++ -local result = { - road_classification = {}, - forward_speed = -1, - backward_speed = -1, -} - --- the profile we want to debug -require("foot") - --- call the way function -way_function(way,result) - --- and print the output -pprint(way) -print("=>") -pprint(result) -print("\n") ---print("Tag fetches:") ---sorted_counts = get_keys_sorted_by_value(way._debug._counts, function(a, b) return a > b end) ---print_sorted(sorted_counts, way._debug._counts) ---print(way._debug._total, 'total') diff --git a/profiles/debug_example.lua b/profiles/debug_example.lua new file mode 100644 index 00000000000..6bfb735ade5 --- /dev/null +++ b/profiles/debug_example.lua @@ -0,0 +1,50 @@ +-- +-- Example of how to use debug.lua to debug profiles in a pure lua environment. +-- It makes it easy to manually set tags, run the way processing and check the result. +-- +-- To use, make a copy of this file and gitignore your copy. (If you use the name ndebug.lua, +-- it's already gitignored.) +-- +-- You run your copy via the lua command line: +-- > cd profiles +-- > lua5.1 debug.lua +-- +-- You can then modify the input tags and rerun the file to check the output. +-- +-- TODO: there are a few helper methods that are implemented in C++, which are currently +-- just mocked as empty methods in LUA. Tag processing that uses these helpers will +-- not yet work correctly in this pure LUA debugging environment. + + +-- for better printing +local pprint = require('lib/pprint') + +-- require the debug tool +local Debug = require('lib/profile_debugger') + +-- load the profile we want to debug +Debug.load_profile('foot') + +-- define some input tags. they would normally by extracted from OSM data, +-- but here we can set them manually which makes debugging the profile eaiser + +local way = { + highway = 'primary', + name = 'Magnolia Boulevard', + ["access:forward"] = 'no' +} + +-- output will go here +local result = {} + +-- call the way function +Debug.way_function(way,result) + +-- print input and output +pprint(way) +print("=>") +pprint(result) +print("\n") + +-- report what tags where fetched, and how many times +Debug.report_tag_fetches() diff --git a/profiles/lib/profile_debugger.lua b/profiles/lib/profile_debugger.lua new file mode 100644 index 00000000000..eb85fa1f3e3 --- /dev/null +++ b/profiles/lib/profile_debugger.lua @@ -0,0 +1,138 @@ +-- Enable calling our lua profile code directly from the lua command line, +-- which makes it easier to debug. +-- We simulate the normal C++ environment by defining the required globals and functions. + +-- See debug_example.lua for an example of how to require and use this file. + +-- for more convenient printing of tables +local pprint = require('lib/pprint') + + +-- globals that are normally set from C++ + +-- profiles code modifies this table +properties = {} + +-- should match values defined in include/extractor/guidance/road_classification.hpp +road_priority_class = { + motorway = 0, + trunk = 2, + primary = 4, + secondary = 6, + tertiary = 8, + main_residential = 10, + side_residential = 11, + link_road = 14, + bike_path = 16, + foot_path = 18, + connectivity = 31, +} + +-- should match values defined in include/extractor/travel_mode.hpp +mode = { + inaccessible = 0, + driving = 1, + cycling = 2, + walking = 3, + ferry = 4, + train = 5, + pushing_bike = 6, +} + +-- Mock C++ helper functions which are called from LUA. +-- TODO +-- Debugging LUA code that uses these will not work correctly +-- unless we reimplement the methods in LUA. + +function durationIsValid(str) + return true +end + +function parseDuration(str) + return 1 +end + +function canonicalizeStringList(str) + return str +end + + + +-- debug helper +local Debug = {} + +-- helpers for sorting associative array +function Debug.get_keys_sorted_by_value(tbl, sortFunction) + local keys = {} + for key in pairs(tbl) do + table.insert(keys, key) + end + + table.sort(keys, function(a, b) + return sortFunction(tbl[a], tbl[b]) + end) + + return keys +end + +-- helper for printing sorted array +function Debug.print_sorted(sorted,associative) + for _, key in ipairs(sorted) do + print(associative[key], key) + end +end + +function Debug.report_tag_fetches() + print("Tag fetches:") + sorted_counts = Debug.get_keys_sorted_by_value(Debug.tags.counts, function(a, b) return a > b end) + Debug.print_sorted(sorted_counts, Debug.tags.counts) + print(Debug.tags.total, 'total') +end + +function Debug.load_profile(profile) + require(profile) +end + +function Debug.reset_tag_fetch_counts() + Debug.tags = { + total = 0, + counts = {} + } +end + +function Debug.register_tag_fetch(k) + if Debug.tags.total then + Debug.tags.total = Debug.tags.total + 1 + else + Debug['tags']['total'] = 1 + end + + if Debug['tags']['counts'][k] then + Debug['tags']['counts'][k] = Debug['tags']['counts'][k] + 1 + else + Debug['tags']['counts'][k] = 1 + end + +end + +function Debug.way_function(way,result) + + -- setup result table + result.road_classification = {} + result.forward_speed = -1 + result.backward_speed = -1 + + -- intercept tag function normally provided via C++ + function way:get_value_by_key(k) + Debug.register_tag_fetch(k) + return self[k] + end + + -- reset tag counts + Debug:reset_tag_fetch_counts() + + -- call the global method defined in the profile file + way_function(way,result) +end + +return Debug