Module:Coordonnées
Aller à la navigation
Aller à la recherche
Source : cette page a été partiellement adaptée de la page Module:Coordinates de Wikipédia.
Source : cette page a été partiellement adaptée de la page Module:Math de Wikipédia.
Le module : Coordonnées implémente le modèle : Coord (fonction Coord
, voir la documentation du modèle) et sert au modèle : Infobox CoordGéo (fonction CoordGeog
).
Les deux modèles affichent à la fois (lorsque demandé) un texte qui expose les coordonnées du point donné, et une icône de titre (le module : Icône de titre est alors appelé).
À faire
- Beaucoup de choses mais pas trop, pour ne pas s’éloigner trop du code de Wikipédia. Documenter un petit peu, peut-être.
- Le code est importé de Wikipédia, et plein de fonctions ne sont ni utilisables ni souhaitables ici, il faudrait donc les enlever.
- Les cartes devraient (un jour) utiliser l’extension Kartographer (qui est installée), mais cela n’est pas possible actuellement.
La documentation de ce module est incluse depuis sa sous-page de documentation (modifier | historique).
Veuillez placer les catégories dans la sous-page /Documentation.
Les éditeurs peuvent travailler dans le bac à sable (créer).
local p = {}
--
-- fonctions d’aide
--
local function icone( url, texte )
return require( 'Module:Icône de titre' ).iconeDeTitre( nil, -- fonction réservée aux modules
'coords', -- id
'Compass icon matte.svg',
url,
texte )
end
--
-- deux fonctions importées du module : Math de Wikipédia, voir les auteurs
-- https://fr.wikipedia.org/w/index.php?title=Module:Math&oldid=116008789
--
local function _precision( x )
x = string.upper( x )
local decimal = string.find( x, '.', 1, true )
local exponent_pos = string.find( x, 'E', 1, true )
local result = 0;
if exponent_pos ~= nil then
local exponent = string.sub( x, exponent_pos + 1 )
x = string.sub( x, 1, exponent_pos - 1 )
result = result - tonumber( exponent )
end
if decimal ~= nil then
result = result + string.len( x ) - decimal
return result
end
local pos = string.len( x );
while x:byte(pos) == string.byte( '0' ) do
pos = pos - 1
result = result - 1
if pos <= 0 then
return 0
end
end
return result
end
local function _round( value, precision )
local rescale = math.pow( 10, precision )
return math.floor( value * rescale + 0.5 ) / rescale
end
--
-- fonctions importées du module : Coordinates de Wikipédia, voir les auteurs
-- https://fr.wikipedia.org/w/index.php?title=Module:Coordinates&oldid=192947244
--
local NBSP = '\194\160' -- espace insécable (code UTF-8 sur deux octets)
local i18n = {
N = 'N',
Nlong = 'nord',
W = 'O',
Wlong = 'ouest',
E = 'E',
Elong = 'est',
S = 'S',
Slong = 'sud',
degrees = '°' .. NBSP,
minutes = '′' .. NBSP,
seconds = '″' .. NBSP,
geohackurl = 'https://tools.wmflabs.org/geohack/geohack.php?language=fr',
tooltip = 'Cartes, vues aériennes, etc.',
errorcat = 'Page avec des balises de coordonnées mal formées',
invalidFormat = 'format invalide', -- 'invalid coordinate format',
invalidNSEW = 'orientation invalide, devrait être "N", "S", "E" or "W"', -- 'invalid direction should be "N", "S", "E" or "W"',
invalidNS = 'orientation de latitude invalide, devrait être "N" ou "S"', -- 'could not find latitude direction (should be N or S)',
invalidEW = 'orientation de longitude invalide, devrait être "E" ou "W"', -- 'could not find longitude direction (should be W or E) ',
noCardinalDirection = 'orientation cardinale non trouvée', -- 'no cardinal direction found in coordinates',
invalidDirection = 'direction invalide', -- 'invalid direction',
latitude90 = 'latitude > 90',
longitude360 = 'longitude > 360',
minSec60 = 'minutes ou secondes > 60',
negativeCoode = 'en format dms les degrés doivent être positifs', -- 'dms coordinates should be positive',
dmIntergers = 'degrés et minutes doivent être des nombres entiers', -- 'degrees and minutes should be integers',
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 = {
NORTH = 'N',
NORD = 'N',
EAST = 'E',
EST = 'E',
WEST = 'W',
O = 'W',
OUEST = 'W',
SOUTH = 'S',
SUD = 'S',
}
local globedata = {
--[[ notes:
radius in kilometers (especially imprecise for non spheric bodies)
defaultdisplay is currently disabled, activate it ?
]]--
ariel = {radius = 580, defaultdisplay = 'dec east'},
callisto = {radius = 2410, defaultdisplay = 'dec west'},
ceres = {radius = 470, defaultdisplay = 'dec east'},
charon = {radius = 1214, defaultdisplay = 'dec east'},
deimos = {radius = 7, defaultdisplay = 'dec west'},
dione = {radius = 560, defaultdisplay = 'dec west'},
enceladus = {radius = 255, defaultdisplay = 'dec west'},
ganymede = {radius = 2634, defaultdisplay = 'dec west'},
earth = {radius = 6371, defaultdisplay = 'dms' },
europa = {radius = 1561, defaultdisplay = 'dec east'},
hyperion = {radius = 140, defaultdisplay = 'dec west'},
iapetus = {radius = 725, defaultdisplay = 'dec west'},
['io'] = {radius = 1322, defaultdisplay = 'dec west'},
jupiter = {radius = 68911, defaultdisplay = 'dec east'},
mars = {radius = 3389.5, defaultdisplay = 'dec east'},
mercury = {radius = 2439.7, defaultdisplay = 'dec west'},
mimas = {radius = 197, defaultdisplay = 'dec west'},
miranda = {radius = 335, defaultdisplay = 'dec east'},
moon = {radius = 1736, defaultdisplay = 'dec' },
neptune = {radius = 24553, defaultdisplay = 'dec east'},
oberon = {radius = 761, defaultdisplay = 'dec east'},
phoebe = {radius = 110, defaultdisplay = 'dec west'},
phobos = {radius = 11, defaultdisplay = 'dec west'},
pluto = {radius = 1185, defaultdisplay = 'dec east'},
rhea = {radius = 765, defaultdisplay = 'dec west'},
saturn = {radius = 58232, defaultdisplay = 'dec east'},
titan = {radius = 2575.5, defaultdisplay = 'dec west'},
tethys = {radius = 530, defaultdisplay = 'dec west'},
titania = {radius = 394, defaultdisplay = 'dec east'},
triton = {radius = 1353, defaultdisplay = 'dec east'},
umbriel = {radius = 584, defaultdisplay = 'dec east'},
uranus = {radius = 25266, defaultdisplay = 'dec east'},
venus = {radius = 6051.8, defaultdisplay = 'dec east'},
vesta = {radius = 260, defaultdisplay = 'dec east'}
}
globedata[''] = globedata.earth
local lang = mw.language.getContentLanguage()
local default_zoom = 13
local function makecat(cat, sortkey)
if type( sortkey ) == 'string' then
return '[[Category:' .. cat .. '|' .. sortkey .. ']]'
else
return '[[Category:' .. cat .. ']]'
end
end
----------------------------------------
--Error handling
--[[ Notes:
when errors occure a new error message is concatenated to errorstring
an error message contains an error category with a sortkey
For major errors, it can also display an error message (the error message will the usually be returned and the function terminated)
More minor errors do only add a category, so that readers are not bothered with error texts
sortkeys:
* A: invalid latitude, longitude or direction
* B: invalid globe
* C: something wrong with other parameters
* D: more than one primary coord
]]--
local errorstring = ''
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
errorstring = errormessage .. errorcat -- reinitializes the string to avoid absurdly long messages
return nil
end
local function showerrors()
return errorstring
end
local function geoHackUrl(decLat, decLong, globe, displayformat, objectname, extraparams)
extraparams = extraparams or ''
local geohacklatitude, geohacklongitude
-- format latitude and longitude for the URL
if tonumber(decLat) < 0 then
geohacklatitude = tostring(-tonumber(decLat)) .. '_S'
else
geohacklatitude = decLat .. '_N'
end
if tonumber(decLong) < 0 then
geohacklongitude = tostring(-tonumber(decLong)) .. '_W'
elseif globedata[globe].defaultdisplay == 'dec west' then
geohacklongitude = decLong .. '_W'
else
geohacklongitude = decLong .. '_E'
end
-- prepares the 'paramss=' parameter
local geohackparams = geohacklatitude .. '_' .. geohacklongitude .. '_' ..extraparams
-- concatenate parameteres for geohack
return i18n.geohackurl ..
"&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") ..
"¶ms=" .. geohackparams ..
(objectname and ("&title=" .. mw.uri.encode(objectname)) or "")
end
local function twoDigit( value )
if ( value < 10 ) then
value = '0' .. lang:formatNum( value )
else
value = lang:formatNum( value )
end
return value
end
local function displaydmsdimension(valuetable, format) -- formate en latitude ou une longitude dms
local str = ''
local direction = valuetable.direction
local degrees, minutes, seconds = '', '', ''
local dimension
if format == 'dms long' then
direction = i18n[direction .. 'long']
else
direction = i18n[direction]
end
degrees = lang:formatNum( valuetable.degrees ) .. i18n.degrees
if valuetable.minutes then
minutes = twoDigit( valuetable.minutes ) .. i18n.minutes
end
if valuetable.seconds then
seconds = twoDigit( valuetable.seconds ) .. i18n.seconds
end
return degrees .. minutes .. seconds .. direction
end
--- decimal specific functions
local function 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 )
end
if format == 'dec west' then
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
end
local function parsedec(dec, coordtype, globe) -- coordtype = latitude or longitude
dec = mw.text.trim(dec)
if not dec then
return nil
end
if coordtype ~= 'latitude' and coordtype ~= 'longitude' then
makeerror({'invalid coord type', sortkey = "A"})
return nil
end
local numdec = tonumber(dec) -- numeric value, kept separated as it looses significant zeros
if not numdec then -- tries the decimal + direction format
dec = mw.ustring.gsub( mw.ustring.upper( dec ), '%a+', coordParse )
local direction = mw.ustring.sub(dec, mw.ustring.len(dec), mw.ustring.len(dec))
dec = mw.ustring.sub(dec, 1, mw.ustring.len(dec)-2) -- removes the /N at the end
if not dec or not tonumber(dec) then
return nil
end
if direction == 'N' or direction == 'E' or direction == 'W' and globedata[globe].defaultdisplay == 'dec west' then
numdec = tonumber( dec )
elseif direction == 'W' or direction == 'S' then
dec = '-' .. dec
numdec = tonumber( dec )
else
if coordtype == 'latitude' then
makeerror({message = i18n.invalidNS, sortkey = 'A'})
else
makeerror({message = i18n.invalidEW, sortkey = 'A'})
end
return nil
end
end
if coordtype == 'latitude' and math.abs(numdec) > 90 then
makeerror({message = i18n.latitude90 , sortkey = 'A'})
return nil
end
if coordtype == 'longitude' and math.abs(numdec) > 360 then
makeerror({message = i18n.longitude360 , sortkey = 'A'})
return nil
end
return dec
end
--HTML builder for a geohack link
local function buildHTML(decLat, decLong, dmsLat, dmsLong, globe, displayformat, displayinline, displaytitle, objectname, extraparams)
-- geohack url
local url = geoHackUrl(decLat, decLong, globe, displayformat, objectname, extraparams)
-- displayed coordinates
local displaycoords
if string.sub(displayformat, 1, 3) == 'dec' then
displaycoords = displaydec(decLat, decLong, displayformat)
else
displaycoords = {
displaydmsdimension(dmsLat, displayformat),
displaydmsdimension(dmsLong, displayformat),
}
end
-- build coordinate in h-geo / h-card microformat
local globeNode
if globe and globe ~= 'earth' then
globeNode = mw.html.create('data')
:addClass('p-globe')
:attr{ value = globe }
:done()
end
local coordNode = mw.html.create('')
if objectname then
coordNode = mw.html.create('span')
:addClass('h-card')
:tag('data')
:addClass('p-name')
:attr{ value = objectname }
:done()
end
coordNode
:tag('span')
:addClass('h-geo')
:addClass('geo-' .. string.sub(displayformat, 1, 3))
:tag('data')
:addClass('p-latitude')
:attr{ value = decLat }
:wikitext( displaycoords[1] )
:done()
:wikitext(", ")
:tag('data')
:addClass('p-longitude')
:attr{ value = decLong }
:wikitext( displaycoords[2] )
:done()
:node( globeNode )
:done()
-- buid GeoHack link
local root = mw.html.create('span')
:addClass('plainlinks nourlexpansion')
:attr('title', i18n.tooltip)
:wikitext('[' .. url )
:node(coordNode)
:wikitext("]")
:done()
-- format result depending on args["display"] (nil, "inline", "title", "inline,title")
local inlineText = displayinline and tostring(root) or ''
local titleText = ''
if displaytitle then
titleText = icone( url, 'GeoHack' )
end
return inlineText .. titleText
end
local function zoom( extraparams )
local zoomParam = extraparams:match( '%f[%w]zoom: ?(%d+)' )
if zoomParam then
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
local zoomType = {
country = 5,
state = 6,
adm1st = 7,
adm2nd = 8,
city = 9,
isle = 10,
mountain = 10,
waterbody = 10,
airport = 12,
landmark = 13,
}
return zoomType[ extraType ]
end
end
-- dms specific functions
local function validdms(coordtable)
local direction = coordtable.direction
local degrees = coordtable.degrees or 0
local minutes = coordtable.minutes or 0
local seconds = coordtable.seconds or 0
local dimension = coordtable.dimension
if not dimension then
if direction == 'N' or direction == 'S' then
dimension = 'latitude'
elseif direction == 'E' or direction == 'W' then
dimension = 'longitude'
else
makeerror({message = i18n.invalidNSEW, sortkey = 'A'})
return false
end
end
if type(degrees) ~= 'number' or type(minutes) ~= 'number' or type(seconds) ~= 'number' then
makeerror({message = i18n.invalidFormat, sortkey = 'A'})
return false
end
if dimension == 'latitude' and direction ~= 'N' and direction ~= 'S' then
makeerror({message = i18n.invalidNS, sortkey = 'A'})
return false
end
if dimension == 'longitude' and direction ~= 'W' and direction ~= 'E' then
makeerror({message = i18n.invalidEW, sortkey = 'A'})
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'})
return false
end
return true
end
local function builddmsdimension(degrees, minutes, seconds, direction, dimension)
-- no error checking, done in function validdms
local dimensionobject = {}
-- direction and dimension (= latitude or longitude)
dimensionobject.direction = direction
if dimension then
dimensionobject.dimension = dimension
elseif direction == 'N' or direction == 'S' then
dimensionobject.dimension = 'latitude'
elseif direction == 'E' or direction == 'W' then
dimensionobject.dimension = 'longitude'
end
-- degrees, minutes, seconds
dimensionobject.degrees = tonumber(degrees)
dimensionobject.minutes = tonumber(minutes)
dimensionobject.seconds = tonumber(seconds)
if degrees and not dimensionobject.degrees then dimensionobject.degrees = 'error' end
if minutes and not dimensionobject.minutes then dimensionobject.minutes = 'error' end
if seconds and not dimensionobject.seconds then dimensionobject.seconds = 'error' end
return dimensionobject
end
local function _parsedmsstring( str, dimension ) -- prend une séquence et donne des noms aux paramètres
-- output table: { latitude=, longitude = , direction = }
if type( str ) ~= 'string' then
return nil
end
str = mw.ustring.gsub( mw.ustring.upper( str ), '%a+', coordParse )
if not tonumber( str ) and not str:find( '/' ) and str:find( '°' ) then
local str2 = mw.ustring.gsub( str, '[°″′\"\'\194\160 ]+', '/' )
-- avoid cases were there is degree ans seconds but no minutes
if not mw.ustring.find( str, '[″"]' ) or mw.ustring.find( str, '%d[′\'][ \194\160%d]' ) then
str = str2
end
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)
local degrees, minutes, seconds = args[1], args[2], args[3]
local dimensionobject = builddmsdimension(degrees, minutes, seconds, direction, dimension)
if validdms(dimensionobject) then
return dimensionobject
else
return nil
end
end
-- dms/dec conversion functions
local function convertprecision(precision) -- converts a decimal precision like "2" into "dm"
if precision >= 3 then
return 'dms'
elseif precision >=1 then
return 'dm'
else
return 'd'
end
end
local function determinedmsprec(decs) -- returns the most precision for a dec2dms conversion, depending on the most precise value in the decs table
local precision = 0
for d, val in ipairs(decs) do
precision = math.max(precision, _precision(val))
end
return convertprecision(precision)
end
local function dec2dms_d(dec)
local degrees = _round( dec, 0 )
return degrees
end
local function dec2dms_dm(dec)
dec = _round( dec * 60, 0 )
local minutes = dec % 60
dec = math.floor( (dec - minutes) / 60 )
local degrees = dec % 360
return degrees, minutes
end
local function dec2dms_dms(dec)
dec = _round( dec * 60 * 60, 0 )
local seconds = dec % 60
dec = math.floor( (dec - seconds) / 60 )
local minutes = dec % 60
dec = math.floor( (dec - minutes) / 60 )
local degrees = dec % 360
return degrees, minutes, seconds
end
local function _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
precision = determinedmsprec({dec})
end
if precision ~= 'd' and precision ~= 'dm' and precision ~= 'dms' then
return makeerror({sortkey = 'C'})
end
local dec = tonumber(dec)
-- direction
local direction
if coordtype == 'latitude' then
if dec < 0 then
direction = 'S'
else
direction = 'N'
end
elseif coordtype == 'longitude' then
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
degrees, minutes = dec2dms_dm(dec)
else
degrees = dec2dms_d(dec)
end
return builddmsdimension(degrees, minutes, seconds, direction)
end
local function _dms2dec(dmsobject) -- transforme une table degré minute secondes en nombre décimal
local direction, degrees, minutes, seconds = dmsobject.direction, dmsobject.degrees, dmsobject.minutes, dmsobject.seconds
local factor = 0
local precision = 0
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
else
makeerror({message = i18n.invalidDirection, sortkey = 'A'})
return nil
end
if dmsobject.seconds then -- vérifie la précision des données initiales
precision = 5 + math.max( _precision(tostring(seconds), 0 ) ) -- passage par des strings assez tarabiscoté ?
elseif dmsobject.minutes then
precision = 3 + math.max( _precision(tostring(minutes), 0 ) )
else
precision = math.max( _precision(tostring(degrees), 0 ) )
end
local decimal = factor * (degrees+(minutes+seconds/60)/60)
return _round(decimal, precision)
end
-- main function for displaying coordinates
local function _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 dmslatitude, dmslongitude -- table (when created)
local extraparams = args.extraparams or '' -- string (legacy, corresponds to geohackparams)
local rawlat, rawlong = args.latitude, args.longitude
if rawlat == '' then rawlat = nil end
if rawlong == '' then rawlong = nil end
local globe = string.lower( args.globe or extraparams:match( 'globe:(%a+)' ) or '' ) -- string: see the globedata table for accepted values
local latitude, longitude, precision, dmslatitude, dmslongitude -- latitude and longitude in decimal / dmslatitude and dmslongitude: tables withdms coords
local maplink = false -- use maplink whenever it is possible
-- II extract coordinates from Wikitext
if (rawlat or rawlong) then
if (not rawlat) or (not rawlong) then -- if latitude is provided so should be longitude
makeerror({message = i18n.coordMissing, sortkey = 'A'})
return showerrors()
end
latitude = parsedec(rawlat, 'latitude', globe)
if latitude then -- if latitude is decimal
longitude = parsedec(rawlong, 'longitude', globe) -- so should be longitude
precision = determinedmsprec({latitude, longitude}) -- before conversion from string to number for trailing zeros
if not latitude or not longitude then
if errorstring == '' then
makeerror({message = i18n.invalidFormat, sortkey = 'A'})
end
return showerrors()
end
dmslatitude, dmslongitude = _dec2dms(latitude, 'latitude', precision), _dec2dms(longitude, 'longitude', precision, globe)
latitude, longitude = tonumber(latitude), tonumber(longitude)
else -- if latitude is not decimal try to parse it as a dms string
dmslatitude, dmslongitude = _parsedmsstring(args.latitude, 'latitude'), _parsedmsstring(args.longitude, 'longitude')
if not dmslatitude or not dmslongitude then
return showerrors()
end
latitude, longitude = _dms2dec(dmslatitude), _dms2dec(dmslongitude)
end
end
-- III extract coordinate data from Wikidata and compare them to local data
-- supprimé
-- exit if stil no latitude or no longitude
if not latitude and not longitude then
return nil -- ne rien ajouter ici pour que l'appel à cette fonction retourne bien nil en l'absence de données
end
-- IV best guesses for missing parameters
--- globe
if globe == '' then
globe = 'earth'
elseif not globedata[globe] then
makeerror({message = i18n.invalidGlobe .. globe})
globe = 'earth'
end
if globe ~= 'earth' then
extraparams = extraparams .. '_globe:' .. globe -- pas de problème si le globe est en double
maplink = false
end
--- diplayformat
if not displayformat or displayformat == '' then
displayformat = globedata[globe].defaultdisplay
end
-- displayinline/displaytitle
if not displayinline and not displaytitle then
displayinline = true
if displayplace ~= '' then
makeerror({sortkey = 'C'}) --error if display not empty, but not a major error, continue
end
end
-- V geodata
-- supprimé
-- VI final output
local mainstring = buildHTML(latitude, longitude, dmslatitude, dmslongitude, globe, displayformat, displayinline, displaytitle, objectname, extraparams)
return mainstring .. notes .. showerrors()
end
function p.Coord( frame ) -- parses the strange parameters of Template:Coord before sending them to p._coord
local args = frame:getParent().args
local numericargs = {}
for i, j in ipairs( args ) do
args[i] = mw.text.trim( j )
if args[i] ~= '' then
table.insert( numericargs, args[i] )
end
end
if #numericargs %2 == 1 then -- if the number of args is odd, the last one provides formatting parameters
args.extraparams = numericargs[#numericargs]
if #numericargs == 1 and tonumber( numericargs[1] ) then
makeerror({ message = i18n.coordMissing, sortkey = 'A' })
return showerrors()
end
table.remove( numericargs )
end
for i, j in ipairs( numericargs ) do
if i <= (#numericargs / 2) then
if not args.latitude then
args.latitude = j
else
args.latitude = args.latitude .. '/' .. j
end
else
if not args.longitude then
args.longitude = j
else
args.longitude = args.longitude .. '/' .. j
end
end
end
if string.find( args.latitude or '', 'E' ) or string.find( args.latitude or '', 'W' ) then
args.latitude, args.longitude = args.longitude, args.latitude
end
return _coord( args )
end
--
-- réécriture du [[modèle : CoordGéog]] pour le [[modèle : Infobox CoordGéo]]
--
local function lettreDirection( lettre )
if not lettre or lettre == '' then
return ''
end
lettre = mw.ustring.upper( lettre )
if lettre == 'S' then
return 'S'
elseif lettre == 'N' then
return 'N'
elseif lettre == 'E' then
return 'E'
elseif lettre == 'W' or lettre == 'O' then
return 'W'
else
error( 'mauvaise lettre en entrée de la fonction « lettreDirection »' )
end
end
local function nomDirection( lettre )
if not lettre or lettre == '' then
error( 'pas de lettre en entrée de la fonction « nomDirection »' )
end
lettre = mw.ustring.upper( lettre )
if lettre == 'S' then
return 'Sud'
elseif lettre == 'N' then
return 'Nord'
elseif lettre == 'E' then
return 'Est'
elseif lettre == 'W' or lettre == 'O' then
return 'Ouest'
else
error( 'mauvaise lettre en entrée de la fonction « nomDirection »' )
end
end
local function axeDirection( lettre )
if not lettre or lettre == '' then
error( 'pas de lettre en entrée de la fonction « axeDirection »' )
end
lettre = mw.ustring.upper( lettre )
if lettre == 'S' or lettre == 'N' then
return 'latitude'
elseif lettre == 'E' or lettre == 'W' or lettre == 'O' then
return 'longitude'
else
error( 'mauvaise lettre en entrée de la fonction « axeDirection »' )
end
end
local function coordGeog( coord, format )
local split = mw.text.split( coord, '/', true )
local rendu = format == '°'
local retour
if split[2] and split[2] ~= '' then -- coordonnées fournies au format D/M/S/X ou D/M//X
retour = split[1]
if rendu then
retour = retour .. "° "
else
retour = retour .. "_"
end
retour = retour .. split[2]
if rendu then
retour = retour .. "′"
end
if split[3] and split[3] ~= '' then
if rendu then
retour = retour .. " "
.. mw.ustring.gsub( split[3], '%.', ',' )
.. "″"
else
retour = retour .. "_"
.. mw.ustring.gsub( split[3], ',', '.' )
end
end
if rendu then
retour = retour .. " "
.. nomDirection( split[4] )
else
retour = retour .. "_"
.. lettreDirection( split[4] )
end
else -- coordonnées fournies au format D///X
if rendu then
local coords = _dec2dms( mw.ustring.gsub( split[1], ',', '.' ),
axeDirection( split[4] ))
retour = coords.degrees .. "°"
if coords.minutes ~= nil then
retour = retour .. " "
.. coords.minutes
.. "′"
if coords.seconds ~= nil then
retour = retour .. " "
.. mw.ustring.gsub( coords.seconds, '%.', ',' )
.. "″"
end
end
retour = retour .. " " .. nomDirection( coords.direction )
else
retour = mw.ustring.gsub( split[1], ',', '.' )
.. '_'
.. lettreDirection( split[4] )
end
end
return retour
end
-- pour le [[modèle : Infobox CoordGéo]]
function p.CoordGeog( frame )
local args = frame:getParent().args
local latitude = args['latitude']
local longitude = args['longitude']
local retour = coordGeog( latitude .. "///N", "°" )
.. "<br />"
.. coordGeog( longitude .. "///E", "°" )
local altitude = args['altitude']
if altitude and altitude ~= '' then
retour = retour .. "<br />[[altitude]] : "
.. altitude
.. " m" -- TODO abréviation
end
local url = "https://tools.wmflabs.org/geohack/geohack.php?language=fr"
.. "&pagename="
.. mw.uri.encode( mw.title.getCurrentTitle().prefixedText, 'PATH' )
.. "¶ms="
.. coordGeog( latitude .. "///N", "_" )
.. "_"
.. coordGeog( longitude .. "///E", "_" )
.. "_type:" .. args['type']
local tmp = args['échelle']
if tmp and tmp ~= '' then
url = url .. "_scale:"
.. tmp
end
tmp = args['dimension']
if tmp and tmp ~= '' then
url = url .. "_dim:"
.. tmp
end
tmp = args['région']
if tmp and tmp ~= '' then
url = url .. "_region:"
.. tmp
end
tmp = args['nom du lieu']
if tmp and tmp ~= '' then
url = url .. "&title="
.. mw.uri.encode( tmp, 'PATH' )
end
return retour .. icone( url, "Cartes, vues aériennes et satellitaires" )
end
return p