Modul:OSM
Utseende
Dokumentationen för denna modul kan skapas på Modul:OSM/dok
p={}
require("Modul:Referenshantering")
require("Modul:Debug")
-- Variables to help localisation (i.e. just copy the rest of the code and change here if you want to use the module on another wikipedia language version)
localisation=localisation or {}
localisation.txtCategory='Kategori'
localisation.pipes=localisation.pipes or {}
localisation.pipes.all='allt'
localisation.pipes.ancient='fornminnen'
localisation.pipes.energy='energi'
localisation.pipes.transport='transport'
localisation.pipes.history='historia'
localisation.pipes.education='utbildning'
localisation.pipes.wateractivity='vattenaktivitet'
localisation.pipes.abbeys='kloster'
localisation.pipes.airports='flygplatser'
localisation.pipes.amusementparks='nöjesparker'
localisation.pipes.ancientgraves='forngravar'
localisation.pipes.archaeologicalfinds='arkeologiska fynd'
localisation.pipes.battles='slag'
localisation.pipes.beaches='stränder'
localisation.pipes.bogs='mossar'
localisation.pipes.bridges='broar'
localisation.pipes.castles='herresäten'
localisation.pipes.churches='kyrkor'
localisation.pipes.combustion='förbränning'
localisation.pipes.companies='företag'
localisation.pipes.glacialerratic='flyttblock'
localisation.pipes.harbours='hamnar'
localisation.pipes.hospitals='sjukhus'
localisation.pipes.hotels='hotell'
localisation.pipes.hydropower='vattenkraft'
localisation.pipes.lighthouses='fyrar'
localisation.pipes.mines='gruvor'
localisation.pipes.museums='museum'
localisation.pipes.nuclearpower='kärnkraft'
localisation.pipes.nursinghomes='vårdhem'
localisation.pipes.peaks='höjder'
localisation.pipes.populatedplaces='bebodda platser'
localisation.pipes.quarries='stenbrott'
localisation.pipes.restaurants='restauranger'
localisation.pipes.schools='skolor'
localisation.pipes.seniorhomes='äldreboenden'
localisation.pipes.settlements_localdefinition='tätorter'
localisation.pipes.sieges='belägringar'
localisation.pipes.solarpower='solkraft'
localisation.pipes.sportsvenues='sport'
localisation.pipes.springs='källor'
localisation.pipes.stations='stationer'
localisation.pipes.theatres='teatrar'
localisation.pipes.towns='städer'
localisation.pipes.trade='handel'
localisation.pipes.universities='universitet'
localisation.pipes.villages='byar'
localisation.pipes.wastewater='reningsverk'
localisation.pipes.waterfalls='vattenfall'
localisation.pipes.waterworks='vattenverk'
localisation.pipes.watermills='vattenkvarnar'
localisation.pipes.windpower='vindkraft'
localisation.pipes.ferryroutes='färjeleder'
localisation.pipes.railroads='järnvägar'
localisation.pipes.roads='vägar'
localisation.pipes.watercourses='vattendrag'
localisation.pipes.lakes='sjöar'
localisation.pipes.naturereserves='naturreservat'
localisation.arguments=localisation.arguments or {}
localisation.arguments.longitude="longitud"
localisation.arguments.latitude="latitud"
localisation.arguments.width="bredd"
localisation.arguments.height="höjd"
localisation.arguments.area="area"
localisation.arguments.connectingline="järnvägslinje"
localisation.arguments.diocese='stift'
localisation.arguments.mountainrange='bergskedja'
localisation.arguments.partof="delav"
localisation.arguments.place="plats"
localisation.arguments.water="vatten"
localisation.maintenance=localisation.maintenance or {}
localisation.maintenance.allalternatives='Artiklar som visar OSM-karta med alla alternativ'
localisation.maintenance.noname='Namn inte inlagt'
p.iCounter=0
p.allowedTypes = {}
p.allowedTypesLines={}
p.allowedTypesShapes={}
p.icon_instances={}
p.icon_symbols={}
p.icon_colours={}
p.line_instances={}
p.line_widths={}
p.line_colours={}
p.shape_instances={}
p.shape_widths={}
p.shape_opacities={}
p.shape_colours={}
local txtBaseTitle="BIND(CONCAT('[[', COALESCE(SUBSTR(STR(?article), 31),'" .. localisation.maintenance.noname .. "'), '|', COALESCE(?idLabel,'" .. localisation.maintenance.noname .. "'), ']]') AS ?title)"
local txtOptionalAddition=""
local txtBaseQueryIcons = [=[SELECT DISTINCT ?geo ?id ?title (%s) as ?marker_symbol) (%s) as ?marker_color) ('small' as ?marker_size) WHERE {?id p:P31 ?typeStatement. ?typeStatement ps:P31 ?type. ?id wdt:P625 ?geo; wdt:%s ?qids. VALUES ?qids { %s } %s %s VALUES ?allowedTypes { %s } FILTER (?type IN (?allowedTypes)) OPTIONAL { ?article schema:about ?id; schema:inLanguage 'sv'; schema:isPartOf <https://sv.wikipedia.org/>. } %s SERVICE wikibase:label { bd:serviceParam wikibase:language '%s'. ?id rdfs:label ?idLabel. ?type rdfs:label ?typeLabel. } %s } ORDER BY ?type]=]
local txtBaseQueryLines = [=[SELECT DISTINCT ?id ?title (%s) as ?line_width) (%s) as ?line_color) WHERE {?id p:P31 ?typeStatement. ?typeStatement ps:P31 ?type. ?id wdt:%s ?qids. VALUES ?qids { %s } %s %s VALUES ?allowedTypes { %s } FILTER (?type IN (?allowedTypes)) OPTIONAL { ?article schema:about ?id; schema:inLanguage 'sv'; schema:isPartOf <https://sv.wikipedia.org/>. } %s SERVICE wikibase:label { bd:serviceParam wikibase:language '%s'. ?id rdfs:label ?idLabel. ?type rdfs:label ?typeLabel. } %s } ORDER BY ?type]=]
local txtBaseQueryShapes = [=[SELECT DISTINCT ?id ?title (%s) as ?line_width) (%s) as ?fill_color) (%s) as ?fill_opacity) WHERE {?id p:P31 ?typeStatement. ?typeStatement ps:P31 ?type. ?id wdt:%s ?qids. VALUES ?qids { %s } %s %s VALUES ?allowedTypes { %s } FILTER (?type IN (?allowedTypes)) OPTIONAL { ?article schema:about ?id; schema:inLanguage 'sv'; schema:isPartOf <https://sv.wikipedia.org/>. } %s SERVICE wikibase:label { bd:serviceParam wikibase:language '%s'. ?id rdfs:label ?idLabel. ?type rdfs:label ?typeLabel. } %s } ORDER BY ?type]=]
local txtBaseActiveOnly = "FILTER NOT EXISTS { ?id wdt:P576 [] } FILTER NOT EXISTS { ?type pq:P582 [] } FILTER NOT EXISTS { ?typeStatement pq:P582 [] }"
local txtBaseActive = "FILTER NOT EXISTS { ?id wdt:P576 [] }"
local txtBaseInactive = "?id wdt:P576 []"
kartpositionmall = {
Ryssland = 'Ryssland3',
Sverige = 'Sverige3',
USA = 'USA2'
}
-- Define a "class" (a table with methods and a constructor)
local Colour = {}
Colour.__index = Colour
-- Constructor function
function Colour:new(red,green,blue)
local instance = setmetatable({}, Colour)
-- Ensure values are within the valid range (0-255)
instance.red = math.max(0, math.min(255, red))
instance.green = math.max(0, math.min(255, green))
instance.blue = math.max(0, math.min(255, blue))
return instance
end
-- Add a fade method to the Colour class
function Colour:fade(fadeFactor)
-- Ensure fadeFactor is between 0 and 1
fadeFactor = math.min(1, math.max(0, fadeFactor or 0.7))
-- Calculate faded RGB values
local fadedR = math.floor(self.red + (255 - self.red) * fadeFactor)
local fadedG = math.floor(self.green + (255 - self.green) * fadeFactor)
local fadedB = math.floor(self.blue + (255 - self.blue) * fadeFactor)
-- Create and return a new Colour object with the faded values
return Colour:new(fadedR, fadedG, fadedB)
end
-- Method
function Colour:html()
-- Convert each component to a two-digit hexadecimal string
local hexRed = string.format("%02x", self.red)
local hexGreen = string.format("%02x", self.green)
local hexBlue = string.format("%02x", self.blue)
-- Concatenate and return the result
return "#" .. hexRed .. hexGreen .. hexBlue
end
_black=Colour:new(0, 0, 0)
_white=Colour:new(255, 255, 255)
_red=Colour:new(128,0,0)
_green=Colour:new(0,128,0)
_grey=Colour:new(12,128,128)
_blue=Colour:new(0, 0, 128)
_gold=Colour:new(128, 128, 0)
_brown=Colour:new(139, 69, 19) --"#8B4513"
_strongred=Colour:new(170, 0, 0)
_strongblue=Colour:new(0, 0, 170)
_educationcolour=Colour:new(69, 19, 139) -- "#45138B"
_historicalcolour=Colour:new(139, 69, 19) --"#8B4513"
_roadcolour=_historicalcolour -- Colour:new(240, 194, 121) --"#F0C279"
_sportscolour=Colour:new(232, 122,23) --"#E87A17"
_economycolour=Colour:new(240, 194, 121)
_beachcolour=Colour:new(210, 170, 120) -- #D2AA78
_lighthousecolour=Colour:new(127, 179, 224) --#7FB3E0
_mountaincolour=_historicalcolour --#8B4513
colourInverseFill=Colour:new(221, 221, 221) --'#dddddd'
colourInverseStroke=Colour:new(34, 34, 34) --'#222222'
_basincolour=Colour:new(255, 255, 0) -- #FFFF00
boggreen=Colour:new(138, 154, 91) -- #8A9A5B
-- Non-language settings
settings=settings or {}
settings.width=250
settings.height=250
settings.paths={}
settings.paths.width={}
settings.paths.width.main=5
settings.paths.width.tributary=1
settings.paths.colour={}
settings.paths.colour.rivers=_blue
settings.areas={}
settings.areas.width=1
settings.areas.lake_opacity=0.5
settings.pipes={}
settings.pipes.settlement_localdefinition='Q12813115'
settings.languages="mul, sv, da, no, en"
-- p.addSurroundings
-- Fills a map with icons based on sparql-queries (created by the function listed under FUNCTIONS TO ADD VARIOUS ICONS/SHADED AREA TO MAPS below). The sparql query will find objects that has a relevant p.pid (like P206 for bodies of water) set to qid.
-- The icons it returns is determined by the content of args
--
-- Arguments:
-- qid [string] id of the relevant wikidata object
-- args [array] what will be shown on the map (the function will check the content of this array against )
p.addSurroundings=function(qids,args)
local checkconditions=true
local conditionNo=1
p.filter=''
while args['condition' .. conditionNo] do
p.addFilter(args["condition" .. conditionNo])
conditionNo=conditionNo+1
end
if (bHasArgument(args,'ancient') or bHasArgument(args,localisation.pipes.ancient)) then -- Adds ancient monuments
p.addIcons('ancient')
end
if (bHasArgument(args,'education') or bHasArgument(args,localisation.pipes.education)) then -- Adds educational institutions
p.addIcons('schools')
p.addIcons('universities')
end
if (bHasArgument(args,'energy') or bHasArgument(args,localisation.pipes.energy)) then -- Adds all type of energy extraction units
p.addIcons('hydropower')
p.addIcons('nuclearpower')
p.addIcons('solarpower')
p.addIcons('windpower')
p.addIcons('combustion')
end
if (bHasArgument(args,'history') or bHasArgument(args,localisation.pipes.history)) then
p.addIcons('abbeys')
p.addIcons('battles')
p.addIcons('castles')
p.addIcons('churches')
end
if (bHasArgument(args,'transport') or bHasArgument(args,localisation.pipes.transport)) then -- Adds airports, ports, railway stations
-- points
p.addIcons('airports')
p.addIcons('harbours')
p.addIcons('stations')
p.addIcons('bridges')
-- lines
p.addLines('roads')
p.addLines('railroads')
p.addLines('ferryroutes')
end
if (bHasArgument(args,'wateractivity') or bHasArgument(args,localisation.pipes.wateractivity)) then -- Add hydropower plants
p.addIcons('hydropower')
p.addIcons('beaches')
p.addIcons('lighthouses')
p.addIcons('waterfalls')
p.addIcons('watermills')
p.addIcons('wastewater')
p.addIcons('waterworks')
-- p.addWatercourses()
end
if (bHasArgument(args,'abbeys') or bHasArgument(args,localisation.pipes.abbeys)) then
p.addIcons('abbeys')
end
if (bHasArgument(args,'ancientgraves') or bHasArgument(args,localisation.pipes.ancientgraves)) then -- Adds ancient graves
p.addIcons('ancientgraves')
end
if (bHasArgument(args,'airports') or bHasArgument(args,localisation.pipes.airports)) then
p.addIcons('airports')
end
if (bHasArgument(args,'amusementparks') or bHasArgument(args,localisation.pipes.amusementparks)) then
p.addIcons('amusementparks')
end
if (bHasArgument(args,'archaeologicalfinds') or bHasArgument(args,localisation.pipes.archaeologicalfinds)) then
p.addIcons('archaeologicalfinds')
end
if (bHasArgument(args,'battles') or bHasArgument(args,localisation.pipes.battles) or bHasArgument(args,'all') or bHasArgument(args,localisation.pipes.all)) then -- Adds battles
p.addIcons('battles')
end
if (bHasArgument(args,'beaches') or bHasArgument(args,localisation.pipes.beaches) or bHasArgument(args,'all') or bHasArgument(args,localisation.pipes.all)) then -- Adds beaches
p.addIcons('beaches')
end
if (bHasArgument(args,'bogs') or bHasArgument(args,localisation.pipes.bogs)) then -- Adds bogs
p.addShapes('bogs')
end
if (bHasArgument(args,'bridges') or bHasArgument(args,localisation.pipes.bridges) or bHasArgument(args,'all') or bHasArgument(args,localisation.pipes.all)) then
p.addIcons('bridges')
end
if (bHasArgument(args,'castles') or bHasArgument(args,localisation.pipes.castles) or bHasArgument(args,'all') or bHasArgument(args,localisation.pipes.all)) then -- Adds castles
p.addIcons('castles')
end
if (bHasArgument(args,'churches') or bHasArgument(args,localisation.pipes.churches) or bHasArgument(args,'all') or bHasArgument(args,localisation.pipes.all)) then
p.addIcons('churches')
end
if (bHasArgument(args,'combustion') or bHasArgument(args,localisation.pipes.combustion)) then
p.addIcons('combustion')
end
if (bHasArgument(args,'companies') or bHasArgument(args,localisation.pipes.companies) or bHasArgument(args,'all') or bHasArgument(args,localisation.pipes.all)) then
p.addIcons('companies')
end
if (bHasArgument(args,'ferryroutes') or bHasArgument(args,localisation.pipes.ferryroutes)) then
p.addLines('ferryroutes')
end
if (bHasArgument(args,'glacialerratic') or bHasArgument(args,localisation.pipes.glacialerratic)) then -- Adds quarries
p.addIcons('glacialerratic')
end
if (bHasArgument(args,'harbours') or bHasArgument(args,localisation.pipes.harbours) or bHasArgument(args,'all') or bHasArgument(args,localisation.pipes.all)) then
p.addIcons('harbours')
end
if (bHasArgument(args,'hospitals') or bHasArgument(args,localisation.pipes.hospitals) or bHasArgument(args,'all') or bHasArgument(args,localisation.pipes.all)) then -- Adds hospitals
p.addIcons('hospitals')
end
if (bHasArgument(args,'hotels') or bHasArgument(args,localisation.pipes.hotels)) then
p.addIcons('hotels')
end
if (bHasArgument(args,'hydropower') or bHasArgument(args,localisation.pipes.hydropower) or bHasArgument(args,'all') or bHasArgument(args,localisation.pipes.all)) then -- Add hydropower plants
p.addIcons('hydropower')
end
if (bHasArgument(args,'lakes') or bHasArgument(args,localisation.pipes.lakes)) then
p.addAreas('lakes')
end
if (bHasArgument(args,'lighthouses') or bHasArgument(args,localisation.pipes.lighthouses)) then
p.addIcons('lighthouses')
end
if (bHasArgument(args,'mines') or bHasArgument(args,localisation.pipes.mines)) then -- Adds mines
p.addIcons('mines')
end
if (bHasArgument(args,'museums') or bHasArgument(args,localisation.pipes.museums) or bHasArgument(args,'all') or bHasArgument(args,localisation.pipes.all)) then -- Adds educational institutions
p.addIcons('museums')
end
if (bHasArgument(args,'naturereserves') or bHasArgument(args,localisation.pipes.naturereserves) or bHasArgument(args,'all') or bHasArgument(args,localisation.pipes.all)) then
p.addAreas('naturereserves')
end
if (bHasArgument(args,'nursinghomes') or bHasArgument(args,localisation.pipes.nursinghomes)) then -- Adds hospitals
p.addIcons('nursinghomes')
end
if (bHasArgument(args,'peaks') or bHasArgument(args,localisation.pipes.peaks)) then
p.addIcons('peaks')
end
if (bHasArgument(args,'populatedplaces') or bHasArgument(args,localisation.pipes.populatedplaces)) then
p.addIcons('populatedplaces')
end
if (bHasArgument(args,'quarries') or bHasArgument(args,localisation.pipes.quarries)) then -- Adds quarries
p.addIcons('quarries')
end
if (bHasArgument(args,'railroads') or bHasArgument(args,localisation.pipes.railroads)) then
p.addLines('railroads')
end
if (bHasArgument(args,'restaurants') or bHasArgument(args,localisation.pipes.restaurants)) then
p.addIcons('restaurants')
end
if (bHasArgument(args,'roads') or bHasArgument(args,localisation.pipes.roads)) then
p.addLines('roads')
end
if (bHasArgument(args,'schools') or bHasArgument(args,localisation.pipes.schools) or bHasArgument(args,'all') or bHasArgument(args,localisation.pipes.all)) then -- Adds educational institutions
p.addIcons('schools')
end
if (bHasArgument(args,'sieges') or bHasArgument(args,localisation.pipes.sieges)) then -- Adds sieges
p.addIcons('sieges')
end
if (bHasArgument(args,'seniorhomes') or bHasArgument(args,localisation.pipes.seniorhomes)) then -- Adds senior homes
p.addIcons('seniorhomes')
end
if (bHasArgument(args,localisation.pipes.settlements_localdefinition)) then
p.addIcons('settlements_localdefinition')
end
if (bHasArgument(args,'solarpower') or bHasArgument(args,localisation.pipes.solarpower)) then
p.addIcons('solarpower')
end
if (bHasArgument(args,'sportsvenues') or bHasArgument(args,localisation.pipes.sportsvenues) or bHasArgument(args,'all') or bHasArgument(args,localisation.pipes.all)) then -- Adds sports venue
p.addIcons('sportsvenues')
end
if (bHasArgument(args,'springs') or bHasArgument(args,localisation.pipes.springs)) then
p.addIcons('springs')
end
if (bHasArgument(args,'stations') or bHasArgument(args,localisation.pipes.stations) or bHasArgument(args,'all') or bHasArgument(args,localisation.pipes.all)) then
p.addIcons('stations')
end
if (bHasArgument(args,'theatres') or bHasArgument(args,localisation.pipes.theatres) or bHasArgument(args,'all') or bHasArgument(args,localisation.pipes.all)) then -- Adds hospitals
p.addIcons('theatres')
end
if (bHasArgument(args,'towns') or bHasArgument(args,localisation.pipes.towns) or bHasArgument(args,'settlements') or bHasArgument(args,'all') or bHasArgument(args,localisation.pipes.all)) then
p.addIcons('towns')
end
if (bHasArgument(args,'trade') or bHasArgument(args,localisation.pipes.trade) or bHasArgument(args,'all') or bHasArgument(args,localisation.pipes.all)) then
p.addIcons('trade')
end
if (bHasArgument(args,'universities') or bHasArgument(args,localisation.pipes.universities)) then -- Adds educational institutions
p.addIcons('universities')
end
if (bHasArgument(args,'villages') or bHasArgument(args,localisation.pipes.villages) or bHasArgument(args,'settlements') or bHasArgument(args,'all') or bHasArgument(args,localisation.pipes.all)) then
p.addIcons('villages')
end
if (bHasArgument(args,'wastewater') or bHasArgument(args,localisation.pipes.wastewater)) then
p.addIcons('wastewater')
end
if (bHasArgument(args,'watercourses') or bHasArgument(args,localisation.pipes.watercourses)) then
p.addLines('watercourses')
end
if (bHasArgument(args,'waterfalls') or bHasArgument(args,localisation.pipes.waterfalls)) then -- Adds water fall
p.addIcons('waterfalls')
end
if (bHasArgument(args,'watermills') or bHasArgument(args,localisation.pipes.watermills) or bHasArgument(args,'all') or bHasArgument(args,localisation.pipes.all)) then -- Adds watermills
p.addIcons('watermills')
end
if (bHasArgument(args,'waterworks') or bHasArgument(args,localisation.pipes.waterworks)) then
p.addIcons('waterworks')
end
if (bHasArgument(args,'windpower') or bHasArgument(args,localisation.pipes.windpower)) then -- Add hydropower plants
p.addIcons('windpower')
end
local qidValues = {}
for qid in pairs(qids) do
table.insert(qidValues, string.format("wd:%s", qid))
end
p.qidValuesStr = table.concat(qidValues, " ")
p.onlyActive=args["onlyactive"];
local txtContent=p.buildSparqlQueryIcons() .. p.buildSparqlQueryShapes()
if (not bHasArgument(args,'all')) or (not bHasArgument(args,localisation.pipes.showlines)) then
txtContent=txtContent .. p.buildSparqlQueryLines()
end
return txtContent
end
-- p.addQueriedLocations
-- Creates a sparql-query that returns point objects (like cities, battles etc.). The sparql-query is then used to create a mapframe block.
--
-- Arguments:
-- qid [string] id of the relevant wikidata object
-- iInstanceOf [string] what the returned items should be an instance of (so for example Q159719 for power stations)
-- txtIcon [string] icon shown (see https://www.mediawiki.org/wiki/Help:Extension:Kartographer/Icons for available icons)
-- txtIconSize [number] icon size (usually small)
-- txtIconColour [string] icon rgb colour
p.addQueriedLocations=function (iInstanceOf,txtIcon,txtIconSize,colourIcon)
table.insert(p.allowedTypes, "wd:" .. iInstanceOf)
table.insert(p.icon_instances,iInstanceOf)
table.insert(p.icon_symbols,txtIcon)
table.insert(p.icon_colours,colourIcon)
end
--p.addQueriedLines
-- Create a sparql-query that returns line objects (like water courses). The sparql-query is then used to create a mapframe block.
--
-- Arguments:
-- qid [string] id of the relevant wikidata object
-- iInstanceOf [string] what the returned items should be an instance of (so for example Q159719 for power stations)
-- iWidth [number] width of border in pixels
-- txColour [string] icon colour
p.addQueriedLines=function (iInstanceOf,iWidth,colour)
table.insert(p.allowedTypesLines, "wd:" .. iInstanceOf)
table.insert(p.line_instances,iInstanceOf)
table.insert(p.line_widths,iWidth)
table.insert(p.line_colours,colour)
end
--p.addQueriedAreas
-- Create a sparql-query that returns area objects (like countries or nature reserves). The sparql-query is then used to create a mapframe block.
--
-- Arguments:
-- qid [string] id of the relevant wikidata object
-- iInstanceOf [string] what the returned items should be an instance of (so for example Q159719 for power stations)
-- iWidth [number] width of border in pixels
-- txColour [string] icon colour
p.addQueriedAreas=function (iInstanceOf,iWidth,colour,fOpacity)
table.insert(p.allowedTypesShapes, "wd:" .. iInstanceOf)
table.insert(p.shape_instances,iInstanceOf)
table.insert(p.shape_widths,iWidth)
table.insert(p.shape_colours,colour)
table.insert(p.shape_opacities,fOpacity)
-- table.insert(p.widthShapes, string.format("?type = wd:%s, '%s'", iInstanceOf, iWidth))
-- table.insert(p.colourShapes, string.format("?type = wd:%s, '%s'", iInstanceOf, colour:html()))
-- table.insert(p.opacityShapes, string.format("?type = wd:%s, %s", iInstanceOf, fOpacity))
end
local function mergeTables(table1, table2, formatString, methodChain)
local mergedTable = {}
for i = 1, math.min(#table1, #table2) do
local arg1 = table1[i]
local arg2 = table2[i]
-- Apply the method chain to arg2 (e.g., arg2:fade(0.5):html())
if methodChain then
for method in methodChain:gmatch("[^:]+") do
-- Extract method name and arguments (if any)
local methodName, argsStr = method:match("^([%a%_]+)(%b())$")
methodName = methodName or method -- No arguments
-- Parse arguments manually (e.g., "0.5" from "fade(0.5)")
local args = {}
if argsStr then
-- Remove parentheses and split by commas
local argsContent = argsStr:sub(2, -2)
for arg in argsContent:gmatch("[^%,%s]+") do
-- Convert to number if possible, otherwise keep as string
local num = tonumber(arg)
table.insert(args, num or arg)
end
end
-- Call the method on arg2
if type(arg2[methodName]) == "function" then
if #args > 0 then
arg2 = arg2[methodName](arg2, unpack(args))
else
arg2 = arg2[methodName](arg2)
end
end
end
end
-- Insert the formatted string into the merged table
table.insert(mergedTable, string.format(formatString, arg1, arg2))
end
return mergedTable
end
local function buildNestedIfLogic(conditions, defaultValue)
-- Start with the last condition and the default value
local nestedIf = string.format("if (%s, '%s'", conditions[#conditions], defaultValue)
-- For each preceding condition, nest it as the "else" part of the next
for i = #conditions - 1, 1, -1 do
nestedIf = string.format("if(%s, %s)", conditions[i], nestedIf)
end
return nestedIf
end
p.buildSparqlQueryIcons=function()
if p.icon_instances and (not (next(p.icon_instances) == nil)) then
local allowedTypesStr = table.concat(p.allowedTypes, " ")
local symbolLogic = mergeTables(
p.icon_instances,
p.icon_symbols,
"?type = wd:%s, '%s'" -- Format string
)
local colourLogicActive = mergeTables(
p.icon_instances,
p.icon_colours,
"?type = wd:%s, '%s'", -- Format string
"html" -- Method chain: call :html()
)
local colourLogicInactive = mergeTables(
p.icon_instances,
p.icon_colours,
"?type = wd:%s, '%s'", -- Format string
"fade():html" -- Method chain: call :html()
)
local symbolLogicStr = buildNestedIfLogic(symbolLogic, "square")
local colourLogicActiveStr = buildNestedIfLogic(colourLogicActive, "#000000")
local colourLogicInactiveStr = buildNestedIfLogic(colourLogicInactive, "#000000")
if (p.onlyActive) then
local txtQuery = string.format(txtBaseQueryIcons, symbolLogicStr, colourLogicActiveStr, p.pid, p.qidValuesStr, p.filter, txtBaseActiveOnly, allowedTypesStr, txtOptionalAddition, settings.languages, txtBaseTitle)
return p.addMapContent ("{" .. p.addArgument("type","ExternalData") .. " ," .. p.addArgument("service","geopoint") .. " ," ..p.addArgument("query",txtQuery) .. "}" )
else
local txtQuery = string.format(txtBaseQueryIcons, symbolLogicStr, colourLogicActiveStr, p.pid, p.qidValuesStr, p.filter, txtBaseActive, allowedTypesStr, txtOptionalAddition, settings.languages, txtBaseTitle)
local txtReturn=p.addMapContent ("{" .. p.addArgument("type","ExternalData") .. " ," .. p.addArgument("service","geopoint") .. " ," ..p.addArgument("query",txtQuery) .. "}" )
txtQuery = string.format(txtBaseQueryIcons, symbolLogicStr, colourLogicInactiveStr, p.pid, p.qidValuesStr, p.filter, txtBaseInactive, allowedTypesStr, txtOptionalAddition, settings.languages, txtBaseTitle)
txtReturn=txtReturn .. p.addMapContent ("{" .. p.addArgument("type","ExternalData") .. " ," .. p.addArgument("service","geopoint") .. " ," ..p.addArgument("query",txtQuery) .. "}" )
return txtReturn
end
else
return ""
end
end
p.buildSparqlQueryLines=function()
if p.line_instances and (not (next(p.line_instances) == nil)) then
local allowedTypesStr = table.concat(p.allowedTypesLines, " ")
local widthLines = mergeTables(
p.line_instances,
p.line_widths,
"?type = wd:%s, %s" -- Format string
)
local colourLogicActive = mergeTables(
p.line_instances,
p.line_colours,
"?type = wd:%s, '%s'", -- Format string
"html" -- Method chain: call :html()
)
local colourLogicInactive = mergeTables(
p.line_instances,
p.line_colours,
"?type = wd:%s, '%s'", -- Format string
"fade():html" -- Method chain: call :html()
)
local widthStr = buildNestedIfLogic(widthLines, 1)
local colourLogicActiveStr = buildNestedIfLogic(colourLogicActive, "#000000")
local colourLogicInactiveStr = buildNestedIfLogic(colourLogicInactive, "#000000")
if (p.onlyActive) then
local txtQuery = string.format(txtBaseQueryLines, widthStr, colourLogicActiveStr, p.pid, p.qidValuesStr, p.filter, txtBaseActiveOnly, allowedTypesStr, txtOptionalAddition, settings.languages, txtBaseTitle)
return p.addMapContent ("{" .. p.addArgument("type","ExternalData") .. " ," .. p.addArgument("service","geoline") .. " ," ..p.addArgument("query",txtQuery) .. "}" )
else
local txtQuery = string.format(txtBaseQueryLines, widthStr, colourLogicActiveStr, p.pid, p.qidValuesStr, p.filter, txtBaseActive, allowedTypesStr, txtOptionalAddition, settings.languages, txtBaseTitle)
local txtReturn=p.addMapContent ("{" .. p.addArgument("type","ExternalData") .. " ," .. p.addArgument("service","geoline") .. " ," ..p.addArgument("query",txtQuery) .. "}" )
txtQuery = string.format(txtBaseQueryLines, widthStr, colourLogicInactiveStr, p.pid, p.qidValuesStr, p.filter, txtBaseInactive, allowedTypesStr, txtOptionalAddition, settings.languages, txtBaseTitle)
txtReturn=txtReturn .. p.addMapContent ("{" .. p.addArgument("type","ExternalData") .. " ," .. p.addArgument("service","geoline") .. " ," ..p.addArgument("query",txtQuery) .. "}" )
return txtReturn
end
else
return ""
end
end
p.buildSparqlQueryShapes=function()
if p.shape_instances and (not (next(p.shape_instances) == nil)) then
local allowedTypesStr = table.concat(p.allowedTypesShapes, " ")
local widthShapes = mergeTables(
p.shape_instances,
p.shape_widths,
"?type = wd:%s, %s" -- Format string
)
local colourLogicActive = mergeTables(
p.shape_instances,
p.shape_colours,
"?type = wd:%s, '%s'", -- Format string
"html" -- Method chain: call :html()
)
local colourLogicInactive = mergeTables(
p.shape_instances,
p.shape_colours,
"?type = wd:%s, '%s'", -- Format string
"fade():html" -- Method chain: call :html()
)
local opacityShapes = mergeTables(
p.shape_instances,
p.shape_opacities,
"?type = wd:%s, %s" -- Format string
)
local widthStr = buildNestedIfLogic(widthShapes, "1")
local colourLogicActiveStr = buildNestedIfLogic(colourLogicActive, "#000000")
local colourLogicInactiveStr = buildNestedIfLogic(colourLogicInactive, "#000000")
local opacityStr = buildNestedIfLogic(opacityShapes, 1)
if (p.onlyActive) then
local txtQuery = string.format(txtBaseQueryShapes, widthStr, colourLogicActiveStr, opacityStr, p.pid, p.qidValuesStr, p.filter, txtBaseActiveOnly, allowedTypesStr, txtOptionalAddition, settings.languages, txtBaseTitle)
return p.addMapContent ("{" .. p.addArgument("type","ExternalData") .. " ," .. p.addArgument("service","geoshape") .. " ," ..p.addArgument("query",txtQuery) .. "}" )
else
local txtQuery = string.format(txtBaseQueryShapes, widthStr, colourLogicActiveStr, opacityStr, p.pid, p.qidValuesStr, p.filter, txtBaseActive, allowedTypesStr, txtOptionalAddition, settings.languages, txtBaseTitle)
local txtReturn=p.addMapContent ("{" .. p.addArgument("type","ExternalData") .. " ," .. p.addArgument("service","geoshape") .. " ," ..p.addArgument("query",txtQuery) .. "}" )
txtQuery = string.format(txtBaseQueryShapes, widthStr, colourLogicInactiveStr, opacityStr, p.pid, p.qidValuesStr, p.filter, txtBaseInactive, allowedTypesStr, txtOptionalAddition, settings.languages, txtBaseTitle)
txtReturn=txtReturn .. p.addMapContent ("{" .. p.addArgument("type","ExternalData") .. " ," .. p.addArgument("service","geoshape") .. " ," ..p.addArgument("query",txtQuery) .. "}" )
return txtReturn
end
else
return ""
end
end
p.addIconWD=function(qid,colour,txtIcon,txtTitle,txtSitelink)
if (txtTitle) then
if txtSitelink then
txtTitle="[["..txtSitelink.."|"..txtTitle.."]]"
end
return p.addMapContent ("{" .. p.addArgument("type","ExternalData") .. " ," .. p.addArgument("service","geopoint") .. " ," ..p.addArgument("ids",qid) .. " , \"properties\":{"..p.addArgument("title",txtTitle) .. " ," .. p.addArgument("marker-color",colour:html()) .. " ," .. p.addArgument("marker-symbol",txtIcon) .. " ," .. p.addArgument("marker-size","small") .. "} }" )
else
return p.addMapContent ("{" .. p.addArgument("type","ExternalData") .. " ," .. p.addArgument("service","geopoint") .. " ," ..p.addArgument("ids",qid) .. " , \"properties\":{"..p.addArgument("marker-color",colour:html()) .. " ," .. p.addArgument("marker-symbol",txtIcon) .. " ," .. p.addArgument("marker-size","small") .. "} }" )
end
end
-- p.addLineWD
-- Adds a line for a specific wikidata object (given by qid)
--
-- Arguments:
-- qid [string] id of the relevant wikidata object
-- txColour [string] line colour
-- iWidth [number] width of line in pixels
-- txtTitle [string] title for the line shown on the map
-- txtSitelink [string] article on the local wikipedia that the title links to
p.addLineWD=function(qid,colour,iWidth,txtTitle,txtSitelink)
if (txtTitle) then
if txtSitelink then
txtTitle="[["..txtSitelink.."|"..txtTitle.."]]"
end
return p.addMapContent ("{" .. p.addArgument("type","ExternalData") .. " ," .. p.addArgument("service","geoline") .. " ," ..p.addArgument("ids",qid) .. " , \"properties\":{"..p.addArgument("title",txtTitle) .. " ," .. p.addArgument("stroke",colour:html()) .. " ," .. p.addArgumentNoQuote("stroke-width",iWidth) .. "} }" )
else
return p.addMapContent ("{" .. p.addArgument("type","ExternalData") .. " ," .. p.addArgument("service","geoline") .. " ," ..p.addArgument("ids",qid) .. " , \"properties\":{"..p.addArgument("stroke",colour:html()) .. " ," .. p.addArgumentNoQuote("stroke-width",iWidth) .. "} }" )
end
end
-- p.addAreaWD
-- Adds an area for a specific wikidata object (given by qid)
--
-- Arguments:
-- qid [string] id of the relevant wikidata object
-- txColour [string] fill colour
-- iWidth [number] width of border in pixels
-- fFillOpacity [number] opacity of the area
-- txtTitle [string] title for the line shown on the map
-- txtSitelink [string] article on the local wikipedia that the title links to
p.addAreaWD=function(qid,colour,iWidth,fFillOpacity,txtTitle,txtSitelink)
if (txtTitle) then
if (txtSitelink) then
txtTitle="[["..txtSitelink.."|"..txtTitle.."]]"
end
return p.addMapContent ("{" .. p.addArgument("type","ExternalData") .. " ," .. p.addArgument("service","geoshape") .. " ," ..p.addArgument("ids",qid) .. " , \"properties\":{"..p.addArgument("title",txtTitle) .. " ," .. p.addArgument("stroke",colour:html()) .. " ," .. p.addArgumentNoQuote("stroke-width",iWidth) .. " ," .. p.addArgumentNoQuote("fill-opacity",fFillOpacity).. "} }")
else
return p.addMapContent ("{" .. p.addArgument("type","ExternalData") .. " ," .. p.addArgument("service","geoshape") .. " ," ..p.addArgument("ids",qid) .. " , \"properties\":{"..p.addArgument("stroke",colour:html()) .. " ," .. p.addArgumentNoQuote("stroke-width",iWidth) .. " ," .. p.addArgumentNoQuote("fill-opacity",fFillOpacity).. "} }")
end
end
-- p.addAreaCommons
-- Adds an area from a specific commons file (given by filename)
--
-- txtFilename [string] filename (without "Data:")
-- txColour [string] fill colour
-- iWidth [string] width of border in pixels
-- fOpacity [string] opacity of the area
p.addAreaCommons=function(txtFilename)
return p.addMapContent("{" .. p.addArgument("type","ExternalData") .. " ," .. p.addArgument("service","page") .. " ," ..p.addArgument("title",txtFilename) .. "}")
end
p.addAreaCommonsId=function(qid)
local txtFullFilename=readProperty(qid,"P3896")
if (txtFullFilename) then
local txtFilename=string.sub(txtFullFilename,6)
if txtFilename then
return p.addAreaCommons(txtFilename)
end
end
return ""
end
p.addFilter=function(condition)
local txtRelation,txtProperty,txtValue = getComparisonOperator(condition)
if (txtRelation) then
p.filter=p.filter.."?id wdt:" .. txtProperty .. " ?" .. txtProperty .. " . " .. "FILTER(?" .. txtProperty .." " .. txtRelation .. " " .. txtValue .. ")"
end
end
-- Check for comparison characters
function getComparisonOperator(str)
local found = {}
local positions = {}
-- Check for each character and record their positions
for char in pairs({[">"] = true, ["<"] = true, ["="] = true}) do
local pos = str:find(char, 1, true) -- plain search (no regex)
if pos then
table.insert(found, char)
table.insert(positions, pos)
end
end
-- Return nil if not exactly one operator is found
if #found ~= 1 then
return nil, nil, nil
end
local op = found[1]
local pos = positions[1]
local before = str:sub(1, pos - 1)
local after = str:sub(pos + 1)
return op, before, after
end
-- Function to find rows where column `col` has value `value`
local function findRowsByColumn(matrix, col, value)
local result = {}
for i, row in ipairs(matrix) do
if row[col] == value then
-- table.insert(result, i) -- Store the row index
table.insert(result, row) -- Store the row index
end
end
if not(isempty(result)) then
return result
else
return false
end
end
local function getPropertyType(pid)
local property = mw.wikibase.getEntity(pid)
if property then
return property.datatype
else
return nil
end
end
local function propertyToSparql(pid, propertyType)
local varVal = "?_val_" .. pid
local varLabel = "?_label_" .. pid
local varFormatted = "?_formatted_" .. pid
-- SPARQL to bind the raw value and label
local optionalClause = string.format([[
OPTIONAL { ?item wdt:P%s %s. }
OPTIONAL { %s rdfs:label %s. FILTER(LANG(%s) = "en") }
]], pid, varVal, varVal, varLabel, varLabel)
-- SPARQL to format the value based on its type
local bindClause
if propertyType == "time" then
bindClause = string.format([[
BIND(
COALESCE(
(IF(BOUND(%s),
CONCAT(STRYEAR(%s), "-", STRMONTH(%s), "-", STRDAY(%s)),
NULL
)),
(STR(%s)),
"?"
) AS %s
)
]], varVal, varVal, varVal, varVal, varVal, varFormatted)
elseif propertyType == "quantity" then
bindClause = string.format([[
BIND(
COALESCE(
(IF(BOUND(%s),
CONCAT(STR(%s), " ", %s),
NULL
)),
(STR(%s)),
"?"
) AS %s
)
]], varVal, varVal, varLabel, varVal, varFormatted)
elseif propertyType == "wikibase-item" then
bindClause = string.format([[
BIND(
COALESCE(
(STR(%s)),
(STR(%s)),
"?"
) AS %s
)
]], varLabel, varVal, varFormatted)
else -- string, url, etc.
bindClause = string.format([[
BIND(
COALESCE(
(STR(%s)),
"?"
) AS %s
)
]], varVal, varFormatted)
end
return optionalClause, bindClause
end
local function moreinfoToSparql(moreinfo)
local optionalClauses = {}
local pids = {} -- Array to store unique PIDs
local placeholders = {} -- Map PIDs to their placeholders
-- Replace P\d+ with placeholders and collect PIDs
local processedString = moreinfo:gsub("P%d+", function(pid)
local placeholder = "%%P" .. pid .. "%%"
table.insert(pids, pid)
placeholders[pid] = placeholder
table.insert(optionalClauses, string.format(
"OPTIONAL { ?id wdt:%s ?val_%s. }", pid, pid
))
return placeholder
end)
-- Split the string into parts separated by placeholders
local parts = {}
local currentPos = 1
for _, pid in ipairs(pids) do
local placeholder = placeholders[pid]
local startPos, endPos = processedString:find(placeholder, currentPos, true)
if startPos then
-- Add the text before the placeholder
table.insert(parts, processedString:sub(currentPos, startPos - 1))
-- Add the placeholder as a property reference
table.insert(parts, { type = "property", pid = pid })
currentPos = endPos + 1
end
end
-- Add the remaining text after the last placeholder
table.insert(parts, processedString:sub(currentPos))
-- Build the CONCAT expression
local concatParts = {}
for _, part in ipairs(parts) do
if type(part) == "table" then
local pid = part.pid
local propertyType = getPropertyType(pid)
if propertyType == "time" then
---- table.insert(concatParts, string.format("(FORMAT(?val_%s, 'd MMMM yyyy'))", part.pid))
-- table.insert(concatParts, string.format("(STR(YEAR(?val_%s))),'-',(STR(MONTH(?val_%s))),'-',(STR(DAY(?val_%s)))", part.pid, part.pid, part.pid))
table.insert(optionalClauses, string.format("BIND(MONTH(?val_%s) AS ?m) BIND( IF(?m = 1, 'januari', IF(?m = 2, 'februari', IF(?m = 3, 'mars', IF(?m = 4, 'april', IF(?m = 5, 'maj', IF(?m = 6, 'juni', IF(?m = 7, 'juli', IF(?m = 8, 'augusti', IF(?m = 9, 'september', IF(?m = 10, 'oktober', IF(?m = 11, 'november', 'december'))))))))))) AS ?manad)", part.pid))
table.insert(concatParts, string.format("STR(DAY(?val_%s)), ' ', ?manad, ' ', STR(YEAR(?val_%s))", part.pid, part.pid))
else
table.insert(concatParts, string.format("(STR(?val_%s))", part.pid))
end
else
table.insert(concatParts, string.format("'%s'", part:gsub("'", "\\'")))
end
end
local concatExpr = ", ' '," .. table.concat(concatParts, ", ")
return table.concat(optionalClauses, " "), concatExpr
end
--------------- FUNCTIONS TO ADD VARIOUS ICONS/SHADED AREA TO MAPS----------------------------------------
local arrayIcons={}
table.insert(arrayIcons,{"Q160742","monument","small",_historicalcolour,"abbeys"})
table.insert(arrayIcons,{"Q1701174","monument","small",_historicalcolour:fade(),"abbeys"})
table.insert(arrayIcons,{"Q1248784","airport","small",_black,"airports"})
table.insert(arrayIcons,{"Q194195","amusement-park","small",_educationcolour,"amusementparks"})
table.insert(arrayIcons,{"Q2593777","cemetery","small",_historicalcolour,"ancient"})
table.insert(arrayIcons,{"Q34023","triangle","small",_historicalcolour,"ancient"})
table.insert(arrayIcons,{"Q7321974","landmark-JP","small",_historicalcolour,"ancient"})
table.insert(arrayIcons,{"Q3395377","monument","small",_historicalcolour,"ancient"})
table.insert(arrayIcons,{"Q1426772","monument","small",_historicalcolour,"ancientgraves"})
table.insert(arrayIcons,{"Q10855061","historic","small",_historicalcolour,"archaeologicalfinds"})
table.insert(arrayIcons,{"Q178561","danger","small",_historicalcolour,"battles"})
table.insert(arrayIcons,{"Q1261499","danger","small",_historicalcolour,"battles"})
table.insert(arrayIcons,{"Q567998","beach","small",_beachcolour,"beaches"})
table.insert(arrayIcons,{"Q40080","beach","small",_beachcolour,"beaches"})
table.insert(arrayIcons,{"Q12280","bridge","small",_black,"bridges"})
table.insert(arrayIcons,{"Q23413","castle","small",_historicalcolour,"castles"})
table.insert(arrayIcons,{"Q751876","castle","small",_historicalcolour,"castles"})
table.insert(arrayIcons,{"Q879050","castle","small",_historicalcolour,"castles"})
table.insert(arrayIcons,{"Q17715832","castle","small",_historicalcolour:fade(),"castles"})
table.insert(arrayIcons,{"Q16970","religious-christian","small",_historicalcolour,"churches"})
table.insert(arrayIcons,{"Q17485079","religious-christian","small",_historicalcolour:fade(),"churches"})
table.insert(arrayIcons,{"Q918457","industry","small",_green,"combustion"})
table.insert(arrayIcons,{"Q1601458","industry","small",_green,"combustion"})
table.insert(arrayIcons,{"Q4830453","bank","small",_economycolour,"companies"})
table.insert(arrayIcons,{"Q372934","square","small",_black,"glacialerratic"})
table.insert(arrayIcons,{"Q44782","harbor","small",_black,"harbours"})
table.insert(arrayIcons,{"Q283202","harbor","small",_black,"harbours"})
table.insert(arrayIcons,{"Q16917","hospital","small",_strongred,"hospitals"})
table.insert(arrayIcons,{"Q27686","suitcase","small",_green,"hotels"})
table.insert(arrayIcons,{"Q15911738","dam","small",_strongblue,"hydropower"})
table.insert(arrayIcons,{"Q39715","lighthouse","small",_lighthousecolour,"lighthouses"})
table.insert(arrayIcons,{"Q820477","triangle","small",_black,"mines"})
table.insert(arrayIcons,{"Q33506","museum","small",_educationcolour,"museums"})
table.insert(arrayIcons,{"Q10416961","museum","small",_educationcolour,"museums"})
table.insert(arrayIcons,{"Q134447","building-alt1","small",_black,"nuclearpower"})
table.insert(arrayIcons,{"Q837142","heart","small",_strongred,"nursinghomes"})
table.insert(arrayIcons,{"Q8502","mountain","small",_mountaincolour,"peaks"})
table.insert(arrayIcons,{"Q123964505","home","small",_green,"populatedplaces"})
table.insert(arrayIcons,{"Q15115254","landmark-JP","small",_black,"quarries"})
table.insert(arrayIcons,{"Q11707","restaurant","small",_green,"restaurants"})
table.insert(arrayIcons,{"Q22908","cricket","small",_strongred,"seniorhomes"})
table.insert(arrayIcons,{"Q3914","school","small",_educationcolour,"schools"})
table.insert(arrayIcons,{"Q9842","school","small",_educationcolour,"schools"})
table.insert(arrayIcons,{"Q159334","school","small",_educationcolour,"schools"})
table.insert(arrayIcons,{"Q170087","school","small",_educationcolour,"schools"})
table.insert(arrayIcons,{"Q10511371","school","small",_educationcolour,"schools"})
table.insert(arrayIcons,{settings.pipes.settlement_localdefinition,"home","small",_green,"settlements_localdefinition"})
table.insert(arrayIcons,{"Q188055","gate","small",_historicalcolour,"sieges"})
table.insert(arrayIcons,{"Q285927","star","small",_gold,"solarpower"})
table.insert(arrayIcons,{"Q1003207","star","small",_gold,"solarpower"})
table.insert(arrayIcons,{"Q2298412","star","small",_gold,"solarpower"})
table.insert(arrayIcons,{"Q8524","soccer","small",_sportscolour,"sportsvenues"})
table.insert(arrayIcons,{"Q1076486","soccer","small",_sportscolour,"sportsvenues"})
table.insert(arrayIcons,{"Q1154710","soccer","small",_sportscolour,"sportsvenues"})
table.insert(arrayIcons,{"Q1202618","soccer","small",_sportscolour,"sportsvenues"})
table.insert(arrayIcons,{"Q2338524","car","small",_sportscolour,"sportsvenues"})
table.insert(arrayIcons,{"Q124714","wetland","small",_blue,"springs"})
table.insert(arrayIcons,{"Q55488","rail","small",_black,"stations"})
table.insert(arrayIcons,{"Q55678","rail","small",_black,"stations"})
table.insert(arrayIcons,{"Q336514","theatre","small",_educationcolour,"theatres"})
table.insert(arrayIcons,{"Q515","city","small",_red,"towns"})
table.insert(arrayIcons,{"Q3957","city","small",_red,"towns"})
table.insert(arrayIcons,{"Q216107","bank","small",_green,"trade"})
table.insert(arrayIcons,{"Q288514","bank","small",_green,"trade"})
table.insert(arrayIcons,{"Q3918","college","small",_educationcolour,"universities"})
table.insert(arrayIcons,{"Q532","home","small",_green,"villages"})
table.insert(arrayIcons,{"Q5084","home","small",_green,"villages"})
table.insert(arrayIcons,{"Q486972","home","small",_green,"villages"})
table.insert(arrayIcons,{"Q15242449","recycling","small",_brown,"wastewater"})
table.insert(arrayIcons,{"Q34038","waterfall","small",_blue,"waterfalls"})
table.insert(arrayIcons,{"Q185187","watermill","small",_strongblue,"watermills"})
table.insert(arrayIcons,{"Q10373565","recycling","small",_blue,"waterworks"})
table.insert(arrayIcons,{"Q49833","windmill","small",_lighthousecolour,"windpower"})
table.insert(arrayIcons,{"Q194356","windmill","small",_lighthousecolour,"windpower"})
p.addIcons=function(txtTopic)
local matchingRows=findRowsByColumn(arrayIcons, 5, txtTopic)
for _, row in ipairs(matchingRows) do
p.addQueriedLocations(row[1],row[2],row[3],row[4])
end
end
local arrayLines={}
table.insert(arrayLines,{"Q34442",3,_roadcolour,"roads"})
table.insert(arrayLines,{"Q909299",3,_roadcolour,"roads"})
table.insert(arrayLines,{"Q728937",3,_black,"railroads"})
table.insert(arrayLines,{"Q18984099",3,_strongblue,"ferryroutes"})
table.insert(arrayLines,{"Q355304",1,_blue,"watercourses"})
table.insert(arrayLines,{"Q63565252",1,_blue,"watercourses"})
table.insert(arrayLines,{"Q4022",1,_blue,"watercourses"})
table.insert(arrayLines,{"Q3529419",1,_blue,"watercourses"})
p.addLines=function(txtTopic)
local matchingRows=findRowsByColumn(arrayLines, 4, txtTopic)
for _, row in ipairs(matchingRows) do
p.addQueriedLines(row[1],row[2],row[3])
end
end
local arrayAreas={}
table.insert(arrayAreas,{"Q23397",1,_blue,0.2,"lakes"})
table.insert(arrayAreas,{"Q104093746",1,_blue,0.2,"lakes"})
table.insert(arrayAreas,{"Q46169",1,_green,0.3,"naturereserves"})
table.insert(arrayAreas,{"Q179049",1,_green,0.3,"naturereserves"})
table.insert(arrayAreas,{"Q3240227",1,boggreen,0.2,"bogs"})
p.addAreas=function(txtTopic)
local matchingRows=findRowsByColumn(arrayAreas, 5, txtTopic)
for _, row in ipairs(matchingRows) do
p.addQueriedAreas(row[1],row[2],row[3],row[4])
end
end
p.addArgument=function(txtLabel,txtValue)
if (txtValue) then return "\"" .. txtLabel .. "\"" .. ":" .. "\"" .. txtValue .. "\"" end
end
p.addArgumentNoQuote=function(txtLabel,txtValue)
return "\"" .. txtLabel .. "\"" .. ":" .. txtValue
end
-- Function to fill up the mapframe correctly
p.addMapContent=function(txt)
if (not isempty(txt)) then
if (p.bNotfirst) then
p.txtConnect=","
else
p.txtConnect=" "
p.bNotfirst=true
end
end
return p.txtConnect .. txt
end
-- Creates an inverse mask (so that only items with the area specified by qid is shown)
p.addInverse=function(qid,colourFill,fFillOpacity,colourStroke,fStrokeOpacity,iWidth)
return p.addMapContent ("{" .. p.addArgument("type","ExternalData") .. " ," .. p.addArgument("service","geomask") .. " ," ..p.addArgument("ids",qid) .. " , \"properties\":{"..p.addArgument("fill",colourFill:html()) .. " ," .. p.addArgumentNoQuote("fill-opacity",fFillOpacity) .. " ," .. p.addArgument("stroke",colourStroke:html()) .. " ," .. p.addArgumentNoQuote("stroke-opacity",fStrokeOpacity) .. " ," .. p.addArgumentNoQuote("stroke-width",iWidth) .. "} }" )
end
-- Sets basic mapframe settings (not mandatory for mapframe except for height and width and this function sets default values for them if no value is supplied)
p.showBase=function (frame)
p.myArgs={}
-- local iHeight, iWidth, bHasMaxLevel, iMaxLevel
if (not isempty(frame.args['height'])) then
iHeight=frame.args['height']
else
if (not isempty(frame.args[localisation.arguments.height])) then
iHeight=frame.args[localisation.arguments.height]
else
iHeight=settings.height
end
end
if (not isempty(frame.args['width'])) then
iWidth=frame.args['width']
else
if (not isempty(frame.args[localisation.arguments.width])) then
iWidth=frame.args[localisation.arguments.width]
else
iWidth=settings.width
end
end
if (not isempty(frame.args['zoom'])) then
p.myArgs['zoom']=frame.args['zoom']
end
if (not isempty(frame.args['longitude'])) then
p.myArgs['longitude']=frame.args['longitude']
end
if (not isempty(frame.args[localisation.arguments.longitude])) then
p.myArgs['longitude']=frame.args[localisation.arguments.longitude]
end
if (not isempty(frame.args['latitude'])) then
p.myArgs['latitude']=frame.args['latitude']
end
if (not isempty(frame.args[localisation.arguments.latitude])) then
p.myArgs['latitude']=frame.args[localisation.arguments.latitude]
end
if (not isempty(frame.args['align'])) then
p.myArgs['align']=frame.args['align']
end
if (not isempty(frame.args['text'])) then
p.myArgs['text']=frame.args['text']
end
if (bHasArgument(frame.args,"frameless")) then
p.myArgs['frameless']=""
end
p.myArgs['height']=iHeight
p.myArgs['width']=iWidth
return p.myArgs
end
-- Function to split a string by a delimiter (by chatgpt)
split=function(inputStr, delimiter)
if not delimiter then error "No delimiter supplied to function split" end
local result = {}
if inputStr then
for match in (inputStr .. delimiter):gmatch("(.-)" .. delimiter) do
result[match]=true
end
end
return result
end
-- Function to split a string by a delimiter (by chatgpt)
split2=function(inputStr, delimiter)
if not delimiter then error "No delimiter supplied to function split2" end
local result = {}
if inputStr then
for match in (inputStr .. delimiter):gmatch("(.-)" .. delimiter) do
table.insert(result,match)
end
end
return result
end
p.include=function(qid,bIsinline)
local claim=mw.wikibase.getBestStatements(qid, "P31" )
for key,value in pairs(claim) do
iInstance=read(value,'id')
local row=findRowsByColumn(arrayIcons, 1, iInstance)
if (#row)>0 then
local txtContent=p.addIconWD(qid,row[1][4],row[1][2],getLabelFundamental(qid),mw.wikibase.getSitelink(qid))
if (txtContent) then
if (bIsinline) then
return txtContent
else
return p.frame:extensionTag{ name = 'mapframe', content = txtContent, args = p.showBase(p.frame) }
end
end
end
local row=findRowsByColumn(arrayLines, 1, iInstance)
if (#row)>0 then
local txtContent=p.addLineWD(qid,row[3],row[2],getLabelFundamental(qid),mw.wikibase.getSitelink(qid))
if (txtContent) then
if (bIsinline) then
return txtContent
else
return p.frame:extensionTag{ name = 'mapframe', content = txtContent, args = p.showBase(p.frame) }
end
end
end
local row=findRowsByColumn(arrayAreas, 1, iInstance)
if (#row)>0 then
local txtContent=p.addAreaWD(qid,row[3],row[2],row[4],getLabelFundamental(qid),mw.wikibase.getSitelink(qid))
if (txtContent) then
if (bIsinline) then
return txtContent
else
return p.frame:extensionTag{ name = 'mapframe', content = txtContent, args = p.showBase(p.frame) }
end
end
end
end
return ''
end
p.show=function(frame)
local qid=frame.args['id']
p.frame=frame
return p.include(qid,bHasArgument(frame.args,"inline"))
end
function processTable(t)
local result = {}
local length = #t
for i, v in ipairs(t) do
-- Remove the first '[' (even with leading spaces)
v = v:gsub("^%s*%[", "")
-- Remove the last ']' (even with trailing spaces)
v = v:gsub("%]%s*$", "")
table.insert(result, v)
end
-- Concatenate all elements with a ',' in between
return table.concat(result, ", ")
end
p.showMerge=function(frame)
local txtContent = "[" .. processTable(frame.args) .. "]"
return frame:extensionTag{ name = 'mapframe', content = txtContent, args = p.showBase(frame) }
end
function bHasArgument(args,txtName)
-- Check for the presence of txtName among args
for _, arg in pairs(args) do
if arg == txtName then
-- return true if txtName is found
return true
end
end
return false -- otherwise return false
end
function readProperty(qid,pid)
statements=mw.wikibase.getBestStatements(qid,pid)
if not(next(statements)==nil) then
if not(statements[1]==nil) then
return statements[1].mainsnak.datavalue.value
end
end
return nil
end
p.showArea=function (frame)
p.txtLabel=frame.args['label']
-- if (not(isempty(p.txtLabel))) then
if (p.txtLabel) then
txtOptionalAddition,txtTitleAddition=moreinfoToSparql(p.txtLabel)
txtBaseTitle="BIND(CONCAT(COALESCE(CONCAT('[[',SUBSTR(STR(?article), 31),'|',?idLabel,']]'),?idLabel,'" .. localisation.maintenance.noname .. "')" .. txtTitleAddition .. ") AS ?title)"
end
local data=frame.args
local myArgs=p.showBase(frame)
local many=false
local qids={}
if (not(isempty(data['id']))) then
if (string.find(data['id'], ",")) then
qids=split(data['id'],",")
many=true
else
qid=data['id']
qids[qid]=true
end
else
if (not(isempty(data['state']))) then
qid=mw.wikibase.getEntityIdForTitle(data['state'])
qids[qid]=true
else
qid=mw.wikibase.getEntityIdForCurrentPage()
if not qid then return "Modulen behöver ett Wikidata id! Det kan antingen komma automatiskt från artikeln eller anges genom argumentet 'id' vid anrop av mall eller funktion" end
qids[qid]=true
end
end
loopids=qids -- to avoid messing up the arrays by adding items to an aray that is currently being looped through
for keyid in pairs(loopids) do
local territories=useStatement(keyid,"P150")
if (territories) then
for key,value in pairs(territories) do
if (type(value)=="table") and (next(value) ~= nil) then
qids[value["id"]]=true
end
end
end
end
local property=data["propertysettoobject"]
if (not(isempty(property))) then
arrayProperty=split2(property,",")
p.pid=p.getProperty(arrayProperty)
else
p.pid=p.getProperty(data)
end
p.iItems=0
p.frame=frame
p.txtContent=p.addSurroundings(qids,p.frame.args)
local include=frame.args['include']
if (not isempty(include)) then
if (string.find(include, ",")) then
includeids=split(include,",")
for includeid, _ in pairs(includeids) do
p.txtContent=p.txtContent .. p.include(includeid,true)
end
else
p.txtContent=p.txtContent .. p.include(include,true)
end
end
if bHasArgument(p.frame.args,'nobackground') then
p.txtContent=p.txtContent..p.addAreaWD(qid,_black,0,0,txtTitle) -- Print the area invisibly (so that the mape gets the right size, but that the area doesn't show)
else
if bHasArgument(p.frame.args,'commons') then
txtFilename=string.sub(readProperty(qid,"P3896"),6)
p.txtContent=p.txtContent..p.addAreaCommons(txtFilename) -- Print the area visibly based on coordinates from Commons
else
p.txtContent=p.txtContent..p.addAreaWD(qid,_black,1,0.2,txtTitle) -- Print the area visibly based on coordinates from OpenStreetMap
end
end
if (not isempty(frame.args['commonsinclude'])) then
if (string.find(frame.args['commonsinclude'], ",")) then
commonsincludeids=split(frame.args['commonsinclude'],",")
for commonsincludeid, _ in pairs(commonsincludeids) do
p.txtContent=p.txtContent .. p.addAreaCommonsId(commonsincludeid)
end
else
p.txtContent=p.txtContent .. p.addAreaCommonsId(frame.args['commonsinclude'])
end
end
if (not isempty(frame.args['commonspages'])) then
commonspages=split(frame.args['commonspages'],",")
for txtCommonsPage, _ in pairs(commonspages) do
p.txtContent=p.txtContent .. p.addAreaCommons(txtCommonsPage)
end
end
if (not isempty(frame.args['inverse'])) then
p.txtContent=p.txtContent .. p.addInverse(frame.args['inverse'],colourInverseFill,0.1,colourInverseStroke,0.5,3)
end
if (not isempty(p.txtContent)) then
p.txtContent="["..p.txtContent.."]"
end
if (bHasArgument(data,"inline")) then
return p.txtContent
else
return frame:extensionTag{ name = 'mapframe', content = p.txtContent, args = myArgs }
end
end
p.getProperty=function(arrayTheme)
if (bHasArgument(arrayTheme,'connectingline') or bHasArgument(arrayTheme,localisation.arguments.connectingline)) then
return "P81"
end
if (bHasArgument(arrayTheme,'area') or bHasArgument(arrayTheme,localisation.arguments.area)) then
return "P131"
end
if (bHasArgument(arrayTheme,'water') or bHasArgument(arrayTheme,localisation.arguments.water)) then
return "P206"
end
if (bHasArgument(arrayTheme,'place') or bHasArgument(arrayTheme,localisation.arguments.place)) then
return "P276"
end
if (bHasArgument(arrayTheme,'partof') or bHasArgument(arrayTheme,localisation.arguments.partof)) then
return "P361"
end
if (bHasArgument(arrayTheme,'diocese') or bHasArgument(arrayTheme,localisation.arguments.diocese)) then
return "P708"
end
if (bHasArgument(arrayTheme,'mountainrange') or bHasArgument(arrayTheme,localisation.arguments.mountainrange)) then
return "P4553"
end
return "P17" -- default value
end
local iRiver=1
local myArgs={};
local iCounter=1
local denylist={}
local allrivers={}
local allakes={}
local riverdatabase={}
local lakedatabase={}
local denyassource={Q46831=true,Q3958626=true,Q3777462=true,Q2074737=true}
-- bergskedja, alpine section, alpine group, kommun i Spanien
-- This function fills a structure with data about the river, its tributaries etc.
p.data_river=function(frame)
-- first check which id(s) are used
many=false
-- if an id is set use it
p.qids={}
fid=frame.args['id']
if (not(isempty(fid))) then
-- if id is set to something that includes an "," (like "Q1,Q2") it is not one id, but many, in that case store it as ids instead
if (string.find(fid, ",")) then
p.qids=split2(fid,",")
many=true
else
table.insert(p.qids,fid)
end
else
-- if no id is set use the one for wikidata object connected to the page
table.insert(p.qids,mw.wikibase.getEntityIdForCurrentPage())
end
-- create a deny list with water bodies to ignore (can for example be channels that would otherwise connect the water with lots of water bodies that are not tributaries)
if (not(isempty(frame.args['deny']))) then
denylist=split(frame.args['deny'],",")
end
-- show its drainage basin (defaults to true, so will be shown unless basin is set to something that is not true)
if (not(isempty(frame.args['basin']))) then
bBasin=frame.args['basin'] == "true"
else
bBasin=true
end
-- show lakes (defaults to true, so will be shown unless lakes is set to something that is not true)
if (not(isempty(frame.args['lakes']))) then
bLakes=frame.args['lakes'] == "true"
else
bLakes=true
end
-- show tributaries (defaults to true, so will be shown unless tributaries is set to something that is not true)
if (not(isempty(frame.args['tributaries']))) then
bTributaries=frame.args['tributaries'] == "true"
else
bTributaries=true
end
if (bTributaries==nil) then
bTributaries=true -- Default value
end
if (isempty(frame.args['maxlevel'])) then
bHasMaxLevel=false
else
bHasMaxLevel=true
iMaxLevel=tonumber(frame.args['maxlevel'])
end
for _, id in pairs( p.qids ) do
p.addRiver(id,0,bTributaries)
end
return tprint(riverdatabase) .. tprint(lakedatabase) .. tprint(denylist)
end
p.showRiver=function (frame)
p.pid='P206' -- Use located in or next to body of water for sparql queries related to the river
myArgs=p.showBase(frame) -- fill a map frame
p.data_river(frame) -- Retrieve data about the rivers and lake in the water system (to the degree that relevant properties like lakes and tributaries are set)
p.iItems=0
local txtContent=''
-- Look through the database that has been filled by p.data_river
tmp={}
for key, valueRiver in pairs( riverdatabase ) do
-- select what thickness to use for the river
if (valueRiver.level==0) then
iThickness=settings.paths.width.main
end
if (valueRiver.level>0) then
iThickness=settings.paths.width.tributary
end
-- draw a line for the river
txtContent= txtContent..p.addLineWD(valueRiver.id,settings.paths.colour.rivers,iThickness,valueRiver.name,valueRiver.sitelink)
-- print out icons based on sparql queries (depending on what arguments have been set)
end
txtContent= txtContent..p.addSurroundings(allrivers,frame.args)
if (bLakes) then -- if showing lakes ..
for keyLake, valueLake in pairs( lakedatabase ) do -- .. loop through all the lakes
-- draw an area for the lake
txtContent= txtContent..p.addAreaWD(valueLake.id,settings.paths.colour.rivers,settings.areas.width,settings.areas.lake_opacity,valueLake.name,valueLake.sitelink)
-- print out icons based on sparql queries (depending on what arguments have been set)
end
end
txtContent= txtContent..p.addSurroundings(allakes,frame.args)
if (bBasin) then -- if showing the river basin(s)
for _, id in ipairs(p.qids) do
iBasin=readFirstStatementId(id,'P4614')
if (iBasin) then
statements=mw.wikibase.getBestStatements(iBasin,'P3896')
if not(next(statements)==nil) then
if not(statements[1]==nil) then
local txtBasin=statements[1].mainsnak.datavalue.value
local newtxt=txtBasin:gsub("^Data:%s*", "")
txtContent=txtContent .. p.addAreaCommons(newtxt)
end
end
end
end
end
if (not isempty(frame.args['inverse'])) then
txtContent=txtContent .. p.addInverse(frame.args['inverse'],colourInverseFill,0.5,colourInverseStroke,0.9,3)
end
if (txtContent) then
txtContent="["..txtContent.."]"
end
txtExtraCategory=''
if (bHasArgument(frame.args,'all') or bHasArgument(frame.args,localisation.pipes.all)) then
txtExtraCategory='[[' .. localisation.txtCategory .. ':' .. localisation.maintenance.allalternatives .. ']]'
end
if (bHasArgument(frame.args,"inline")) then
return txtContent
else
return frame:extensionTag{ name = 'mapframe', content = txtContent, args = myArgs } .. txtExtraCategory -- return the mapframe
end
end
p.addLake=function(qid,iLevel)
if (qid and ((not bHasMaxLevel) or (iLevel<=iMaxLevel)) and (not denylist[qid]) and p.isAllowed(qid)) then
if not allakes[qid] then
local item={}
item.id=qid
item.name=mw.wikibase.getLabel(qid)
item.sitelink=mw.wikibase.getSitelink(qid)
table.insert(lakedatabase,item)
allakes[qid]=true
local entityTributary=mw.wikibase.getBestStatements(qid, 'P200' )
for key, value in pairs( entityTributary ) do
local qidTributary=read(value,'id')
if (p.isLake(qidTributary)) then
p.addLake(qidTributary,iLevel)
else
p.addRiver(qidTributary,iLevel+1,true)
end
end
local entityPart=mw.wikibase.getBestStatements(qid, 'P527' )
for key, value in pairs( entityPart ) do
qidPart=read(value,'id')
if (p.isLake(qidPart)) then
p.addLake(qidPart,iLevel)
end
end
local entityBorders=mw.wikibase.getBestStatements(qid, 'P47' )
for key, value in pairs( entityBorders ) do
qidBorder=read(value,'id')
if (p.isLake(qidBorder)) then
p.addLake(qidBorder,iLevel)
end
end
end
end
end
p.isAllowed=function(qid)
local entity=mw.wikibase.getBestStatements(qid, 'P31' )
for key, value in pairs( entity ) do
id=read(value,'id')
if (denyassource[id]) then
return false
end
end
return true
end
p.isLake=function(qid)
if (not qid) then return false end
local entity=mw.wikibase.getBestStatements(qid, 'P31' )
for key, value in pairs( entity ) do
id=read(value,'id')
if (id=='Q23397') or (id=='Q104093746') or (id=='Q17018380') then
return true
end
end
return false
end
p.isRiver=function(qid)
if (not qid) then return false end
local entity=mw.wikibase.getBestStatements(qid, 'P31' )
for key, value in pairs( entity ) do
id=read(value,'id')
if (id=='Q355304') or (id=='Q4022') or (id=='Q3529419') or (id=='Q47521') then
-- vattendrag, flod, å, bäck
return true
end
end
return false
end
p.addRiver=function(qid,iLevel,bTributaries)
local level=iLevel
if qid and ((not allrivers[qid]) and ((not bHasMaxLevel) or (iLevel<=iMaxLevel)) and (not denylist[qid])) then
local item={}
item.id=qid
item.level=level
item.name=mw.wikibase.getLabel(qid)
item.sitelink=mw.wikibase.getSitelink(qid)
table.insert(riverdatabase,item)
allrivers[qid]=true
if (bTributaries) then
-- Tributaries directly from the river
local entityTributary=mw.wikibase.getBestStatements(qid, 'P974' )
local id
for key, value in pairs( entityTributary ) do
id=read(value,'id')
if not allrivers[id] then
tblRiver=p.addRiver(id,level+1,bTributaries)
end
end
-- Tributaries via the river's source(s)
local entitySources=mw.wikibase.getBestStatements(qid, 'P885' )
for keySource, valueSource in pairs( entitySources ) do
local id=read(valueSource,'id')
if (bLakes and p.isLake(id)) then
p.addLake(id,level)
end
if (p.isRiver(id)) then
p.addRiver(id,level+1,bTributaries)
end
end
if (bLakes) then
-- Tributaries via lakes the river pass by
local entityLakes=mw.wikibase.getBestStatements(qid, 'P469' )
for keyLake, valueLake in pairs( entityLakes ) do
local iLake=read(valueLake,'id')
p.addLake(iLake,level)
end
end
end
end
end
function almostsame(a,b)
return (a.txtLocalName==b.txtLocalName) and (a.icon==b.icon) and (a.colour==b.colour)
end
p.documentation_icons=function(frame)
local processedlist={}
for i = 1, #arrayIcons do
local row={}
row.txtEnglishName=arrayIcons[i][5]
row.txtLocalName=localisation.pipes[row.txtEnglishName] or "ööö"
row.qid=convertQID(frame,arrayIcons[i][1])
row.icon=arrayIcons[i][2]
row.colour=arrayIcons[i][4]:html()
table.insert(processedlist,row)
end
table.sort(processedlist, function(a, b) return
a.txtLocalName < b.txtLocalName or
(a.txtLocalName == b.txtLocalName and a.icon < b.icon) or
(a.txtLocalName == b.txtLocalName and a.icon == b.icon and a.colour < b.colour)
end)
local lastactive=1
processedlist[1].rowspan=1
processedlist[1].txt=processedlist[1].qid
for i = 2, #processedlist do
if (almostsame(processedlist[i],processedlist[lastactive])) then
processedlist[lastactive].rowspan=i-lastactive+1
processedlist[lastactive].txt=processedlist[lastactive].txt .. ", " .. processedlist[i].qid
else
lastactive=i
processedlist[lastactive].rowspan=1
processedlist[lastactive].txt=processedlist[i].qid
end
end
txtReturn={}
table.insert(txtReturn,"<table class=\"wikitable sortable\"><tr><th>Namn</th><th>Wikidata objekt</th><th>Ikon</th><th>Färg</th></tr>")
local i=1
while i <= #processedlist do
row=processedlist[i]
table.insert(txtReturn,"<tr rowspan=\"" .. row.rowspan .. "\">")
if (row.txtLocalName=="ööö") then
table.insert(txtReturn,"<td style='background:#FFFF00'>"..row.txtEnglishName .. "</td>")
else
table.insert(txtReturn,"<td>"..row.txtLocalName .. "</td>")
end
table.insert(txtReturn,"<td>"..row.txt .. "</td>")
table.insert(txtReturn,"<td>".."[[Fil:Maki7-".. row.icon .. ".svg]]" .. "</td>")
table.insert(txtReturn,"<td>"..frame:expandTemplate{ title = "Färgbox", args = { row.colour } } .. "</td>")
table.insert(txtReturn,"</tr>")
i=i+processedlist[i].rowspan
end
table.insert(txtReturn,"</table>")
return table.concat(txtReturn, "")
end
p.documentation_lines=function(frame)
local processedlist={}
for i = 1, #arrayLines do
local row={}
row.txtEnglishName=arrayLines[i][4]
row.txtLocalName=localisation.pipes[row.txtEnglishName] or "ööö"
row.qid=convertQID(frame,arrayLines[i][1])
row.width=arrayLines[i][2]
row.colour=arrayLines[i][3]:html()
table.insert(processedlist,row)
end
table.sort(processedlist, function(a, b) return
a.txtLocalName < b.txtLocalName or
(a.txtLocalName == b.txtLocalName and a.colour < b.colour) or
(a.txtLocalName == b.txtLocalName and a.colour == b.colour and a.width < b.width)
end)
local lastactive=1
processedlist[1].rowspan=1
processedlist[1].txt=processedlist[1].qid
for i = 2, #processedlist do
if (almostsame(processedlist[i],processedlist[lastactive])) then
processedlist[lastactive].rowspan=i-lastactive+1
processedlist[lastactive].txt=processedlist[lastactive].txt .. ", " .. processedlist[i].qid
else
lastactive=i
processedlist[lastactive].rowspan=1
processedlist[lastactive].txt=processedlist[i].qid
end
end
txtReturn={}
table.insert(txtReturn,"<table class=\"wikitable sortable\"><tr><th>Namn</th><th>Wikidata objekt</th><th>Bredd</th><th>Färg</th></tr>")
local i=1
while i <= #processedlist do
row=processedlist[i]
table.insert(txtReturn,"<tr rowspan=\"" .. row.rowspan .. "\">")
if (row.txtLocalName=="ööö") then
table.insert(txtReturn,"<td style='background:#FFFF00'>"..row.txtEnglishName .. "</td>")
else
table.insert(txtReturn,"<td>"..row.txtLocalName .. "</td>")
end
table.insert(txtReturn,"<td>"..row.txt .. "</td>")
table.insert(txtReturn,"<td>".. row.width .. "</td>")
table.insert(txtReturn,"<td>"..frame:expandTemplate{ title = "Färgbox", args = { row.colour } } .. "</td>")
table.insert(txtReturn,"</tr>")
i=i+processedlist[i].rowspan
end
table.insert(txtReturn,"</table>")
return table.concat(txtReturn, "")
end
--table.insert(arrayAreas,{"Q3240227",1,boggreen,0.2,"bogs"})
p.documentation_shapes=function(frame)
local processedlist={}
for i = 1, #arrayAreas do
local row={}
row.txtEnglishName=arrayAreas[i][5]
row.txtLocalName=localisation.pipes[row.txtEnglishName] or "ööö"
row.qid=convertQID(frame,arrayAreas[i][1])
row.width=arrayAreas[i][2]
row.colour=arrayAreas[i][3]:html()
row.opacity=arrayAreas[i][4]
table.insert(processedlist,row)
end
table.sort(processedlist, function(a, b) return
a.txtLocalName < b.txtLocalName or
(a.txtLocalName == b.txtLocalName and a.colour < b.colour) or
(a.txtLocalName == b.txtLocalName and a.colour == b.colour and a.opacity < b.opacity) or
(a.txtLocalName == b.txtLocalName and a.colour == b.colour and a.opacity == b.opacity and a.width < b.width)
end)
local lastactive=1
processedlist[1].rowspan=1
processedlist[1].txt=processedlist[1].qid
for i = 2, #processedlist do
if (almostsame(processedlist[i],processedlist[lastactive])) then
processedlist[lastactive].rowspan=i-lastactive+1
processedlist[lastactive].txt=processedlist[lastactive].txt .. ", " .. processedlist[i].qid
else
lastactive=i
processedlist[lastactive].rowspan=1
processedlist[lastactive].txt=processedlist[i].qid
end
end
txtReturn={}
table.insert(txtReturn,"<table class=\"wikitable sortable\"><tr><th>Namn</th><th>Wikidata objekt</th><th>Bredd</th><th>Opacitet</th><th>Färg</th></tr>")
local i=1
while i <= #processedlist do
row=processedlist[i]
table.insert(txtReturn,"<tr rowspan=\"" .. row.rowspan .. "\">")
if (row.txtLocalName=="ööö") then
table.insert(txtReturn,"<td style='background:#FFFF00'>"..row.txtEnglishName .. "</td>")
else
table.insert(txtReturn,"<td>"..row.txtLocalName .. "</td>")
end
table.insert(txtReturn,"<td>"..row.txt .. "</td>")
table.insert(txtReturn,"<td>".. row.width .. "</td>")
table.insert(txtReturn,"<td>".. row.opacity .. "</td>")
table.insert(txtReturn,"<td>"..frame:expandTemplate{ title = "Färgbox", args = { row.colour } } .. "</td>")
table.insert(txtReturn,"</tr>")
i=i+processedlist[i].rowspan
end
table.insert(txtReturn,"</table>")
return table.concat(txtReturn, "")
end
function symbols (arrayNames,arraySymbols,iIdColumn,first,symbol_type,frame)
local txtReturn=''
for _, txtArgument in pairs(arrayNames) do
local txtArrayArgument=txtArgument
for txtEnglishName, txtLocalName in pairs(localisation.pipes) do
if (txtLocalName==txtArgument) then
txtArrayArgument=txtEnglishName
break
end
end
local matchingRows=findRowsByColumn(arraySymbols, iIdColumn, txtArrayArgument)
if next(matchingRows) then
if first then
first = false
else
txtReturn = txtReturn .. ", "
end
if symbol_type=="icons" then
txtReturn=txtReturn.. "[[Fil:Maki7-".. matchingRows[1][2] .. ".svg|16px]] " .. txtArgument
end
if symbol_type=="areas" then
local thiscolour=matchingRows[1][3]
txtReturn=txtReturn.. frame:expandTemplate{ title = "Färgbox", args = { thiscolour:html() } } .. " " .. txtArgument
end
end
end
return txtReturn,first
end
function allsymbols(arrayNames,first,frame)
txtIcons,first=symbols(arrayNames,arrayIcons,5,first,"icons")
txtAreas,first=symbols(arrayNames,arrayAreas,5,first,"areas",frame)
return txtIcons .. txtAreas,first
end
p.showSymbols=function(frame)
local themes=frame.args["themes"]
local arrayThemes
if (isempty(themes)) then
arrayThemes=frame.args
else
arrayThemes=split2(themes,",")
end
txtArguments,first=allsymbols(arrayThemes,true,frame)
arrayExtraArguments=split2(frame.args['description_extra'],",")
txtExtraArguments,first=allsymbols(arrayExtraArguments,first,frame)
return txtArguments .. txtExtraArguments
end
p.documentation=function(frame)
if bHasArgument(frame.args,'icons') then
return p.documentation_icons(frame)
end
if bHasArgument(frame.args,'lines') then
return p.documentation_lines(frame)
end
if bHasArgument(frame.args,'shapes') then
return p.documentation_shapes(frame)
end
return ""
end
function convertQID(frame,qid)
if qid:match("^Q%d+$") then
local number = qid:sub(2)
-- Expand the template and return the rendered output
return frame:expandTemplate{
title = "Q",
args = { number }
}
else
return qid
end
end
return p