From c34081d5976d8f47f65dd3d9d458143e22230dac Mon Sep 17 00:00:00 2001 From: Symmetricity <184246+Symmetricity@users.noreply.github.com> Date: Wed, 13 May 2026 17:47:27 +0200 Subject: [PATCH] Make POI tag ranking deterministic GetPOIRank returned the first matching POI tag group, but it iterated poiTags with pairs(). Lua does not specify table traversal order, so objects matching multiple POI groups could receive different class and rank values across runs or platforms. Iterate an explicit POI key list with ipairs() so the profile priority order is stable, and keep the subclass temporary local to the ranking function. --- resources/process-debug.lua | 5 +++-- resources/process-openmaptiles.lua | 6 ++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/resources/process-debug.lua b/resources/process-debug.lua index 4ea5e629..aada52a3 100644 --- a/resources/process-debug.lua +++ b/resources/process-debug.lua @@ -155,6 +155,7 @@ poiTags = { aerialway = Set { "station" }, sport = Set { "american_football", "archery", "athletics", "australian_football", "badminton", "baseball", "basketball", "beachvolleyball", "billiards", "bmx", "boules", "bowls", "boxing", "canadian_football", "canoe", "chess", "climbing", "climbing_adventure", "cricket", "cricket_nets", "croquet", "curling", "cycling", "disc_golf", "diving", "dog_racing", "equestrian", "fatsal", "field_hockey", "free_flying", "gaelic_games", "golf", "gymnastics", "handball", "hockey", "horse_racing", "horseshoes", "ice_hockey", "ice_stock", "judo", "karting", "korfball", "long_jump", "model_aerodrome", "motocross", "motor", "multi", "netball", "orienteering", "paddle_tennis", "paintball", "paragliding", "pelota", "racquet", "rc_car", "rowing", "rugby", "rugby_league", "rugby_union", "running", "sailing", "scuba_diving", "shooting", "shooting_range", "skateboard", "skating", "skiing", "soccer", "surfing", "swimming", "table_soccer", "table_tennis", "team_handball", "tennis", "toboggan", "volleyball", "water_ski", "yoga" }, tourism = Set { "alpine_hut", "aquarium", "artwork", "attraction", "bed_and_breakfast", "camp_site", "caravan_site", "chalet", "gallery", "guest_house", "hostel", "hotel", "information", "motel", "museum", "picnic_site", "theme_park", "viewpoint", "zoo" }, waterway = Set { "dock" } } +poiTagKeys = { "aerialway", "amenity", "barrier", "building", "highway", "historic", "landuse", "leisure", "railway", "shop", "sport", "tourism", "waterway" } -- POI "class" values: based on https://github.com/openmaptiles/openmaptiles/blob/master/layers/poi/poi.yaml poiClasses = { townhall="town_hall", public_building="town_hall", courthouse="town_hall", community_centre="town_hall", @@ -504,7 +505,8 @@ function GetPOIRank(obj) local k,list,v,class,rank -- Can we find the tag? - for k,list in pairs(poiTags) do + for _,k in ipairs(poiTagKeys) do + list = poiTags[k] if list[Find(k)] then v = Find(k) -- k/v are the OSM tag pair class = poiClasses[v] or v @@ -535,4 +537,3 @@ function split(inputstr, sep) -- https://stackoverflow.com/a/7615129/4288232 end return t end - diff --git a/resources/process-openmaptiles.lua b/resources/process-openmaptiles.lua index 342c2951..32575d40 100644 --- a/resources/process-openmaptiles.lua +++ b/resources/process-openmaptiles.lua @@ -258,6 +258,7 @@ poiTags = { aerialway = Set { "station" }, sport = Set { "american_football", "archery", "athletics", "australian_football", "badminton", "baseball", "basketball", "beachvolleyball", "billiards", "bmx", "boules", "bowls", "boxing", "canadian_football", "canoe", "chess", "climbing", "climbing_adventure", "cricket", "cricket_nets", "croquet", "curling", "cycling", "disc_golf", "diving", "dog_racing", "equestrian", "fatsal", "field_hockey", "free_flying", "gaelic_games", "golf", "gymnastics", "handball", "hockey", "horse_racing", "horseshoes", "ice_hockey", "ice_stock", "judo", "karting", "korfball", "long_jump", "model_aerodrome", "motocross", "motor", "multi", "netball", "orienteering", "paddle_tennis", "paintball", "paragliding", "pelota", "racquet", "rc_car", "rowing", "rugby", "rugby_league", "rugby_union", "running", "sailing", "scuba_diving", "shooting", "shooting_range", "skateboard", "skating", "skiing", "soccer", "surfing", "swimming", "table_soccer", "table_tennis", "team_handball", "tennis", "toboggan", "volleyball", "water_ski", "yoga" }, tourism = Set { "alpine_hut", "aquarium", "artwork", "attraction", "bed_and_breakfast", "camp_site", "caravan_site", "chalet", "gallery", "guest_house", "hostel", "hotel", "information", "motel", "museum", "picnic_site", "theme_park", "viewpoint", "zoo" }, waterway = Set { "dock" } } +poiTagKeys = { "aerialway", "amenity", "barrier", "building", "highway", "historic", "landuse", "leisure", "railway", "shop", "sport", "tourism", "waterway" } -- POI "class" values: based on https://github.com/openmaptiles/openmaptiles/blob/master/layers/poi/poi.yaml poiClasses = { townhall="town_hall", public_building="town_hall", courthouse="town_hall", community_centre="town_hall", @@ -842,10 +843,11 @@ end -- Calculate POIs (typically rank 1-4 go to 'poi' z12-14, rank 5+ to 'poi_detail' z14) -- returns rank, class, subclass function GetPOIRank() - local k,list,v,class,rank + local k,list,v,class,rank,subclassKey -- Can we find the tag? - for k,list in pairs(poiTags) do + for _,k in ipairs(poiTagKeys) do + list = poiTags[k] if list[Find(k)] then v = Find(k) -- k/v are the OSM tag pair class = poiClasses[v] or k