Modulo:Location map
Istruzioni per l'uso
Questo è un modulo scritto in Lua. Le istruzioni che seguono sono contenute nella sottopagina Modulo:Location map/man (modifica · cronologia)
Sandbox: Modulo:Location map/sandbox (modifica · cronologia) · Test: Modulo:Location map/test (modifica · cronologia · Esegui)
Questo è un modulo scritto in Lua. Le istruzioni che seguono sono contenute nella sottopagina Modulo:Location map/man (modifica · cronologia)
Sandbox: Modulo:Location map/sandbox (modifica · cronologia) · Test: Modulo:Location map/test (modifica · cronologia · Esegui)
Funzione
Luoghi in Egitto |
Mappa della Russia |
Funzioni della mappa
function locMap.locationMap(frame)
Rappresenta una mappa con una posizione. È possibile inserire posizioni e oggetti aggiuntivi.
function locMap.addLocation(frame)
Aggiunge un'altra posizione sulla mappa.
function locMap.addObject(frame)
Inserisce qualsiasi oggetto nella mappa.
Documentazione dei dati cartografici regionali
function locMap.getMapValue(frame)
Restituisce il valore di un parametro associato ad una mappa.
function locMap.getMapValueSet(frame)
Crea una tabella con i valori di tutti i parametri associati ad una mappa.
Ulteriori moduli necessari
Utilizza le segeunti sottopagine:
-- documentation
local LocationMap = {
suite = 'Location map',
serial = '2020-10-24',
item = 15934920
}
-- module import
-- require('strict')
local cd = require( 'Module:Coordinates' )
local li = require( 'Module:Location map/i18n' )
local lp = require( 'Module:Location map/Params' )
-- module variable
local locMap = {
maintenance = {}
}
-- Local functions, please do not call them directly
local function split( s )
local tb = mw.text.split( s, ';' )
for i = #tb, 1, -1 do
tb[ i ] = mw.text.trim( tb[ i ] )
if tb[ i ] == '' then
table.remove( tb, i )
end
end
return tb
end
local function analyzeStyle( style, list )
local tb = split( style )
local l
for i, tbItem in ipairs( tb ) do
l = list[ tbItem ]
if l then
tb[ i ] = l
end
end
return table.concat( tb, '; ' )
end
local function addMaintenance( s )
if s and s ~= '' then
table.insert( locMap.maintenance, s )
end
end
local function getMaintenance()
local m = table.concat( locMap.maintenance, ' ' )
if m ~= '' then
m = '<span class="error">' .. m .. '</span>'
end
return m
end
local function setLocation( args )
local lmarksize = math.floor( args.marksize + 0.5 )
local msize = math.floor( ( args.marksize - 1 ) / 2 + 0.5 )
local msize3 = math.floor( ( args.marksize + 2 ) / 2 + 0.5 )
local msize5 = math.floor( ( args.marksize + 4 ) / 2 + 0.5 )
local centerPosition = -msize .. 'px'
-- create marker box
local markerBox = mw.html.create( 'div' )
:cssText( li.styles.location:gsub( ';$', '' ) )
:css( { top = args.y * 100 .. '%',
left = args.x * 100 .. '%' } )
-- add marker symbol
if args.mark ~= 'none' then
markerBox:node( mw.html.create( 'div' )
:cssText( li.styles.location:gsub( ';$', '' ) )
:css( {
top = centerPosition,
left = centerPosition,
[ 'min-width' ] = lmarksize .. 'px',
[ 'min-height' ] = lmarksize .. 'px'
} )
:wikitext( mw.ustring.format( '[[File:%s|%sx%spx|top|class=noviewer|link=%s|%s]]',
args.mark, lmarksize, lmarksize, args.name, args.name) )
)
end
-- add label
if args.label ~= '' and args.label ~= 'none' then
local styles = { li.styles.location }
if args.labelWrap and args.labelWrap == 'manual' then
table.insert( styles, li.styles.labelWidthNowrap )
else
-- prevent early wrapping
table.insert( styles, li.styles.labelWidth )
end
local pos = li.labelPositions[ args.labelPosition ]
if pos then
pos = pos:gsub( 'msize_', msize )
:gsub( 'msize3_', msize3 )
:gsub( 'msize5_', msize5 )
table.insert( styles, pos )
else
-- estimation of posititon
if args.y <= 0.5 then
table.insert( styles, 'top:' .. msize3 .. 'px;' )
else
table.insert( styles, 'bottom:' .. msize3 .. 'px;' )
end
if args.x < 0.25 then
table.insert( styles, 'text-align:left; left:'
.. math.floor( 3 - 60 * args.x ) / 10 .. 'em;' )
elseif args.x < 0.75 then
table.insert( styles, li.styles.centerX )
else
table.insert( styles, 'text-align:right; right:'
.. math.floor( 10 * ( 0.3 - ( 1 - args.x ) * 6 ) ) / 10 .. 'em;' )
end
end
table.insert( styles, analyzeStyle( args.labelStyle, li.labelStyles ) )
markerBox:node( mw.html.create( 'div' )
:cssText( table.concat( styles, ' ' ) )
:wikitext( args.label )
)
end
return tostring( markerBox )
end
local function baseMap( args )
-- map and map container
local map = mw.ustring.format( '[[File:%s|%spx|center|class=noviewer|%s]]',
args.mapImage, args.width, args.description )
-- add marker
if args.x < 0 or args.x > 1 or args.y < 0 or args.y > 1 then
map = map .. tostring( mw.html.create( 'div' )
:cssText( li.styles.mapError )
:wikitext( mw.ustring.format( li.errMsgs.coordError, args.name ) )
)
else
map = map .. setLocation( args )
end
-- add places
map = map .. args.places
local style = li.styles.mapDiv .. ( args.caption == '' and 'border:none'
or ( 'border:' .. args.captionInnerBorder ) )
map = mw.html.create( 'div' )
:cssText( style )
:wikitext( map )
-- create outer box
style = li.styles.mapBox
if args.caption ~= '' then
style = style .. 'border:' .. args.captionOuterBorder .. ';'
end
style = style .. analyzeStyle( args.mapStyle, li.mapStyles )
local mapBox = mw.html.create( 'table' )
:addClass( 'locationMap' )
:cssText( style )
local row = mw.html.create( 'tr' )
:node( mw.html.create( 'td' )
:addClass( 'thumb' )
:cssText( li.styles.mapCell
.. ( args.caption == '' and 'padding:0' or '' ) )
:node( map )
)
mapBox:node( row )
-- add map caption
if args.caption ~= '' then
row = mw.html.create( 'tr' )
:node( mw.html.create( 'td' )
:addClass( 'thumbcaption' )
:cssText( li.styles.mapCaption .. args.captionStyle )
:wikitext( args.caption )
)
mapBox:node( row )
end
return tostring( mapBox )
end
-- Handling regional map data
-- This function is never to be called directly but with a pcall()
-- to handle exceptions in case of missing map modules
local function getMapData( id )
local region = require( li.modulePrefix .. id )
if region then
region.id = id
return region
end
return nil
end
local function linearX( mapData, long )
local left = mapData.left
local right = mapData.right
if not mapData or not left or not right or left == right then
-- error
return -1
elseif left < right then
return ( long - left ) / ( right - left )
elseif long < 0 then
return ( 360 + long - left ) / ( 360 + right - left )
else
return ( long - left ) / ( 360 + right - left )
end
end
local function linearY( mapData, lat )
local top = mapData.top
local bottom = mapData.bottom
if not mapData or not top or not bottom or top == bottom then
-- error
return -1
end
return ( lat - top ) / ( bottom - top )
end
local function getX( mapData, long, lat )
if mapData.x then
return mapData.x( lat, long )
else
return linearX( mapData, long )
end
end
local function getY( mapData, long, lat )
if mapData.y then
return mapData.y( lat, long )
else
return linearY( mapData, lat )
end
end
local function getMapImage( mapData, which )
local image = mapData.default
if which == 'quickbar' then
which = li.defaults.quickbarMapType
if mapData.quickbar and mapData.quickbar ~= '' then
which = mapData.quickbar
end
end
if which ~= '' and mapData[ which ] and mapData[ which ] ~= '' then
image = mapData[ which ]
end
return image
end
-- parameters handling
local function argCheck( param, altValue )
if not param or param == '' then
return altValue
end
local val = mw.text.trim( param )
if val == '' then
val = altValue
end
return val
end
local function checkMarkerProperties( args, mapData )
args.name = argCheck( args.name, '' )
args.label = argCheck( args.label, '' )
args.mark = argCheck( args.mark, mapData.mark or li.defaults.marker )
args.marksize = argCheck( args.marksize, mapData.marksize or li.defaults.marksize )
args.labelStyle = argCheck( args.labelStyle, '' )
args.labelBackground = argCheck( args.labelBackground, '' )
if args.labelBackground ~= '' then
args.labelBackground = 'background: ' .. args.labelBackground
if args.labelStyle ~= '' then
args.labelStyle = args.labelStyle .. '; ' .. args.labelBackground
else
args.labelStyle = args.labelBackground
end
end
args.labelWrap = argCheck( args.labelWrap, 'auto' )
args.labelPosition = argCheck( args.labelPosition, 'auto' )
return args
end
local function checkCoordinate( args, mapData )
local success = true
local t
args.lat = argCheck( tostring( args.lat ), '' )
args.long = argCheck( tostring( args.long ), '' )
if args.lat ~= '' and args.long ~= '' then
t = tonumber( args.lat )
if t then
args.lat = math.abs( t ) <= 90 and t or ''
else
t = cd.toDec( args.lat, 'lat', 6 )
args.lat = t.error == 0 and t.dec or ''
end
t = tonumber( args.long )
if t then
args.long = ( t > -180 and t <= 180 ) and t or ''
else
t = cd.toDec( args.long, 'long', 6 )
args.long = t.error == 0 and t.dec or ''
end
end
if args.lat == '' or args.long == '' then
return -1, -1, false
end
local x = getX( mapData, args.long, args.lat )
if x < 0 or x > 1 then
success = false
if x == -1 then
addMaintenance( li.errMsgs.wrongXBorders )
else
addMaintenance( mw.ustring.format( li.errMsgs.wrongLong,
tonumber( args.long ) or 0 ) )
end
end
local y = getY( mapData, args.long, args.lat )
if y < 0 or y > 1 then
success = false
if y == -1 then
addMaintenance( li.errMsgs.wrongYBorders )
else
addMaintenance( mw.ustring.format( li.errMsgs.wrongLat,
tonumber( args.lat ) or 0 ) )
end
end
return x, y, success
end
local function checkParameters( args, list )
local unknown = {}
for key, value in pairs( args ) do
if not list[ key ] then
table.insert( unknown, "''" .. key .. "''" )
end
end
local category = li.errMsgs.wrongParam
if #unknown == 1 then
addMaintenance( category
.. mw.ustring.format( li.errMsgs.unknownParam, unknown[ 1 ] ) )
elseif #unknown > 1 then
addMaintenance( category .. mw.ustring.format( li.errMsgs.unknownParams,
table.concat( unknown, ', ' ) ) )
end
end
-- Map functions
local function apiLocationMap( args )
local map = argCheck( args.map, 'missing' )
local success, mapData = pcall( getMapData, map )
if not success then
return mw.ustring.format( li.errMsgs.unknownMap, map )
end
-- Parameters check
addMaintenance( checkParameters( args, lp.locationMap ) )
if not args.lat or not args.long then
addMaintenance( li.errMsgs.notANumber )
return getMaintenance()
end
args.x, args.y, success = checkCoordinate( args, mapData )
args.maptype = argCheck( args.maptype, 'default' )
args.mapImage = argCheck( args.alternativeMap, getMapImage( mapData, args.maptype ) )
if not args.mapImage or args.mapImage == '' then
success = false
addMaintenance( li.errMsgs.noMapImage )
end
if not success then
return getMaintenance()
end
args.caption = argCheck( args.caption, '' )
args.captionStyle = argCheck( args.captionStyle, '' )
args.captionInnerBorder = argCheck( args.captionInnerBorder, li.styles.innerBorder )
args.captionOuterBorder = argCheck( args.captionOuterBorder, li.styles.outerBorder )
args.places = argCheck( args.places, '' )
args.mapStyle = argCheck( args.mapStyle, 'center' )
-- Image size and description
args.width = argCheck( tostring( args.width ), '' )
if not args.width:match( '^%d+$' ) and not args.width:match( '^%d*x%d+$' ) then
args.width = li.defaults.imgSize
end
args.description = ''
if mapData.description then
args.description = mapData.description
end
args = checkMarkerProperties( args, mapData )
return baseMap( args ) .. getMaintenance()
end
local function apiAddLocation( args )
local map = argCheck( args.map, 'missing' )
local success, mapData = pcall( getMapData, map )
if not success then
return mw.ustring.format( li.errMsgs.unknownMap, map )
end
-- Parameters check
addMaintenance( checkParameters( args, lp.locationMapLocation ) )
if not args.lat or not args.long then
addMaintenance( li.errMsgs.notANumber )
return getMaintenance()
end
args.x, args.y, success = checkCoordinate( args, mapData )
if not success then
return getMaintenance()
end
args = checkMarkerProperties( args, mapData )
return setLocation( args ) .. getMaintenance()
end
local function apiAddObject( args )
args.object = argCheck( args.object, '' )
if args.object == '' then
return li.errMsgs.noObject
end
local success = true
addMaintenance( checkParameters( args, lp.locationMapObject ) )
args.right = argCheck( args.right, '' )
args.left = argCheck( args.left, '' )
if args.right == '' and args.left == '' then
success = false
addMaintenance( li.errMsgs.noXPos )
end
args.top = argCheck( args.top, '' )
args.bottom = argCheck( args.bottom, '' )
if args.top == '' and args.bottom == '' then
success = false
addMaintenance( li.errMsgs.noYPos )
end
if not success then
return getMaintenance()
end
args.objectStyle = argCheck( args.objectStyle, '' )
args.objectBackground = argCheck( args.objectBackground, '' )
if args.objectBackground ~='' then
args.objectBackground = 'background: ' .. args.objectBackground
if args.objectStyle ~='' then
args.objectStyle = args.objectStyle .. '; ' .. args.objectBackground
else
args.objectStyle = args.objectBackground
end
end
local style = li.styles.objectBox
if args.left ~= '' then
style = style .. 'left:' .. args.left .. ';'
else
style = style .. 'right:' .. args.right .. ';'
end
if args.top ~= '' then
style = style .. 'top: ' .. args.top .. ';'
else
style = style .. 'bottom: ' .. args.bottom .. ';'
end
style = style .. analyzeStyle( args.objectStyle, li.labelStyles )
return tostring( mw.html.create( 'div' )
:addClass( 'locationMapObject' )
:cssText( style )
:wikitext( args.object )
) .. getMaintenance()
end
-- Documentation of map data
local function apiGetMapValue( args )
local map = argCheck( args.map, 'missing' )
local success, mapData = pcall( getMapData, map )
if not success then
return mw.ustring.format( li.errMsgs.unknownMap, map )
end
args.param = argCheck( args.param, '' )
if args.param == '' then
return li.errMsgs.noParam
else
return mapData[ args.param ] or li.errMsgs.anError
end
end
local function apiGetMapValueSet( args )
local map = argCheck( args.map, 'missing' )
local success, mapData = pcall( getMapData, map )
if not success then
return mw.ustring.format( li.errMsgs.unknownMap, map )
end
local row, v
local list = mw.html.create( 'table' )
:addClass( li.mapDocs.tableClass )
for i, j in ipairs( li.paramList ) do
v = mapData[ j ]
if not v then
v = li.errMsgs.notDefined
else
if j == 'default' or j == 'relief' then
v = mw.ustring.format( '[[c:File:%s|%s]]', v, v )
elseif li.mapDocs[ v ] then
v = li.mapDocs[ v ]
end
end
row = mw.html.create( 'tr' )
:node(
mw.html.create( 'th' )
:css( 'text-align', 'left' )
:wikitext( li.mapDocs[ j ] )
)
:node(
mw.html.create( 'td' )
:wikitext( v )
)
list:node( row )
end
local titleObj = mw.title.getCurrentTitle()
if titleObj.text == titleObj.baseText then
-- not a subpage
if not mapData.relief then
addMaintenance( li.errMsgs.noReliefMap )
end
end
return tostring( list ) .. getMaintenance()
end
-- API function calls
locMap[ li.api.apiLocationMap ] = function( frame )
return apiLocationMap( frame.args )
end
locMap[ li.api.apiAddLocation ] = function( frame )
return apiAddLocation( frame.args )
end
locMap[ li.api.apiAddObject ] = function( frame )
return apiAddObject( frame.args )
end
locMap[ li.api.apiGetMapValue ] = function( frame )
return apiGetMapValue( frame.args )
end
locMap[ li.api.apiGetMapValueSet ] = function( frame )
return apiGetMapValueSet(frame.args)
end
-- example for usage in a Lua script
function locMap.exampleLuaCall()
local frame = {}
frame.args = {
map = 'it',
lat = 41.88333,
long = 12.48333,
name = 'Roma',
label = '[[Roma]]',
}
return locMap.locationMap( frame )
end
return locMap