Modul:Marker
Notwendiges Modul für die Benutzung der Vorlage {{Marker}}
-- module import
local mc = require( 'Modul:Marker/Colors' )
local mi = require( 'Modul:Marker/Maki icons' )
local mp = require( 'Modul:Marker/Params' )
local ma = require( 'Modul:Map' )
local pc = require( 'Modul:ParamsCheck' )
local vt = require( 'Modul:Marker/Types' ) -- types to groups like drink, eat, go, see, sleep, ...
local pt = require( 'Modul:Marker/POITypes' ) -- WD types to vCard/Poi types
local cd = require( 'Modul:Coordinates' )
local uc = require( 'Modul:UrlCheck' )
local yn = require( 'Modul:Yesno' )
local mk = {}
mk.categories = {
['poiNumbersUsed'] = '[[Category:Poi-Nummer manuell vergeben]]',
['poiNumberIsZero'] = '[[Category:Poi-Nummer auf Null gesetzt]]',
['missingCoord'] = '[[Category:Marker: Ohne Koordinaten]]',
['missingName'] = '[[Category:Marker: Ohne Namen]]',
['unknownFormat'] = '[[Category:Marker: Unbekanntes Format]]',
['unknownIcon'] = '[[Category:Marker: Unbekanntes Symbol]]',
['unknownType'] = '[[Category:Marker: Unbekannter Typ]]',
['dmsCoordinate'] = '[[Category:Marker: DMS-Koordinate]] <span class="listing-vcardInfo" title="DMS-Koordinate">DMS-Koordinate</span>'
}
mk.errorMsg = {
['poiNumbersUsed'] = 'Poi-Nummer manuell vergeben',
['poiNumberIsZero'] = 'Poi-Nummer auf Null gesetzt',
['missingCoord'] = 'Länge und/oder Breite fehlt',
['missingName'] = 'Name fehlt',
['missingImg'] = '[[Category:Marker: Datei existiert nicht]] Nicht vorhandenes Bild:',
['missingParameter1'] = 'Parameter 1 fehlt',
['unknownFormat'] = 'Unbekanntes Format',
['unknownIcon'] = 'Unbekanntes Marker-Symbol',
['unknownType'] = 'Unbekannter Typ',
['wrongQualifier'] = '[[Category:Marker: Fehlerhafter Wikidata-Qualifikator]] Fehlerhafter Wikidata-Qualifikator',
['wrongUrl'] = '[[Category:URL ist ungültig]] <span class="error" title="URL ist ungültig">URL ist ungültig</span>',
['UrlWithIP'] = '[[Category:URL enthält IP-Adresse]] <span class="listing-vcardInfo" title="URL enthält IP-Adresse">URL enthält IP-Adresse</span>',
['nonASCII'] = '[[Category:URL enthält Unicode-Zeichen]] <span class="listing-vcardInfo" title="URL enthält Unicode-Zeichen">URL enthält Unicode-Zeichen</span>'
}
mk.Icons = {
['commons'] = '[[File:Commons-logo.svg|x16px|text-bottom|link=|Wikimedia Commons – Sammlung von Bildern, Videos und Audiodateien zu dieser Einrichtung]]',
['internet'] = '[[File:Applications-internet.svg|16px|text-bottom|link=|Website dieser Einrichtung]]',
['wikidata'] = '[[File:Wikidata-logo.svg|16px|middle|link=|Wikidata – Daten zu dieser Einrichtung]]',
['wikipedia'] = '[[File:Antu wikipedia.svg|16px|text-bottom|link=|Wikipedia-Artikel zu dieser Einrichtung]]',
['wikivoyage']= '[[File:Wikivoyage-Logo-v3-icon.svg|16px|text-bottom|link=|Wikivoyage-Artikel zu dieser Einrichtung in einer anderen Sprache]]',
}
mk.mapServer = 'http://maps.wikivoyage-ev.org'
mk.coordURL = 'https://de.wikivoyage.org/w/index.php?title=Special%3AMapsources¶ms='
mk.texts = {
latitude = 'Breitengrad',
longitude = 'Längengrad',
tooltip = 'Nummer in der Karte KLICK: direkt zur Karte',
legend = 'Legende für Typ '
}
function mk.errorInfo( s )
return '<span class="error" title="' .. s .. '">' .. s .. '</span>'
end
-- Wikidata related functions
local wrongQualifier = false
local mkEntity = nil -- marker entity
local searchLimit = 4 -- for P31
local function checkId( id )
local i = id and id:upper() or ''
local l
if i ~= '' then
if string.match( i, '^[%d]+$') ~= nil then -- only number
i = 'Q' .. i
elseif string.match( i, '^Q[%d]+$') == nil then -- Q and number
wrongQualifier = true
i = ''
end
end
if i ~= '' then
mkEntity = mw.wikibase.getEntity( i )
if mkEntity == nil then
i = ''
wrongQualifier = true
end
end
return i
end
local function getEntWDvalue( anEntity, p )
if anEntity == nil then return '' end
local w = anEntity:getBestStatements( p )
local i = ''
if (#w > 0) and (w[1].mainsnak.snaktype == 'value') then
i = w[1].mainsnak.datavalue.value
end
return i
end
local function getEntWDid( anEntity, p )
if anEntity == nil then return '' end
local w = anEntity:getBestStatements( p )
local i = ''
if (#w > 0) and (w[1].mainsnak.snaktype == 'value') then
i = w[1].mainsnak.datavalue.value['id']
end
return i
end
local function getWDid( id, p )
return getEntWDid( mw.wikibase.getEntity( id ), p )
end
-- types to groups translation for map legend
local function translateType( aType )
local t = vt.groups[aType]
if (t ~= nil) and (t ~= '') then return t else return aType end
end
local function outputCoordinates( lat, long, name )
local latDMS = ''
local longDMS = ''
local latMs = '' -- Map sources parameters
local longMs = ''
latDMS, _, latMs = cd.getDMSString( lat, 4, 'lat', '', '', 'f1' )
longDMS, _, longMs = cd.getDMSString( long, 4, 'long', '', '', 'f1' )
return '<span class="listing-dms-coordinates printNoLink plainlinks">['
.. mk.coordURL .. latMs
.. '_' .. longMs .. '_' .. mw.uri.encode( 'type:landmark_globe:earth' )
.. '&locname=' .. mw.uri.encode( name )
.. ' <span class="coordStyle" title="' .. mk.texts.latitude .. '">'
.. latDMS .. '</span>'
.. ' <span class="coordStyle" title="' .. mk.texts.longitude .. '">'
.. longDMS .. '</span>]</span>'
end
local function getWikiLink( langArray, wiki, entity )
local i, lang
local result = ''
local prefix = '' -- empty in case of Wikivoyage
if wiki == 'wiki' then prefix = 'w:' end
for i, lang in ipairs( langArray ) do
if entity.sitelinks[lang .. wiki] ~= nil then
result = tostring( mw.uri.fullUrl( prefix .. lang .. ':'
.. mw.uri.encode( entity.sitelinks[lang .. wiki].title, 'WIKI' ) ) )
break
end
end
return result
end
-- main marker function
function mk._marker( args, frame )
args.zoom = tonumber( args.zoom or '' )
args.name = args.name or ''
args.alt = args.alt or ''
args.symbol = args.symbol or ''
args.symbol = args.symbol:lower()
args.text = args.text or ''
args['map-group'] = args['map-group'] or ''
args['type'] = string.lower( args['type'] or '' )
args.counter = string.lower( args.counter or '' ) -- for backward compatibility
if args['type'] == '' then args['type'] = args.counter end
args.url = args.url or ''
args.addMf = args.addMf or ''
args.wikidata = checkId( args.wikidata or '' )
local r, t, a, j
local noURL = false
-- checking coordinates given as template parameters
local dms = false
if args.lat ~= '' then
t = tonumber( args.lat )
if t == nil then
r = cd.toDec( args.lat, 'lat', 6 )
if r.error > 0 then args.lat = ''
else
args.lat = r.dec
dms = true
end
else
if (t < -90) or (t > 90) then args.lat = ''
else args.lat = t end
end
end
if args.long ~= '' then
t = tonumber( args.long )
if t == nil then
r = cd.toDec( args.long, 'long', 6 )
if r.error > 0 then args.long = ''
else
args.long = r.dec
dms = true
end
else
if (t <= -180) or (t > 180) then args.long = ''
else args.long = t end
end
end
-- getting values from Wikidata
t = ''
local wikipedia = ''
local wikivoyage = ''
local thisWikivoyage = '' -- current Wikivoyage branch
local wmCommons = ''
local wmCommonsCat = ''
local wikiLang = mw.getContentLanguage():getCode()
if args.url ~= '' then
a = yn( args.url, nil )
if a ~= nil then -- is boolean
args.url = ''
noURL = not a
end
end
if args.wikidata ~= '' then
if args.name == '' then
args.name = mkEntity:getLabel() or ''
if args.name == '' then args.name = mkEntity:getLabel( 'en' ) or '' end
end
if (mkEntity ~= nil) and (mkEntity.sitelinks ~= nil) then
if mkEntity.sitelinks[wikiLang .. 'wikivoyage'] ~= nil then
thisWikivoyage = mkEntity.sitelinks[wikiLang .. 'wikivoyage'].title
if thisWikivoyage == mw.title.getCurrentTitle().text then
thisWikivoyage = '' end -- no link to the article itself
end
wikipedia = getWikiLink( {wikiLang, 'en'}, 'wiki', mkEntity )
wikivoyage = getWikiLink( {'en'}, 'wikivoyage', mkEntity )
end
wmCommonsCat = getEntWDvalue( mkEntity, 'P373' )
if (wmCommonsCat ~= '') then
wmCommonsCat = mw.ustring.gsub( wmCommonsCat, ' ', '_' )
wmCommons = tostring( mw.uri.fullUrl( 'c:Category:' .. mw.uri.encode( wmCommonsCat, 'WIKI' ) ) )
end
if args.image == '' then args.image = getEntWDvalue( mkEntity, 'P18' ) end
if (args.url == '') and (not noURL) then
args.url = getEntWDvalue( mkEntity, 'P856' ) end
if (args.lat == '') or (args.long == '') then
t = mkEntity:getBestStatements( 'P625' )
if (#t > 0) and t[1].mainsnak.snaktype == 'value' then
args.lat = t[1].mainsnak.datavalue.value.latitude
args.long = t[1].mainsnak.datavalue.value.longitude
end
end
if args['type'] == '' then
t = getEntWDid( mkEntity, 'P31' )
if t == '' then a = vt.types.default else a = pt[t] end
if a == nil then
j = 0
repeat
t = getWDid( t, 'P279' )
if t ~= '' then a = pt[t] end
j = j + 1
until (j >= searchLimit) or (t == '') or (a ~= nil)
end
if a == nil then a = vt.types.default end
args['type'] = a
end
end
args['type'] = args['type']:gsub( ' ', '_' )
local origType = args['type']
if vt.groups[args['type']] == nil then args['type'] = vt.types[args['type']] end
if args['type'] == nil then args['type'] = vt.types.default end
if args.symbol ~= 'legend' then
if (args.lat == '') or (args.long == '') then
return mk.categories.missingCoord .. mk.errorInfo( mk.errorMsg.missingCoord )
end
end
local imageMsg = ''
local imageEx = false
if args.image ~= '' then
imageEx = frame:callParserFunction( '#ifexist', { 'Media:' .. args.image , 1 , 0 } ) == '1'
if not imageEx then
imageMsg = ' <span class="error">' .. mk.errorMsg.missingImg .. ' '
.. args.image .. '</span>'
end
end
if dms then imageMsg = imageMsg .. mk.categories.dmsCoordinate end
if ( args.url ~= '' ) then
j = uc.isUrl( args.url )
if j > 2 then
imageMsg = imageMsg .. ' ' .. mk.errorMsg.wrongUrl
args.url = ''
end
if j == 2 then imageMsg = imageMsg .. ' ' .. mk.errorMsg.UrlWithIP end
if j == 1 then imageMsg = imageMsg .. ' ' .. mk.errorMsg.nonASCII end
end
local result = ''
local color = ''
if (args.zoom == nil) or (args.zoom == '') or (type( args.zoom ) ~= 'number')
then args.zoom = 17
else
args.zoom = math.floor( args.zoom )
if (args.zoom < 0) or (args.zoom > 19) then
args.zoom = 17
end
end
if args.name == '' then
args.name = mk.errorMsg.missingName
imageMsg = imageMsg .. ' ' .. mk.categories.missingName .. mk.errorInfo( mk.errorMsg.missingName )
end
args.linkName = mw.ustring.gsub( args.name, '^(.*)%[%[(.*)%]%](.*)$', '%2' )
if args.linkName ~= '' then
local t = mw.ustring.gsub( args.linkName, '^(.*)|(.*)$', '%2' )
if t ~= '' then args.linkName = t end
args.linkName = mw.text.trim( args.linkName )
end
if args.linkName == '' then args.linkName = args.name end
if (args.linkName == args.name) and (thisWikivoyage ~= '') then
args.name = '[[' .. thisWikivoyage .. '|' .. args.name .. ']]'
end
color, args['type'] = mc.getColor( args['type'] )
local useIcon = false
if args.symbol == 'legend' then
if args.name == '' then args.name = '1' end
return '<span class="plainlinks printNoLink poi" style="background-color: #' .. color
.. '; border-color: #' .. color .. ';" title="' .. mk.texts.legend .. args['type']
.. '"><span class="mw-kartographer-autostyled">' .. args.name .. '</span></span>'
end
if args.symbol == 'letter' then
args.symbol = '-letter-' .. args['type']
elseif (args.symbol == '') or (args.symbol == 'number') then
args.symbol = '-number-' .. args['type']
elseif (args.symbol ~= '') and (mi[args.symbol] == nil) then
args.symbol = 'cross'
color, args['type'] = mc.getColor( 'error' )
args.text = '[[Datei:Close x - white.png|15px|' .. mk.errorMsg.unknownIcon .. '|link=]]'
imageMsg = imageMsg .. ' ' .. mk.categories.unknownIcon
elseif (args.text == '' ) then
args.text = string.upper( string.sub( args.symbol, 1, 1 ) )
useIcon = true
end
if args['type'] == 'error' then
imageMsg = imageMsg .. ' ' .. mk.categories.unknownType .. mk.errorInfo( mk.errorMsg.unknownType )
end
local mArgs = {}
mArgs['type'] = 'maplink'
mArgs.geotype = 'Point'
if args.alt == '' then args.alt = args.name end
mArgs.title = args.alt
if args.text == '' then mArgs.text = nil
else
mArgs.text = args.text
if not useIcon then mArgs.class = 'no-icon' end
end
if not useIcon then mArgs.class = 'no-icon' end
-- hier muss ich mal sehen, was passiert: args.text
mArgs['marker-symbol'] = args.symbol
mArgs['marker-color'] = color
mArgs.latitude = args.lat
mArgs.longitude = args.long
mArgs.zoom = args.zoom
if args['map-group'] == '' then mArgs.group = translateType( args['type'] )
else mArgs.group = args['map-group'] end
mArgs.show = vt.showAll
if imageEx then mArgs.image = args.image else mArgs.image = nil end
local tag, geojson, tagArgs = ma._tag( mArgs )
local result = frame:extensionTag( tag, geojson, tagArgs )
result = '<span class="plainlinks printNoLink poi listing-map" style="background-color: #' .. color
.. '; border-color: #' .. color .. ';" title="' .. mk.texts.tooltip .. '">'
.. result .. '</span>'
local s = ''
if args['format'] == 'f2' then
-- marker only
elseif args['format'] == 'f3' then -- marker and coordinates
result = result .. ' ' .. outputCoordinates( args.lat, args.long, args.linkName )
elseif (args['format'] == 'f0') or (args['format'] == 'f1') then
-- f0: default: marker and name
-- f1: marker and name (coordinates)
if args.name ~= '' then
if result ~= '' then result = result .. ' ' end
s = '<span id="vCard_' .. mw.uri.anchorEncode( args.linkName )
.. '" class="p-name fn org listing-name">' .. args.name .. '</span>'
if args.url == '' then
result = result .. s
else
if args.linkName == args.name then
result = result .. '[' .. args.url .. ' ' .. s .. ']'
else
-- both article and web links
result = result .. s .. ' <span class="listing-url">['
.. args.url .. ' ' .. mk.Icons['internet'] .. ']</span>'
end
end
else
if args.url ~= '' then
if result ~= '' then result = result .. ' ' end
result = result .. '[' .. args.url .. ']'
end
end
-- adding Wikimedia icons
if (thisWikivoyage == '') and (wikivoyage ~= '') then
result = result .. ' <span class="listing-sister-icons">['
.. wikivoyage .. ' ' .. mk.Icons['wikivoyage'] .. ']</span>'
end
if wikipedia ~= '' then
result = result .. ' <span class="listing-sister-icons">['
.. wikipedia .. ' ' .. mk.Icons['wikipedia'] .. ']</span>'
end
if wmCommons ~= '' then
result = result .. ' <span class="listing-sister-icons">['
.. wmCommons .. ' ' .. mk.Icons['commons'] .. ']</span>'
end
if args.wikidata ~= '' then
result = result .. '<span class="listing-sister-icons listing-sister-wikidata">['
.. tostring( mw.uri.fullUrl( 'd:' .. args.wikidata ) )
.. ' ' .. mk.Icons['wikidata'] .. ']</span>'
end
if args['format'] == 'f1' then
result = result .. ' (' .. outputCoordinates( args.lat, args.long, args.linkName ) .. ')'
end
else
result = result .. ' ' .. mk.categories.unknownFormat
.. mk.errorInfo( mk.errorMsg.unknownFormat ) .. ' '
end
if args.addMf == 'true' then
s = '<span class="h-card vcard Marker"'
.. ' data-wikilang="' .. wikiLang .. '"'
.. ' data-color="#' .. color .. '"'
.. ' data-type="' .. origType .. '"'
.. ' data-group="' .. args['type'] .. '"'
if args.url ~= '' then
s = s .. ' data-url="' .. mw.text.nowiki( args.url ) .. '"' end
if args['map-group'] ~= '' then
s = s .. ' data-mapgroup="' .. args['map-group'] .. '"' end
if args.wikidata ~= '' then
s = s .. ' data-wikidata="' .. args.wikidata .. '"' end
if wmCommonsCat ~='' then
s = s .. ' data-commonscat="' .. wmCommonsCat .. '"' end
result = s .. '><span class="p-geo geo listing-coordinates" style="display: none">'
.. '<abbr class="p-latitude latitude">' .. args.lat .. '</abbr>'
.. '<abbr class="p-longitude longitude">' .. args.long .. '</abbr></span>'
.. result
if (args['format'] == 'f2') or (args['format'] == 'f3') then
result = result .. '<span class="p-name fn org listing-name" style="display: none">'
.. args.linkName .. '</span>'
end
result = result .. '</span>'
-- result = result .. frame:callParserFunction{ name = '#coordinates',
-- args = { args.lat, args.long, 'type:landmark_globe:earth', name = args.linkName } }
end
if wrongQualifier then result = result .. '<span class="error">'
.. mk.errorMsg.wrongQualifier .. '</span>' end
if args.demo == 'true' then return result
else return result .. imageMsg end
end
function mk.marker( frame )
local args = frame:getParent().args
args.lat = args.lat or ''
args.long = args.long or ''
args.image = args.image or ''
args.addMf = args.addMf or 'true'
args.symbol = args.symbol or ''
args['format'] = args['format'] or 'f0'
return mk._marker( args, frame ) .. pc.checkParams( args, mp._marker, '' )
end
-- the following templates are used only at the German Wikivoyage
-- evtl. marker-dummy
function mk.externalMapService( args )
return '<span class="plainlinks printNoLink poi poi_man type_' .. args['type']
.. '" title="Nummer in der Karte KLICK: direkt zur Karte (externe Webseite)">'
.. '[' .. mk.mapServer .. '/w/poimap2.php?lat=' .. args.lat .. '&lon='
.. args.long .. '&zoom=17&layer=' .. args[7] .. '&lang=' .. mw.getContentLanguage():getCode()
.. '&name=' .. mw.uri.encode( mw.title.getCurrentTitle().text ) .. ' '
.. args[1] .. ']</span>'
end
function mk.poi( frame )
local args = frame:getParent().args
args[1] = mw.text.trim( args[1] or '' )
args['type'] = mw.text.trim( string.lower( args[2] or '' ) )
if args['type'] == '' then args['type'] = 'other' end
args.lat = pc.checkNumber( args[3] or '' )
args.long = pc.checkNumber( args[4] or '' )
args.name = mw.text.trim( args[5] or '' )
args.image = mw.text.trim( args[6] or '' )
args[7] = mw.text.trim( args[7] or '' )
if args[7] == '' then args[7] = 'W' end
args['format'] = 'f2'
args.addMf = 'true'
local function vcardInfo( s )
return '<span class="wv-vcardInfo" title="' .. s .. '">' .. s .. '</span>'
end
local categs = ''
if args[1] ~= '' then
if (args[1] == '0') or (args[1] == 0) then
categs = mk.categories.poiNumberIsZero .. vcardInfo( mk.errorMsg.poiNumberIsZero )
else
categs = mk.categories.poiNumbersUsed .. vcardInfo( mk.errorMsg.poiNumbersUsed )
return mk.externalMapService( args ) .. pc.checkParams( args, mp._poi, '' ) .. categs
end
end
return mk._marker( args, frame ) .. pc.checkParams( args, mp._poi, '' ) .. categs
end
function mk.poidummy( frame )
local args = frame:getParent().args
args[1] = mw.text.trim( args[1] or '' ) -- is necessary
args['type'] = mw.text.trim( string.lower( args[2] or '' ) )
if args['type'] == '' then args['type'] = 'other' end
args.lat = pc.checkNumber( args[3] or '' )
args.long = pc.checkNumber( args[4] or '' )
args[7] = mw.text.trim( args[7] or '' )
if args[7] == '' then args[7] = 'W' end
if args[1] == '' then return mk.errorInfo( mk.errorMsg.missingParameter1 ) end
if (args.lat == '') or (args.long == '') then
return mk.categories.missingCoord .. mk.errorInfo( mk.errorMsg.missingCoord )
end
return mk.externalMapService( args ) .. pc.checkParams( args, mp._poi, '' )
end
return mk