Module:DefaultSpeedLimits

From OpenStreetMap Wiki
Jump to navigation Jump to search
[Create] Documentation
-- An experiment for [[Default speed limits]].
local p = {}

function p.define(frame)
	local rules = mw.text.split(mw.text.trim(frame.args.rules), '\n')
	for k, v in pairs(rules) do
		if v == '' then
			table.remove(rules, k)
		end
	end
	
	local roadTypeDefLines = mw.text.split(mw.text.trim(frame.args['road types']), '\n')
	local roadTypes = {}
	for _, line in pairs( roadTypeDefLines ) do
		local values = mw.text.split(line, ' := ', true)
		roadTypes[values[1]] = values[2]
	end
	
	local div = mw.html.create('div')
	local wikitable = div:tag('table'):addClass('wikitable')
	local header = wikitable:tag('tr')
	header:tag('th'):wikitext('[[Country code]]')
	header:tag('th'):wikitext('Road type')
	header:tag('th'):wikitext('Vehicle type')
	header:tag('th'):wikitext('[[Key:maxspeed|maxspeed]]')
	header:tag('th'):wikitext('[[Key:maxspeed:conditional|maxspeed:conditional]]')
	
	local lastCountryCode = nil
	local lastRoadType = nil
	local countryCodeCell = nil
	local roadTypeCell = nil
	local rulesForLastCountry = nil
	local rulesForLastCountryAndRoadType = nil
	
	local data = {}
	local curCountry = nil
	
	for _, rule in pairs( rules ) do
		local row = wikitable:tag('tr')
		local values = mw.text.split(rule, ';', true)
		local countryCode = table.remove(values, 1) -- as per ISO 3166
		local roadType = mw.text.trim(table.remove(values, 1))
		local vehicle = mw.text.trim(table.remove(values, 1))
		local maxSpeed = mw.text.trim(table.remove(values, 1))
		local maxSpeedConditional = mw.text.trim(table.concat(values, '; '))
		
		if not data[countryCode] then
			curCountry = {}
			data[countryCode] = curCountry
		end
		
		local newTags = {}
		local suffix = ''
		if vehicle ~= 'default' then
			suffix = ':' .. vehicle
		end
		newTags['maxspeed' .. suffix] = mw.text.killMarkers(maxSpeed)
		if maxSpeedConditional then
			newTags['maxspeed' .. suffix .. ':conditional'] = mw.text.killMarkers(maxSpeedConditional)
		end
		
		for _, type in pairs(mw.text.split(mw.text.killMarkers(roadType), ' or ', true)) do
			local tags = curCountry[type]
		
			if not tags then
				tags = {}
				curCountry[type] = tags
			end
			
			for k, v in pairs(newTags) do
				tags[k] = v	
			end
		end
		
		if countryCode == lastCountryCode then
			rulesForLastCountry = rulesForLastCountry + 1
			countryCodeCell:attr('rowspan', rulesForLastCountry)
		else
			lastCountryCode = countryCode
			countryCodeCell = row:tag('td'):wikitext(mw.text.nowiki(countryCode))
			rulesForLastCountry = 1
		end
		
		if countryCode == lastCountryCode and lastRoadType and mw.text.killMarkers(roadType) == mw.text.killMarkers(lastRoadType) then
			rulesForLastCountryAndRoadType = rulesForLastCountryAndRoadType + 1
			roadTypeCell:attr('rowspan', rulesForLastCountryAndRoadType)
		else
			roadTypeCell = row:tag('td'):wikitext(roadType)
			lastRoadType = roadType
			rulesForLastCountryAndRoadType = 1
		end
		
		row:tag('td'):wikitext(mw.text.nowiki(vehicle))
		row:tag('td'):wikitext(maxSpeed)
		if maxSpeedConditional then
			row:tag('td'):wikitext(maxSpeedConditional)
		end
	end
	div:tag('h2'):wikitext('Road types')
	local roadTypeTable = div:tag('table'):addClass('wikitable')
	
	for name, filter in pairs( roadTypes ) do
		local row = roadTypeTable:tag('tr')
		row:tag('th'):wikitext(mw.text.nowiki(name))
		row:tag('td'):wikitext(mw.text.nowiki(filter))
	end
	div:tag('h2'):wikitext('JSON')
	div:tag('pre'):wikitext(mw.text.jsonEncode({rules=data, road_types=roadTypes}, mw.text.JSON_PRETTY))
	
	return tostring( div )
end

return p