Модуль: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}