Modul:Location map
This module is rated as ready for general use. It has reached a mature form and is thought to be relatively bug-free and ready for use wherever appropriate. It is ready to mention on help pages and other Wikipedia resources as an option for new users to learn. To reduce server load and bad output, it should be improved by sandbox testing rather than repeated trial-and-error editing. |
Dieses Modul verwendet TemplateStyles. Die Stilvorlagen sind in den folgenden Dateien notiert: |
Das Modul Location map
stellt Funktionen zur Erstellung von Positionskarten bereit. Technische Hintergrundinformationen befinden sich in Wikivoyage:Location map.
Funktionen
Kartenfunktionen
function locMap.locationMap(frame)
Stellt eine Karte mit einem Ort dar. Es können weitere Orte und Objekte eingefügt werden.
function locMap.addLocation(frame)
Ergänzt einen weiteren Ort auf der Karte.
function locMap.addObject(frame)
Fügt ein beliebiges Objekt in die Karte ein.
Dokumentation regionaler Kartendaten
function locMap.getMapValue(frame)
Gibt den Wert eines Parameters einer Kartendefinition aus.
function locMap.getMapValueSet(frame)
Erstellt eine Tabelle mit den Parametern einer Kartendefinition.
Benötigte weitere Module
Dieses Modul benötigt folgende weitere Module: Coordinates • Location map/i18n • Location map/Params • Location map/styles.css
Verwendung in anderen Modulen
Dieses Modul ist notwendig für die Ausführung folgender Module. Bei Anpassungen sollte die Funktionstüchtigkeit der folgenden Module geprüft werden. Benutze dazu auch diese Tracking-Kategorie um Fehler zu finden, die sich dann auf Artikel auswirken:
- Quickbar2
- Modul benötigt das Modul Location map – Wartungskategorie, in der nochmals alle Module gelistet sind, die von diesem Modul abhängig sind.
-- documentation local LocationMap = { suite = 'Location map', serial = '2022-10-21', 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 getClass( style, list ) local tb = split( style ) local class, rule for i = #tb, 1, -1 do rule = tb[ i ] if list[ rule ] then class = list[ rule ] table.remove( tb, i ) end end return class, 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 isSet( s ) if not s then return s end s = mw.text.trim( s ) if s ~= '' then return s else return nil end end local function round( n ) return math.floor( n * 100 + 0.5 ) / 100 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' ) :addClass( 'voy-locmap-marker-box' ) :css( { top = round( args.y * 100 ) .. '%', left = round( args.x * 100 ) .. '%' } ) -- add marker symbol if args.mark ~= 'none' then markerBox:node( mw.html.create( 'div' ) :addClass( 'voy-locmap-marker-symbol' ) :css( { top = centerPosition, left = centerPosition, [ 'min-width' ] = lmarksize .. 'px', [ 'min-height' ] = lmarksize .. 'px' } ) :wikitext( mw.ustring.format( '[[File:%s|%sx%spx|top|class=noviewer notpageimage|link=%s|%s]]', args.mark, lmarksize, lmarksize, args.name, args.name) ) ) end -- add label local wrapClass, labelClass if args.label ~= '' and args.label ~= 'none' then if args.labelWrap == 'manual' then wrapClass = 'voy-locmap-marker-label-nowrap' end local styles = {} 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, li.labelPositions.yTop:format( msize3 ) ) else table.insert( styles, li.labelPositions.yBottom:format( msize3 ) ) end if args.x < 0.25 then table.insert( styles, li.labelPositions.xLeft:format( math.floor( 3 - 60 * args.x ) / 10 ) ) elseif args.x <= 0.75 then table.insert( styles, li.labelPositions.xCenter ) else table.insert( styles, li.labelPositions.xRight:format( math.floor( 3 - 60 * ( 1 - args.x ) ) / 10 ) ) end end labelClass, args.labelStyle = getClass( args.labelStyle, li.labelClasses ) table.insert( styles, args.labelStyle ) markerBox:node( mw.html.create( 'div' ) :addClass( 'voy-locmap-marker-label' ) :addClass( wrapClass ) :addClass( labelClass ) :cssText( isSet( table.concat( styles, ' ' ) ) ) :node( mw.html.create( 'span' ) :addClass( 'voy-locmap-marker-label-text' ) :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 notpageimage|link=|%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' ) :addClass( 'voy-locmap-error' ) :wikitext( mw.ustring.format( li.errMsgs.coordError, args.name ) ) ) else map = map .. setLocation( args ) end local style = ( args.caption ~= '' and args.captionInnerBorder ~= '' ) and ( 'border:' .. args.captionInnerBorder ) or '' map = mw.html.create( 'div' ) :addClass( 'voy-locmap-map-box' ) :cssText( isSet( style ) ) :wikitext( map .. args.places ) -- adding places to map -- add map caption local caption, class if args.caption ~= '' then caption = mw.html.create( 'div' ) :addClass( 'thumbcaption voy-locmap-caption' ) :cssText( isSet( args.captionStyle ) ) :wikitext( args.caption ) end -- create outer box class, style = getClass( args.mapStyle, li.mapClasses ) class = isSet( class ) or 'voy-locmap-center' if args.caption ~= '' and args.captionOuterBorder ~= '' then style = style .. '; border:' .. args.captionOuterBorder end return tostring( mw.html.create( 'div' ) :addClass( 'voy-locmap' ) :addClass( class ) :addClass( args.caption ~= '' and 'voy-locmap-with-caption' or nil ) :cssText( isSet( style ) ) :node( map ) :node( caption ) ) 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 end return region 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 return -1 -- error 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 return -1 -- error 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 or '' ) ~= '' then which = mapData.quickbar end end if which ~= '' and ( mapData[ which ] or '' ) ~= '' then image = mapData[ which ] end return image end -- parameters handling local function argCheck( param, altValue ) if not param or param == '' then return altValue end param = mw.text.trim( param ) if param == '' then param = altValue end return param end -- checking a set of arguments local function argsCheck( args, keys ) for i, key in ipairs( keys ) do args[ key ] = argCheck( args[ key ], '' ) end end local function checkMarkerProperties( args, mapData ) args.mark = argCheck( args.mark, mapData.mark or li.defaults.markerImg ) args.marksize = argCheck( args.marksize, mapData.marksize or li.defaults.markerSize ) argsCheck( args, { 'name', 'label', 'labelWrap', 'labelPosition', 'labelStyle', '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 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 ( args.mapImage or '' ) == '' then success = false addMaintenance( li.errMsgs.noMapImage ) end if not success then return getMaintenance() end argsCheck( args, { 'caption', 'captionStyle', 'captionInnerBorder', 'captionOuterBorder', 'places', 'mapStyle' } ) -- 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.mapSize end args.description = mapData.description or '' 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 ) argsCheck( args, { 'object', 'right', 'left', 'top', 'bottom', 'objectStyle', 'objectBackground' } ) if args.object == '' then return li.errMsgs.noObject end local success = true addMaintenance( checkParameters( args, lp.locationMapObject ) ) if args.right == '' and args.left == '' then success = false addMaintenance( li.errMsgs.noXPos ) end if args.top == '' and args.bottom == '' then success = false addMaintenance( li.errMsgs.noYPos ) end if not success then return getMaintenance() end 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, labelClass if args.left ~= '' then style = 'left: ' .. args.left .. ';' else style = 'right: ' .. args.right .. ';' end if args.top ~= '' then style = style .. 'top: ' .. args.top .. ';' else style = style .. 'bottom: ' .. args.bottom .. ';' end labelClass, args.objectStyle = getClass( args.objectStyle, li.labelClasses ) style = style .. args.objectStyle return tostring( mw.html.create( 'div' ) :addClass( 'voy-locmap-object' ) :addClass( labelClass ) :cssText( isSet( 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 local function templateStyles() local frame = mw.getCurrentFrame() return frame:extensionTag( 'templatestyles', '', { src = 'Module:Location map/styles.css' } ); end locMap[ li.api.apiLocationMap ] = function( frame ) return templateStyles() .. 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 = 'de', lat = 52.51789, long = 13.38873, name = 'Berlin', label = '[[Berlin]]', } return locMap.locationMap( frame ) end return locMap
- Seiten mit Syntaxhervorhebungsfehlern
- Modules for general use
- Vorlagen:Mit templatestyles
- Modul benötigt das Modul Coordinates
- Modul benötigt das Modul Location map/i18n
- Modul benötigt das Modul Location map/Params
- Modul benötigt das Modul Location map/styles.css
- Module, die in anderen Modulen verwendet werden
- Module:Positionskarten