Modul:Kartposisjon
Denne siden er midlertidig beskyttet mot redigering av nye og uregistrerte brukere. Hvis du ikke kan redigere denne siden, men ønsker å gjøre en endring, kan du foreslå endringen på diskusjonssiden. |
Moduldokumentasjon
| Denne modulen brukes på over 10 000 sider. Det anbefales at endringer testes i en sandkasse før de legges inn. Diskuter gjerne også endringer på diskusjonssiden først. |
| Denne modulen brukes av andre moduler (vha require):Dersom du endrer denne modulen så sørg for at de moduler som er avhengig av denne fremdeles fungerer. Det anbefales at endringer testes i en sandkasse før de legges inn. Diskutér gjerne også endringer på diskusjonssiden først. |
Denne modulen benyttes av kartmalene {{Kartposisjon}}, {{Kartposisjon+}}, {{Kartposisjon~}} og {{Kartposisjon mange}}. Se dokumentasjonssidene til disse malene for bruk og instruksjoner.
- Modul:Kartposisjon • Modul:Kartposisjon/sandkasse • forskjellig (diff)
- Modul:Kartposisjon/multi • Modul:Kartposisjon/multi/sandkasse • forskjellig (diff)
- Modul:Kartposisjon/info • Modul:Kartposisjon/info/sandkasse • samme innhold
require('strict')
local p = {}
local getArgs = require('Module:Arguments').getArgs
local Pgname = require('Modul:String').replace
local function round(n, decimals)
local pow = 10^(decimals or 0)
return math.floor(n * pow + 0.5) / pow
end
function p.getMapParams(map, frame)
if not map then
error('Navnet på kartdefinisjonen som skal brukes må angis', 2)
end
local moduletitle = mw.title.new('Modul:Kartposisjon/data/' .. map)
if not moduletitle then
error('"' .. map .. '" er ikke et gyldig navn for en kartdefinisjon', 2)
elseif moduletitle.exists then
local mapData = mw.loadData('Modul:Kartposisjon/data/' .. map)
return function(name, params)
if name == nil then
return 'Modul:Kartposisjon/data/' .. map
elseif mapData[name] == nil then
return ''
elseif params then
return mw.message.newRawMessage(tostring(mapData[name]), unpack(params)):plain()
else
return mapData[name]
end
end
elseif mw.title.new('Mal:Kartposisjon ' .. map).exists then
local cache = {}
if type(frame) ~= 'table' or type(frame.expandTemplate) ~= 'function' then
error('En ramme må oppgis ved bruk av et eldre positionskart')
end
return function(name, params)
if params then
return frame:expandTemplate{title = 'Kartposisjon ' .. map, args = { name, unpack(params) }}
else
if name == nil then
return 'Mal:Kartposisjon ' .. map
elseif cache[name] == nil then
cache[name] = frame:expandTemplate{title = 'Kartposisjon ' .. map, args = { name }}
end
return cache[name]
end
end
else
error('Kunne ikke finne angitt kartdefinisjon. Verken "Modul:Kartposisjon/data/' .. map .. '" eller "Mal:Kartposisjon ' .. map .. '" finnes', 2)
end
end
function p.data(frame, args, map)
if not args then
args = getArgs(frame, {frameOnly = true})
end
if not map then
map = p.getMapParams(args[1], frame)
end
local params = {}
for k,v in ipairs(args) do
if k > 2 then
params[k-2] = v
end
end
return map(args[2], #params ~= 0 and params)
end
local hemisphereMultipliers = {
longitude = { W = -1, w = -1, E = 1, e = 1 },
latitude = { S = -1, s = -1, N = 1, n = 1 }
}
local function decdeg(degrees, minutes, seconds, hemisphere, decimal, direction)
if decimal then
if degrees then
error('Desimal og DMS-grader kan ikke begge angis for ' .. direction, 2)
elseif minutes then
error('Minutter kan kun angis som ' .. direction .. ' sammen med DMS-grader', 2)
elseif seconds then
error('Sekunder kan kun angis som ' .. direction .. ' sammen med DMS-grader', 2)
elseif hemisphere then
error('En halvkule kan kun angis som ' .. direction .. ' sammen med DMS-grader', 2)
end
local retval = tonumber(decimal)
if retval then
return retval
end
error('Verdien "' .. decimal .. '" angitt for ' .. direction .. ' er ugyldig', 2)
elseif seconds and not minutes then
error('Sekunder ble angitt for ' .. direction .. ' uten at minutes også ble angitt', 2)
elseif not degrees then
if minutes then
error('Minutter ble angitt for ' .. direction .. ' uten at grader også ble angitt', 2)
elseif hemisphere then
error('En halvkule ble angitt for ' .. direction .. ' uten at grader også ble angitt', 2)
end
return nil
end
decimal = tonumber(degrees)
if not decimal then
error('Gradeverdien "' .. degrees .. '" angitt for ' .. direction .. ' er ugyldig', 2)
elseif minutes and not tonumber(minutes) then
error('Minuttverdien "' .. minutes .. '" angitt for ' .. direction .. ' er ugyldig', 2)
elseif seconds and not tonumber(seconds) then
error('Sekundverdien "' .. seconds .. '" angitt for ' .. direction .. ' er ugyldig', 2)
end
decimal = decimal + (minutes or 0)/60 + (seconds or 0)/3600
if hemisphere then
local multiplier = hemisphereMultipliers[direction][hemisphere]
if not multiplier then
error('Halvkulen "' .. hemisphere .. '" angitt for ' .. direction .. ' er ugyldig', 2)
end
decimal = decimal * multiplier
end
return decimal
end
-- effectively make removeBlanks false for caption and maplink, and true for everything else
-- if useWikidata is present but blank, convert it to false instead of nil
-- p.top, p.bottom, and their callers need to use this
function p.valueFunc(key, value)
if value then
value = mw.text.trim(value)
end
if value ~= '' or key == 'caption' or key == 'maplink' then
return value
elseif key == 'useWikidata' then
return false
end
end
local function getContainerBilde(args, map)
if args.AlternativeMap then
return args.AlternativeMap
elseif args.relieff and map('relieff') ~= '' then
return map('relieff')
else
return map('bilde')
end
end
function p.top(frame, args, map)
if not args then
args = getArgs(frame, {frameOnly = true, valueFunc = p.valueFunc})
end
if not map then
map = p.getMapParams(args[1], frame)
end
local width
if not args.bredde then
width = round((args.standardwidth or 240) * (tonumber(map('standardskala')) or 1))
elseif mw.ustring.sub(args.bredde, -2) == 'px' then
width = mw.ustring.sub(args.bredde, 1, -3)
else
width = args.bredde
end
local retval = args.float == 'center' and '<div class="center">' or ''
if args.undertekst and args.undertekst ~= '' and args.ramme ~= 'infobox' then
retval = retval .. '<div class="noviewer thumb '
if args.float == '"left"' or args.float == 'left' or args.float == '"venstre"' or args.float == 'venstre' then
retval = retval .. 'floatleft'
elseif args.float == '"center"' or args.float == 'center' or args.float == '"senter"' or args.float == 'senter' or args.float == '"none"' or args.float == 'none' then
retval = retval .. 'tnone'
else
retval = retval .. 'floatright'
end
retval = retval .. '"><div class="thumbinner" style="width:' .. (width + 2) .. 'px'
if args.ramme == 'none' then
retval = retval .. ';border:none'
elseif args.ramme then
retval = retval .. ';border-color:' .. args.ramme
end
retval = retval .. '"><div style="position:relative;width:' .. width .. 'px' .. (args.ramme ~= 'none' and ';border:1px solid lightgray">' or '">')
else
retval = retval .. '<div style="width:' .. width .. 'px;'
if args.float == '"left"' or args.float == 'left' then
retval = retval .. 'float:left;clear:left'
elseif args.float == '"center"' or args.float == 'center' then
retval = retval .. 'float:none;clear:both;margin-left:auto;margin-right:auto'
elseif args.float == '"none"' or args.float == 'none' then
retval = retval .. 'float:none;clear:none'
else
retval = retval .. 'float:right;clear:right'
end
retval = retval .. '"><div style="width:' .. width .. 'px;padding:0"><div style="position:relative;width:' .. width .. 'px">'
end
local bilde = getContainerBilde(args, map)
retval = string.format(
'%s[[File:%s|%spx|%s%s]]',
retval,
bilde,
width,
args.alt or args.undertekst or ((args.label or Pgname({args = {[1] = mw.title.getCurrentTitle().text, [2] = '%s%(.*%)', [3] = '', ['plain'] = 'false'}})) .. ' ligger i ' .. map('navn')),
args.kartlenke and ('|lenke=' .. args.kartlenke) or ''
)
if args.overlay_bilde then
return retval .. '<div style="position:absolute;top:0;left:0">[[Fil:' .. args.overlay_bilde .. '|' .. width .. 'px]]</div>'
else
return retval
end
end
function p.bottom(frame, args, map)
if not args then
args = getArgs(frame, {frameOnly = true, valueFunc = p.valueFunc})
end
if not map then
map = p.getMapParams(args[1], frame)
end
local retval = '</div>'
if not args.undertekst or args.ramme == 'infoboks' or args.ramme == 'infobox' then
if args.ramme then
retval = retval .. '<div>'
else
retval = retval .. '<div style="font-size:90%;padding-top:3px">'
end
retval = retval
.. (args.undertekst or (args.label or Pgname({args = {[1] = mw.title.getCurrentTitle().text, [2] = '%s%(.*%)', [3] = '', ['plain'] = 'false'}})) .. ' (' .. map('navn') .. ')')
.. '</div>'
elseif args.undertekst ~= '' then
-- This is not the pipe trick. We're creating a link with no text on purpose, so that CSS can give us a nice image
retval = retval .. '<div class="thumbcaption"><div class="magnify">[[:File:' .. getContainerBilde(args, map) .. '| ]]</div>' .. args.undertekst .. '</div>'
end
if args.labelBryter then
retval = retval .. '<span class="switcher-label" style="display:none">' .. args.labelBryter .. '</span>'
elseif args.autoSwitcherLabel then
retval = retval .. '<span class="switcher-label" style="display:none">Show map of ' .. map('navn') .. '</span>'
end
retval = retval .. '</div></div>'
if args.undertekst_udefinert then
mw.log('Removed parameter caption_undefined used.')
local parent = frame:getParent()
if parent then
mw.log('Parent is ' .. parent:getTitle())
end
mw.logObject(args, 'args')
retval = retval .. '[[Kategori:Kartposisjoner med mulige feil|Side bruker fjernet parameter]]'
end
if map('skew') ~= '' or map('lat_skew') ~= '' or map('krysser180') ~= '' or map('type') ~= '' then
mw.log('Removed parameter used in map definition ' .. map())
retval = retval .. '[[Kategori:Kartposisjoner med mulige feil|Side bruker fjernet parameter]]'
end
if string.find(map('navn'), '|', 1, true) then
mw.log('Pipe used in name of map definition ' .. map())
retval = retval .. '[[Kategori:Kartposisjoner med mulige feil|Navn inneholder pipe]]'
end
if args.float == 'center' then
retval = retval .. '</div>'
end
return retval
end
local function markOuterDiv(x, y, imageDiv, labelDiv)
return mw.html.create('div')
:cssText('position:absolute;top:' .. round(y, 3) .. '%;left:' .. round(x, 3) .. '%')
:node(imageDiv)
:node(labelDiv)
end
local function markImageDiv(mark, marksize, label, lenke, alt, tittel)
local builder = mw.html.create('div')
:cssText('position:absolute;left:-' .. round(marksize / 2) .. 'px;top:-' .. round(marksize / 2) .. 'px;line-height:0')
:attr('title', tittel)
if marksize ~= 0 then
builder:wikitext(string.format(
'[[Fil:%s|%dx%dpx|%s|link=%s%s]]',
mark,
marksize,
marksize,
label,
lenke,
alt and ('|alt=' .. alt) or ''
))
end
return builder
end
local function markLabelDiv(label, label_size, label_width, position, background, x, marksize)
if tonumber(label_size) == 0 then
return mw.html.create('div'):cssText('font-size:0%;position:absolute'):wikitext(label)
end
local builder = mw.html.create('div')
:cssText('font-size:' .. label_size .. '%;line-height:110%;position:absolute;width:' .. label_width .. 'em')
local distance = round(marksize / 2 + 1)
local spanCss
if position == 'top' or position == 'topp' then -- specified top
builder:cssText('bottom:' .. distance .. 'px;left:' .. (-label_width / 2) .. 'em;text-align:center')
elseif position == 'bottom' or position == 'bunn' then -- specified bottom
builder:cssText('top:' .. distance .. 'px;left:' .. (-label_width / 2) .. 'em;text-align:center')
elseif position == 'left' or position == 'venstre' or (tonumber(x) > 70 and position ~= 'right') or (tonumber(x) > 70 and position ~= 'høyre') then -- specified left or autodetected to left
builder:cssText('top:-0.75em;right:' .. distance .. 'px;text-align:right')
spanCss = 'float:right'
else -- specified right or autodetected to right
builder:cssText('top:-0.75em;left:' .. distance .. 'px;text-align:left')
spanCss = 'float:left'
end
builder = builder:tag('div')
:css('display', 'inline')
:cssText('padding:1px')
:cssText(spanCss)
:wikitext(label)
if background then
builder:cssText('background-color:' .. background)
end
return builder:done()
end
local function getX(longitude, left, right)
local width = (right - left) % 360
if width == 0 then
width = 360
end
local distanceFromLeft = (longitude - left) % 360
-- the distance needed past the map to the right equals distanceFromLeft - width. the distance needed past the map to the left equals 360 - distanceFromLeft. to minimize page stretching, go whichever way is shorter
if distanceFromLeft - width / 2 >= 180 then
distanceFromLeft = distanceFromLeft - 360
end
return 100 * distanceFromLeft / width
end
local function getY(latitude, top, bottom)
return 100 * (top - latitude) / (top - bottom)
end
function p.mark(frame, args, map)
if not args then
args = getArgs(frame, {wrappers = 'Mal:Kartposisjon~','Mal:Kartposisjon', 'Mal:Kartposisjon+', 'Mal:Koord+kart'})
end
if not map then
map = p.getMapParams(args[1], frame)
end
local x, y, longitude, latitude
longitude = decdeg(args.lon_deg, args.lon_min, args.lon_sec, args.lon_dir, args.long, 'longitude')
latitude = decdeg(args.lat_deg, args.lat_min, args.lat_sec, args.lat_dir, args.lat, 'latitude')
if not longitude and not latitude and args.brukWikidata then
-- If they didn't provide either coordinate, try Wikidata. If they provided one but not the other, don't.
local entity = mw.wikibase.getEntity()
if entity and entity.claims and entity.claims.P625 and entity.claims.P625[1].mainsnak.snaktype == 'value' then
local value = entity.claims.P625[1].mainsnak.datavalue.value
longitude, latitude = value.longitude, value.latitude
end
end
if not longitude then
error('Ingen verdi angitt for lengdegrad')
end
if not latitude then
error('Ingen verdi angitt for breddegrad')
end
local builder = mw.html.create()
if (not args.lon_deg) ~= (not args.lat_deg) then
builder:wikitext('[[Kategori:Kartposisjoner med ulike presisjoner for lengde- og breddegrad|Grader]]')
elseif (not args.lon_min) ~= (not args.lat_min) then
builder:wikitext('[[Kategori:Kartposisjoner med ulike presisjoner for lengde- og breddegrad|Minutter]]')
elseif (not args.lon_sec) ~= (not args.lat_sec) then
builder:wikitext('[[Kategori:Kartposisjoner med ulike presisjoner for lengde- og breddegrad|Sekunder]]')
elseif (not args.lon_dir) ~= (not args.lat_dir) then
builder:wikitext('[[Kategori:Kartposisjoner med ulike presisjoner for lengde- og breddegrad|Halvkule]]')
elseif (not args.long) ~= (not args.lat) then
builder:wikitext('[[Kategori:Kartposisjoner med ulike presisjoner for lengde- og breddegrad|Desimal]]')
end
if args.skjevhet or args.lon_shift or args.markhigh then
mw.log('Removed parameter used in invocation.')
local parent = frame:getParent()
if parent then
mw.log('Parent is ' .. parent:getTitle())
end
mw.logObject(args, 'args')
builder:wikitext('[[Kategori:Kartposisjoner med mulige feil|Side bruker fjernet parameter]]')
end
if map('x') ~= '' then
x = tonumber(mw.ext.ParserFunctions.expr(map('x', { latitude, longitude })))
else
x = tonumber(getX(longitude, map('venstre'), map('høyre')))
end
if map('y') ~= '' then
y = tonumber(mw.ext.ParserFunctions.expr(map('y', { latitude, longitude })))
else
y = tonumber(getY(latitude, map('topp'), map('bunn')))
end
if (x < 0 or x > 100 or y < 0 or y > 100) and not args.utenfor then
mw.log('Mark placed outside map boundaries without outside flag set. x = ' .. x .. ', y = ' .. y)
local parent = frame:getParent()
if parent then
mw.log('Parent is ' .. parent:getTitle())
end
mw.logObject(args, 'args')
builder:wikitext('[[Kategori:Kartposisjoner med mulige feil|Utsideflagg ikke satt med merke utenfor kart]]')
end
local mark = args.merke or map('merke')
if mark == '' then
mark = 'Red pog.svg'
end
local marksize = tonumber(args.merke_str) or tonumber(map('merke_str')) or 8
local imageDiv = markImageDiv(mark, marksize, args.label or mw.title.getCurrentTitle().text, args.lenke or '', args.alt, args[2])
local labelDiv
if args.stedsnavn and args.posisjon ~= 'none' then
labelDiv = markLabelDiv(args.stedsnavn, args.stedsnavn_str or args['tekststørrelse'] or 90, args.label_width or args.tekstbredde or 6, args.posisjon, args.farge, x, marksize)
end
return builder:node(markOuterDiv(x, y, imageDiv, labelDiv))
end
function p.main(frame, args, map)
if not args then
args = getArgs(frame, {wrappers = 'Mal:Kartposisjon ', valueFunc = p.valueFunc})
end
if args.brukWikidata == nil then
args.brukWikidata = true
end
if not map then
if args[1] then
map = {}
for mapname in string.gmatch(args[1], '[^#]+') do
map[#map + 1] = p.getMapParams(mapname, frame)
end
if #map == 1 then map = map[1] end
else
map = p.getMapParams('Verden', frame)
end
end
if type(map) == 'table' then
local outputs = {}
args.autoSwitcherLabel = true
for k,v in ipairs(map) do
outputs[k] = p.main(frame, args, v)
end
return '<div class="switcher-container">' .. table.concat(outputs) .. '</div>'
else
return p.top(frame, args, map) .. tostring( p.mark(frame, args, map) ) .. p.bottom(frame, args, map)
end
end
function p.printCoordRegion(frame)
local mappage = require("Modul:Kartposisjon/data/" .. frame.args[1])
local coordregion = mappage.region
return coordregion
end
function p.printWidth(frame)
local mappage = require("Modul:Kartposisjon/data/" .. frame.args[1])
local width = mappage.bredde or 240
local scale = mappage.standardskala or 1
local widthOut = width * scale
return widthOut
end
return p
Content Disclaimer
Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.
- The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
- There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
- It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
- Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
- Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.