« Module:Carte » : différence entre les versions

De Lagny-sur-Marne Wiki
Aller à la navigation Aller à la recherche
0x010D (discussion | contributions)
Aucun résumé des modifications
0x010D (discussion | contributions)
affinage
Ligne 177 : Ligne 177 :
local data = require('Module:Carte/données')
local data = require('Module:Carte/données')
local validmaps = {}
local validmaps = {}
local lat, long = tonumber(params.latitude), tonumber(params.longitude)
local lat = tonumber(params.latitude) or tonumber(coord.dms2dec({args={params.latitude}}))
local long = tonumber(params.longitude) or tonumber(coord.dms2dec({args={params.longitude}}))
if not lat or not long then return nil end
if not lat or not long then return nil end
for i, map in pairs(data) do
for i, map in pairs(data) do
Ligne 199 : Ligne 200 :


local chosenmaps = {} -- on ne les gardes pas toutes, ça serait souvent trop
local chosenmaps = {} -- on ne les gardes pas toutes, ça serait souvent trop
 
local function addmap(map)
local havezone = {} -- paramètre "zone" des carte déjà obtenu, pour ne pas avoir le même deux fois: { zone = {nom de la carte, position de la carte} }
return table.insert(chosenmaps, map.name)
 
local forbiddenzones = { -- zone peu utiles, à ne pas utiliser par défaut
['future région française'] = true
}
 
local function addmap(map, pos) -- ajoute la carte à la liste et enregistre qu'elle a une carte avec ce paramètre "zone"
if pos then
chosenmaps[pos] = map.name
havezone[map.zone] = {map, pos}
else
table.insert(chosenmaps, map.name)
havezone[map.zone] = {map, #chosenmaps}
end
end
local function centrality(map)
-- retourne un indice ah hoc de centralité, plus faible si le point est près d'un bord
local function compute(point, end1, end2)
local pct = (point - end1) / (end2- end1)
return 0.5 - math.abs(0.5 - pct)
end
local latcentrality = compute(lat, map.top, map.bottom)
local longcentrality = compute(long, map.left, map.right)
return math.min(latcentrality, longcentrality)
end
end
local havezone = {} -- paramètre "zone" des carte déjà obtenu, pour ne pas avoir le même deux fois


for i, map in pairs(validmaps) do
for i, map in pairs(validmaps) do
if #chosenmaps > 2 then -- 3 au maximum
if not(havezone[map.zone]) and  (not forbiddenzones[map.zone]) and #chosenmaps < 3 then
break
end
if not(havezone[map.zone]) then -- sinon, il faudrait peut-être essayer de trouver la plus centrée
addmap(map)
addmap(map)
end
end
if map.zone then
if map.zone and havezone[map.zone] and (centrality(map) > centrality(havezone[map.zone][1] ))  then -- si deux cartes ont le même paramètre "zone", on prend la mieux centrée
havezone[map.zone] = true
addmap(map, havezone[map.zone][2])
end
end
end
end

Version du 9 mars 2015 à 15:45

local p = {} local pointmod = require('Module:Carte/Points') local linguistic = require('Module:Linguistique') local maintenance = local coord = require('Module:Coordinates') local function loaddata(name) return require('Module:Carte/données/' .. mw.ustring.lower(name)) end

local divstyle = { ['clear'] = 'right', ['width'] ='25em', ['text-align'] = 'center', ['font-size'] = '0.9em', ['line-height'] = '1.4em', ['margin'] = '0 0 0.5em 1em', ['max-width'] = '325px', ['word-wrap'] = 'break-word', ['max-width'] = '99%', ['height'] = 'auto', ['justify-content'] = 'space-around', ['align-items'] = 'center', }

local function addmaintenancecat(cat, sortkey) -- ajoute du texte à la string maintenance en cas de problème if mw.title.getCurrentTitle().namespace ~= 0 then return end maintenance = maintenance .. end

-- 'Projection conique avec DL' local function dllat(latitude, longitude, mapdata) -- conique avec DL local val = (mapdata.y0 + ( mapdata.iheight/2 - mapdata.y0 ) * (1 - mapdata.t * (latitude - mapdata.centrallat) * (0.01745329252 + 0.00000177219231 * (latitude - mapdata.centrallat) ^2) )* ( 1- 0.00015230871 * (longitude-mapdata.centrallong) ^2 * mapdata.s^2) ) / mapdata.iheight

return val end local function dllong(latitude, longitude, mapdata) local val = ( (mapdata.x0 or (mapdata.iwidth/2)) + ( mapdata.iheight/2 - mapdata.y0 ) * ( 1 -mapdata.t * (latitude-mapdata.centrallat) * ( 0.01745329252 + 0.00000177219231 * (latitude-mapdata.centrallat) * (latitude-mapdata.centrallat) ) ) * (longitude-mapdata.centrallong) * mapdata.s * (0.01745329252 - 0.000000886096156 * (longitude-(mapdata.centrallong)) * (longitude-(mapdata.centrallong)) * mapdata.s^2 ) ) / mapdata.iwidth return val end

--longitude équirectangulaire local function equirecLong(longitude, mapdata) local left, right = mapdata.left, mapdata.right if right < left then -- si la carte passe le méridien 180 right = 360 + right if longitude < 0 then longitude = (360 + longitude) end end return (longitude - left) / (right - left) end

local function equirecLat(latitude, mapdata) return (latitude - mapdata.top) / (mapdata.bottom - mapdata.top) end


local function pointposition(latitude, longitude, mapdata) local latitude = tonumber(latitude) or tonumber(coord.dms2dec({args={latitude}})) local longitude = tonumber(longitude) or tonumber(coord.dms2dec({args={longitude}}))

local ypos, xpos if mapdata.x and mapdata.y then -- pour les cartes complexes : calcul de la position à partir de formules en Wikicode dans les clés "x" et "y" xpos = mapdata.x(latitude, longitude) / 100 ypos = mapdata.y(latitude, longitude) / 100

elseif mapdata.projection == 'Projection équirectangulaire' then ypos = equirecLat(latitude, mapdata) xpos = equirecLong(longitude, mapdata) elseif mapdata.projection == 'Projection conique avec DL' then ypos = dllat(latitude, longitude, mapdata) xpos = dllong(latitude, longitude, mapdata) end return ypos, xpos end

local function placepoint(mapdata, point) -- fonction d'aige pour buildmap point est une table contenant latitude, longitude, type de point... local ypos, xpos = pointposition(point.latitude, point.longitude, mapdata)

if (not xpos) or (not ypos) then return "données de géolocalisation invalides" end

if (ypos > 1.1) or (xpos) > 1.1 or (ypos < -0.1) or (xpos < -0.1) then return .. 'les coordonnées indiquées sont hors de la carte de géolocalisation demandée' end

local pointsize = tostring(point.pointsize or '8') local pointtext = point.text or local pointtype = point.pointtype or 'default' local pointimage = pointmod[pointtype] if not pointimage then pointimage = pointmod[pointtype] addmaintenancecat('Page avec un modèle de point de carte non supporté') end

local htmlheight = tostring(ypos * 100) .. '%' local htmlwidth = tostring(xpos * 100) .. '%'

local pointdiv = mw.html.create('div') :css{position = 'absolute', border = 'none', top = htmlheight, left = htmlwidth} :tag('div') :css{position = 'absolute', top = '-4px', left = '-4px', ['line-height'] = '0', width = '8px'} :wikitext('' .. pointsize .. 'px') :tag('span') :css{position = 'absolute', ['text-align'] = 'left', width = '150px'} :wikitext(pointtext) :done() :allDone()

return pointdiv end

local function buildmap(map, maptype, width, pointtable, caption) -- fonction d'aige pour multimap if map == '-' then return end local success, mapdata = pcall(loaddata, map) if not success or not mapdata.images then addmaintenancecat('Page avec des données de géolocalisation non supportées') end local name = mapdata.name or '?'

-- analyse linguistique pour le texte de la carte local datagender = mapdata.genre or local gender = string.sub(datagender, 1, 1) -- ms = masculin-singulier, fp = féminin pluriel etc. local number = string.sub(datagender, 2, 2) local determiner = mapdata.determiner local ofstring = linguistic.of(name, gender, number, determiner) -- restitue "de France" ou "du Japon"

local mapname = mapdata.name local file = mapdata.images[maptype] or mapdata.images['default'] or mapdata.images[1] if not file then file = mapdata.images['default'] end local alt = 'voir sur la carte ' .. ofstring

local map = mw.html.create('div') :css(divstyle) :addClass("geobox") :wikitext(caption or ('Localisation sur la carte ' .. ofstring)) :tag('table') :addClass('DebutCarte') :attr({border="0", cellspacing="0", cellpadding="0"}) :css({margin = '0', border = 'none', padding = '0'}) :tag('tr') :tag('td') :tag('div') :css({position= 'relative', margin = "auto", width = '100%', ['text-align'] = 'right' }) :wikitext('' .. alt .. '' )

for i, j in pairs(pointtable) do -- pour chque point à placer, do map:node(placepoint(mapdata,j)) end return map:done():done():done():done() end

local function guessmaps(params) local data = require('Module:Carte/données') local validmaps = {} local lat = tonumber(params.latitude) or tonumber(coord.dms2dec({args={params.latitude}})) local long = tonumber(params.longitude) or tonumber(coord.dms2dec({args={params.longitude}})) if not lat or not long then return nil end for i, map in pairs(data) do if lat < map.top and lat > map.bottom then if map.left > map.right then -- correction pour les cartes passant le méridien 180 map.right = 360 + map.right if long < 0 then long = 360 + long end end if (long > map.left and long < map.right) then table.insert(validmaps, map) end end end if #validmaps == 0 then return nil end local function area(map) -- fonction simple juste pour pouvoir classer apprximativement les cartes pas superficie return (math.abs(map.top - map.bottom)) * (math.abs(map.left- map.right)) end table.sort(validmaps, function(a, b) return area(a) < area(b) end)

local chosenmaps = {} -- on ne les gardes pas toutes, ça serait souvent trop

local havezone = {} -- paramètre "zone" des carte déjà obtenu, pour ne pas avoir le même deux fois: { zone = {nom de la carte, position de la carte} }

local forbiddenzones = { -- zone peu utiles, à ne pas utiliser par défaut ['future région française'] = true }

local function addmap(map, pos) -- ajoute la carte à la liste et enregistre qu'elle a une carte avec ce paramètre "zone" if pos then chosenmaps[pos] = map.name havezone[map.zone] = {map, pos} else table.insert(chosenmaps, map.name) havezone[map.zone] = {map, #chosenmaps} end end local function centrality(map) -- retourne un indice ah hoc de centralité, plus faible si le point est près d'un bord local function compute(point, end1, end2) local pct = (point - end1) / (end2- end1) return 0.5 - math.abs(0.5 - pct) end local latcentrality = compute(lat, map.top, map.bottom) local longcentrality = compute(long, map.left, map.right) return math.min(latcentrality, longcentrality) end

for i, map in pairs(validmaps) do if not(havezone[map.zone]) and (not forbiddenzones[map.zone]) and #chosenmaps < 3 then addmap(map) end if map.zone and havezone[map.zone] and (centrality(map) > centrality(havezone[map.zone][1] )) then -- si deux cartes ont le même paramètre "zone", on prend la mieux centrée addmap(map, havezone[map.zone][2]) end end

return chosenmaps end

function p.multimap(params) local maplist = params.maplist if not maplist then maplist = guessmaps(params) end if type(maplist) == 'string' then if maplist == 'non' or maplist == 'pas pertinent' or maplist == 'non' then return end maplist = mw.text.split(maplist, '/', true) end if not maplist then return nil end local maptype = params.maptype -- à retravailler pour quand on veut la même région, mais avec plusieurs types de carte local width = params.width local pointtable = params.pointtable local caption = params.caption if not pointtable then -- pointtable est la liste des points à placer, mais lorsqu'il n'y a qu'un seul point, on peut avoir des paramètres distinctions : pointtable = Modèle:Latitude = params.latitude, longitude = params.longitude, pointtype = params.pointtype end -- traitement de la largeur if width and tonumber(width) then width = tonumber(width) else width = 280 end-- si pas un nombre, erreur ? local div = mw.html.create('div'):addClass('img_toogle')

-- met la carte à afficher par défaut à la fin, pour qu'elle soit affichée en premier table.insert(maplist, maplist[1]) table.remove(maplist, 1)

	--transition: appel aux Modèle:Géolocalisation/ n en l'absence de données dans le module

for i, j in pairs(maplist) do if j == then break end local success, data = pcall(loaddata, j) if not success then local mapliststring = for i, j in pairs(maplist) do mapliststring = j .. '/' .. mapliststring end return mw.getCurrentFrame():expandTemplate{ title = 'Infobox/Géolocalisation multiple/transition', args = {['géolocalisation'] = mapliststring, type = maptype, latitude = params.latitude, longitude = params.longitude }} .. end end for i, j in pairs(maplist) do if j == then break end local newmap = buildmap( j, maptype, width, pointtable, caption) div:node(newmap) end return div end

function p.map(frame) local args = frame.args -- utilisation du franaçs args.maplist = mw.text.split( args.carte, '/', true) return p.multimap(args) end return p