mirror of https://github.com/systemed/tilemaker
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
539 lines
21 KiB
Lua
539 lines
21 KiB
Lua
-- Data processing based on openmaptiles.org schema
|
|
-- https://openmaptiles.org/schema/
|
|
-- Copyright (c) 2016, KlokanTech.com & OpenMapTiles contributors.
|
|
-- Used under CC-BY 4.0
|
|
|
|
--------
|
|
-- Alter these lines to control which languages are written for place/streetnames
|
|
-- Preferred language can be (for example) "en" for English, "de" for German, or nil to use OSM's name tag:
|
|
preferred_language = "cy"
|
|
-- This is written into the following vector tile attribute:
|
|
preferred_language_attribute = "name:latin"
|
|
-- If OSM's name tag differs, then write it into this attribute:
|
|
default_language_attribute = "name_int"
|
|
-- Also write these languages if they differ - for example, { "de", "fr" }
|
|
additional_languages = { "en","de","fr" }
|
|
--------
|
|
|
|
-- Enter/exit Tilemaker
|
|
function init_function()
|
|
end
|
|
function exit_function()
|
|
end
|
|
|
|
-- Implement Sets in tables
|
|
function Set(list)
|
|
local set = {}
|
|
for _, l in ipairs(list) do set[l] = true end
|
|
return set
|
|
end
|
|
|
|
-- Meters per pixel if tile is 256x256
|
|
ZRES5 = 4891.97
|
|
ZRES6 = 2445.98
|
|
ZRES7 = 1222.99
|
|
ZRES8 = 611.5
|
|
ZRES9 = 305.7
|
|
ZRES10 = 152.9
|
|
ZRES11 = 76.4
|
|
ZRES12 = 38.2
|
|
ZRES13 = 19.1
|
|
|
|
-- Process node/way tags
|
|
aerodromeValues = Set { "international", "public", "regional", "military", "private" }
|
|
|
|
-- Process node tags
|
|
|
|
node_keys = { "amenity", "shop", "sport", "tourism", "place", "office", "natural", "addr:housenumber", "aeroway" }
|
|
function node_function()
|
|
-- Write 'aerodrome_label'
|
|
local aeroway = Find("aeroway")
|
|
if aeroway == "aerodrome" then
|
|
Layer("aerodrome_label", false)
|
|
SetNameAttributes()
|
|
Attribute("iata", Find("iata"))
|
|
SetEleAttributes()
|
|
Attribute("icao", Find("icao"))
|
|
|
|
local aerodrome_value = Find("aerodrome")
|
|
local class
|
|
if aerodromeValues[aerodrome_value] then class = aerodrome_value else class = "other" end
|
|
Attribute("class", class)
|
|
end
|
|
-- Write 'housenumber'
|
|
local housenumber = Find("addr:housenumber")
|
|
if housenumber~="" then
|
|
Layer("housenumber", false)
|
|
Attribute("housenumber", housenumber)
|
|
end
|
|
|
|
-- Write 'place'
|
|
-- note that OpenMapTiles has a rank for countries (1-3), states (1-6) and cities (1-10+);
|
|
-- we could potentially approximate it for cities based on the population tag
|
|
local place = Find("place")
|
|
if place ~= "" then
|
|
local rank = nil
|
|
local mz = 13
|
|
local pop = tonumber(Find("population")) or 0
|
|
|
|
if place == "continent" then mz=2
|
|
elseif place == "country" then mz=3; rank=1
|
|
elseif place == "state" then mz=4; rank=2
|
|
elseif place == "city" then mz=5; rank=3
|
|
elseif place == "town" and pop>8000 then mz=7
|
|
elseif place == "town" then mz=8
|
|
elseif place == "village" and pop>2000 then mz=9
|
|
elseif place == "village" then mz=10
|
|
elseif place == "suburb" then mz=11
|
|
elseif place == "hamlet" then mz=12
|
|
elseif place == "neighbourhood" then mz=13
|
|
elseif place == "locality" then mz=13
|
|
end
|
|
|
|
Layer("place", false)
|
|
Attribute("class", place)
|
|
MinZoom(mz)
|
|
if rank then AttributeNumeric("rank", rank) end
|
|
SetNameAttributes()
|
|
return
|
|
end
|
|
|
|
-- Write 'poi'
|
|
local rank, class, subclass = GetPOIRank()
|
|
if rank then WritePOI(node,class,subclass,rank) end
|
|
|
|
-- Write 'mountain_peak' and 'water_name'
|
|
local natural = Find("natural")
|
|
if natural == "peak" or natural == "volcano" then
|
|
Layer("mountain_peak", false)
|
|
SetEleAttributes()
|
|
AttributeNumeric("rank", 1)
|
|
Attribute("class", natural)
|
|
SetNameAttributes()
|
|
return
|
|
end
|
|
if natural == "bay" then
|
|
Layer("water_name", false)
|
|
SetNameAttributes()
|
|
return
|
|
end
|
|
end
|
|
|
|
-- Process way tags
|
|
|
|
majorRoadValues = Set { "motorway", "trunk", "primary" }
|
|
mainRoadValues = Set { "secondary", "motorway_link", "trunk_link", "primary_link", "secondary_link" }
|
|
midRoadValues = Set { "tertiary", "tertiary_link" }
|
|
minorRoadValues = Set { "unclassified", "residential", "road", "living_street" }
|
|
trackValues = Set { "cycleway", "byway", "bridleway", "track" }
|
|
pathValues = Set { "footway", "path", "steps" }
|
|
linkValues = Set { "motorway_link", "trunk_link", "primary_link", "secondary_link", "tertiary_link" }
|
|
constructionValues = Set { "primary", "secondary", "tertiary", "motorway", "service", "trunk", "track" }
|
|
|
|
aerowayBuildings= Set { "terminal", "gate", "tower" }
|
|
landuseKeys = Set { "school", "university", "kindergarten", "college", "library", "hospital",
|
|
"railway", "cemetery", "military", "residential", "commercial", "industrial",
|
|
"retail", "stadium", "pitch", "playground", "theme_park", "bus_station", "zoo" }
|
|
landcoverKeys = { wood="wood", forest="wood",
|
|
wetland="wetland",
|
|
beach="sand", sand="sand",
|
|
farmland="farmland", farm="farmland", orchard="farmland", vineyard="farmland", plant_nursery="farmland",
|
|
glacier="ice", ice_shelf="ice",
|
|
grassland="grass", grass="grass", meadow="grass", allotments="grass", park="grass", village_green="grass", recreation_ground="grass", garden="grass", golf_course="grass" }
|
|
|
|
-- POI key/value pairs: based on https://github.com/openmaptiles/openmaptiles/blob/master/layers/poi/mapping.yaml
|
|
poiTags = { aerialway = Set { "station" },
|
|
amenity = Set { "arts_centre", "bank", "bar", "bbq", "bicycle_parking", "bicycle_rental", "biergarten", "bus_station", "cafe", "cinema", "clinic", "college", "community_centre", "courthouse", "dentist", "doctors", "embassy", "fast_food", "ferry_terminal", "fire_station", "food_court", "fuel", "grave_yard", "hospital", "ice_cream", "kindergarten", "library", "marketplace", "motorcycle_parking", "nightclub", "nursing_home", "parking", "pharmacy", "place_of_worship", "police", "post_box", "post_office", "prison", "pub", "public_building", "recycling", "restaurant", "school", "shelter", "swimming_pool", "taxi", "telephone", "theatre", "toilets", "townhall", "university", "veterinary", "waste_basket" },
|
|
barrier = Set { "bollard", "border_control", "cycle_barrier", "gate", "lift_gate", "sally_port", "stile", "toll_booth" },
|
|
building = Set { "dormitory" },
|
|
highway = Set { "bus_stop" },
|
|
historic = Set { "monument", "castle", "ruins" },
|
|
landuse = Set { "basin", "brownfield", "cemetery", "reservoir", "winter_sports" },
|
|
leisure = Set { "dog_park", "escape_game", "garden", "golf_course", "ice_rink", "hackerspace", "marina", "miniature_golf", "park", "pitch", "playground", "sports_centre", "stadium", "swimming_area", "swimming_pool", "water_park" },
|
|
railway = Set { "halt", "station", "subway_entrance", "train_station_entrance", "tram_stop" },
|
|
shop = Set { "accessories", "alcohol", "antiques", "art", "bag", "bakery", "beauty", "bed", "beverages", "bicycle", "books", "boutique", "butcher", "camera", "car", "car_repair", "carpet", "charity", "chemist", "chocolate", "clothes", "coffee", "computer", "confectionery", "convenience", "copyshop", "cosmetics", "deli", "delicatessen", "department_store", "doityourself", "dry_cleaning", "electronics", "erotic", "fabric", "florist", "frozen_food", "furniture", "garden_centre", "general", "gift", "greengrocer", "hairdresser", "hardware", "hearing_aids", "hifi", "ice_cream", "interior_decoration", "jewelry", "kiosk", "lamps", "laundry", "mall", "massage", "mobile_phone", "motorcycle", "music", "musical_instrument", "newsagent", "optician", "outdoor", "perfume", "perfumery", "pet", "photo", "second_hand", "shoes", "sports", "stationery", "supermarket", "tailor", "tattoo", "ticket", "tobacco", "toys", "travel_agency", "video", "video_games", "watches", "weapons", "wholesale", "wine" },
|
|
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" } }
|
|
|
|
-- 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",
|
|
golf="golf", golf_course="golf", miniature_golf="golf",
|
|
fast_food="fast_food", food_court="fast_food",
|
|
park="park", bbq="park",
|
|
bus_stop="bus", bus_station="bus",
|
|
subway_entrance="entrance", train_station_entrance="entrance",
|
|
camp_site="campsite", caravan_site="campsite",
|
|
laundry="laundry", dry_cleaning="laundry",
|
|
supermarket="grocery", deli="grocery", delicatessen="grocery", department_store="grocery", greengrocer="grocery", marketplace="grocery",
|
|
books="library", library="library",
|
|
university="college", college="college",
|
|
hotel="lodging", motel="lodging", bed_and_breakfast="lodging", guest_house="lodging", hostel="lodging", chalet="lodging", alpine_hut="lodging", dormitory="lodging",
|
|
chocolate="ice_cream", confectionery="ice_cream",
|
|
post_box="post", post_office="post",
|
|
cafe="cafe",
|
|
school="school", kindergarten="school",
|
|
alcohol="alcohol_shop", beverages="alcohol_shop", wine="alcohol_shop",
|
|
bar="bar", nightclub="bar",
|
|
marina="harbor", dock="harbor",
|
|
car="car", car_repair="car", taxi="car",
|
|
hospital="hospital", nursing_home="hospital", clinic="hospital",
|
|
grave_yard="cemetery", cemetery="cemetery",
|
|
attraction="attraction", viewpoint="attraction",
|
|
biergarten="beer", pub="beer",
|
|
music="music", musical_instrument="music",
|
|
american_football="stadium", stadium="stadium", soccer="stadium",
|
|
art="art_gallery", artwork="art_gallery", gallery="art_gallery", arts_centre="art_gallery",
|
|
bag="clothing_store", clothes="clothing_store",
|
|
swimming_area="swimming", swimming="swimming",
|
|
castle="castle", ruins="castle" }
|
|
poiClassRanks = { hospital=1, railway=2, bus=3, attraction=4, harbor=5, college=6,
|
|
school=7, stadium=8, zoo=9, town_hall=10, campsite=11, cemetery=12,
|
|
park=13, library=14, police=15, post=16, golf=17, shop=18, grocery=19,
|
|
fast_food=20, clothing_store=21, bar=22 }
|
|
poiKeys = Set { "amenity", "sport", "tourism", "office", "historic", "leisure", "landuse", "information" }
|
|
waterClasses = Set { "river", "riverbank", "stream", "canal", "drain", "ditch", "dock" }
|
|
waterwayClasses = Set { "stream", "river", "canal", "drain", "ditch" }
|
|
|
|
|
|
function way_function()
|
|
local highway = Find("highway")
|
|
local waterway = Find("waterway")
|
|
local water = Find("water")
|
|
local building = Find("building")
|
|
local natural = Find("natural")
|
|
local historic = Find("historic")
|
|
local landuse = Find("landuse")
|
|
local leisure = Find("leisure")
|
|
local amenity = Find("amenity")
|
|
local aeroway = Find("aeroway")
|
|
local railway = Find("railway")
|
|
local sport = Find("sport")
|
|
local shop = Find("shop")
|
|
local tourism = Find("tourism")
|
|
local man_made = Find("man_made")
|
|
local isClosed = IsClosed()
|
|
local housenumber = Find("addr:housenumber")
|
|
local write_name = false
|
|
local construction = Find("construction")
|
|
|
|
-- Miscellaneous preprocessing
|
|
if Find("disused") == "yes" then return end
|
|
if highway == "proposed" then return end
|
|
if aerowayBuildings[aeroway] then building="yes"; aeroway="" end
|
|
if landuse == "field" then landuse = "farmland" end
|
|
if landuse == "meadow" and Find("meadow")=="agricultural" then landuse="farmland" end
|
|
|
|
-- Roads ('transportation' and 'transportation_name', plus 'transportation_name_detail')
|
|
if highway~="" then
|
|
local h = highway
|
|
local layer = "transportation_detail"
|
|
if majorRoadValues[highway] then layer="transportation" end
|
|
if mainRoadValues[highway] then layer="transportation_main" end
|
|
if midRoadValues[highway] then layer="transportation_mid" end
|
|
if minorRoadValues[highway] then h = "minor"; layer="transportation_mid" end
|
|
if trackValues[highway] then h = "track"; layer="transportation_detail" end
|
|
if pathValues[highway] then h = "path" ; layer="transportation_detail" end
|
|
if h=="service" then layer="transportation_detail" end
|
|
Layer(layer, false)
|
|
Attribute("class", h)
|
|
SetBrunnelAttributes()
|
|
|
|
-- Construction
|
|
if highway == "construction" then
|
|
if constructionValues[construction] then
|
|
Attribute("class", construction .. "_construction")
|
|
else
|
|
Attribute("class", "minor_construction")
|
|
end
|
|
end
|
|
|
|
-- Service
|
|
local service = Find("service")
|
|
if highway == "service" and service ~="" then Attribute("service", service) end
|
|
|
|
-- Links (ramp)
|
|
if linkValues[highway] then
|
|
splitHighway = split(highway, "_")
|
|
highway = splitHighway[1]
|
|
AttributeNumeric("ramp",1)
|
|
end
|
|
|
|
local oneway = Find("oneway")
|
|
if oneway == "yes" or oneway == "1" then
|
|
AttributeNumeric("oneway",1)
|
|
end
|
|
if oneway == "-1" then
|
|
-- **** TODO
|
|
end
|
|
|
|
-- Write names
|
|
if layer == "motorway" or layer == "trunk" then
|
|
Layer("transportation_name", false)
|
|
elseif h == "minor" or h == "track" or h == "path" or h == "service" then
|
|
Layer("transportation_name_detail", false)
|
|
else
|
|
Layer("transportation_name_mid", false)
|
|
end
|
|
SetNameAttributes()
|
|
Attribute("class",h)
|
|
Attribute("network","road") -- **** needs fixing
|
|
if h~=highway then Attribute("subclass",highway) end
|
|
local ref = Find("ref")
|
|
if ref~="" then
|
|
Attribute("ref",ref)
|
|
AttributeNumeric("ref_length",ref:len())
|
|
end
|
|
end
|
|
|
|
-- Railways ('transportation' and 'transportation_name', plus 'transportation_name_detail')
|
|
if railway~="" then
|
|
Layer("transportation", false)
|
|
Attribute("class", railway)
|
|
|
|
Layer("transportation_name", false)
|
|
SetNameAttributes()
|
|
MinZoom(14)
|
|
Attribute("class", "rail")
|
|
end
|
|
|
|
-- 'Aeroway'
|
|
if aeroway~="" then
|
|
Layer("aeroway", isClosed)
|
|
Attribute("class",aeroway)
|
|
Attribute("ref",Find("ref"))
|
|
write_name = true
|
|
end
|
|
|
|
-- 'aerodrome_label'
|
|
if aeroway=="aerodrome" then
|
|
LayerAsCentroid("aerodrome_label")
|
|
SetNameAttributes()
|
|
Attribute("iata", Find("iata"))
|
|
SetEleAttributes()
|
|
Attribute("icao", Find("icao"))
|
|
|
|
local aerodrome = Find(aeroway)
|
|
local class
|
|
if aerodromeValues[aerodrome] then class = aerodrome else class = "other" end
|
|
Attribute("class", class)
|
|
end
|
|
|
|
-- Set 'waterway' and associated
|
|
if waterwayClasses[waterway] and not isClosed then
|
|
if waterway == "river" and Holds("name") then
|
|
Layer("waterway", false)
|
|
else
|
|
Layer("waterway_detail", false)
|
|
end
|
|
if Find("intermittent")=="yes" then AttributeNumeric("intermittent", 1) else AttributeNumeric("intermittent", 0) end
|
|
Attribute("class", waterway)
|
|
SetNameAttributes()
|
|
SetBrunnelAttributes()
|
|
elseif waterway == "boatyard" then Layer("landuse", isClosed); Attribute("class", "industrial")
|
|
elseif waterway == "dam" then Layer("building",isClosed)
|
|
elseif waterway == "fuel" then Layer("landuse", isClosed); Attribute("class", "industrial")
|
|
end
|
|
-- Set names on rivers
|
|
if waterwayClasses[waterway] and not isClosed then
|
|
if waterway == "river" and Holds("name") then
|
|
Layer("water_name", false)
|
|
else
|
|
Layer("water_name_detail", false)
|
|
MinZoom(14)
|
|
end
|
|
Attribute("class", waterway)
|
|
SetNameAttributes()
|
|
end
|
|
|
|
-- Set 'building' and associated
|
|
if building~="" then
|
|
Layer("building", true)
|
|
SetMinZoomByArea()
|
|
end
|
|
|
|
-- Set 'housenumber'
|
|
if housenumber~="" then
|
|
LayerAsCentroid("housenumber")
|
|
Attribute("housenumber", housenumber)
|
|
end
|
|
|
|
-- Set 'water'
|
|
if natural=="water" or natural=="bay" or leisure=="swimming_pool" or landuse=="reservoir" or landuse=="basin" or waterClasses[waterway] then
|
|
if Find("covered")=="yes" or not isClosed then return end
|
|
local class="lake"; if natural=="bay" then class="ocean" elseif waterway~="" then class="river" end
|
|
Layer("water",true)
|
|
-- SetMinZoomByArea()
|
|
Attribute("class",class)
|
|
|
|
if Find("intermittent")=="yes" then Attribute("intermittent",1) end
|
|
-- we only want to show the names of actual lakes not every man-made basin that probably doesn't even have a name other than "basin"
|
|
-- examples for which we don't want to show a name:
|
|
-- https://www.openstreetmap.org/way/25958687
|
|
-- https://www.openstreetmap.org/way/27201902
|
|
-- https://www.openstreetmap.org/way/25309134
|
|
-- https://www.openstreetmap.org/way/24579306
|
|
if Holds("name") and natural=="water" and water ~= "basin" and water ~= "wastewater" then
|
|
LayerAsCentroid("water_name_detail")
|
|
SetNameAttributes()
|
|
-- SetMinZoomByArea()
|
|
Attribute("class", class)
|
|
end
|
|
|
|
return -- in case we get any landuse processing
|
|
end
|
|
|
|
-- Set 'landcover' (from landuse, natural, leisure)
|
|
local l = landuse
|
|
if l=="" then l=natural end
|
|
if l=="" then l=leisure end
|
|
if landcoverKeys[l] then
|
|
Layer("landcover", true)
|
|
SetMinZoomByArea()
|
|
Attribute("class", landcoverKeys[l])
|
|
if l=="wetland" then Attribute("subclass", Find("wetland"))
|
|
else Attribute("subclass", l) end
|
|
write_name = true
|
|
|
|
-- Set 'landuse'
|
|
else
|
|
if l=="" then l=amenity end
|
|
if l=="" then l=tourism end
|
|
if landuseKeys[l] then
|
|
Layer("landuse", true)
|
|
Attribute("class", l)
|
|
write_name = true
|
|
end
|
|
end
|
|
|
|
-- Parks
|
|
if boundary=="national_park" then Layer("park",true); Attribute("class",boundary); SetNameAttributes()
|
|
elseif leisure=="nature_reserve" then Layer("park",true); Attribute("class",leisure ); SetNameAttributes() end
|
|
|
|
-- POIs ('poi' and 'poi_detail')
|
|
local rank, class, subclass = GetPOIRank()
|
|
if rank then WritePOI(way,class,subclass,rank); return end
|
|
|
|
-- Catch-all
|
|
if (building~="" or write_name) and Holds("name") then
|
|
LayerAsCentroid("poi_detail")
|
|
SetNameAttributes()
|
|
if write_name then rank=6 else rank=25 end
|
|
AttributeNumeric("rank", rank)
|
|
end
|
|
end
|
|
|
|
-- Remap coastlines
|
|
function attribute_function(attr)
|
|
return { class="ocean" }
|
|
end
|
|
|
|
-- ==========================================================
|
|
-- Common functions
|
|
|
|
-- Write a way centroid to POI layer
|
|
function WritePOI(obj,class,subclass,rank)
|
|
local layer = "poi"
|
|
if rank>4 then layer="poi_detail" end
|
|
LayerAsCentroid(layer)
|
|
SetNameAttributes(obj)
|
|
AttributeNumeric("rank", rank)
|
|
Attribute("class", class)
|
|
Attribute("subclass", subclass)
|
|
end
|
|
|
|
-- Set name attributes on any object
|
|
function SetNameAttributes(obj)
|
|
local name = Find("name")
|
|
local main_written = name
|
|
local iname
|
|
-- if we have a preferred language, then write that (if available), and additionally write the base name tag
|
|
if preferred_language and Holds("name:"..preferred_language) then
|
|
iname = Find("name:"..preferred_language)
|
|
print("Found "..preferred_language..": "..iname)
|
|
Attribute(preferred_language_attribute, iname)
|
|
if iname~=name and default_language_attribute then
|
|
Attribute(default_language_attribute, name)
|
|
else main_written = iname end
|
|
else
|
|
Attribute(preferred_language_attribute, name)
|
|
end
|
|
-- then set any additional languages
|
|
for i,lang in ipairs(additional_languages) do
|
|
iname = Find("name:"..lang)
|
|
if iname=="" then iname=name end
|
|
if iname~=main_written then Attribute("name:"..lang, iname) end
|
|
end
|
|
end
|
|
|
|
-- Set ele and ele_ft on any object
|
|
function SetEleAttributes(obj)
|
|
local ele = Find("ele")
|
|
if ele ~= "" then
|
|
local meter = math.floor(tonumber(ele) or 0)
|
|
local feet = math.floor(meter * 3.2808399)
|
|
AttributeNumeric("ele", meter)
|
|
AttributeNumeric("ele_ft", feet)
|
|
end
|
|
end
|
|
|
|
function SetBrunnelAttributes(obj)
|
|
if Find("bridge") == "yes" then Attribute("brunnel", "bridge")
|
|
elseif Find("tunnel") == "yes" then Attribute("brunnel", "tunnel")
|
|
elseif Find("ford") == "yes" then Attribute("brunnel", "ford")
|
|
end
|
|
end
|
|
|
|
-- Set minimum zoom level by area
|
|
function SetMinZoomByArea()
|
|
local area=Area()
|
|
if area>ZRES5^2 then MinZoom(6)
|
|
elseif area>ZRES6^2 then MinZoom(7)
|
|
elseif area>ZRES7^2 then MinZoom(8)
|
|
elseif area>ZRES8^2 then MinZoom(9)
|
|
elseif area>ZRES9^2 then MinZoom(10)
|
|
elseif area>ZRES10^2 then MinZoom(11)
|
|
elseif area>ZRES11^2 then MinZoom(12)
|
|
elseif area>ZRES12^2 then MinZoom(13)
|
|
else MinZoom(14) end
|
|
end
|
|
|
|
-- Calculate POIs (typically rank 1-4 go to 'poi' z12-14, rank 5+ to 'poi_detail' z14)
|
|
-- returns rank, class, subclass
|
|
function GetPOIRank(obj)
|
|
local k,list,v,class,rank
|
|
|
|
-- Can we find the tag?
|
|
for k,list in pairs(poiTags) do
|
|
if list[Find(k)] then
|
|
v = Find(k) -- k/v are the OSM tag pair
|
|
class = poiClasses[v] or v
|
|
rank = poiClassRanks[class] or 25
|
|
return rank, class, v
|
|
end
|
|
end
|
|
|
|
-- Catch-all for shops
|
|
local shop = Find("shop")
|
|
if shop~="" then return poiClassRanks['shop'], "shop", shop end
|
|
|
|
-- Nothing found
|
|
return nil,nil,nil
|
|
end
|
|
|
|
-- ==========================================================
|
|
-- Lua utility functions
|
|
|
|
function split(inputstr, sep) -- https://stackoverflow.com/a/7615129/4288232
|
|
if sep == nil then
|
|
sep = "%s"
|
|
end
|
|
local t={} ; i=1
|
|
for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
|
|
t[i] = str
|
|
i = i + 1
|
|
end
|
|
return t
|
|
end
|
|
|