
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