Moduldokumentasjon

Coordinates er en Lua-modul som formaterer koordinater for visning enten i løpetekst i tittelområdet (minikartet oppe til høyre). Den lager også koordinater til #coordinates-parserfunksjonen.

Modulen henter koordinater fra Wikidata. Hvis koordinater finnes både lokalt og på Wikidata vil modulen sammenligne dem og putte siden i en av kategoriene Kategori:Sider med koordinater som samsvarer med Wikidata (0) eller Kategori:Sider med koordinater som avviker fra Wikidata (0).

Bruk rediger

Eksporte funksjoner :

  • coordinates.coord(frame) – formaterer geografiske koordinater for visning enten i løpetekst eller i

statusindikatorområdet (oppe til høyre). Lager også koordinater til #coordinates-parserfunksjonen.

  • p.dec2dms(frame) – konverterer koordinater uttrykt i titallsystemet til seksagesimalsystemet
  • p.dms2dec(frame) – konverterer koordinater uttrykt i seksagesimalsystemet til titallsystemet
  • p.latitude(frame) – henter ut breddegrad (fra lokale malparametre eller fra Wikidata). Spesielt nyttig for infobokser
  • p.longitude(frame) – henter ut lengdegrad (fra lokale malparametre eller fra Wikidata). Spesielt nyttig for infobokser
  • p.distance(frame) – beregner avstanden mellom to punkter
  • p._coord(args) – funksjon ála p.coord til bruk i andre Lua-moduler
  • p._dms2dec(dmsobject) – funksjon ála p.dms2dec til bruk i andre Lua-moduler
  • p._dec2dms(coordtype, precision) – funksjon ála p.dec2dms til bruk i andre Lua-moduler
  • p._distance(a, b, globe) – funksjon ála p.distance til bruk i andre Lua-moduler
  • p._parsedmsstring(str, dimension) - lager en dms-tabell fra en streng av typen "48/22/16/W".

Interne funksjoner:

  • makeerror - lager feilmeldinger
  • buildHTML - formaterer resultatet for p.coord() som en GeoHack-lenke
  • buildMaplinkHTML - formaterer resultatet for p.coord() som en maplink-lenke
  • displaydmsdimension - gjør om en dms-tabell som inneholder grader, minutter, sekunder, himmelretning og koordtype (= breddegrad eller lengdegrad) til en streng av typen 48° 29'32 "N
  • validdms - sjekker at en dms-tabell er gyldig (gyldig himmelretning og gyldig koordtype, gyldige verdier for grader, minutter og sekunder)
  • builddmsdimension - lager en dms-tabell
  • displaydec - gjør om en desimalbreddegrad og en desimallengdegrad til en streng av typen "34.294, 12.321"
  • parsedec - tolker og validerer desimalkoordinater
  • convertprcision - gjør om presisjonen funnet av Module:Math.precision til "d", "dm" eller "dms"
  • convertwikidataprecision - gjør om presisjonen fra Wikidata til "d", "dm" eller "dms"
  • determinedmsprec - beregner graden av presisjon som passer best for gitt desimalkoordinater
  • dec2dms_d - konverterer et desimalt koordinat til dms med presisjon på gradnivå
  • dec2dms_dm - konverterer et desimalt koordinat til dms med presisjon på minuttnivå
  • dec2dms_dms - konverterer et desimalt koordinat til dms med presisjon på sekundnivå
  • wikidatacoords - henter koordinater fra Wikidata

Interne variabler:

  • wikidatathreshold : For sider som har koordinater både lokalt og på Wikidata: Hvis koordinatene avviker med mer enn denne avstanden (i kilometer),

havner siden i Kategori:Sider med koordinater som avviker fra Wikidata. Ellers havner den i Kategori:Sider med koordinater som samsvarer med Wikidata.

Modulavhengigheter:

  • Module:Math – For å håndtere avrunding og presisjon

Grunleggende eksempler rediger

Grunnleggende sett støtter modulen tre måter å angi geografiske koordinater på:

  1. Med desimalgrader:
  2. Med tradisjonell angivelse:
  1. Fra d:Property:P625 på Wikidata (hvis artikkelsubjektet har flere koordinater brukes det første settet)
  2. * {{#invoke:Coordinates | coord | wikidata=true}}

Som standard er utdataformatet det samme som inngangsformatet, men det kan endres ved å sende et ekstra argument |format=xxx

  1. dms for tradisjonell angivelse med grader, minutter og sekunder
  2. dms long for tradisjonell angivelse med grader, minutter og sekunder samt himmelretning fullt utskrevet
  3. dec for desimalgrader:

Valg for funksjonen p.coord rediger

Option de la fonction p.coord (utilisable depuis Lua)

  • latitude =
  • longitude =
  • globe = (planet, hvis annen planet enn jorda)
  • format = 'dms', 'dec' eller 'dms long'
  • displaytitle = "true" for å vise koordinater i statusindikatorområdet (tittel)
  • formattitle = hvis koordinatene i statusindikatorområdet skal ha et bestemt format
  • wikidata = "true" for å hente koordinater fra Wikidata
  • wikidataprop = Wikidata-egenskap som skal brukes, standard er P625

Detaljerte eksempler rediger

Desimalgrader rediger

Kode Resultat Resultat
|format=dec
Resultat
|format=dms
Resultat
|format=dms long
Notes
{{#invoke:Coordinates|coord|43.651234|-79.383333}} 43° 39′ 04″ N, 79° 23′ 00″ V 43,651234, −79,383333 43° 39′ 04″ N, 79° 23′ 00″ V 43° 39′ 04″ nord, 79° 23′ 00″ vest Toronto
{{#invoke:Coordinates|coord|-33.856111|151.1925}} 33° 51′ 22″ S, 151° 11′ 33″ Ø −33,856111, 151,1925 33° 51′ 22″ S, 151° 11′ 33″ Ø 33° 51′ 22″ sør, 151° 11′ 33″ øst Sydney
{{#invoke:Coordinates|coord|43.65|-79.38}} 43° 39′ N, 79° 23′ V 43,65, −79,38 43° 39′ N, 79° 23′ V 43° 39′ nord, 79° 23′ vest Toronto, med lavere presisjon
{{#invoke:Coordinates|coord|43.6500|-79.3800}} 43° 39′ 00″ N, 79° 22′ 48″ V 43,65, −79,38 43° 39′ 00″ N, 79° 22′ 48″ V 43° 39′ 00″ nord, 79° 22′ 48″ vest Toronto, med flere nuller for å angi høyere presisjon
{{#invoke:Coordinates|coord|43.651234|N|79.383333|W}} 43° 39′ 04″ N, 79° 23′ 00″ V 43,651234, −79,383333 43° 39′ 04″ N, 79° 23′ 00″ V 43° 39′ 04″ nord, 79° 23′ 00″ vest Toronto, med N/W i stedet for +/-

Tradisjonell angivelse rediger

Kode Resultat Resultat
|format=dec
Resultat
|format=dms
Resultat
|format=dms long
Notes
{{#invoke:Coordinates|coord|43|39|N|79|23|W}} 43° 39′ N, 79° 23′ V 43,65, −79,383 43° 39′ N, 79° 23′ V 43° 39′ nord, 79° 23′ vest Toronto, med grader og minutter
{{#invoke:Coordinates|coord|43|39|4|N|79|23|0|W}} 43° 39′ 04″ N, 79° 23′ 00″ V 43,65111, −79,38333 43° 39′ 04″ N, 79° 23′ 00″ V 43° 39′ 04″ nord, 79° 23′ 00″ vest Toronto, med grader, minutter og sekunder
{{#invoke:Coordinates|coord|43|39|4.5|N|79|23|0.5|W}} 43° 39′ 04,5″ N, 79° 23′ 00,5″ V 43,65125, −79,383472 43° 39′ 04,5″ N, 79° 23′ 00,5″ V 43° 39′ 04,5″ nord, 79° 23′ 00,5″ vest Toronto, med grader, minutter, sekunder og sekunddeler
{{#invoke:Coordinates|coord|43/39/N|79/23/W}} 43° 39′ N, 79° 23′ V 43,65, −79,383 43° 39′ N, 79° 23′ V 43° 39′ nord, 79° 23′ vest Toronto, med hvert koordinat samlet i et felt hver

Ekstra parametre for maplink rediger

Enkelte av de gamle GeoHack-parametrene støttes, men ikke alle.

  • Zoomnivå for kartet kan settes enten med zoom: (fra 0 til 19).

Alternativt kan type: brukes med et sett av forhåndsdefinerte verdier (type:city gir for eksempel zoomnivå 9). Det gamle GeoHack-argumentet scale: er også støttet, det konverteres til zoomnivå internt. Det gamle GeoHack-argumentet dim: er ikke støttet.

  • region: er ikke støttet av maplink (enda???). Det betyr at vi ikke kan bruke region:NO for å angi at Norgeskart skal dukke opp i lista over eksterne kart f.eks.
  • Flere parametre skilles med understrek.

Trykk på lenkene under for å se resultatet av de forskjellige verdiene

Parameter Eksempel Resultat Notes
{{#invoke:Coordinates|coord|43.65|-79.38}} 43° 39′ N, 79° 23′ V Toronto, standardvisning
zoom: {{#invoke:Coordinates|coord|43.65|-79.38|zoom:5}} 43° 39′ N, 79° 23′ V Toronto, med zoomnivå 5 for å vise hele landet i kartvisningen
scale: {{#invoke:Coordinates|coord|43.65|-79.38|scale:3000000}} 43° 39′ N, 79° 23′ V Toronto, med skala 3000000 for å vise hele landet i kartvisningen
dim: {{#invoke:Coordinates|coord|40.6892|-74.0445|dim:100}} 40° 41′ 21″ N, 74° 02′ 40″ V Frihetsgudinnen, med dimensjon 100 for å gi en passende skala (ikke støttet)
type: {{#invoke:Coordinates|coord|43.65|-79.38|type:city}} 43° 39′ N, 79° 23′ V Toronto, med en skala som typisk passer for en by (type:city tilsvarer zoomnivå 9)
region: {{#invoke:Coordinates|coord|43.65|-79.38|region:CA}} 43° 39′ N, 79° 23′ V Toronto, ved å angi region:CA kan det vises karttjenester som er spesielt tilpasset Canada (ikke støttet)
globe: {{#invoke:Coordinates|coord|9.7|-20.0|globe:moon}} 9,7, −20 Copernicus (månekrater), med kartlag for månen
name= {{#invoke:Coordinates|coord|43.65|-79.38|name=Toronto}} 43° 39′ N, 79° 23′ V Toronto, med et navn som vises når du trykker på pekeren

Visning i statusindikatorområdet (tittellinjen) rediger

Bruk |display= for å endre hvor koordinatene vises:

  • {{#invoke:Coordinates|coord|43.65|-79.38|display=inline}} : Vis bare i løpetekst (standard)
  • {{#invoke:Coordinates|coord|43.65|-79.38|display=title}} : Vis bare i statusindikatorområdet
  • {{#invoke:Coordinates|coord|43.65|-79.38|display=inline,title}} : Vis begge steder

For å vise koordinatene i statusindikatorområdet på et annet format går det an å bruke |formatitle:

  • {{#invoke:Coordinates|coord|43.65|-79.38|display=inline,title|format=dec|formatitle=dms}} : Koordinatene vises som desimalgrader i løpeteksten, men på tradisjonelt format i statusindikatorområdet

Feilmeldinger rediger

Modulen viser en feilmelding hvis parametrene ikke utgjør gyldige koordinater.

Eksempel på feilaktig bruk
  • {{#invoke:Coordinates|coord|2843.65|-79.38}} : Koordinater : ugyldig himmelretning for lengdegrad, må være «E», «Ø», «V» eller «W»

Sider med feilaktig bruk havner i Kategori:Sider med feilaktige koordinattagger.

Bruk av andre funksjoner rediger

Konvertering fra desimalgrader til seksagesimal rediger

{{#invoke:Coordinates | dec2dms | verdi | positiv retning | negativ retning | presisjon}}

  • verdi : desimaltall
  • positiv retning : positiv himmelretning (N for breddegrad / E for lengdegrad)
  • negativ retning : negativ himmelretning (S for breddegrad / W for lengdegrad)
  • presisjon : D, DM eller DMS
Eksempel
  • {{#invoke:Coordinates|dec2dms|43.651234|N|S|DMS}} : 43° 39′ 04″ N
  • {{#invoke:Coordinates|dec2dms|43.651234|Ø|V|DM}} : 43° 39′ Ø

Konvertering fra seksagesimal til desimal rediger

{{#invoke:Coordinates | dms2dec | retning | grader | minutter | sekunder}}

  • retning: himmelretning (N/S/V/Ø)
  • grader, minutter, sekunder
Eksempel
  • {{#invoke:Coordinates|dms2dec|N|43|39|4}} : 43.65111
  • {{#invoke:Coordinates|dms2dec|N|43|39}} : 43.65
  • {{#invoke:Coordinates|dms2dec|43/39/4/N}} : 43.65111
  • {{#invoke:Coordinates|dms2dec|43/39/N}} : 43.65

Sporingskategorier rediger


require('strict')
local math_mod = require( "Module:Math" )

local p = {}

local i18n = {
	N = 'N',
	Nlong = 'nord',
	W = 'V',
	Wlong = 'vest',
	E = 'Ø',
	Elong = 'øst',
	S = 'S',
	Slong = 'sør',
	degrees = '° ',
	minutes = '′ ',
	seconds = '″ ',
	geohackurl = 'http://tools.wmflabs.org/geohack/geohack.php?language=nb',
	tooltip = 'Kart, flyfoto m.m.',
	errorcat = 'Sider med feilaktige koordinattagger',
	sameaswikidata = 'Sider med koordinater som samsvarer med Wikidata',
	notaswikidata = 'Sider med koordinater som avviker fra Wikidata',
	nowikidata = 'Sider med koordinater som mangler på Wikidata',
	throughwikidata = 'Sider med koordinater fra Wikidata',
	invalidFormat = 'ugyldig format ',                                                  -- 'invalid coordinate format',
	invalidNSEW = 'ugyldig himmelretning, må være «N», «S», «E», «Ø», «W» eller «V»',   -- 'invalid direction should be "N", "S", "E" or "W"',
	invalidNS = 'ugyldig himmelretning for breddegrad, må være «N» eller «S»',          -- 'could not find latitude direction (should be N or S)',
	invalidEW = 'ugyldig himmelretning for lengdegrad, må være «E», «Ø», «V» eller «W»', -- 'could not find longitude direction (should be W or E) ',
	noCardinalDirection = 'mangler himmelretning',                                      -- 'no cardinal direction found in coordinates',
	invalidDirection = 'ugyldig himmelretning',                                         -- 'invalid direction',
	latitude90 = 'breddegrad > 90',
	longitude360 = 'lengdegrad > 360',
	minSec60 = 'minutter eller sekunder > 60',
	negativeCoode = 'dms-koordinater skal ikke være negative',                          -- 'dms coordinates should be positive',
	dmIntergers = 'grader og minutter må være tall',                                    -- 'degrees and minutes should be integers',
	tooManyParam = 'for mange parametere',                                              -- 'too many parameters for coordinates',
	coordMissing = 'mangler lengdegrad eller breddegrad',                               -- 'latitude or longitude missing',
	invalidGlobe = 'ugyldig globe : ',                                                  -- 'invalid globe:',
}
local coordParse = {
	['Ø'] = 'E',
	['V'] = 'W',
}

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 wikidataglobes = { -- maps Wikidata items used in coordinate-types properties of Wikidata to globe names as used by geohack
	['http://www.wikidata.org/entity/Q3343'] = 'ariel',
	['http://www.wikidata.org/entity/Q3134'] = 'callisto',
	['http://www.wikidata.org/entity/Q596'] = 'ceres',
	['http://www.wikidata.org/entity/Q6604'] = 'charon',
	['http://www.wikidata.org/entity/Q7548'] = 'deimos',
	['http://www.wikidata.org/entity/Q15040'] = 'dione',
	['http://www.wikidata.org/entity/Q2'] = 'earth',
	['http://www.wikidata.org/entity/Q3303'] = 'enceladus',
	['http://www.wikidata.org/entity/Q3143']  = 'europa',
	['http://www.wikidata.org/entity/Q3169'] = 'ganymede',
	['http://www.wikidata.org/entity/Q15037'] = 'hyperion',
	['http://www.wikidata.org/entity/Q17958'] = 'iapetus',
	['http://www.wikidata.org/entity/Q3123'] = 'io',
	['http://www.wikidata.org/entity/Q319'] = 'jupiter',
	['http://www.wikidata.org/entity/Q111'] = 'mars',
	['http://www.wikidata.org/entity/Q308'] = 'mercury',
	['http://www.wikidata.org/entity/Q15034'] = 'mimas',
	['http://www.wikidata.org/entity/Q3352'] = 'miranda',
	['http://www.wikidata.org/entity/Q405'] = 'moon',
	['http://www.wikidata.org/entity/Q332'] = 'neptune',
	['http://www.wikidata.org/entity/Q3332'] = 'oberon',
	['http://www.wikidata.org/entity/Q7547'] = 'phobos',
	['http://www.wikidata.org/entity/Q17975'] = 'phoebe',
	['http://www.wikidata.org/entity/Q339'] = 'pluto',
	['http://www.wikidata.org/entity/Q15050'] ='rhea',
	['http://www.wikidata.org/entity/Q193'] = 'saturn',
	['http://www.wikidata.org/entity/Q15047'] = 'tethys',
	['http://www.wikidata.org/entity/Q2565'] = 'titan',
	['http://www.wikidata.org/entity/Q3322'] = 'titania',
	['http://www.wikidata.org/entity/Q3359'] = 'triton',
	['http://www.wikidata.org/entity/Q3338'] = 'umbriel',
	['http://www.wikidata.org/entity/Q324'] = 'uranus',
	['http://www.wikidata.org/entity/Q313'] = 'venus',
	['http://www.wikidata.org/entity/Q3030'] ='vesta',
}

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 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"> Koordinater : ' .. 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

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") ..
		"&params=" .. geohackparams ..
		(objectname and ("&title=" .. mw.uri.encode(objectname)) or "")
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 = p.displaydec(decLat, decLong, displayformat)
	else
		displaycoords = {
			p.displaydmsdimension(dmsLat, displayformat),
			p.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
		local htmlTitle = mw.html.create('span')
			:attr{ id = 'coordinates' }
			:addClass( displayinline and 'noprint' or nil )
			:node( root )
		local frame = mw.getCurrentFrame()
		titleText = frame:extensionTag( 'indicator', tostring(htmlTitle), { name = 'coordinates' }	)
	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

--HTML builder for a geohack link
local function buildMaplinkHTML( decLat, decLong, dmsLat, dmsLong, globe, displayformat, displayinline, displaytitle, objectname, extraparams )
	-- displayed coordinates
	local displaycoords
	if string.sub(displayformat,1,3) == 'dec' then
		displaycoords = p.displaydec(decLat, decLong, displayformat)
	else
		displaycoords = {
			p.displaydmsdimension(dmsLat, displayformat),
			p.displaydmsdimension(dmsLong, displayformat),
		}
	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 )
			}
		},
		properties = {
			['marker-color'] = "228b22",
		}
	}
	if objectname then
		jsonParams.properties.title = objectname
	end
	-- ajout de geoshape via externaldata
	local geoshape = extraparams:match( '%f[%w]geoshape: ?(Q%d+)' )
	if not geoshape and displaytitle and mw.wikibase.getEntity() then
		geoshape = mw.wikibase.getEntity().id
	end
	if geoshape then
		jsonParams = {
			jsonParams,
			{
				type = 'ExternalData',
				service = 'geoshape',
				ids = geoshape,
				properties = {
					['fill-opacity'] = 0.2
				}
			}
		}
	end

	local maplink = mw.getCurrentFrame():extensionTag{
		name = 'maplink',
		content = mw.text.jsonEncode( jsonParams ),
		args = { 
			text = displaycoords[1] .. ", " .. displaycoords[2],
			zoom = zoom( extraparams ) or default_zoom,
			latitude = decLat,
			longitude = decLong,
		}
	}
	
	-- format result depending on args["display"] (nil, "inline", "title", "inline,title")
	local inlineText = displayinline and maplink or ''
	local titleText = ''
	if displaytitle then
		local htmlTitle = mw.html.create('span')
			:attr{ id = 'coordinates' }
			:addClass( displayinline and 'noprint' or nil )
			:wikitext( maplink )
		local frame = mw.getCurrentFrame()
		titleText = frame:extensionTag( 'indicator', tostring(htmlTitle), { name = 'coordinates' }	)
	end
	
	return inlineText .. titleText
end

-- dms specific funcions

local function twoDigit( value )
	if ( value < 10 ) then
		value = '0' .. lang:formatNum( value )
	else
		value = lang:formatNum( value )
	end
	return value
end

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 = 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

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

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
		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

--- 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 = lat:sub( 2 )
		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

-- 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, 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

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'})
		return showerrors()
	end
	local dirpositive = string.lower(args[2] or '')
	local dirnegative = string.lower(args[3] or '')
	local precision = string.lower(args[4] or '')
	local displayformat, coordtype
	
	if dirpositive == 'n' or dirpositive == 'nord' then
		coordtype = 'latitude'
	else 
		coordtype = 'longitude'
	end
	if dirpositive == 'nord' or dirpositive == 'est' or dirnegative == 'ouest' or dirnegative == '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 = 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( 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 = p._parsedmsstring(args[1])
		if dmsobject then
			return p._dms2dec(dmsobject) -- coordonnées sous la fore 23/22/N
		else
			local coordType
			if args[1]:match( '[NS]' ) then
				coordType = 'latitude'
			elseif args[1]:match( '[EWO]') then
				coordType = 'longitude'
			end
			if coordType then
				local result = parsedec( args[1],  coordType, args.globe or 'earth' )
				if result then
					return result
				end
			end
			return showerrors()
		end
	else 
		return p._dms2dec({direction = args[1], degrees = tonumber(args[2]), minutes = tonumber(args[3]), seconds = tonumber(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(property) -- gets coordinates from wikidata
	property = property or 'P625'
	property = mw.ustring.upper(property)
	local entity = mw.wikibase.getEntityObject()
	if entity
		and entity.claims
		and entity.claims[property]
		and entity.claims[property][1]
		and entity.claims[property][1].mainsnak
		and entity.claims[property][1].mainsnak.snaktype == 'value'
		and entity.claims[property][1].mainsnak.datavalue
	then
		local coords = entity.claims[property][1].mainsnak.datavalue.value
		return coords.latitude, coords.longitude, wikidataglobes[coords.globe], convertwikidataprecision(coords.precision or .001)
	end
	return nil
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 wikidataprop = args.wikidataprop -- Wikidata property to use, defaults to P625
	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)
 	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 = true -- 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 = p._dec2dms(latitude, 'latitude', precision), p._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 = p._parsedmsstring(args.latitude, 'latitude'), p._parsedmsstring(args.longitude, '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, wikidataprecision
	if wikidata == 'true' then
		wikidatalatitude, wikidatalongitude, wikidataglobe, wikidataprecision = wikidatacoords(wikidataprop)
		
		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, globe)
			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
		globe = 'earth'
	end
	if 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
	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
	
-- 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
	local mainstring = ''
	if maplink then
		mainstring = buildMaplinkHTML(latitude, longitude, dmslatitude, dmslongitude, globe, displayformat, displayinline, displaytitle, objectname,extraparams )
	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 = 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 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