Module:Infobox mapframe: Difference between revisions
>Evad37 (only allow shapes/lines based on wikidata id if there is an id) |
(Fix) |
||
(2 intermediate revisions by the same user not shown) | |||
Line 19: | Line 19: | ||
local DEFAULT_LINE_STROKE_COLOR = "#FF0000" | local DEFAULT_LINE_STROKE_COLOR = "#FF0000" | ||
local DEFAULT_MARKER_COLOR = "#5E74F3" | local DEFAULT_MARKER_COLOR = "#5E74F3" | ||
-- Trim whitespace from args, and remove empty args | -- Trim whitespace from args, and remove empty args | ||
function trimArgs(argsTable) | function trimArgs(argsTable) | ||
local cleanArgs = {} | |||
for key, val in pairs(argsTable) do | |||
if type(val) == 'string' then | |||
val = val:match('^%s*(.-)%s*$') | |||
if val ~= '' then | |||
cleanArgs[key] = val | |||
end | |||
else | |||
cleanArgs[key] = val | |||
end | |||
end | |||
return cleanArgs | |||
end | end | ||
function shouldAutoRun(frame) | function shouldAutoRun(frame) | ||
-- Check if should be running | |||
local explicitlyOn = yesno(mw.text.trim(frame.getParent(frame).args.mapframe or "")) -- true of false or nil | |||
local onByDefault = (explicitlyOn == nil) and yesno(mw.text.trim(frame.args.onByDefault or ""), false) -- true or false | |||
return explicitlyOn or onByDefault | |||
end | end | ||
function argsFromAuto(frame) | function argsFromAuto(frame) | ||
-- Get args from the frame (invoke call) and the parent (template call). | |||
-- Frame arguments are default values which are overridden by parent values | |||
-- when both are present | |||
local args = getArgs(frame, { parentFirst = true }) | |||
-- Discard args not prefixed with "mapframe-", remove that prefix from those that remain | |||
local fixedArgs = {} | |||
for name, val in pairs(args) do | |||
local fixedName = string.match(name, "^mapframe%-(.+)$" ) | |||
if fixedName then | |||
fixedArgs[fixedName] = val | |||
-- allow coord, coordinates, etc to be unprefixed | |||
elseif name == "coordinates" or name == "coord" or name == "coordinate" and not fixedArgs.coord then | |||
fixedArgs.coord = val | |||
-- allow id, qid to be unprefixed, map to id (if not already present) | |||
elseif name == "id" or name == "qid" and not fixedArgs.id then | |||
fixedArgs.id = val | |||
end | |||
end | |||
return fixedArgs | |||
end | end | ||
Line 133: | Line 69: | ||
p.autocaption = function(frame) | p.autocaption = function(frame) | ||
if not shouldAutoRun(frame) then return "" end | |||
local args = argsFromAuto(frame) | |||
if args.caption then | |||
return args.caption | |||
elseif args.switcher then | |||
return "" | |||
end | |||
return "" | |||
end | end | ||
function parseCustomWikitext(customWikitext) | function parseCustomWikitext(customWikitext) | ||
-- infoboxImage will format an image if given wikitext containing an | |||
-- image, or else pass through the wikitext unmodified | |||
return infoboxImage({ | |||
args = { | |||
image = customWikitext | |||
} | |||
}) | |||
end | end | ||
p.auto = function(frame) | p.auto = function(frame) | ||
if not shouldAutoRun(frame) then return "" end | |||
local args = argsFromAuto(frame) | |||
if args.custom then | |||
return frame:preprocess(parseCustomWikitext(args.custom)) | |||
end | |||
local mapframe = p._main(args) | |||
return frame:preprocess(mapframe) | |||
end | end | ||
p.main = function(frame) | p.main = function(frame) | ||
local parent = frame.getParent(frame) | |||
local parentArgs = parent.args | |||
local mapframe = p._main(parentArgs) | |||
return frame:preprocess(mapframe) | |||
end | |||
function getZoom(value, unit) | |||
local length_km | |||
if unit == 'km' then | |||
length_km = tonumber(value) | |||
elseif unit == 'mi' then | |||
length_km = tonumber(value)*1.609344 | |||
elseif unit == 'km2' then | |||
length_km = math.sqrt(tonumber(value)) | |||
elseif unit == 'mi2' then | |||
length_km = math.sqrt(tonumber(value))*1.609344 | |||
end | |||
-- max for zoom 2 is 6400km, for zoom 3 is 3200km, for zoom 4 is 1600km, etc | |||
local zoom = math.floor(8 - (math.log10(length_km) - 2)/(math.log10(2))) | |||
-- limit to values below 17 | |||
zoom = math.min(17, zoom) | |||
-- take off 1 when calculated from area, to account for unusual shapes | |||
if unit == 'km2' or unit == 'mi2' then | |||
zoom = zoom - 1 | |||
end | |||
-- minimum value is 1 | |||
return math.max(1, zoom) | |||
end | end | ||
p._main = function(_config) | p._main = function(_config) | ||
-- `config` is the args passed to this module | |||
local config = trimArgs(_config) | |||
-- `args` is the arguments which will be passed to the mapframe module | |||
local args = {} | |||
-- Some defaults/overrides for infobox presentation | |||
args.display = "inline" | |||
args.frame = "yes" | |||
args.plain = "yes" | |||
args["frame-width"] = config["frame-width"] or config.width or DEFAULT_FRAME_WIDTH | |||
args["frame-height"] = config["frame-height"] or config.height or DEFAULT_FRAME_HEIGHT | |||
args["frame-align"] = "center" | |||
args["frame-coord"] = config["frame-coordinates"] or "" | |||
-- deprecated lat and long parameters | |||
args["frame-lat"] = config["frame-lat"] or config["frame-latitude"] or "" | |||
args["frame-long"] = config["frame-long"] or config["frame-longitude"] or "" | |||
-- Calculate zoom from length or area (converted to km or km2) | |||
if config.length_km then | |||
args.zoom = getZoom(config.length_km, 'km') | |||
elseif config.length_mi then | |||
args.zoom = getZoom(config.length_mi, 'mi') | |||
elseif config.area_km2 then | |||
args.zoom = getZoom(config.area_km2, 'km2') | |||
elseif config.area_mi2 then | |||
args.zoom = getZoom(config.area_mi2, 'mi2') | |||
else | |||
args.zoom = config.zoom or DEFAULT_ZOOM | |||
end | |||
local mapframe = mf._main(args) | |||
local tracking = '' | |||
return mapframe .. tracking | |||
end | end | ||
return p | return p |
Latest revision as of 21:31, 23 July 2023
Documentation for this module may be created at Module:Infobox mapframe/doc
local mf = require('Module:Mapframe') local getArgs = require('Module:Arguments').getArgs local yesno = require('Module:Yesno') local infoboxImage = require('Module:InfoboxImage').InfoboxImage -- Defaults local DEFAULT_FRAME_WIDTH = "270" local DEFAULT_FRAME_HEIGHT = "200" local DEFAULT_ZOOM = 10 local DEFAULT_GEOMASK_STROKE_WIDTH = "1" local DEFAULT_GEOMASK_STROKE_COLOR = "#777777" local DEFAULT_GEOMASK_FILL = "#888888" local DEFAULT_GEOMASK_FILL_OPACITY = "0.5" local DEFAULT_SHAPE_STROKE_WIDTH = "3" local DEFAULT_SHAPE_STROKE_COLOR = "#FF0000" local DEFAULT_SHAPE_FILL = "#606060" local DEFAULT_SHAPE_FILL_OPACITY = "0.5" local DEFAULT_LINE_STROKE_WIDTH = "5" local DEFAULT_LINE_STROKE_COLOR = "#FF0000" local DEFAULT_MARKER_COLOR = "#5E74F3" -- Trim whitespace from args, and remove empty args function trimArgs(argsTable) local cleanArgs = {} for key, val in pairs(argsTable) do if type(val) == 'string' then val = val:match('^%s*(.-)%s*$') if val ~= '' then cleanArgs[key] = val end else cleanArgs[key] = val end end return cleanArgs end function shouldAutoRun(frame) -- Check if should be running local explicitlyOn = yesno(mw.text.trim(frame.getParent(frame).args.mapframe or "")) -- true of false or nil local onByDefault = (explicitlyOn == nil) and yesno(mw.text.trim(frame.args.onByDefault or ""), false) -- true or false return explicitlyOn or onByDefault end function argsFromAuto(frame) -- Get args from the frame (invoke call) and the parent (template call). -- Frame arguments are default values which are overridden by parent values -- when both are present local args = getArgs(frame, { parentFirst = true }) -- Discard args not prefixed with "mapframe-", remove that prefix from those that remain local fixedArgs = {} for name, val in pairs(args) do local fixedName = string.match(name, "^mapframe%-(.+)$" ) if fixedName then fixedArgs[fixedName] = val -- allow coord, coordinates, etc to be unprefixed elseif name == "coordinates" or name == "coord" or name == "coordinate" and not fixedArgs.coord then fixedArgs.coord = val -- allow id, qid to be unprefixed, map to id (if not already present) elseif name == "id" or name == "qid" and not fixedArgs.id then fixedArgs.id = val end end return fixedArgs end local p = {} p.autocaption = function(frame) if not shouldAutoRun(frame) then return "" end local args = argsFromAuto(frame) if args.caption then return args.caption elseif args.switcher then return "" end return "" end function parseCustomWikitext(customWikitext) -- infoboxImage will format an image if given wikitext containing an -- image, or else pass through the wikitext unmodified return infoboxImage({ args = { image = customWikitext } }) end p.auto = function(frame) if not shouldAutoRun(frame) then return "" end local args = argsFromAuto(frame) if args.custom then return frame:preprocess(parseCustomWikitext(args.custom)) end local mapframe = p._main(args) return frame:preprocess(mapframe) end p.main = function(frame) local parent = frame.getParent(frame) local parentArgs = parent.args local mapframe = p._main(parentArgs) return frame:preprocess(mapframe) end function getZoom(value, unit) local length_km if unit == 'km' then length_km = tonumber(value) elseif unit == 'mi' then length_km = tonumber(value)*1.609344 elseif unit == 'km2' then length_km = math.sqrt(tonumber(value)) elseif unit == 'mi2' then length_km = math.sqrt(tonumber(value))*1.609344 end -- max for zoom 2 is 6400km, for zoom 3 is 3200km, for zoom 4 is 1600km, etc local zoom = math.floor(8 - (math.log10(length_km) - 2)/(math.log10(2))) -- limit to values below 17 zoom = math.min(17, zoom) -- take off 1 when calculated from area, to account for unusual shapes if unit == 'km2' or unit == 'mi2' then zoom = zoom - 1 end -- minimum value is 1 return math.max(1, zoom) end p._main = function(_config) -- `config` is the args passed to this module local config = trimArgs(_config) -- `args` is the arguments which will be passed to the mapframe module local args = {} -- Some defaults/overrides for infobox presentation args.display = "inline" args.frame = "yes" args.plain = "yes" args["frame-width"] = config["frame-width"] or config.width or DEFAULT_FRAME_WIDTH args["frame-height"] = config["frame-height"] or config.height or DEFAULT_FRAME_HEIGHT args["frame-align"] = "center" args["frame-coord"] = config["frame-coordinates"] or "" -- deprecated lat and long parameters args["frame-lat"] = config["frame-lat"] or config["frame-latitude"] or "" args["frame-long"] = config["frame-long"] or config["frame-longitude"] or "" -- Calculate zoom from length or area (converted to km or km2) if config.length_km then args.zoom = getZoom(config.length_km, 'km') elseif config.length_mi then args.zoom = getZoom(config.length_mi, 'mi') elseif config.area_km2 then args.zoom = getZoom(config.area_km2, 'km2') elseif config.area_mi2 then args.zoom = getZoom(config.area_mi2, 'mi2') else args.zoom = config.zoom or DEFAULT_ZOOM end local mapframe = mf._main(args) local tracking = '' return mapframe .. tracking end return p