La documentation pour ce module peut être créée à Module:Coordinates/doc

local math_mod = require( "Module:Math" ) local p = {}  --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 = { 	N = ' N', 	Nlong = ' Nord', 	W = ' O', 	Wlong = ' Ouest', 	E = ' E', 	Elong = ' Est', 	S = ' S', 	Slong = ' Sud', 	degrees = '° ', 	minutes = '\′ ', 	seconds = '″ ', 	geohackurl = 'http://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', 	sameaswikidata = 'Page avec coordonnées similaires sur Wikidata', 	notaswikidata = 'Page avec coordonnées différentes sur Wikidata', 	nowikidata = 'Page sans coordonnées Wikidata', 	throughwikidata = 'Page géolocalisée par Wikidata' }  --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 "} }  local globedata = 	{ 	--[[ notes: 		radius in kilometers (especially imprecise for non spheric bodies) 		defaultdisplay is currently disabled, activate it ? 	]]--  	ariel = {radius = 580, defaultdisplay = 'dec east', trackingcat = 'Article géolocalisé extraterrestre'}, 	callisto =  {radius = 2410, defaultdisplay = 'dec east', trackingcat = 'Article géolocalisé extraterrestre'}, 	ceres =  {radius = 470, defaultdisplay = 'dec east', trackingcat = 'Article géolocalisé extraterrestre'}, 	deimos =  {radius = 7, defaultdisplay = 'dec east', trackingcat = 'Article géolocalisé extraterrestre'}, 	dione =  {radius = 560, defaultdisplay = 'dec east', trackingcat = 'Article géolocalisé extraterrestre'}, 	enceladus =  {radius = 255, defaultdisplay = 'dec east', trackingcat = 'Article géolocalisé extraterrestre'}, 	ganymede =  {radius = 1631, defaultdisplay = 'dec east', trackingcat = 'Article géolocalisé extraterrestre'}, 	earth = {radius = 6371, defaultdisplay = 'dms', trackingcat = 'Article géolocalisé sur Terre'}, 	europa =  {radius = 1561, defaultdisplay = 'dec east', trackingcat = 'Article géolocalisé extraterrestre'}, 	hyperion =  {radius = 140, defaultdisplay = 'dec east', trackingcat = 'Article géolocalisé extraterrestre'}, 	iapetus =  {radius = 725, defaultdisplay = 'dec east', trackingcat = 'Article géolocalisé extraterrestre'}, 	['io'] =  {radius = 1322, defaultdisplay = 'dec east', trackingcat = 'Article géolocalisé extraterrestre'}, 	jupiter =  {radius = 68911, defaultdisplay = 'dec east', trackingcat = 'Article géolocalisé extraterrestre'}, 	mars =  {radius = 3389.5, defaultdisplay = 'dec east', trackingcat =  'Article géolocalisé sur Mars' }, 	mercury =  {radius = 2439.7, defaultdisplay = 'dec east', trackingcat = 'Article géolocalisé extraterrestre'}, 	mimas =  {radius = 197, defaultdisplay = 'dec east', trackingcat = 'Article géolocalisé extraterrestre'}, 	miranda =  {radius = 335, defaultdisplay = 'dec east', trackingcat = 'Article géolocalisé extraterrestre'}, 	moon =  {radius = 1736, defaultdisplay = 'dec east', trackingcat = 'Article géolocalisé sur la Lune'}, 	neptune =  {radius = 24553, defaultdisplay = 'dec east', trackingcat = 'Article géolocalisé extraterrestre'}, 	oberon =  {radius = 761, defaultdisplay = 'dec east', trackingcat = 'Article géolocalisé extraterrestre'}, 	phoebe =  {radius = 110, defaultdisplay = 'dec east', trackingcat = 'Article géolocalisé extraterrestre'}, 	phobos =  {radius = 11, defaultdisplay = 'dec east', trackingcat = 'Article géolocalisé extraterrestre'}, 	rhea =  {radius = 765, defaultdisplay = 'dec east', trackingcat = 'Article géolocalisé extraterrestre'}, 	saturn =  {radius = 58232, defaultdisplay = 'dec east', trackingcat = 'Article géolocalisé extraterrestre'}, 	titan =  {radius = 2575.5, defaultdisplay = 'dec west', trackingcat = 'Article géolocalisé extraterrestre'}, 	tethys =  {radius = 530, defaultdisplay = 'dec east', trackingcat = 'Article géolocalisé extraterrestre'}, 	titania =  {radius = 394, defaultdisplay = 'dec east', trackingcat = 'Article géolocalisé extraterrestre'}, 	triton = {radius = 1353, defaultdisplay = 'dec west', trackingcat = 'Article géolocalisé extraterrestre'}, 	umbriel =  {radius = 584, defaultdisplay = 'dec east', trackingcat = 'Article géolocalisé extraterrestre'}, 	uranus =  {radius = 25266, defaultdisplay = 'dec east', trackingcat = 'Article géolocalisé extraterrestre'}, 	venus =  {radius = 6051.8, defaultdisplay = 'dec east', trackingcat = 'Article géolocalisé extraterrestre'}, 	vesta =  {radius = 260, defaultdisplay = 'dec east', trackingcat = 'Article géolocalisé extraterrestre'} 	 }  local wikidatathreshold = 10 -- si la distance entre coordonnées Wikipédia et Wikidata dépasse se seuil (en kilomètes), une catégorie de maintenance est ajoutée  local function makecat(cat, sortkey) 	return '[[Category:' .. cat .. '|' .. (sortkey or '*') .. ']]' 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: ' .. 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  -- Distance computation function p._distance(a, b, globe) -- calcule la [[distance orthodromique]] en kilomètres entre deux points du globe  	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 	if (not latA) or (not latB) or (not longA) or (not longB) then return 		error('coordinates missing, can\'t compute distance') 	end 	if type(latA) ~= 'number' or type(latB) ~= 'number' or type(longA) ~= 'number' or type(longB) ~= 'number' then 		error('coordinates are not numeric, can\'t compute distance') 	end 		if not globe or not globedata[globe] then 		return error('globe: ' .. globe .. 'is not supported') 	end 	 	-- calcul de la distance angulaire en radians 	local convratio = math.pi / 180 -- convertit en radians 	latA, latB, longA, longB = convratio * latA, convratio * latB, convratio * longA, convratio * longB 	local cosangle = math.sin(latA) * math.sin(latB) + math.cos(latA) * math.cos(latB) * math.cos(longB - longA) 	if cosangle >= 1 then -- may be above one because of rounding errors 		return 0 	end 	local angle = math.acos(cosangle) 	-- calcul de la distance en km 	local radius = globedata[globe].radius 	return radius * angle end  function p.distance(frame) 	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) end  --HTML builder for a geohack link local function buildHTML(decLat, decLong, dmsLat, dmsLong, globe, displayformat, displayinline, displaytitle, objectname, extraparams)     local root, text, url, noprint 	extraparams = extraparams or ''     -- geohack url and parameters     local decimalcoords = p.displaydec(decLat, decLong, displayformat)     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'     else      	geohacklongitude = decLong .. '_E' 	end 	-- prepares the 'paramss=' parameter 	local geohackparams = geohacklatitude .. '_' .. geohacklongitude .. '_' ..extraparams 	-- concatenate parameteres for geohack 	local url = i18n.geohackurl ..  		"&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. 		"&params=" .. geohackparams .. 		(objectname and ("&title=" .. mw.uri.encode(objectname)) or "")      root = mw.html.create('')     root 		:tag("span") 			:addClass("plainlinks nourlexpansion")             :attr('title', i18n.tooltip) 			:wikitext("[" .. url) 			:tag("span")             	:addClass(string.sub(displayformat,1,3) == "dec" and "geo-nondefault" or "geo-default")                  	:tag("span") 					:addClass("geo-dms") 					:tag("span") 						:addClass("latitude") 						:wikitext(p.displaydmsdimension(dmsLat, displayformat)) 						:done() 					:wikitext(" ") 					:tag("span") 						:addClass("longitude") 						:wikitext(p.displaydmsdimension(dmsLong, displayformat)) 						:done() 					:done() 				:done() 			:tag("span") 				:addClass("geo-multi-punct") 				:wikitext("&ensp;/&ensp;") 				:done() 			:tag("span") 				:addClass(string.sub(displayformat,1,3) == 'dec' and "geo-default" or "geo-nondefault") 				:wikitext(objectname and "<span class=\"vcard\">" or "") 				:tag("span") 					:addClass("geo-dec") 					:wikitext(decimalcoords) 					:done() 				:wikitext(objectname and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. 						objectname .. "</span>)</span></span>") or "") 				:done() 			:wikitext("]") 			:done()      -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title")     text = tostring(root)      noprint = displayinline and "class=\"noprint\" " or ""     htmlTitle = "<span style=\"font-size: small;\"><span " .. noprint .. "id=\"coordinates\">"       return (displayinline and text or "") ..            (displaytitle and (htmlTitle .. text .. "</span></span>") or "") end   -- dms specific funcions  function p.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 = valuetable.degrees .. i18n.degrees 	 	if valuetable.minutes then 		minutes = valuetable.minutes .. i18n.minutes 		if (valuetable.minutes < 10) then 			minutes = '0' .. minutes 		end 	end 	if valuetable.seconds then 		seconds = valuetable.seconds .. i18n.seconds 		if (valuetable.seconds < 10) then 			seconds = '0' .. seconds 		end 	end 	return degrees .. minutes .. seconds .. direction end  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 = 'invalid direction should be "N", "S", "E" or "W"', sortkey = 'A'}) 			return false 		end end  	if type(degrees) ~= 'number' or type(minutes) ~= 'number' or type(seconds) ~= 'number' then 		makeerror({message = 'invalid format', sortkey = 'A'}) 		return false 	end 	 	if dimension == 'latitude' and direction ~= 'N' and direction ~= 'S' then 		makeerror({message = 'could not find latitude direction (should be N or S)', sortkey = 'A'}) 		return false 	end 	if dimension == 'longitude' and direction ~= 'W' and direction ~= 'E' then 		makeerror({message = 'could not find longitude direction (should be W or E) ', sortkey = 'A'}) 		return false 	end 	 	if dimension == 'latitude' and degrees > 90 then 		makeerror({message = 'latitude > 90', sortkey = 'A'}) 		return false 	end 	 	if dimension == 'longitude' and degrees > 360 then 		makeerror({message = 'longitude > 360', sortkey = 'A'}) 		return false 	end 	 	if degrees < 0 or minutes < 0 or seconds < 0 then 		makeerror({message = 'dms coordinates should be positive', sortkey = 'A'}) 		return false 	end 	 	if minutes > 60 or seconds > 60 then 		makeerror({message = 'minutes or seconds > 60', sortkey = 'A'}) 		return false 	end	 	if (math.floor(degrees) ~= degrees and minutes ~= 0) or (math.floor(minutes) ~= minutes and seconds ~= 0) then 		makeerror({message = 'degrees and minutes should be integers', sortkey = 'A'}) 		return false 	end 	return true end  local function builddmsdimension(degrees, minutes, seconds, direction) 	-- no error checking, done in function validdms 	local dimensionobject = {}  	 	-- direction and dimension (= latitude or longitude) 	dimensionobject.direction = direction 	if direction == 'N' or direction == 'S' then 		dimensionobject.dimension = 'latitude' 	else 		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) -- prend une séquence et donne des noms aux paramètres  	-- output table: {latitude=, longitude = , direction =  } 	if not str then 		return nil 	end 	if not tonumber(str) and not string.find(str, '/') then 		makeerror({message ='invalid coordinate format', sortkey= 'A'}) 		return nil 	end 	args = mw.text.split(str, '/', true) 	if #args > 4 then 		makeerror({message = "too many parameters for coordinates", 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) 	if validdms(dimensionobject) then 		return dimensionobject 	else 		return nil 	end end  --- decimal specific functions function p.displaydec(latitude, longitude, format) 	if format == 'dec west' then 		local latsymbol = i18n.N 		longitude = - longitude 		if latitude < 0 then latsymbol = i18n.S end 		if longitude < 0 then  			longitude = 360 + longitude 		end 	return latitude .. i18n.degrees .. latsymbol .. ', ' .. longitude ..  i18n.degrees .. i18n.W 		 	elseif format == 'dec east' then 		local latsymbol = i18n.N 		if latitude < 0 then latsymbol = i18n.S end 		if longitude < 0 then  			longitude = 360 + longitude 		end 		return latitude .. i18n.degrees .. latsymbol .. ', ' .. longitude  ..  i18n.degrees .. i18n.E 		 	else  		return latitude .. ', ' .. longitude  	end end   local function parsedec(dec, coordtype) -- coordtype = latitude or longitude 	dec = mw.text.trim(dec) 	if coordtype ~= 'latitude' and coordtype ~= 'longitude' then 		makeerror({'invalid coord type', sortkey = "A"}) 		return nil 	end 	if not dec then 		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 		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' then 			return dec 		elseif direction == 'W' or direction == 'S' then 			return '-' .. dec 		else 			makeerror({message = 'could not find longitude direction (should be W or E) ', sortkey = 'A'}) 			return nil 		end 	end  	if coordtype == 'latitude' and math.abs(numdec) > 90 then 		makeerror({message = 'latitude > 90' , sortkey = 'A'}) 		return nil 	end 	if coordtype == 'longitude' and math.abs(numdec) > 360 then 		makeerror({message = 'longitude > 360' , sortkey = 'A'}) 		return nil 	end 	return dec 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, math_mod._precision(val)) 	end 	return convertprecision(precision) end  local function dec2dms_d(dec) 	local degrees = math_mod._round( dec, 0 ) 	return degrees end  local function dec2dms_dm(dec) 	dec = math_mod._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 = math_mod._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  function p._dec2dms(dec, coordtype, precision) -- type: latitude or longitude  	local degrees, minutes, seconds 	 	-- 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  	if coordtype == 'latitude' then  		if dec < 0 then 			direction = 'S' 		else  			direction = 'N' 		end 	elseif coordtype == 'longitude' then 		if dec < 0 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  function p.dec2dms(frame) -- legacy function somewhat cumbersome syntax 	args = frame.args 	local dec = args[1]  	if not tonumber(dec) then 		makeerror({message='invalid coordinate format', sortkey = 'A'}) 		return showerrors() 	end 	local precision = string.lower(args[4] or '') 	local displayformat, coordtype 	 	if args[2] == 'N' or args[2] == 'Nord' then 		coordtype = 'latitude' 	else  		coordtype = 'longitude' 	end 	if args[2] == 'Nord' or args[2] == 'Est' or args[3] == 'Ouest' or args[3] == 'Sud' then 		displayformat = 'dms long' 	end 	local coordobject = p._dec2dms(dec, coordtype, precision) 	if coordobject then 		return p.displaydmsdimension(coordobject, displayformat) .. showerrors() 	else 		return showerrors() 	end end   function p._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 = 'no cardinal direction found in coordinates', sortkey = 'A'}) 		return nil 	else 		makeerror({message = 'invalid direction', sortkey = 'A'}) 		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é ? 	elseif dmsobject.minutes then 		precision = 3 + math.max( math_mod._precision(tostring(minutes), 0 ) ) 	else 		precision = math.max( math_mod._precision(tostring(degrees), 0 ) ) 	end 	 	local decimal = factor * (degrees+(minutes+seconds/60)/60) 	return math_mod._round(decimal, precision) end  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 		local dmsobject = parsedmsstring(args[1]) 		if dmsobject then 			return p._dms2dec(dmsobject) -- coordonnées sous la fore 23/22/N 		else 			return showerrors() 		end 	else  		return p._dms2dec({direction = args[1], degrees = args[2], minutes = args[3], seconds = args[4]}) 	end end  -- Wikidata local function convertwikidataprecision(precision) -- converts a decima like "0.1" into "dm" 	if precision < 0.016 then 		return 'dms' 	elseif precision < 1 then 		return 'dm' 	else 		return 'd' 	end end  local function wikidatacoords(query) 	query = query or {property = 'p625'} 	query.formatting = 'raw' 	local wd = require('Module:Wikidata') 	local claim = wd.getClaims(query) 	if claim and claim[1] then -- redundant but more robust in case of a change in the code of Module:Wikidata 		local coords = wd.formatSnak(claim[1].mainsnak) -- todo: check for special values 		return coords.latitude, coords.longitude, coords.globe or 'earth', convertwikidataprecision(coords.precision or .001) 	end 	return nil end   local function wikidatacat(globe) 	--catbase= Article géolocalisé sur Terre 	local entitycat = mw.wikibase.getEntityObject() 	 	local basecat = 'Article géolocalisé' 	local finalcat = {} 	--BADGES     if entitycat then     	--BADGES        	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 	end  	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.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 ' 						local thecat=basecat .. ' '..prep ..mw.wikibase.label( 'Q'.. qid) 						if mw.title.new('category:'..thecat).exists then 							table.insert(finalcat,thecat) 						else 							--Dommage! 							mw.log(thecat .. ' à créer') 						end 					else 						--pas d'id? 						mw.log(qid .. ' à paramétrer') 					end 				end 				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  globe == 'moon'  then 			basecat=basecat .. ' sur la Lune' 			table.insert(finalcat,basecat) 	elseif  globe == 'mars'  then 			basecat=basecat .. ' sur Mars' 			table.insert(finalcat,basecat) 	else 			basecat=basecat .. ' extraterrestre' 			table.insert(finalcat,basecat) 	end 	return finalcat end   -- main function for displaying coordinates 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 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 = string.lower(args.extraparams or '') -- string (legacy, corresponds to geohackparams)  	local trackingstring = '' -- tracking cats except error cats (already in errorstring)  	local rawlat, rawlong = args.latitude, args.longitude  	if ralwat == '' then rawlat = nil end  	if rawlong == '' then rawlong = nil end  	local globe = string.lower(args.globe 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 	 	-- 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 = 'latitude or longitude missing', sortkey = 'A'}) 			return showerrors() 		end 		latitude = parsedec(rawlat, 'latitude')  		if latitude then -- if latitude is decimal 			longitude = parsedec(rawlong, 'longitude') -- 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 = 'invalid format', sortkey = 'A'}) 				end 				return showerrors() 			end 			dmslatitude, dmslongitude = p._dec2dms(latitude, 'latitude', precision), p._dec2dms(longitude, 'longitude', precision) 			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), parsedmsstring(args.longitude) 			if not dmslatitude or not dmslongitude then 				return showerrors() 			end 			latitude, longitude = p._dms2dec(dmslatitude), p._dms2dec(dmslongitude) 		end 	end  	-- III extract coordinate data from Wikidata and compare them to local data 	local wikidatalatitude, wikidatalongitude, wikidataglobe 	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 				trackingstring = trackingstring .. makecat(i18n.notaswikidata) 			end 		end 		if wikidatalatitude and not latitude then 			latitude, longitude, globe, precision = wikidatalatitude, wikidatalongitude, wikidataglobe, wikidataprecision 			dmslatitude, dmslongitude = p._dec2dms(latitude, 'latitude', precision), p._dec2dms(longitude, 'longitude', precision) 			trackingstring = trackingstring .. makecat(i18n.throughwikidata) 		end 		 		if latitude and not wikidatalatitude then 			if mw.title.getCurrentTitle().namespace == 0 then 				trackingstring = trackingstring .. makecat(i18n.nowikidata) 			end 		end 	end   	-- 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 -- cherche le globe dans l'extraparams destinée à geohack 		local globe2 = string.match(extraparams, 'globe\:%a+') 		if globe2 then  			globe = string.sub(globe2, 7)  		end 		if globe == '' then 			globe = 'earth' 		end 	end 	if not globedata[globe] then 		makeerror({message = 'invalid globe:' .. globe}) 		globe = 'earth' 	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 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' 		end 		if objectname then 			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 = '' 			makeerror({sortkey='D'}) 		end     end -- VI final output 	if globe ~= 'earth' then 		extraparams = extraparams .. '_globe:' .. globe -- pas de problème si le globe est en double 	end  	local mainstring = '' 	if args.formatitle then 		if displaytitle then 			mainstring = mainstring .. buildHTML(latitude, longitude, dmslatitude, dmslongitude, globe, args.formatitle, false, true, objectname,extraparams ) 		end 		if displayinline then 			mainstring = mainstring .. buildHTML(latitude, longitude, dmslatitude, dmslongitude, globe, displayformat, true, false, objectname,extraparams ) 		end 	else 		mainstring = buildHTML(latitude, longitude, dmslatitude, dmslongitude, globe, displayformat, displayinline, displaytitle, objectname,extraparams ) 	end 	 	return mainstring .. notes .. trackingstring .. geodata .. showerrors() end  function p.coord(frame) -- parrses 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 	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 = 'latitude or longitude missing', sortkey = 'A'}) 			return showerrors() 		end 		table.remove(numericargs) 	end 	if #numericargs == 1 then 		makeerror({message = 'missing data for coords', sortkey = 'A'}) 		return showerrors() 	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 p._coord(args) end  function p.Coord(frame) 	return p.coord(frame) end   function p.latitude(frame) -- helper function pour infobox, à déprécier 	local args = frame.args 	local latitude  = frame.args[1] 	if latitude and mw.text.trim(latitude) ~= '' then 		return latitude 	elseif frame.args['wikidata'] == 'true' then 		local lat, long = wikidatacoords() 		return lat 	end end function p.longitude(frame) -- helper function pour infobox, à déprécier 	local args = frame.args 	local longitude = frame.args[1] 	if longitude and mw.text.trim(longitude) ~= '' then 		return longitude 	elseif frame.args['wikidata'] == 'true' then 		local lat, long = wikidatacoords() 		return long 	end end   return p