Content deleted Content added
Allow shape, point, or line to be turned off; allow point to be forced on; allow shape type to be changed to shape-inverse; allow shape and geomask fill opacity to be specified |
Let line=yes or shape=yes force use of Wikidata for that type + let Kartographer set zoom. Also: parse point, marker, shape, and line with yesno to allow more general yes/no arguments |
||
(16 intermediate revisions by 3 users not shown) | |||
Line 1:
local mf = require('Module:Mapframe')
local getArgs = require('Module:Arguments').getArgs
local yesno = require('Module:Yesno')
local infoboxImage = require('Module:InfoboxImage').InfoboxImage
-- Defaults
Line 74 ⟶ 77:
end
function shouldAutoRun(frame)
-- Check if should be running
local pargs = frame.getParent(frame).args
local explicitlyOn = yesno(mw.text.trim(pargs.mapframe or "")) -- true of false or nil
if pargs.coordinates == "{{{coordinates}}}" then explicitlyOn = false end
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
local maskItem
local maskType = idType(args.geomask)
if maskType == 'item' then
maskItem = args.geomask
elseif maskType == "property" then
maskItem = relatedEntity(args.id or mw.wikibase.getEntityIdForCurrentPage(), args.geomask)
end
local maskItemLabel = maskItem and mw.wikibase.getLabel( maskItem )
return maskItemLabel and "Location in "..maskItemLabel or ""
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)
Line 105 ⟶ 158:
return frame:preprocess(mapframe)
end
--A list of types for objects that are too small to allow Kartographer to take over zoom
local tinyType = {
landmark=true,
railwaystation=true,
edu=true,
pass=true,
camera=true
}
p._main = function(_config)
Line 110 ⟶ 172:
local config = trimArgs(_config)
-- allow alias for config.coord
config.coord = config.coord or config.coordinates
-- Require wikidata item, or specified coords
local wikidataId = config.id or mw.wikibase.getEntityIdForCurrentPage()
Line 125 ⟶ 183:
-- Require coords (specified or from wikidata), so that map will be centred somewhere
-- (P625 = coordinate ___location)
local hasCoordinates = hasWikidataProperty(wikidataId, 'P625')
if not hasCoordinates then
return ''
Line 137 ⟶ 195:
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"
Line 149 ⟶ 207:
args["frame-long"] = config["frame-long"] or config["frame-longitude"] or ""
-- if zoom isn't specified from config:
if not zoom then
-- Calculate zoom from length or area (converted to km or km2)
-- Zoom so that length or area is completely included in mapframe
local getZoom = require('Module:Infobox dim')._zoom
width_km=config.width_km, width_mi=config.width_mi,
area_ha=config.area_ha, area_acre=config.area_acre,
type=config.type, population=config.population,
viewport_px=math.min(args["frame-width"],args["frame-height"])})
end
args.zoom = zoom or DEFAULT_ZOOM
-- Conditionals: whether point, geomask should be shown
local hasOsmRelationId = hasWikidataProperty(wikidataId, 'P402') -- P402 is OSM relation ID
local shouldShowPointMarker;
-- determine marker argument value, determine whether to show marker
local pointValue = config.point
if pointValue == 'none' then
pointValue = 'no'
end
pointValue = yesno(pointValue,'other')
local markerValue = config.marker
if markerValue == 'none' then
markerValue = 'no'
end
markerValue = yesno(markerValue,true)
if pointValue == true then
shouldShowPointMarker = true
elseif
shouldShowPointMarker = false
else
shouldShowPointMarker = not(hasOsmRelationId) or
end
-- determine shape parameter value, determine whether to show or suppress shape
-- also determine whether to invert shape
local shapeValue = config.shape
if shapeValue == 'none' then
shapeValue = 'no'
end
shapeValue = yesno(shapeValue,'other')
local forceShape = shapeValue == true and hasOsmRelationId
local suppressShape = shapeValue == false
local shapeType = config.shape == 'inverse' and 'shape-inverse' or 'shape'
-- determine line parameter value, determine whether to show or suppress line
local lineValue = config.line
if lineValue == 'none' then
lineValue = 'no'
end
local lineValue = yesno(lineValue,'other')
local forceLine = lineValue == true and hasOsmRelationId
local suppressLine = lineValue == false
-- determine whether to use wikidata (independent of shape/line)
local maskItem
local useWikidata = wikidataId -- by default, if wikidata is supplied, use wikidata
-- But do not use wikidata when local coords are specified (and not turned off), unless explicitly set
if useWikidata and config.coord and shouldShowPointMarker then
useWikidata = yesno(config.wikidata,true)
end
-- Switcher
if config.switcher == "zooms" then
-- switching between zoom levels
local maxZoom = math.max(tonumber(args.zoom), 3) -- what zoom would have otherwise been (if 3 or more, otherwise 3)
local minZoom = 1 -- completely zoomed out
local midZoom = math.floor((maxZoom + minZoom)/2) -- midway between maxn and min
args.switch = "zoomed in, zoomed midway, zoomed out"
args.zoom = string.format("SWITCH:%d,%d,%d", maxZoom, midZoom, minZoom)
elseif config.switcher == "auto" then
-- switching between P276 and P131 areas with recursive lookup, e.g. item's city,
-- that city's state, and that state's country
args.zoom = nil -- let kartographer determine the zoom
local maskLabels = {}
local maskItems = {}
local maskItemId = relatedEntity(wikidataId, "P276") or relatedEntity(wikidataId, "P131")
local maskLabel = mw.wikibase.getLabel(maskItemId)
while maskItemId and maskLabel and mw.text.trim(maskLabel) ~= "" do
table.insert(maskLabels, maskLabel)
table.insert(maskItems, maskItemId)
maskItemId = maskItemId and relatedEntity(maskItemId, "P131")
maskLabel = maskItemId and mw.wikibase.getLabel(maskItemId)
end
if #maskLabels > 1 then
args.switch = table.concat(maskLabels, "###")
maskItem = "SWITCH:" .. table.concat(maskItems, ",")
elseif #maskLabels == 1 then
maskItem = maskItemId[1]
end
elseif config.switcher == "geomasks" and config.geomask then
-- switching between items in geomask parameter
args.zoom = nil -- let kartographer determine the zoom
local separator = (mw.ustring.find(config.geomask, "###", 0, true ) and "###") or
(mw.ustring.find(config.geomask, ";", 0, true ) and ";") or ","
local pattern = "%s*"..separator.."%s*"
local maskItems = mw.text.split(mw.ustring.gsub(config.geomask, "SWITCH:", ""), pattern)
local maskLabels = {}
if #maskItems > 1 then
for i, item in ipairs(maskItems) do
table.insert(maskLabels, mw.wikibase.getLabel(item))
end
args.switch = table.concat(maskLabels, "###")
maskItem = "SWITCH:" .. table.concat(maskItems, ",")
end
end
-- resolve geomask item id (if not using geomask switcher)
if not maskItem then --
local maskType = idType(config.geomask)
if maskType == 'item' then
maskItem = config.geomask
elseif maskType == "property" then
maskItem = relatedEntity(wikidataId, config.geomask)
end
end
-- if asking for shape or line from Wikidata
-- and if Wikidata actually has shape/line data (hasOsmRelationId=true)
-- and if no geomask
-- and if zoom not explicitly set
-- and if the object size inferred from its type is not too small
-- then let Kartographer "take over" zoom
if (forceLine or forceShape or (useWikidata and not (suppressShape and suppressLine)))
and hasOsmRelationId and not maskItem and not config.zoom
and not (config.type and tinyType[config.type]) then
args.zoom = nil
end
-- Keep track of arg numbering
Line 201 ⟶ 361:
args["fill"..argNumber] = config["geomask-fill"] or DEFAULT_GEOMASK_FILL
args["fill-opacity"..argNumber] = config["geomask-fill-opacity"] or DEFAULT_SHAPE_FILL_OPACITY
--
if not config.zoom and not config.switcher then
args.zoom = nil
args["frame-coord"] = nil
args["frame-lat"] = nil
args["frame-long"] = nil
local maskArea = getStatementValue( getBestStatement(maskItem, 'P2046') )
end
incrementArgNumber()
-- Hack to fix phab:T255932
if not args.zoom then
args["type"..argNumber] = "line"
args["id"..argNumber] = maskItem
args["stroke-width"..argNumber] = 0
incrementArgNumber()
end
end
-- Shape (or shape-inverse)
if forceShape or (useWikidata and
args["type"..argNumber] = shapeType
if config.id then args["id"..argNumber] = config.id end
Line 227 ⟶ 391:
-- Line
if forceLine or (useWikidata and
args["type"..argNumber] = "line"
if config.id then args["id"..argNumber] = config.id end
Line 245 ⟶ 409:
end
local mapframe = args.switch and mf.multi(args) or mf._main(args)
local tracking = hasOsmRelationId and '' or '[[Category:Infobox mapframe without OSM relation ID on Wikidata]]'
return mapframe .. tracking
|