If you find this page useful and would like to be notified of changes made to this page, start by inputting your email below.
powered by ChangeDetection
40x40px | This module is subject to page protection. It is a highly visible module in use by a very large number of pages, or is substituted very frequently. Because vandalism or mistakes would affect many pages, and even trivial editing might cause substantial load on the servers, it is protected from editing. |
This module implements the {{Location map}}, {{Location map+}}, {{Location map~}}, and {{Location map many}} templates. Please see the template pages for usage instructions.
local p = {} local getArgs = require('Module:Arguments').getArgs local function round(n, digits) local mult = math.pow(10, digits) return math.floor(n * mult + 0.5) / mult end local function getMapParams(map, frame) if mw.title.new('Module:Location map/data/' .. map).exists then local mapData = mw.loadData('Module:Location map/data/' .. map) return function(name, params) if mapData[name] == nil then return '' elseif params then return mw.message.newRawMessage(mapData[name], unpack(params)):plain() else return mapData[name] end end else local cache = {} return function(name, params) if params then return frame:expandTemplate{title = 'Location map ' .. map, args = { name, unpack(params) }} else if cache[name] == nil then cache[name] = frame:expandTemplate{title = 'Location map ' .. map, args = { name }} end return cache[name] end end end end local function decdeg(degrees, minutes, seconds, hemisphere, digits, decimal) if degrees == nil then return tonumber(decimal) end decimal = (degrees or 0) + (minutes or 0)/60 + (seconds or 0)/3600 if hemisphere == 'W' or hemisphere == 'w' or hemisphere == 'S' or hemisphere == 's' then decimal = -decimal end if digits == nil then digits = 7 end return round(decimal, digits) end function p.top(frame, args, map) if not args then args = getArgs(frame) end if not map then map = getMapParams(args[1], frame) end local width if args.width then width = mw.ustring.gsub(args.width, 'px', '') else width = round((args.default_width or 240) * (tonumber(map('defaultscale')) or 1), 0) end local retval = '' if args.float == 'center' then retval = retval .. '<div class="center">' end if args.caption then retval = retval .. '<div class="thumb ' if args.float == '"left"' or args.float == 'left' then retval = retval .. 'tleft' elseif args.float == '"center"' or args.float == 'center' or args.float == '"none"' or args.float == 'none' then retval = retval .. 'tnone' else retval = retval .. 'tright' end retval = retval .. '"><div class="thumbinner" style="width:' .. (width + 2) .. 'px; ' if args.border == 'none' then retval = retval .. 'border: none;' elseif args.border then retval = retval .. 'border-color:' .. args.border .. ';' end retval = retval .. '"><div style="position: relative; ' if args.border ~= 'none' then retval = retval .. 'border: 1px solid lightgray' end retval = retval .. '">' else retval = retval .. '<div style="width:' .. width .. 'px; ' if args.float == '"left"' or args.float == 'left' then retval = retval .. 'float: left; clear: left' elseif args.float == '"center"' or args.float == 'center' then retval = retval .. 'float: none; clear: both; margin-left: auto; margin-right: auto' elseif args.float == '"none"' or args.float == 'none' then retval = retval .. 'float: none; clear: none' else retval = retval .. 'float: right; clear: right' end retval = retval .. '"><div style="width:' .. width .. 'px; padding:0"><div style="position: relative; ">' end local image if args.AlternativeMap then image = args.AlternativeMap elseif args.relief and map('image1') ~= '' then image = map('image1') else image = map('image') end retval = retval .. '[[File:' .. image .. '|' .. width .. 'px|' .. (args.alt or ((args.label or mw.title.getCurrentTitle().text) .. ' is located in ' .. map('name'))) .. ']]' if args.overlay_image then retval = retval .. '<div style="position:absolute; top: 0; left: 0">[[File:' .. args.overlay_image .. '|' .. width .. 'px|link=File:' .. image .. ']]</div>' end return retval end function p.bottom(frame, args, map) if not args then args = getArgs(frame) end if not map then map = getMapParams(args[1], frame) end local retval = '' retval = retval .. '</div><div ' .. (args.caption and 'class="thumbcaption"' or 'style="font-size: 90%; padding-top:3px"') .. '>' local caption = frame.args.caption or frame:getParent().args.caption if caption and not args.caption_undefined then retval = retval .. mw.text.trim(caption) else retval = retval .. (args.label or mw.title.getCurrentTitle().text) .. ' (' .. map('name') .. ')' end retval = retval .. '</div></div></div>' if args.float == 'center' then retval = retval .. '</div>' end return retval end function p.container(frame, args, map) if not args then args = getArgs(frame) end if not map then map = getMapParams(args[1], frame) end return p.top(frame, args, map) .. (args.places or '') .. p.bottom(frame, args, map) end local function markOuterDiv(x, y, content) return '<div style="position:absolute;top:' .. y .. '%;left:' .. x .. '%;height:0;width:0;margin:0;padding:0">' .. content .. '</div>' end local function markImageDiv(mark, marksize, label, link, alt, title) local retval = '<div style="position:relative;text-align:center;left:-' .. round(marksize / 2, 0) .. 'px;top:-' .. round(marksize / 2, 0) .. 'px;width:' .. marksize .. 'px;font-size:' .. marksize .. 'px;line-height:0"' if title then retval = retval .. ' title="' .. title .. '"' end retval = retval .. '>' if marksize ~= 0 then retval = retval .. '[[File:' .. mark .. '|' .. marksize .. 'x' .. marksize .. 'px|' .. label .. '|link=' .. link if alt then retval = retval .. '|alt=' .. alt end retval = retval .. ']]' end return retval .. '</div>' end local function markLabelDiv(label, label_size, label_width, position, background, x) local retval = '<div style="font-size:' .. label_size .. '%;line-height:110%;position:relative;top:-1.5em;width:' .. label_width .. 'em;' if position == 'top' then -- specified top retval = retval .. 'top:-2.65em;left:-3em;text-align:center' elseif position == 'bottom' then -- specified bottom retval = retval .. 'top:-0.15em;left:-3em;text-align:center' elseif position == 'left' or (tonumber(x) > 70 and position ~= 'right') then -- specified left or autodetected to left retval = retval .. 'left:-6.5em;text-align:right' else -- specified right or autodetected to right retval = retval .. 'left:0.5em;text-align:left' end retval = retval .. '"><span style="padding:1px' if background then retval = retval .. ';background-color:' .. background end return retval .. '">' .. label .. '</span></div>' end local function getX(longitude, latitude, lon_dir, left, right, top, bottom, crosses180, skew, lon_shift) local crosses180_correction = crosses180 and lon_dir == 'W' and (-36000/(left - right)) or 0 if skew then local lat_ratio = (top - latitude)/(top - bottom) local skew_factor = (1 - skew) * lat_ratio + skew longitude = (longitude - 0.5 * (right + left) + lon_shift) * skew_factor + 0.5 * (right + left) - lon_shift end return round(crosses180_correction + 100 * (longitude - left) / (right - left), 1) end local function getY(latitude, top, bottom) return round(100 * (top - latitude) / (top - bottom), 1) end function p.mark(frame, args, map) if not args then args = getArgs(frame) end if not map then map = getMapParams(args[1], frame) end local x, y, longitude, latitide longitude = decdeg(args.lon_deg, args.lon_min, args.lon_sec, args.lon_dir, nil, args.long) latitude = decdeg(args.lat_deg, args.lat_min, args.lat_sec, args.lat_dir, nil, args.lat) if map('x') ~= '' then x = frame:callParserFunction('#expr', map('x', { latitude, longitude })) else x = getX(longitude, latitude, args.lon_dir, map('left'), map('right'), map('top'), map('bottom'), map('crosses180') ~= '', tonumber(args.skew or map('skew')), args.lon_shift or 0) end if map('y') ~= '' then y = frame:callParserFunction('#expr', map('y', { latitude, longitude })) else y = getY(latitude, map('top'), map('bottom')) end local mark = args.mark or map('mark') if mark == '' then mark = 'Red pog.svg' end local divContent = markImageDiv(mark, tonumber(args.marksize) or tonumber(map('marksize')) or 8, args.label or mw.title.getCurrentTitle().text, args.link or '', args.alt, args[2]) if args.label and args.position ~= 'none' then divContent = divContent .. markLabelDiv(args.label, args.label_size or 90, args.label_width or 6, args.position, args.background, x) end return markOuterDiv(x, y, divContent) end function p.main(frame, args, map) if not args then args = getArgs(frame) end if not args[1] then args[1] = 'World' end if not map then map = getMapParams(args[1], frame) end return p.top(frame, args, map) .. p.mark(frame, args, map) .. p.bottom(frame, args, map) end return p