Istruzioni per l'uso
Questo è un modulo scritto in Lua. Le istruzioni che seguono sono contenute nella sottopagina Modulo:Mappa di localizzazione IAU/man (modifica · cronologia)
Sandbox: Modulo:Mappa di localizzazione IAU/sandbox (modifica · cronologia) · Sottopagine: lista · Test: Modulo:Mappa di localizzazione IAU/test (modifica · cronologia · Esegui)
Questo è un modulo scritto in Lua. Le istruzioni che seguono sono contenute nella sottopagina Modulo:Mappa di localizzazione IAU/man (modifica · cronologia)
Sandbox: Modulo:Mappa di localizzazione IAU/sandbox (modifica · cronologia) · Sottopagine: lista · Test: Modulo:Mappa di localizzazione IAU/test (modifica · cronologia · Esegui)
Modulo che implementa il template {{Mappa di localizzazione IAU}}.
Ha una sottopagina di configurazione: Modulo:Mappa di localizzazione IAU/Configurazione.
--[[
* Modulo che implementa il template Mappa di localizzazione IAU.
]]--
require('strict')
local getArgs = require('Modulo:Arguments').getArgs
local mRaDec = require('Modulo:RaDec')
local cfg = mw.loadData('Modulo:Mappa di localizzazione IAU/Configurazione')
local errorCategory = '[[Categoria:Voci con errori del modulo Mappa di localizzazione IAU]]'
-- Error handler per xpcall, formatta l'errore.
--
-- @param {string} msg
-- @return {string}
local function errhandler(msg)
local cat = mw.title.getCurrentTitle().namespace == 0 and errorCategory or ''
return string.format('<span class="error">%s</span>%s', msg, cat)
end
-- Restituisce il numero arrotondato al numero di cifre decimali richiesto.
-- http://lua-users.org/wiki/SimpleRound
--
-- @param {number} num
-- @param {number} idp
-- @return {number}
local function round(num, idp)
local mult = 10 ^ (idp or 0)
return math.floor(num * mult + 0.5) / mult
end
-- Converte la declinazione da gradi/minuti/secondi in gradi decimali.
--
-- @param {table} dec
-- @return {number}
local function dec2deg(dec)
return dec.sign * (dec.d + dec.m / 60 + dec.s / 3600)
end
-- Converte l'ascensione retta da ore/minuti/secondi in gradi decimali.
--
-- @param {table} ar
-- @return {number}
local function ar2deg(ar)
return ar.h * 15 + ar.m / 4 + ar.s / 240
end
-- Parsifica il parametro ar con formato "ore/minuti/secondi".
--
-- @param {table} args
-- @return {number}
local function parseArSlash(args)
local h, m, s = string.match(args.ar, '^([%d]+)/(%d+)/([%d,%.]+)$')
h, m, s = tonumber(h), tonumber(m), tonumber(s)
return (h and m and s) and ar2deg({ h = h, m = m, s = s }) or nil
end
-- Parsifica il parametro declinaz con formato "gradi/minuti/secondi".
--
-- @param {table} args
-- @return {number}
local function parseDecSlash(args)
local sign
local d, m, s = string.match(args.declinaz, '^(-?%d+)/(%d+)/([%d,%.]+)$')
d, m, s = tonumber(d), tonumber(m), tonumber(s)
if d then
sign = (d < 0 or tostring(d) == '-0') and -1 or 1
d = math.abs(d)
end
return (sign and d and m and s) and dec2deg({ sign = sign, d = d, m = m, s = s }) or nil
end
-- Restituisce l'offset in pixel dal margine sinistro di un corpo celeste
-- su una certa mappa, in base all'ascensione retta, alla declinazione,
-- alla larghezza voluta della mappa e del marker.
-- Le funzioni getX e getY sono state ottenute dalle formule di Ysogo in
-- Discussioni_progetto:Astronomia#Posizione_nella_mappa_della_costellazione:
-- X = Ax+(Aw/2)+(Ah/(DECsup-DECinf))*(DECogg-DECfuoco)*sen((ARmed-ARogg)/disang)
-- Y = Ay+Ah-(Ah/(DECsup-DECinf))*((DECogg-DECfuoco)*cos((ARmed-ARogg)/disang)-(DECinf-DECfuoco))
--
-- @param {table} map
-- @param {number} ar
-- @param {number} dec
-- @param {number} width
-- @param {number} marksize
-- @return {number}
local function getX(map, ar, dec, width, marksize)
local x = map.ax + map.aw / 2 +
(map.ah / (map.dec_sup - map.dec_inf)) *
(dec - map.dec_fuoco) *
math.sin(((map.ar_med - ar) / map.dis_ang) * (math.pi / 180))
-- scala il risultato in base a width e centra il marker
return round(x * width / map.iw - marksize / 2)
end
-- Restituisce l'offset in pixel dal margine superiore di un corpo celeste
-- su una certa mappa, in base all'ascensione retta, alla declinazione,
-- alla larghezza voluta della mappa e del marker.
--
-- @param {table} map
-- @param {number} ar
-- @param {number} dec
-- @param {number} width
-- @param {number} marksize
-- @return {number}
local function getY(map, ar, dec, width, marksize)
local y = map.ay + map.ah -
(map.ah / (map.dec_sup - map.dec_inf)) *
((dec - map.dec_fuoco) * math.cos(((map.ar_med - ar) / map.dis_ang) * (math.pi / 180)) - (map.dec_inf - map.dec_fuoco) )
-- scala il risultato in base a width e centra il marker
return round(y * width / map.iw - marksize / 2)
end
-- Restituisce un div per il posizionamento della mappa nel corpo della pagina
-- invece che in un sinottico.
--
-- @param {string} text
-- @param {string} image
-- @param {table} args
-- @param {number} width
-- @return {string}
local function getThumbnail(text, image, args, width)
local divNode = mw.html.create('div')
divNode
:addClass('thumb')
:addClass(args.float == 'right' and 'tright' or 'tleft')
:tag('div')
:addClass('thumbinner')
:css('width', width .. 'px')
:wikitext(text)
:tag('div')
:addClass('thumbcaption')
:wikitext(args.didascalia or '')
:tag('div')
:addClass('magnify')
:wikitext(string.format('[[:File:%s]]', image))
return tostring(divNode)
end
-- =============================================================================
-- Funzioni esportate
-- =============================================================================
local p = {}
-- Funzione di utilità per il manuale, restituisce l'elenco dei codici delle mappe configurate.
function p.maps()
local sortedMaps = {}
for key, _ in pairs(cfg.mappe) do
table.insert(sortedMaps, key)
end
table.sort(sortedMaps)
return mw.text.listToText(sortedMaps)
end
-- Funzione di utilità, restituisce 1 se la mappa specificata è disponibile altrimenti nil.
function p.hasmap(frame)
local mappa = frame.args[1] and mw.ustring.lower(frame.args[1])
return (cfg.alias[mappa] or cfg.mappe[mappa]) and 1
end
-- Funzione per l'utilizzo da un altro modulo.
function p._main(args)
local map, ar, dec, text
local width = tonumber(args.width) or 260
local marksize = tonumber(args.marksize) or 15
-- ottiene la mappa
if args.mappa then
args.mappa = mw.ustring.lower(args.mappa)
else
error('mappa non specificata', 2)
end
-- eventuale alias
args.mappa = cfg.alias[args.mappa] or args.mappa
if not cfg.mappe[args.mappa] then
error('mappa non disponibile: ' .. args.mappa, 2)
end
map = cfg.mappe[args.mappa]
-- ottiene ascensione retta e declinazione
if args.RA and args.DEC then
ar = mRaDec.parseRA(args.RA)
dec = mRaDec.parseDEC(args.DEC)
if ar and dec then
ar = ar2deg(ar)
dec = dec2deg(dec)
end
elseif args.ar_dec and args.declinaz_dec then
ar = args.ar_dec
dec = args.declinaz_dec
elseif args.ar and args.declinaz then
ar = parseArSlash(args)
dec = parseDecSlash(args)
end
if not ar or not dec then
error('coordinate celesti invalide', 2)
end
-- mappa doppia
if args.mappa == 'ser' then
map = ar > 255 and map.cauda or map.caput
end
-- per le costellazioni che attraversano il meridiano fondamentale
if map.ar_med > ar + 180 then
ar = ar + 360
end
-- utilizza il template Sovraimmagine
text = mw.getCurrentFrame():expandTemplate {
title = 'Sovraimmagine',
args = {
sotto = map.image,
sotto_larghezza = width .. 'px',
sotto_didascalia = '',
sopra = args.mark or 'Cercle rouge 100%.svg',
sopra_larghezza = marksize .. 'px',
sopra_didascalia = args.nome or '',
x = getX(map, ar, dec, width, marksize),
y = getY(map, ar, dec, width, marksize)
}
}
return args.sinottico and text or getThumbnail(text, map.image, args, width + 2)
end
-- Funzione per il template {{Mappa di localizzazione IAU}}.
function p.main(frame)
return select(2, xpcall(function()
return p._main(getArgs(frame, { parentOnly = true }))
end, errhandler))
end
return p