Module:MapLocations
Aller à la navigation
Aller à la recherche
Documentation
[purge]
Affiche une carte avec un ou plusieurs marqueurs selon les coordonnées données.
Paramètres
Tous optionnels
Paramètre | Par défaut | Description |
---|---|---|
map | Map The Island.jpg | Nom de fichier de la carte |
mapsize | 300 | Taille de carte en px |
markersize | 10 | Taille du marqueur en px |
markercolor | #f40 | |
markericon | Nom de fichier de l'icône par défaut | |
opacity | 1 | Opacité des marqueurs |
text | Texte affiché sous la carte | |
float | Côté où la carte s'aligne (left/right) | |
borderCoordT | 7.2 | Coordonnées du haut |
borderCoordR | 92.8 | Coordonnées de droite |
borderCoordB | 92.8 | Coordonnées du bas |
borderCoordL | 7.2 | Coordonnées de la gauche |
Les lieux doivent être donnés par des valeurs séparées par des virgules et doivent être dans cet ordre (seules les lat et lon sont obligatoires) lat,lon,markersize,markercolor,markertooltip,markericon[,markericon2[,markericon3...]]
. Les paramètres laissés en blanc seront donnés par défaut. Par ex. écrire 20,50,,green
pour un marqueur vert en (20/50) avec la taille par défaut.
- Les virgules ne sont pas autorisées dans le titre du texte (elles brisent le format)
- Un signe égal doit être écrit
{{=}}
, une barre verticale doit être écrite{{!}}
.
Exemple
{{MapLocations|30,50|20,80,20}}
{{MapLocations|40,50|30,80|text=Tellement de points|80,50,30,yellow,Je suis un marqueur jaune!|opacity=0.7|50,50,5|markercolor=green|mapsize=200|10,10,5}}
tant de points |
local json_ordered = require('Module:JsonOrdered')
local p = {}
local function dump(o)
if type(o) == 'table' then
local s = '{ '
for k,v in pairs(o) do
if type(k) ~= 'number' then k = '"'..k..'"' end
s = s .. '['..k..'] = ' .. dump(v) .. ','
end
return s .. '} '
else
return tostring(o)
end
end
local function processMap(map, schema)
local borderCoords = {t=0,r=100,b=100,l=0}
if schema == true then
if map == 'The Island' then map = 'The Island Map.jpg'
elseif map == 'The Center' then map = 'The Center Map.jpg'
elseif map == 'Scorched Earth' then map = 'Scorched Earth Map.jpg'
elseif map == 'Ragnarok' then map = 'Ragnarok Map.jpg'
elseif map == 'Aberration' then map = 'Aberration Map.jpg'
elseif map == 'Extinction' then map = 'Extinction Map.jpg'
elseif map == "Valguero" then map = "Valguero Map.jpg"
elseif map == 'Genesis: Part 1' then map = 'Genesis Part 1 Map.jpg'
elseif map == "Crystal Isles" then map = "Crystal Isles Map.jpg"
elseif map == 'Genesis: Part 2' then map = 'Genesis Part 2 Map.jpg'
elseif map == 'Lost Island' then map = 'Lost Island Map.jpg'
elseif map == 'Fjordur' then map = 'Fjordur Map.jpg'
else
schema = false
end
end
if schema == nil or schema == false then
-- if the map is given as just the name, apply the default map-file
if map == 'The Island' then map = 'The Island Topographic Map.jpg'
elseif map == 'The Center' then map = 'The Center Topographic Map.jpg'
elseif map == 'Scorched Earth' then map = 'Scorched Earth Topographic Map.jpg'
elseif map == 'Ragnarok' then map = 'Ragnarok Topographic Map.jpg'
elseif map == 'Aberration' then map = 'Aberration Topographic Map.jpg'
elseif map == 'Extinction' then map = 'Extinction Topographic Map.jpg'
elseif map == "Valguero" then map = "Valguero Topographic Map.jpg"
elseif map == 'Genesis: Part 1' then map = 'Genesis Part 1 Topographic Map.jpg'
elseif map == "Crystal Isles" then map = "Crystal Isles Topographic Map.jpg"
elseif map == 'Genesis: Part 2' then map = 'Genesis Part 2 Map.jpg'
elseif map == 'Lost Island' then map = 'Lost Island Topographic Map.jpg'
elseif map == 'Fjordur' then map = 'Fjordur Topographic Map.jpg'
elseif map == 'Fjordur Midgard' then map = 'Fjordur Topographic Map.jpg'
elseif map == 'Fjordur Asgard' then map = 'Fjordur Asgard Topographic Map.jpg'
elseif map == 'Fjordur Jotunheim' then map = 'Fjordur Jotunheim Topographic Map.jpg'
elseif map == 'Fjordur Vanaheim' then map = 'Fjordur Vanaheim Topographic Map.jpg'
end
end
-- use the default borders of the chosen map
if map == 'The Island Topographic Map.jpg' then
borderCoords = {t=7.2,r=92.8,b=92.8,l=7.2}
elseif map == 'The Center Topographic Map.jpg' then
borderCoords = {t=-2.5,r=104.5,b=101.0,l=1.0}
elseif map == 'The Center Map.jpg' then
borderCoords = {t=-7.5,r=108.1,b=106.7,l=-3.9}
elseif map == 'Scorched Earth Topographic Map.jpg' then
borderCoords = {t=7.2,r=92.8,b=92.8,l=7.2}
elseif map == 'Ragnarok Topographic Map.jpg' then
borderCoords = {t=11,r=89,b=89,l=11}
elseif map == 'Ragnarok Ocean Topographic Map.jpg' then
borderCoords = {t=-2.6,r=102.4,b=102.4,l=-2.6}
elseif map == 'Ragnarok Map.png' then
borderCoords = {t=0.0,r=100.0,b=100.0,l=0.0}
elseif map == 'Aberration Topographic Map.jpg' then
borderCoords = {t=7.2,r=92.8,b=92.8,l=7.2}
elseif map == 'Extinction Topographic Map.jpg' then
borderCoords = {t=7.2,r=92.8,b=92.8,l=7.2}
elseif map == 'Crystal Isles Topographic Map.jpg' then
-- [ 10.5, 14 ],
-- [ 86 , 87 ],
borderCoords = {t=10.5,r=87,b=86,l=14}
elseif map == 'Genesis: Part 1 Topographic Map.jpg' then
borderCoords = {t=11.5,r=88.5,b=88.5,l=11.5}
elseif map == 'Fjordur Asgard Topographic Map.jpg' then
-- [ 17.47, 5.11 ],
-- [ 68.93, 56.57 ],
borderCoords = {t=17.47,r=56.57,b=68.93,l=5.11}
elseif map == 'Fjordur Jotunheim Topographic Map.jpg' then
-- [ 54.48, 21.35 ],
-- [ 97.36, 64.23 ]
borderCoords = {t=54.48,r=64.23,b=97.36,l=21.35}
elseif map == 'Fjordur Vanaheim Topographic Map.jpg' then
-- [ -9.15, 62.5 ],
-- [ 33.73, 105.38 ]
borderCoords = {t=-9.15,r=105.38,b=33.73,l=62.5}
end
return map, borderCoords
end
-- lat, lon, markersize, markercolor, markertext, markericon(s)
local function decodMarker(l)
local parts = {}
for part in string.gmatch(l..',', "([^,]*),") do -- split avec la , comme séparteur
table.insert(parts,part:match("^%s*(.-)%s*\n*$")) -- trim espace + retour chariot
end
local marker = {}
marker.lat = parts[1]
marker.lon = parts[2]
if #parts > 2 and string.len(parts[3])>0 then -- markersize
marker.ms = parts[3]
else
marker.ms = 10
end
if #parts > 3 and string.len(parts[4])>0 then -- markercolor
marker.mc = parts[4]
else
marker.mc = 'red'
end
if #parts > 4 and string.len(parts[5])>0 then -- markertext
marker.mt = parts[5]
end
local i=5
if #parts > 5 then
marker.mis = {}
while #parts > i do
marker.mis[i-4] = parts[i+1]
i = i + 1
end
end
return marker
end
local function buildMarkerCircle(mapsize, borderCoords, lat, lon, ms, mc, opacity, bc, mt)
return '<div style="position:absolute;line-height:0;left:'.. 100*((lon-borderCoords.l)/(borderCoords.r-borderCoords.l) - ms/(2*mapsize)) ..'%;top:'.. 100*((lat-borderCoords.t)/(borderCoords.b-borderCoords.t) - ms/(2*mapsize)) ..'%;padding:0;width:'..ms..'px;height:'..ms..'px;border-radius:50%;background-color:'..mc..';border:1px solid '..bc..';opacity:'..opacity..'" title="'..mt..'"></div>'
end
local function buildMarkerIcon(mapsize, borderCoords, lat, lon, ms, opacity, mt, mis)
return '<div style="position:absolute;line-height:0;left:'.. 100*((lon-borderCoords.l)/(borderCoords.r-borderCoords.l) - ms/(2*mapsize)) ..'%;top:'.. 100*((lat-borderCoords.t)/(borderCoords.b-borderCoords.t) - ms/(2*mapsize)) ..'%;padding:0;opacity:'..opacity..'" title="'..mt..'"><div style="position:absolute">[[File:'..table.concat(mis,'|'..ms..'px]]</div><div style="position:absolute">[[File:')..'|'..ms..'px]]</div></div>'
end
--[[
maplocations
Cette fonction convertie les données pour la classe HTML 'mapLocations'
Usage :
{{#invoke: MapLocations | maplocations}}
Paramètres :
ensemble de paramètres
voir le modèle 'Arkitexure map'
]]
function p.maplocations( f )
local args = f:getParent().args
-- set default values (borderCoords are for top, right, bottom, left)
local map, borderCoords, mapsize, markersize, markercolor, markericon, opacity, text, float = 'The Island Topographic Map.jpg', {t=0,r=100,b=100,l=0}, 300, 10, '#f40','', 1, '', ''
-- get values from parameters
if args.map ~= nil then
map, borderCoords = processMap(args.map)
end
if args.mapsize ~= nil then
mapsize = args.mapsize
end
if args.markersize ~= nil and tonumber(args.markersize) ~= nil and tonumber(args.markersize) >= 0 then
markersize = tonumber(args.markersize)
end
if args.markercolor ~= nil and type(args.markercolor) == "string" and #args.markercolor > 0 then
markercolor = args.markercolor
end
if args.markericon ~= nil then
markericon = args.markericon
end
if args.opacity ~= nil then
opacity = args.opacity
end
if args.text ~= nil then
text = args.text
end
if args.float ~= nil then
float = args.float
end
if args.borderCoordT ~= nil then
borderCoords.t = args.borderCoordT
end
if args.borderCoordR ~= nil then
borderCoords.r = args.borderCoordR
end
if args.borderCoordB ~= nil then
borderCoords.b = args.borderCoordB
end
if args.borderCoordL ~= nil then
borderCoords.l = args.borderCoordL
end
-- variables for a single marker: lat, lon, ms (markersize), mc (markercolor), mt (markertext/title/tooltip), mis (markericons)
local locations, lat, lon, ms, mc, mt, mis = {}, 0, 0, 0, '','', {}
for _,l in ipairs(args) do
ms = markersize
mc = markercolor
mis = {}
mis[1] = markericon
local parts,i = {},0
for part in string.gmatch(l..',', "([^,]*),") do
table.insert(parts,part:match "^%s*(.-)%s*$")
end
if #parts > 1 then
lat = parts[1]
lon = parts[2]
mt = 'lat '..lat..', lon '..lon
if #parts > 2 and string.len(parts[3])>0 then
ms = parts[3]
parts[3] = nil
end
if #parts > 3 and string.len(parts[4])>0 then
mc = parts[4]
end
if #parts > 4 and string.len(parts[5])>0 then
mt = parts[5]..'
'..mt -- mt = parts[5] + \n + mt
end
i=5
while #parts > i do
mis[i-4] = parts[i+1]
i = i + 1
end
if #mis > 0 and string.len(mis[1]) > 0 then
table.insert(locations,buildMarkerIcon(mapsize, borderCoords, lat, lon, ms, opacity, mt, mis))
else
table.insert(locations,buildMarkerCircle(mapsize, borderCoords, lat, lon, ms, mc, opacity, 'black', mt))
end
end
end
local subtitle = ''
if text ~= '' then
subtitle = '\n|-\n| align="middle" | '..text
end
return '{| class="mapLocations" style="float:'..float..'"\n|-\n|<div class="noviewer" style="position: relative;width:'..mapsize..'px;height:'..mapsize..'px">'..table.concat(locations)..'[[File:'..map..'|'..mapsize..'px]]</div>'..subtitle..'\n|}'
end
local function trim(s)
return s:match'^()%s*$' and '' or s:match'^%s*(.*%S)'
end
local function split(s)
local ret = {}
for v in string.gmatch(s, "([^,]*),?") do
table.insert(ret, v)
end
return ret
end
--[[
buildMarkerPosStr
Cette fonction convertie la chaine d'entrée au format '<lat>, <lon>, ...' en 'Lat <lat>°, Lon <lon>°'
Usage :
{{#invoke:MapLocations|buildMarkerPosStr|string}}
]]
function p.buildMarkerPosStr(frame)
local txt = frame.args[1]
if not txt or txt == "" then
return ""
end
-- '<lat>, <lon>' en 'Lat <lat>°, Lon <lon>°'
-- possible input is the marker string for maplocations: '<lat>, <lon>, <ms>, <mc>, <mt>, <mis>'
local pos = {}
local items = split(txt)
for k, v in pairs(items) do
if k < 3 then
v = trim(v)
table.insert(pos, v)
end
end
return string.format("Lat %s°, Lon %s°", pos[1], pos[2])
end
--[[
buildMarkerLabel
Cette fonction convertie la chaine d'entrée au format '<lat>, <lon>, <ms>, <mc>, <mt>, <mis>' en '<mc><mt>' ou '<mis><mt>'
Usage :
{{#invoke:MapLocations|buildMarkerLabel|string}}
]]
function p.buildMarkerLabel(frame)
local txt = frame.args[1]
if not txt or txt == "" then
return ""
end
-- possible input is the marker string for maplocations: '<lat>, <lon>, <ms>, <mc>, <mt>, <mis>'
-- output '<mc><mt>' or output '<mis><mt>'
local mt, mc, ms, mis
local items = split(txt)
for k, v in pairs(items) do
if k == 3 then
ms = trim(v)
if #ms == 0 then
ms = nil
end
elseif k == 4 then
mc = trim(v)
if #mc == 0 then
mc = nil
end
elseif k == 5 then
mt = trim(v)
if #mt == 0 then
mt = nil
end
elseif k == 6 then
mis = trim(v)
if #mis== 0 then
mis = nil
end
end
end
if ms == nil then
ms = '10'
end
local output = ""
if mis ~= nil then
output = string.format('[[File:%s|%spx]]  ', mis, ms)
elseif mc ~= nil then
output = string.format('<div style="{{#var:dotstyle}}; background-color:%s;"></div>  ', mc)
end
if mt == nil then
mt = "Localisation"
end
return output .. mt
end
-- Supprime "Lieux d'apparition:" ou "Apparition: "
local function filterSpawnName(label)
local str = string.gsub(label, "Lieux d'apparition: ", '')
if str == label then
str = string.gsub(label, "Apparition: ", '')
end
return str
end
local function extractSubMapName(map_name)
-- Fjordur Asgard => {Fjordur, Asgard}
local idx = string.find(map_name, ' ')
if idx ~= nil then
return string.sub(map_name, 1, idx-1), string.sub(map_name, idx+1)
end
return nil
end
-- Table des définitons des groupes normés
local global_groups_def
local function getObeliskList(map_name, titans)
local result = {}
local obelisk_title = mw.title.new('Donnée:Cartes/Obélisques '..map_name)
if obelisk_title.exists == true then
local obelisk_table = mw.text.jsonDecode(obelisk_title:getContent())
for group, location in pairs(obelisk_table.markers) do
local odef = global_groups_def[group]
if odef ~= nil then
-- test si marqueur ou icon
local bc, mt, icon
local mc = odef['fillColor']
if mc then
bc = odef['borderColor']
else -- titan
icon = odef['icon']
end
mt = odef['name']
if icon == nil or titans then -- si icon alors seulement si titans autorisés
for _, pos in pairs(location) do
local obitem = { fill = mc, border = bc, name = mt, pos = pos, icon = {icon}}
table.insert(result,obitem)
end
end
end
end
end
return result
end
--[[
mapPlayerSpawnLocations
Cette fonction affiche les marqueurs d'un fichier de donnée d'arrivée de joueur en json (Donnée:Cartes/ApparitionJoueur <map>)
Usage :
{{#invoke:MapLocations|mapPlayerSpawnLocations
|map=<map name> for example map=The Island
|mapsize=<size> for example mapsize=550
|maptopo=<true/false>
|no_obelisk=<true/false>
|PlayerTeleport=<true/false>
}}
]]
function p.mapPlayerSpawnLocations(frame)
-- process map
local subtitle = ''
local maptopo = false
if frame.args.maptopo == "true" then
maptopo = true
end
local map_name = frame.args.map
local map, borderCoords = processMap(map_name, not maptopo)
map_name = string.gsub(map_name, ':', '')
local ms = 10
local mapsize = 200
if frame.args.mapsize ~= nil then
mapsize = frame.args.mapsize
end
-- Chargement des définitons des groupes normés
global_groups_def = mw.text.jsonDecode(mw.title.new('Donnée:Cartes/Définitions des groupes normés'):getContent()).groups
local locations = {}
-- read obelisk locations
local no_obelisk = false
if frame.args.no_obelisk == "true" then
no_obelisk = true
end
if no_obelisk == false then
local obelisk_list = getObeliskList(map_name)
for _, obelisk in ipairs(obelisk_list) do
table.insert(locations,buildMarkerCircle(mapsize, borderCoords, obelisk.pos.lat, obelisk.pos.lon, 20, obelisk.fill, 1, obelisk.border, obelisk.name))
end
end
if frame.args.PlayerTeleport == "true" then
-- read PlayerTeleport (Fjordur)
local base_map_name, playerTeleport = extractSubMapName(map_name)
local table_data = mw.text.jsonDecode(mw.title.new('Donnée:Cartes/Exploration/'..base_map_name..' ('..playerTeleport..')'):getContent())
for group, marker_list in pairs(table_data.markers) do
if string.find(group, 'obelisk-') ~= nil then
local group_info = table_data.groups[group] or global_groups_def[group]
if group_info ~= nil then
local mc = group_info.fillColor
local bc = group_info.borderColor or '#fff'
for _, pos in pairs(marker_list) do
local mt = string.format("lat %3.1f, lon %3.1f %s", pos.lat, pos.lon, filterSpawnName(group_info.name))
table.insert(locations,buildMarkerCircle(mapsize, borderCoords, pos.lat, pos.lon, 20, mc, 1, bc, mt))
end
end
elseif string.find(group, 'PlayerTeleport') ~= nil then
local group_info = table_data.groups[group]
if group_info ~= nil then
local mc = group_info.fillColor
local bc = group_info.borderColor or '#fff'
for _, pos in pairs(marker_list) do
local mt = string.format("lat %3.1f, lon %3.1f %s", pos.lat, pos.lon, filterSpawnName(group_info.name))
table.insert(locations,buildMarkerCircle(mapsize, borderCoords, pos.lat, pos.lon, ms, mc, 1, bc, mt))
end
end
end
end
else
-- read ApparitionJoueur
local table_data = mw.text.jsonDecode(mw.title.new('Donnée:Cartes/ApparitionJoueur '..map_name):getContent())
for group, spawns in pairs(table_data.markers) do
local group_info = table_data.groups[group]
local mc = group_info.fillColor
local bc = group_info.borderColor
for _, pos in pairs(spawns) do
local mt = string.format("lat %3.1f, lon %3.1f %s", pos.lat, pos.lon, filterSpawnName(group_info.name))
table.insert(locations,buildMarkerCircle(mapsize, borderCoords, pos.lat, pos.lon, ms, mc, 1, bc, mt))
end
end
end
local float = ''
return '{| class="mapLocations" style="float:'..float..'"\n|-\n|<div class="noviewer" style="position: relative;width:'..mapsize..'px;height:'..mapsize..'px">'..table.concat(locations)..'[[File:'..map..'|'..mapsize..'px]]</div>'..subtitle..'\n|}'
end
--[[
mapPlayerSpawnRegions
Cette fonction affiche la liste des régions d'arrivée à partir d'un fichier de donnée d'arrivée de joueur en json (Donnée:Cartes/ApparitionJoueur <map>)
Usage :
{{#invoke:MapLocations|mapPlayerSpawnRegions|map}}
]]
function p.mapPlayerSpawnRegions(frame)
local map_name = string.gsub(frame.args.map, ':', '')
local table_data = json_ordered.decode(mw.title.new('Donnée:Cartes/ApparitionJoueur ' .. map_name):getContent())
local region_list = {'{| cellpadding="3"'}
for group, group_info in pairs(table_data.groups) do
local color = group_info.fillColor
table.insert(region_list, '|-\n| <div style="display:inline-block; padding:0; width:15px; height:15px; margin:-3px; border-radius:50%; background-color:' .. color .. ';border:1px solid black;"></div>\n| ' .. filterSpawnName(group_info.name))
end
table.insert(region_list, '|}')
return table.concat(region_list, '\n')
end
--[[
mapObeliskLocations
Cette fonction affiche les Obélisques à partir d'un fichier de donnée d'Obélisque en json (Donnée:Cartes/Obélisques <map>)
Usage :
{{#invoke:MapLocations|mapObeliskLocations
|map=<map name> exemple: map=The Island
|mapsize=<size> exemple: mapsize=550
|maptopo=<true/false>
|titans=<true/false> pour Extinction
|<marker> même syntaxe qu'avec location
}}
]]
function p.mapObeliskLocations(frame)
-- process map
local subtitle = ''
local maptopo = false
if frame.args.maptopo == "true" then
maptopo = true
end
local titans = false
if frame.args.titans == "true" then
titans = true
end
local map_name = frame.args.map
local map, borderCoords = processMap(map_name, not maptopo)
map_name = string.gsub(map_name, ':', '')
local ms = 10
local mapsize = 200
if frame.args.mapsize ~= nil then
mapsize = frame.args.mapsize
end
-- Chargement des définitons des groupes normés
global_groups_def = mw.text.jsonDecode(mw.title.new('Donnée:Cartes/Définitions des groupes normés'):getContent()).groups
local locations = {}
local obelisk_list = getObeliskList(map_name, titans)
for _, obelisk in ipairs(obelisk_list) do
local mt = string.format("%s
lat %3.1f, lon %3.1f", filterSpawnName(obelisk.name), obelisk.pos.lat, obelisk.pos.lon)
if obelisk.fill then
table.insert(locations,buildMarkerCircle(mapsize, borderCoords, obelisk.pos.lat, obelisk.pos.lon, 20, obelisk.fill, 1, obelisk.border, mt))
else
table.insert(locations,buildMarkerIcon(mapsize, borderCoords, obelisk.pos.lat, obelisk.pos.lon, 35, 1, mt, obelisk.icon))
end
end
-- décodage liste des marqueurs
for _,l in ipairs(frame.args) do
local marker = decodMarker(l)
local mt = ""
if marker.mt then
mt = string.format("%s
lat %3.1f, lon %3.1f", marker.mt, marker.lat, marker.lon)
else
mt = string.format("lat %3.1f, lon %3.1f", marker.lat, marker.lon)
end
if marker.mis then
table.insert(locations,buildMarkerIcon(mapsize, borderCoords, marker.lat, marker.lon, marker.ms, 1, mt, marker.mis))
else
table.insert(locations,buildMarkerCircle(mapsize, borderCoords, marker.lat, marker.lon, marker.ms, marker.mc, 1, 'black', mt))
end
end
local float = ''
return '{| class="mapLocations" style="float:'..float..'"\n|-\n|<div class="noviewer" style="position: relative;width:'..mapsize..'px;height:'..mapsize..'px">'..table.concat(locations)..'[[File:'..map..'|'..mapsize..'px]]</div>'..subtitle..'\n|}'
end
return p