Модуль:MetroMap

Документация

Этот модуль обслуживает шаблоны интерактивных карт метро, в частности Шаблон:Интерактивная схема Московского метрополитена. Он был создан в процессе обсуждения Обсуждение проекта:Метро/Московский метрополитен#Шаблон:Интерактивная схема Московского метрополитена - новое поколение для дальнейшего использования в этом шаблоне.

local jsontable, data, size  local function setglobals(frame) 	jsontable = mw.loadJsonData('Шаблон:Интерактивная схема ' .. frame.args[1] .. 			' метрополитена/data.json') 	data = {} 	for key,value in ipairs(jsontable.lines) do 		if (value.color and value.article and value.name) then 			data[value.article] = {undefined, value.name} 		end 		for key0, value0 in ipairs(value.stations or {}) do 			if (value0.article and value0.coords and not data[value0.article]) then 				data[value0.article] = {value0.coords, value0.name} 			end 		end 	end 	size = ' ' .. (frame.args['size'] or '20') .. ' ' end  function buildnover(args) 	local novertable = {nover = {}} 	local formats = jsontable.nover 	local novername, place 	for key, value in pairs(formats) do 		novername = args[key] 		if (novername and novername ~= "") then 			novertable.nover[novername] = value 		end 	end 	for key, value in pairs(novertable.nover) do 		place = key 	end 	if (formats[place]) then 		local novertablecopy = deepcopy(novertable) 		novertablecopy.nover[place] = formats[place][2 - (args.popup or 3)] or novertablecopy.nover[place] 		return "'" .. mw.text.jsonEncode(novertablecopy) .. "'" 	end 	return "'" .. mw.text.jsonEncode(novertable) .. "'" end  function buildhover(frame) 	setglobals(frame) 	local hovertable = {hover = {}, hoverblocks = {}} 	local linename, lcolor, scolor 	for key, value in pairs(jsontable.lines) do 		if (value.color) then 			for key0, value0 in pairs(value.stations or {}) do 				if (value0.hover) then 					hovertable.hover[value0.name or value0.article] = value0.hover 				end 			end 			linename = value.name or value.article 			lcolor = deepcopy(value.color) 			lcolor.strokeStyle = lcolor.strokeStyle or 'rgb(0,0,0,0)' 			scolor = deepcopy(value.color) 			scolor.strokeStyle = scolor.strokeStyle or scolor.fillStyle 			hovertable.hover[linename] = lcolor 			if (value.article) then 				table.insert(hovertable.hoverblocks, {value = scolor, 					list = convertstations(value.stations, hovertable.hover)}) 			end 		end 	end 	return mw.text.jsonEncode(hovertable) end  function classes(station, line) 	local ans = deepcopy(jsontable.classes) 	ans[station] = ans.localstation 	ans[station .. ' super'] = ans.localsuperstation 	ans[line .. ' super'] = ans.localsuperline 	ans.localstation = nil 	ans.localsuperstation = nil 	ans.localsuperline = nil 	for key, value in pairs(jsontable.lines) do 		if (value.future) then 			ans[value.name or value.article] = ans.future .. ' ' .. value.classes .. ' ' .. ans.lines 		elseif (value.color) then 			ans[value.name or value.article] = value.classes .. ' ' .. ans.lines 		end 		for key0, value0 in pairs(value.stations or {}) do 			if (value0.future) then 				ans[removeparen(value0.article, value0.name, true)] = (ans[removeparen(value0.article, value0.name, true)] or ans.default) .. ' ' .. ans.future 			end 		end 	end 	ans.future = nil 	ans.lines = nil 	return "'" .. mw.text.jsonEncode(ans) .. "'" end  function removeparen(article, name, default) 	local par 	if (name) then 		return name 	end 	par = mw.ustring.find(article, ' (', 1, true) 	if (par) then 		return mw.ustring.sub(article, 1, par-1) 	end 	if (default) then 		return article 	end end  function convertstations(stations, blocks) 	local ans = {} 	for key, value in pairs(stations) do 		if (value.coords) then 			ans[key] = removeparen(value.article, value.name, true) 		else 			ans[key] = '' 		end 	end 	table.sort(ans) 	local removed = {} 	for key,value in pairs(ans) do 		if (value == "" or blocks[value] or value == ans[key+1]) then 			table.insert(removed, key) 		end 	end 	for key = #removed, 1, -1 do 		table.remove(ans, removed[key]) 	end 	return ans end  function deepcopy(original) 	if (type(original) == 'nil') then 		return nil 	elseif (type(original) == 'number') then 		return 0 + original 	elseif (type(original) == 'string') then 		return '' .. original 	elseif (original == true) then 		return true 	elseif (original == false) then 		return false 	elseif (type(original) == 'function') then 		return mw.clone(original) 	elseif (type(original) ~= 'table') then 		error('Unknown type: ' .. type(original)) 	end 	local copy = {} 	for key, value in pairs(original) do 		copy[key] = deepcopy(value) 	end 	return copy end  function imagemaptext() 	local ans = '' 	local linestable = jsontable.lines 	local lineshapes = '# Lines\n' 	local name 	for key,value in ipairs(linestable) do 		if (value.color and value.article) then 			ans = ans .. '# Line ' .. value.number .. '\nrect ' .. value.box .. ' [[' .. value.article 			if (value.name) then 				ans = ans .. '|' .. value.name 			end 			ans = ans .. ']]\n' 			for key0, value0 in ipairs(value.stations) do 				if (value0.coords) then 					name = removeparen(value0.article, value0.name, false) 					ans = ans .. 'circle ' .. value0.coords .. size .. '[[' .. value0.article 					if (name) then 						ans = ans .. '|' .. name 					end 					ans = ans .. ']]\n' 				end 			end 		end 		if (value.shapes) then 			for key0, value0 in ipairs(value.shapes) do 				lineshapes = lineshapes .. value0 				if (not value.hide) then 					lineshapes = lineshapes .. ' [[' .. value.article 					if (value.name) then 						lineshapes = lineshapes .. '|' .. value.name 					end 					lineshapes = lineshapes .. ']]' 				end 				lineshapes = lineshapes .. '\n' 			end 		end 	end 	return ans .. terminals('Вокзалы') .. terminals('Ж/д станции') .. terminals('Аэропорты') .. lineshapes .. areas() end  function terminals(ttype) 	if (not jsontable[ttype]) then 		return '' 	end 	local items = deepcopy(jsontable[ttype]) 	if (not items[1]) then 		return '' 	end 	local link = items[1][1] 	local left = '# ' .. ttype ..'\ncircle ' .. items[1][2] .. size .. link .. '\n' 	local right = '' 	table.remove(items, 1) 	for key, value in pairs(items) do 		left = left .. 'circle ' .. value[2] .. size .. value[1] .. '\n' 		right = right .. 'circle ' .. value[2] .. size .. link .. '\n' 	end 	return left .. right end  function areas() 	local ans ='' 	if (jsontable.areas) then 		for key, value in ipairs(jsontable.areas) do 			for key0, value0 in ipairs(value.shapes) do 				ans = ans .. value0 .. ' ' .. value.link .. '\n' 			end 		end 	end 	return ans end  function miniimagemaptext() 	local ans = '# Lines\n' 	local linestable = jsontable.lines 	local shapes 	for key, value in ipairs(linestable) do 		if (value.color) then 			shapes = value.minishapes or value.shapes 			if (shapes) then 				for key0, value0 in ipairs(shapes) do 					ans = ans .. value0 					if (not value.hide) then 						ans = ans .. ' [[' .. value.article 						if (value.name) then 							ans = ans .. '|' .. value.name 						end 						ans = ans .. ']]' 					end 					ans = ans .. '\n' 				end 			end 		end 	end 	return ans .. '\n' end  function mobile(frame) 	setglobals(frame) 	local ans = '' 	local linestable = jsontable.lines 	local name, class, names 	for key,value in ipairs(linestable) do 		if (value.color and value.article) then 			names = {} 			if (value.future) then 				class = jsontable.classes.future .. ' ' .. value.classes .. ' ' .. jsontable.classes.lines 			else 				class = value.classes .. ' ' .. jsontable.classes.lines 			end 			ans = ans .. "<div class='" .. class .. "' style='text-align:center;white-space:nowrap'>'''[[" .. value.article 			if (value.name) then 				ans = ans .. '|' .. value.name 			end 			ans = ans .. "]]'''</div>\n" 			for key0, value0 in ipairs(value.stations) do 				name = removeparen(value0.article, value0.name, false) 				if (value0.coords and not names[name or value0.article]) then 					names[name or value0.article] = true 					if (value0.future) then 						class = jsontable.classes.future 					else 						class = '' 					end 					ans = ans .. "* <span class='" .. class .. "'>[[" .. value0.article 					if (name) then 						ans = ans .. '|' .. name 					end 					ans = ans .. ']]</span>\n' 				end 			end 		end 	end 	if (jsontable.areas) then 		ans = ans .. '\n\n' 		local bullet = '; ' 		for key, value in ipairs(jsontable.areas) do 			ans = ans .. bullet .. value.link .. '\n' 			bullet = ': ' 		end 	end 	return ans end  function popup0(frame) 	setglobals(frame) 	local stationname = '' 	local linename = '' 	local pagename = mw.title.getCurrentTitle().text 	local name = (data[pagename] and data[pagename][2]) or 			mw.ustring.gsub(pagename, ' %(.*%)', '') 	local minimaptext = miniimagemaptext() 	if (data[pagename] and data[pagename][1]) then 		stationname = name 		minimaptext = minimaptext .. '# Station\ncircle ' .. data[pagename][1] .. 				' 25 [[' .. pagename 		if (pagename ~= stationname) then 			minimaptext = minimaptext .. '|' .. stationname 		end 		minimaptext = minimaptext .. ']]' 	else 		linename = name 	end 	return frame:expandTemplate{title = 'Одноразмерная карта изображений', args = { 		['файл'] = frame.args[2], 		['надпись'] = frame:expandTemplate{title = 'Интерактивная схема ' .. 					frame.args[1] .. ' метрополитена/Шапка'}, 		['надпись_сверху'] = 'да', 		['прижатие'] = frame:getParent().args['прижатие'] or 'центр', 		['развернуть'] = frame:expandTemplate{title = 'Определить язык', args = { 			'полноэкранная схема со станциями', 'full screen map with stations' 		}}, 		['размер'] = frame:getParent().args['минимум'] or 270, 		['иконка'] = 'none', 		['класс'] = 'imgtogglemini', 		nohr = 'yes', 		help = frame:expandTemplate{title = 'Одноразмерная карта изображений/пояснение'}, 		helppage = 'Шаблон:Интерактивная схема ' .. frame.args[1] .. ' метрополитена/Инструкция', 		version = frame.args[1], 		query = mw.text.nowiki(mw.text.jsonEncode(jsontable.query)), 		width = frame.args.mapwidth or 970, 		textwidth = frame.args.textwidth or 250; 		area = buildnover{['mini station local page'] = stationname, ['mini line local page'] = linename, 			pagename = pagename, popup = 0}, 		areafile = '#invoke:MetroMap|buildhover|' .. frame.args[1], 		list = classes(stationname, linename), 		['карта'] = minimaptext 	}} end  function popup1(frame) 	setglobals(frame) 	local stationname = '' 	local linename = '' 	local pagename = frame.args.pagename 	local name = (data[pagename] and data[pagename][2]) or 			mw.ustring.gsub(pagename, ' %(.*%)', '') 	if (data[pagename] and data[pagename][1]) then 		stationname = name 	else 		linename = name 	end 	return frame:expandTemplate{title = 'Одноразмерная карта изображений', args = { 		['файл'] = frame.args[2], 		['надпись_сверху'] = 'нет', 		['прижатие'] = 'центр', 		['размер'] = frame.args.width or 1000, 		['иконка'] = 'none', 		['класс'] = 'popupclass imgtogglefull', 		version = 'opened-' .. frame.args[1], 		links = frame.args.links, 		area = buildnover{['station local page'] = stationname, ['line local page'] = linename, 			pagename = pagename, popup = 1}, 		areafile = '#invoke:MetroMap|buildhover|' .. frame.args[1], 		list = classes(stationname, linename), 		['карта'] = imagemaptext() 	}} end  return {popup0 = popup0, popup1 = popup1, mobile = mobile, buildhover = buildhover}