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

Contenu supprimé Contenu ajouté
correction variable globale, détecté par Module:No globals inclus depuis je ne sais trop où, erreur rencontrée sur la page Bermoothes Insula
performances : exécution de la parser function #coordinates seulement si c'est une géolocalisation affichée à côté du titre (et si namespace article, catégorie ou portail) ; overridable avec un paramètre "geodata" ; refs discussion ; props Zebulon84 en mars et avril 2022 sur le bac à sable
 
(11 versions intermédiaires par 2 utilisateurs non affichées)
Ligne 3 :
local p = {}
 
local NBSP = '\194\160' -- espace insécable (code UTF-8 sur deux octets)
--Chargement de la liste En/Au/Aux/A
local gdata
local success, resultat = pcall (mw.loadData, "Module:Drapeau/Data" )
if success then
gdata = resultat
else
-- Banque de données à minima en cas de bogue dans le Module:Langue/Data
gdata={}
gdata.data={};
gdata.data[142]={qid="Q142", label="France", genre="fs"}
end
 
local i18n = {
Ligne 24 ⟶ 14 :
S = 'S',
Slong = 'sud',
degrees = '° ' .. NBSP,
minutes = '′ ' .. NBSP,
seconds = '″ ' .. NBSP,
geohackurl = 'http://tools.wmflabs.org/geohack/geohack.php?language=fr',
tooltip = 'Cartes, vues aériennes, etc.',
Ligne 47 ⟶ 37 :
tooManyParam = 'trop de paramètres pour la latitude ou la longitude', -- 'too many parameters for coordinates',
coordMissing = 'latitude ou longitude absente', -- 'latitude or longitude missing',
invalidGlobe = 'globe invalide : ', .. NBSP .. ': ', -- 'invalid globe:',
}
local coordParse = {
Ligne 59 ⟶ 49 :
SOUTH = 'S',
SUD = 'S',
}
 
--Aide:Fonction_genre
local genre = {
ms = {le="le ", du="du ", de="du ", au="au ", en="au "},
msa = {le="l'", du="de l'", de="d'", au="à l'", en="en "},
msi = {le="", du="de ", de="de ", au="à ", en="à "},
msia = {le="", du="d'", de="d'", au="à ", en="à "},
msiae = {le="", du="d'", de="d'", au="à ", en="en "},
fs = {le="la ", du="de la ", de="de ", au="à la ",en="en "},
fsa = {le="l'", du="de l'", de="d'", au="à l'", en="en "},
fsi = {le="", du="de ", de="de ", au="à ", en="à "},
fsia = {le="", du="d'", de="d'", au="à ", en="à "},
mp = {le="les ", du="des ", de="des ", au="aux ", en="aux "},
fp = {le="les ", du="des ", de="des ", au="aux ", en="aux "}
}
 
Ligne 80 ⟶ 55 :
radius in kilometers (especially imprecise for non spheric bodies)
defaultdisplay is currently disabled, activate it ?
]]--
ariel = {radius = 580, defaultdisplay = 'dec east', trackingcat = 'extraterrestre'},
callisto = {radius = 2410, defaultdisplay = 'dec west', trackingcat = 'extraterrestre'},
ceres = {radius = 470, defaultdisplay = 'dec east', trackingcat = 'extraterrestre'},
Ligne 89 ⟶ 64 :
enceladus = {radius = 255, defaultdisplay = 'dec west', trackingcat = 'extraterrestre'},
ganymede = {radius = 2634, defaultdisplay = 'dec west', trackingcat = 'sur Ganymède'},
earth = {radius = 6371, defaultdisplay = 'dms', trackingcat = 'sur Terre'},
europa = {radius = 1561, defaultdisplay = 'dec east', trackingcat = 'extraterrestre'},
hyperion = {radius = 140, defaultdisplay = 'dec west', trackingcat = 'extraterrestre'},
Ligne 95 ⟶ 70 :
['io'] = {radius = 1322, defaultdisplay = 'dec west', trackingcat = 'extraterrestre'},
jupiter = {radius = 68911, defaultdisplay = 'dec east', trackingcat = 'extraterrestre'},
mars = {radius = 3389.5, defaultdisplay = 'dec east', trackingcat = 'sur Mars' },
mercury = {radius = 2439.7, defaultdisplay = 'dec west', trackingcat = 'sur Mercure'},
mimas = {radius = 197, defaultdisplay = 'dec west', trackingcat = 'extraterrestre'},
Ligne 110 ⟶ 85 :
tethys = {radius = 530, defaultdisplay = 'dec west', trackingcat = 'extraterrestre'},
titania = {radius = 394, defaultdisplay = 'dec east', trackingcat = 'extraterrestre'},
triton = {radius = 1353, defaultdisplay = 'dec east', trackingcat = 'extraterrestre'},
umbriel = {radius = 584, defaultdisplay = 'dec east', trackingcat = 'extraterrestre'},
uranus = {radius = 25266, defaultdisplay = 'dec east', trackingcat = 'extraterrestre'},
Ligne 118 ⟶ 93 :
globedata[''] = globedata.earth
 
local wikidatathreshold = 10 -- si la distance entre coordonnées Wikipédia et Wikidata dépasse sece seuil (en kilomèteskilomètres), une catégorie de maintenance est ajoutée
local lang = mw.language.getContentLanguage()
local default_zoom = 13
Ligne 148 ⟶ 123 :
local function makeerror(args)
local errormessage = ''
if args.message then
errormessage = '<strong class="error"> Coordonnées ' .. NBSP .. ': ' .. args.message .. '</strong>'
end
local errorcat = ''
if mw.title.getCurrentTitle().namespace == 0 then
errorcat = makecat(i18n.errorcat, args.sortkey)
end
Ligne 169 ⟶ 144 :
 
globe = string.lower(globe or 'earth')
 
-- check arguments and converts degreees to radians
local latA, latB, longA, longB = a.latitude, b.latitude, a.longitude, b.longitude
Ligne 181 ⟶ 156 :
return error('globe: ' .. globe .. 'is not supported')
end
 
-- calcul de la distance angulaire en radians
local convratio = math.pi / 180 -- convertit en radians
Ligne 198 ⟶ 173 :
local args = frame.args
return p._distance(
{latitude = tonumber(args.latitude1), longitude = tonumber(args.longitude1)},
{latitude = tonumber(args.latitude2), longitude = tonumber(args.longitude2)},
args.globe)
Ligne 209 ⟶ 184 :
if tonumber(decLat) < 0 then
geohacklatitude = tostring(-tonumber(decLat)) .. '_S'
else
geohacklatitude = decLat .. '_N'
end
Ligne 222 ⟶ 197 :
local geohackparams = geohacklatitude .. '_' .. geohacklongitude .. '_' ..extraparams
-- concatenate parameteres for geohack
return i18n.geohackurl ..
"&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") ..
"&params=" .. geohackparams ..
Ligne 232 ⟶ 207 :
-- geohack url
local url = geoHackUrl(decLat, decLong, globe, displayformat, objectname, extraparams)
 
-- displayed coordinates
local displaycoords
if string.sub(displayformat, 1, 3) == 'dec' then
displaycoords = p.displaydec(decLat, decLong, displayformat)
else
Ligne 243 ⟶ 218 :
}
end
 
-- build coordinate in h-geo / h-card microformat
local globeNode
Ligne 252 ⟶ 227 :
:done()
end
 
local coordNode = mw.html.create('')
if objectname then
Ligne 265 ⟶ 240 :
:tag('span')
:addClass('h-geo')
:addClass('geo-' .. string.sub(displayformat, 1, 3))
:tag('data')
:addClass('p-latitude')
Ligne 279 ⟶ 254 :
:node( globeNode )
:done()
 
-- buid GeoHack link
local root = mw.html.create('span')
Ligne 288 ⟶ 263 :
:wikitext("]")
:done()
 
-- format result depending on args["display"] (nil, "inline", "title", "inline,title")
local inlineText = displayinline and tostring(root) or ''
Ligne 298 ⟶ 273 :
:node( root )
local frame = mw.getCurrentFrame()
titleText = frame:extensionTag( 'indicator', tostring(htmlTitle), { name = 'coordinates' } )
end
 
return inlineText .. titleText
end
Ligne 309 ⟶ 284 :
return zoomParam
end
 
local scale = extraparams:match( '%f[%w]scale: ?(%d+)' )
if scale then
return math.floor(math.log10( 1 / tonumber( scale ) ) * 3 + 25)
end
 
local extraType = extraparams:match( '%f[%w]type: ?(%w+)' )
if extraType then
Ligne 337 ⟶ 312 :
-- displayed coordinates
local displaycoords
if string.sub(displayformat, 1, 3) == 'dec' then
displaycoords = p.displaydec(decLat, decLong, displayformat)
else
Ligne 345 ⟶ 320 :
}
end
 
-- JSON for maplink
local jsonParams = {
type = 'Feature',
geometry = {
type ='Point',
coordinates = {
math_mod._round( decLong, 6 ), -- max precision in GeoJSON format
math_mod._round( decLat, 6 )
Ligne 385 ⟶ 360 :
name = 'maplink',
content = mw.text.jsonEncode( jsonParams ),
args = {
text = displaycoords[1] .. ", " .. displaycoords[2],
zoom = zoom( extraparams ) or default_zoom,
Ligne 392 ⟶ 367 :
}
}
 
-- format result depending on args["display"] (nil, "inline", "title", "inline,title")
local inlineText = displayinline and maplink or ''
Ligne 402 ⟶ 377 :
:wikitext( maplink )
local frame = mw.getCurrentFrame()
titleText = frame:extensionTag( 'indicator', tostring(htmlTitle), { name = 'coordinates' } )
end
 
return inlineText .. titleText
end
Ligne 431 ⟶ 406 :
end
degrees = lang:formatNum( valuetable.degrees ) .. i18n.degrees
 
if valuetable.minutes then
minutes = twoDigit( valuetable.minutes ) .. i18n.minutes
Ligne 450 ⟶ 425 :
if direction == 'N' or direction == 'S' then
dimension = 'latitude'
elseif direction == 'E' or direction == 'W' then
dimension = 'longitude'
else
Ligne 462 ⟶ 437 :
return false
end
 
if dimension == 'latitude' and direction ~= 'N' and direction ~= 'S' then
makeerror({message = i18n.invalidNS, sortkey = 'A'})
Ligne 471 ⟶ 446 :
return false
end
 
if dimension == 'latitude' and degrees > 90 then
makeerror({message = i18n.latitude90, sortkey = 'A'})
return false
end
 
if dimension == 'longitude' and degrees > 360 then
makeerror({message = i18n.longitude360, sortkey = 'A'})
return false
end
 
if degrees < 0 or minutes < 0 or seconds < 0 then
makeerror({message = i18n.negativeCoode, sortkey = 'A'})
return false
end
 
if minutes > 60 or seconds > 60 then
makeerror({message = i18n.minSec60, sortkey = 'A'})
return false
end
if (math.floor(degrees) ~= degrees and minutes ~= 0) or (math.floor(minutes) ~= minutes and seconds ~= 0) then
makeerror({message = i18n.dmIntergers, sortkey = 'A'})
Ligne 501 ⟶ 476 :
-- no error checking, done in function validdms
local dimensionobject = {}
 
-- direction and dimension (= latitude or longitude)
dimensionobject.direction = direction
Ligne 511 ⟶ 486 :
dimensionobject.dimension = 'longitude'
end
 
-- degrees, minutes, seconds
dimensionobject.degrees = tonumber(degrees)
Ligne 522 ⟶ 497 :
end
 
function p._parsedmsstring( str, dimension ) -- prend une séquence et donne des noms aux paramètres
-- output table: { latitude=, longitude = , direction = }
if type( str ) ~= 'string' then
Ligne 536 ⟶ 511 :
end
if not tonumber(str) and not string.find(str, '/') then
makeerror({message = i18n.invalidFormat, sortkey = 'A'})
return nil
end
local args = mw.text.split(str, '/', true)
if #args > 4 then
makeerror({message = i18n.tooManyParam, sortkey = 'A' })
end
local direction = mw.text.trim(args[#args])
table.remove(args)
Ligne 556 ⟶ 531 :
--- decimal specific functions
function p.displaydec(latitude, longitude, format)
local lat = lang:formatNum( latitude )
local long = lang:formatNum( longitude )
 
if format == 'dec west' or format == 'dec east' then
local symbolNS, symbolEW = i18n.N, i18n.E
if latitude < 0 then
symbolNS = i18n.S
lat = lang:formatNum( -latitude )
Ligne 568 ⟶ 543 :
symbolEW = i18n.W
end
if longitude < 0 then
long = lang:formatNum( 360 + longitude )
end
 
return { lat .. i18n.degrees .. symbolNS, long .. i18n.degrees .. symbolEW }
 
else
return { lat, long }
end
Ligne 653 ⟶ 628 :
local degrees = dec % 360
return degrees, minutes
end
 
local function dec2dms_dms(dec)
Ligne 667 ⟶ 642 :
function p._dec2dms(dec, coordtype, precision, globe) -- coordtype: latitude or longitude
local degrees, minutes, seconds
 
-- vérification du globe
if not ( globe and globedata[ globe ] ) then
globe = 'earth'
end
 
-- precision
if not precision or precision == '' then
Ligne 681 ⟶ 656 :
end
local dec = tonumber(dec)
 
-- direction
local direction
if coordtype == 'latitude' then
if dec < 0 then
direction = 'S'
else
direction = 'N'
end
Ligne 693 ⟶ 668 :
if dec < 0 or globedata[globe].defaultdisplay == 'dec west' then
direction = 'W'
else
direction = 'E'
end
end
 
-- conversion
dec = math.abs(dec) -- les coordonnées en dms sont toujours positives
if precision == 'dms' then
degrees, minutes, seconds = dec2dms_dms(dec)
elseif precision == 'dm' then
Ligne 711 ⟶ 686 :
 
function p.dec2dms(frame) -- legacy function somewhat cumbersome syntax
local args = frame.args
local dec = args[1]
if not tonumber(dec) then
makeerror({message = i18n.invalidFormat, sortkey = 'A'})
Ligne 721 ⟶ 696 :
local precision = string.lower(args[4] or '')
local displayformat, coordtype
 
if dirpositive == 'n' or dirpositive == 'nord' then
coordtype = 'latitude'
else
coordtype = 'longitude'
end
Ligne 745 ⟶ 720 :
if not minutes then minutes = 0 end
if not seconds then seconds = 0 end
 
if direction == "N" or direction == "E" then
factor = 1
elseif direction == "W" or direction == "S" then
factor = -1
elseif not direction then
makeerror({message = i18n.noCardinalDirection, sortkey = 'A'})
return nil
Ligne 757 ⟶ 732 :
return nil
end
 
if dmsobject.seconds then -- vérifie la précision des données initiales
precision = 5 + math.max( math_mod._precision(tostring(seconds), 0 ) ) -- passage par des strings assez tarabiscoté ?
Ligne 765 ⟶ 740 :
precision = math.max( math_mod._precision(tostring(degrees), 0 ) )
end
 
local decimal = factor * (degrees+(minutes+seconds/60)/60)
return math_mod._round(decimal, precision)
Ligne 772 ⟶ 747 :
function p.dms2dec(frame) -- legacy function, somewhat bizarre syntax
local args = frame.args
if tonumber(args[1]) then
return args[1] -- coordonnées déjà en décimal
elseif not args[2] then
Ligne 793 ⟶ 768 :
return showerrors()
end
else
return p._dms2dec({direction = args[1], degrees = tonumber(args[2]), minutes = tonumber(args[3]), seconds = tonumber(args[4])})
end
Ligne 829 ⟶ 804 :
--catbase= Article géolocalisé sur Terre
local entitycat = mw.wikibase.getEntity()
 
local basecat = 'Article géolocalisé'
local finalcat = {}
Ligne 837 ⟶ 812 :
for i, badgeId in ipairs( entitycat.sitelinks['frwiki'].badges ) do
if badgeId == 'Q17437796' then
basecat = string.gsub(basecat, "Article géolocalisé", "Article de qualité géolocalisé")
end
if badgeId == 'Q17437798' then
basecat = string.gsub(basecat, "Article géolocalisé", "Bon article géolocalisé")
end
end
Ligne 847 ⟶ 822 :
if globe == 'earth' then
if entitycat and entitycat.claims then
local country = entitycat.claims['P17']
if not country then
--pas pays à récupérer
basecat = basecat .. ' sur Terre'
table.insert(finalcat, basecat)
else
--parfois plusieurs pays
for i, paysId in ipairs( country ) do
--on fait confiance au label wikidata
local gdataone, qid
 
if paysId.mainsnak.snaktype == 'value' then
qid = paysId.mainsnak.datavalue.value['numeric-id']
gdataone =gdata mw.loadData("Module:Drapeau/Data").data[qid]
else
--Bir Tawil n'a pas de pays connu
qid = '?'
end
if gdataone ~= nil then
local prep=genre[gdataone['genre']]['en'] or= 'en 'mw.loadData("Module:Drapeau/Domaine").genre
local thecatprep =basecat .. genre[gdataone[' genre'..prep]]['en'] ..mw.wikibase.label(or 'Q'..en qid)'
local thecat = basecat .. ' '..prep ..mw.wikibase.label('Q'.. qid)
if mw.title.new('category:'..thecat).exists then
table.insert(finalcat, thecat)
else
--Dommage!
Ligne 881 ⟶ 857 :
if #finalcat == 0 then
--pas pays à récupérer
basecat = basecat .. ' sur Terre'
table.insert(finalcat, basecat)
end
end
else
--pas wikidata
basecat = basecat .. ' sur Terre'
table.insert(finalcat, basecat)
end
elseif globedata[globe] then
basecat = basecat .. ' ' .. globedata[globe].trackingcat
table.insert(finalcat, basecat)
else
basecat = basecat .. ' extraterrestre'
table.insert(finalcat, basecat)
end
return finalcat
Ligne 903 ⟶ 879 :
function p._coord(args)
 
-- I declare variable
local displayformat = args.format -- string: one of: 'dms', 'dms long', 'dec', 'dec east' and 'dec west'
local displayplace = string.lower(args.display or 'inline') --string: one of 'inline', 'title' or 'inline,title'
local displayinline = string.find(displayplace, 'inline') and true or false
local displaytitle = string.find(displayplace, 'title') and true or false
local objectname = (args.name ~= '') and args.name -- string: name of the title displayed in geohack
local notes = (' ' and args.notes) or '' -- string: notes to de displayed after coordinates
local wikidata = args.wikidata -- string: set to "true" if needed
local wikidataquery = args.wikidataquery -- table: see [[Module:Wikidata]] see function wikidatacoords
local dmslatitude, dmslongitude -- table (when created)
local extraparams = args.extraparams or '' -- string (legacy, corresponds to geohackparams)
local trackingstring = '' -- tracking cats except error cats (already in errorstring)
Ligne 919 ⟶ 897 :
local latitude, longitude, precision, dmslatitude, dmslongitude -- latitude and longitude in decimal / dmslatitude and dmslongitude: tables withdms coords
local maplink = true -- use maplink whenever it is possible
local savegeodata = nil
if args.geodata ~= nil and args.geodata ~= '' then
savegeodata = require('Module:Yesno')(args.geodata)
end
if savegeodata == nil then -- args.geodata non renseigné ou valeur non reconnue
savegeodata = (displaytitle and mw.title.getCurrentTitle():inNamespaces(0, 14, 100))
end
 
-- II extract coordinates from Wikitext
if (rawlat or rawlong) then
Ligne 952 ⟶ 937 :
if wikidata == 'true' then
wikidatalatitude, wikidatalongitude, wikidataglobe, wikidataprecision = wikidatacoords(wikidataquery)
 
if wikidatalatitude and latitude and longitude then
local maxdistance = tonumber(args.maxdistance) or wikidatathreshold
if p._distance({latitude = latitude, longitude = longitude}, {latitude = wikidatalatitude, longitude = wikidatalongitude}, wikidataglobe) < maxdistance then
trackingstring = trackingstring .. makecat(i18n.sameaswikidata)
else
Ligne 966 ⟶ 951 :
trackingstring = trackingstring .. makecat(i18n.throughwikidata)
end
 
if latitude and not wikidatalatitude then
if mw.title.getCurrentTitle().namespace == 0 then
Ligne 981 ⟶ 966 :
 
-- IV best guesses for missing parameters
 
--- globe
if globe == '' then
Ligne 994 ⟶ 979 :
maplink = false
end
 
--- diplayformat
if not displayformat or displayformat == '' then
displayformat = globedata[globe].defaultdisplay
end
 
-- displayinline/displaytitle
local displayinline = string.find(displayplace, 'inline')
local displaytitle = string.find(displayplace, 'title')
if not displayinline and not displaytitle then
displayinline = true
if displayplace ~= '' then
makeerror({sortkey = 'C'}) --error if display not empty, but not not a major error, continue
end
end
if displaytitle and mw.title.getCurrentTitle().namespace == 0 then
--local cattoappend = globedata[globe].trackingcat
--Récupération des badges
local cats = wikidatacat(globe)
for i, cat in ipairs( cats ) do
trackingstring = trackingstring .. makecat(cat)
end
 
end
 
-- V geodata
local geodata = ''
if savegeodata and latitude and longitude then
local latstring, longstring = tostring(latitude), tostring(longitude)
local primary = ''
 
local frame = mw.getCurrentFrame()
local geodataparams = {[1] = latstring, [2] = longstring, [3] = extraparams }
if displaytitle then
geodataparams[4] = 'primary'
Ligne 1 033 ⟶ 1 016 :
geodataparams.name = objectname
end
geodata = frame:callParserFunction('#coordinates', geodataparams )
if string.find(geodata, 'error') then -- the only error that has not been caught yet is primary key
geodata = ''
Ligne 1 042 ⟶ 1 025 :
local mainstring = ''
if maplink then
mainstring = buildMaplinkHTML(latitude, longitude, dmslatitude, dmslongitude, globe, displayformat, displayinline, displaytitle, objectname,extraparams extraparams)
else
mainstring = buildHTML(latitude, longitude, dmslatitude, dmslongitude, globe, displayformat, displayinline, displaytitle, objectname,extraparams extraparams)
end
 
return mainstring .. notes .. trackingstring .. geodata .. showerrors()
end
 
function p.coord(frame) -- parrsesparses the strange parameters of Template:Coord before sending them to p.coord
local args = frame.args
local numericargs = {}
for i, j in ipairs(args) do
args[i] = mw.text.trim(j)
if type(i) == 'number' and args[i] ~= '' then
table.insert(numericargs, args[i])
end
Ce document provient de « https://fr.wikipedia.org/wiki/Module:Coordinates ».