Module:Infobox/Localité

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

local localdata = require 'Module:Infobox/Localdata'
local general = require "Module:Infobox/Fonctions"
local building = require "Module:Infobox/Fonctions/Bâtiment"
local wikidata = require "Module:Wikidata"
local linguistic = require "Module:Linguistique"
local convert = require "Module:Conversion"
local str = require "Module:String"
local lng = require "Module:Langue"
local country = wikidata.stringTable{entity = localdata.item, property = "P17", displayformat = "raw"}
local countryid
if country then
	countryid = country[1]
end

local defaultlinks = { -- version de Wikipédia à utiliser pour les liens en l'absence d'article français
	Q17 = 'jawiki', -- Japon
	Q182 = 'dewiki', -- Allemagne
	Q40 = 'dewiki',	-- Autriche
	Q38 = 'itwiki', -- Italie
	Q29 = 'eswiki', -- Espagne
	Q96 = 'eswiki', -- Mexique
	Q739 = 'eswiki', -- Colombie
	Q717 = 'eswiki', -- Vénézuéla
	Q298 = 'eswiki', -- Chili
	Q414 = 'eswiki', -- Argentine
	Q750 = 'eswiki', -- Bolivie
	Q736 = 'eswiki', -- Équateur
	Q45 = 'ptwiki', -- Portugal
	Q155 = 'ptwiki', -- Brésil
	Q881 = 'viwiki', -- Viêt Nam
	Q29999 = 'nlwiki', -- Pays-Bas
	Q34 = 'svwiki', -- Suède
}
local defaultlink = {'enwiki'}
if defaultlinks[countryid] then
	table.insert(defaultlink, defaultlinks[countryid])
end


local function getVal(addargs) -- pour une propriété donnée, retourne la meilleure valeur, ainsi que sa date, sa référence, et si ça vient ou non de Wikidata
	local args = {numval = 1, entity = localdata.item, showunit = '-', displayformat = 'raw', precision = 'year'}
	for i, j in pairs(addargs or {}) do
		args[i] = j
	end
	local statements = wikidata.getClaims(args)
	if not statements then
		return nil
	end
	local val = statements[1]
	local v = wikidata.formatStatement(val, args)
	local period = wikidata.getFormattedDate(val, args)
 	local ref = nil -- TODO : fonction dans Module:Wikidata pour récupérer les refs
 	
 	return v, period, ref, args.property
end



-- Fonctions de récupération de données valables dans plusieurs champs (et appelées plusieurs fois)

local pop, popdate, popref, popprop = localdata["population"], localdata["année pop"], localdata["population notes"], nil
if not pop then
	pop, popdate, popref, popprop = getVal({property = "P1082", sorttype="inverted"})
end

local area, areadate, arearef, areaprop = localdata["superficie"], localdata["année superficie"], localdata["superficie notes"], nil
if not area then
	area, areadate, arearef, areaprop = getVal({property = "P2046", targetunit = "square kilometer", sorttype="inverted"})
end

if pop then pop = tonumber(pop) end
if area then area = tonumber(area) end

-- Fonctions de mise en forme

local function formatVal(val, period, ref, prop)
	local s = tostring(val)
	if period then
		s = s .. "<small>" .. linguistic.inparentheses(period) .. "</small>"
	end
	if ref then
		s = s .. "<ref>" .. ref .. "</ref>"
	end
	
	if prop then
		s = wikidata.formatAndCat{entity = localdata.item, property = prop, value = s} -- permet de mettre le rétrolien à la fin
	end
	return s
end

local function formatPop()
	if not pop then
		return nil
	end
	
	local popstr = convert.displayvalue(pop)
	popstr = string.gsub(popstr, "+", "") -- devrait être fait en amont
	popstr = popstr .. " hab."
	
	return formatVal(popstr, popdate, popref, popprop)
end

local function formatArea()
	if not area then
		return nil
	end

	-- arrondi
	local rounding = 2
	if area < 1 then
		rounding = 2
	end
	
	-- conversion en hectares si trop petit ?
	
	local areastr = convert.displayvalue(area, 'square kilometer', {showunit = true, rounding = rounding})
	return formatVal(areastr, areadate, arearef, areaprop)
end

local function density()
	-- TODO : vérifier que la date de la population correspond à celle de la superficie, pour les quelque cas de changements de frontière

	if not (pop and area) or area == 0 then
		return nil
	end
	local density = pop / area
	local rounding = 1
	if density < 0.1 then
		rounding = 2
	end
	local s = convert.displayvalue(density, nil, {rounding = rounding})
	s = s .. " hab./km<sup>2</sup>"
	
	return formatVal(s, popdate)
end

local function devise() -- fonction de mise en forme pour les devises. exemple :
						-- En [[anglais]] : ''The Gateway to Alberta'' (« La porte d'entrée de l'Alberta »)
	local devises = localdata['devise']
	if devises then -- données entrées en paramètre de l'infobox
		local langDevise = localdata["langue_devise"]
		if langDevise and langDevise ~= '' then
			if str.non_latin({args={devises}}) == '' then
				devises = "<i>" .. devises .. "</i>"
			end
			devises = "en ".. langDevise .. " : " .. devises
			local traductionDevise = localdata["traduction_devise"]
			local transcriptionDevise = localdata["transcription_devise"]
			if transcriptionDevise then
				if traductionDevise then
					devises = devises .. " (<i>" .. transcriptionDevise .. "</i>, « " .. traductionDevise .. " »)"
				else
					devises = devises .. " (<i>" .. transcriptionDevise .. "</i>)"
				end
			elseif traductionDevise then
					devises = devises .. " ( « " .. traductionDevise .. " »)"
			end
		end
		local noteDevise = localdata["note_devise"]
		if noteDevise then
			devises = devises .. noteDevise
		end
	else -- données récupérées de Wikidata
		local query = { property = "P1451", entity = localdata.item}
		
		local claims = wikidata.getClaims(query)
		if not claims or claims == {} then
			return nil
		end
		for i, j in pairs(claims) do
			local devise = wikidata.formatStatement(j, query)
			local langDevise = j.mainsnak.datavalue.value.language
			
			local noteDevise = '' -- récupération des éventuelles sources
			local sources, hashes = wikidata.getReferences(j)
			if sources then
				local source = wikidata.sourceStr(sources, hashes)
				if source then
					noteDevise = noteDevise .. source
				end
			end
			
			if langDevise ~= 'fr' and langDevise ~= '' then
				local fullLanguage = "[[" .. lng.articleLangue(langDevise) .. "|" .. 
						lng.nomLangue(langDevise) .. "]]"
				if str.non_latin({args={devise}}) == '' then
					devise = "<i>" .. devise .. "</i>"
				end
				local traductionDevise
				if j.qualifiers and j.qualifiers.P2441 then
					for _, v in pairs(j.qualifiers.P2441) do
						if v.datavalue.value.language == 'fr' then
							traductionDevise = v.datavalue.value.text
						end
					end
				end
				if traductionDevise then
					claims[i] = "en ".. fullLanguage .. " : " .. devise .. 
							" (« " .. traductionDevise .. " »)" .. noteDevise
				else
					claims[i] = "en ".. fullLanguage .. " : " .. devise .. noteDevise
				end
			else
				claims[i] = devise .. noteDevise
			end
		end
		
		devises = linguistic.conj(claims, 'new line') .. wikidata.addTrackingCat("P1451")
		devises = wikidata.addLinkBack(devises, localdata.item, "P1451")
	end
	return devises
end

-- divisions administratives

--- par paramètres locaux
local function localDivRows() -- liste de lignes de divisions administrative basée sur des données locales
	local rows = {}
	local hasrows = false -- devient vraie si une valeur est non null
	for i = 1, 10 do
		i = tostring(i)
		if i == "1" then
			i = ""
		end
		local param, labelparam = "division" .. i, "nom division" .. i --"nom de division" .. i
		if localdata[param] then
			hasrows = true
			local label = localdata[labelparam] or "Subdivision"
			table.insert(rows, {type = "row", label = label, value = function() return localdata[param] end})
		end
	end
	if hasrows then
		return rows
	end
end

--======================================

local natureformats = {
	--{élément Wikidata, nom charte, couleur titre, couleur sous-titre, couleur texte, icône)  doivent être classés du plus spécifique au plus général
    {'Q23442' , 'île', '#7793E0', '' , '#FFFFFF', 'map'},
    {'Q123705', 'quartier' , '#ECE5CA' , '' , '' , 'map'},
    {'Q8502' , 'montagne' , '#996633', '' , '#FFFFFF' , 'map'},
    {'Q12280' , 'pont', '#D4D0BA' , '' , '' , 'map' },
}

local function setformat() --retourne une table contenant la couleur principale de l'infobox et l'icône de titre
	local natures = wikidata.getIds(localdata.item, {property = 'P31'}) -- récupère les Qid des natures

	if not natures or (#natures > 1) then -- si plusieurs natures, on ne sait pas lequel choisir
		return  {'Q', '', '#DDFFDD', '', '', 'map'}
	end
	natures = wikidata.addVals(natures, {property = 'P279'}, 2) -- nombre d'étages de sous-classes à remonter
	for i, j in pairs(natures) do
		for k, l in pairs(natureformats) do
			if l[1] == j then
				return l
			end
		end
	end
	return {'Q', '', '#DDFFDD', '', '' , 'map'}
end
local function setcharte()
	local charte = localdata['charte']
	if charte then
		for i, j in pairs(natureformats) do
			if j[2] == charte then
				return j
			end
		end
	end
	return setformat()
end
local natureformat = setcharte()
return {
	maincolor = natureformat[3],
	secondcolor = natureformat[4],
	thirdcolor = natureformat[5],
	parts =
    	{
			general.title(natureformat[6]),
			{
			type = 'images',
			imageparameters =  {'blason', 'drapeau'},
			wikidata = {property = {'P94', 'P41'}},
			numval = 2,
			defaultupright = '0.4' --Temporaire. Devrait être plus élevé pour le drapeau que pour le blason
			},	
			general.logo(),
			general.mainimage{ 
				cat = "Subdivision administrative illustrée par defaut.svg", 
				defaultimage = "Defaut 2.svg", 
				wikidata = {property = {"P2716", "P18", "P5252", "P3451", "P1766"}, numval = 1} 
			},
			{type = "table", rows = {
				{type = "row", label = "Nom officiel", plurallabel = "Noms officiels", value = "nom officiel", wikidata = {property = "P1448", showlang = true, showdate = true, precision = 'year', sorttype = 'chronological', conjtype = 'new line'} },
				{type = "row", label = "Nom local", plurallabel = "Noms locaux", value = "nom local", wikidata = {property = "P1705", showlang = true} },
				{type = 'row', label = 'Surnom', plurallabel = "Surnoms", value = "surnom", property = 'P1449'}, -- autres noms
				}
			},
			{type = "table", title = "Géographie", rows = {
				{type = 'row', label = 'Astre', value = 'astre', wikidata = { property = 'P376', excludevalue = 'Q2' }}, -- corps astronomique où se trouve le lieu dont il est question (utile pour les lieux de fictions)
				general.country(),
				{type = "multi", rows = localDivRows() or general.wikidataDivRows(countryid) or {}},	
				{type = 'row', label = 'Île', value= 'île', wikidata = { property = 'P706', targetclass = 'Q23442' }},
				{type = "row", label = "Localisation géographique", value = "localisation géographique", wikidata = { property = 'P706', excludeclasses = 'Q23442' }},
				{type = "row", label = "Partie de", value = "partie de", property = "P361", showsource = true},
				{type = "row", label = "Chef-lieu", value = "chef-lieu", property = "P36", showsource = true},
				{type = "row", label = "Exclave de", value = "exclave de", property = "P500", showsource = true},
				{type = "row", label = "Enclavé dans", value = "enclavé dans", property = "P501", showsource = true},
				{type = "row", label = "Revendiqué par", value = "revendiqué par", property = "P1336", showsource = true},
				{type = "row", label = "Baigné par", value = "baigné par", property = "P206", showsource = true},
				{type = "row", label = "Superficie", value = function() return formatArea() end },
				{type = "row", label = "Surface en eau", value = "surface en eau", property = "P2927", showsource = true},
				{type = "row", label = "Subdivision", plurallabel = "Subdivisions", value = "subdivision", wikidata =
					function(item)
					local vals = wikidata.getClaims{entity = item, property = 'P150', atdate = 'today'}
					if (not vals) or (#vals > 5) then -- si trop de subdivisions, il faut les mettre dans le corps du texte, c'est pas lisible en infobox
						return nil
					end
					return wikidata.formatAndCat{claims = vals, property = 'P150', defaultlink = defaultlink, conjtype = 'new line'}, #vals
					end
				},
				{type = "row", label = "Point le plus bas", plurallabel = "Points les plus bas", value = "point le plus bas", property = "P1589", showsource = true},
				{type = "row", label = "Point culminant", plurallabel = "Points culminants", value = "point culminant", property = "P610", showsource = true},
				{type = "row", label = "Altitude", value = "altitude", wikidata = {property = "P2044", targetunit = "metre", rounding = "0"} , showsource = true},
				building.mountainrange(),
				{type = "row", label = "Aire protégée", plurallabel = "Aires protégées", value = "aire protégée", wikidata = {property = "P3018", showqualifiers = "P518"}, showsource = true},
				{type = "row", label = "Jewografi", value = "jewografi", property = "P2633", showsource = true},
				general.coordinates(),
				}
			},
			general.locationmap(),
			{type = "table", title = "Demografi", rows = {
				{type = "row", label = "Popilasyon", value = function() return formatPop() end },
				{type = "row", label = "Dansite", value = function() return density() end},
				{type = "row", label = "Jantile", value = "gentilé", property = "P1549", showlang = true, showsource = true},
				}
			},
			{type = "table", title = "Fonctionnement", rows = {
				{type = "row", label = "Statut", value = "statut", wikidata = {property = "P31",
					targetsuperclass = "Q56061", --seulement les sous-classes d' "entité territoriale administrative"
					excludevalues = "Q1620908", --"région historique"
					defaultlinkquery = {property = "P2354"}, showdate = true}, showsource = true}, 
				{type = 'row', label = 'Constitution', value = 'constitution'},
				{type = "row", label = localdata["libellé chef de l'exécutif"] or "Chef de l'exécutif", value = "chef de l'exécutif", wikidata = {property = "P6", showdate = true, textformat = 'long', sorttype="inverted", numval = 1}, showsource = true}, -- pour le libellé : utiliser P1313 poste occupé par le chef de l'exécutif" ? il faudrait voir comment retraiter les cas comme Q31388880 "maire de Brême"
				{type = "row", label = "Assemblée délibérante", value = "assemblée", wikidata = {property = "P194", defaultlink = defaultlink}, showsource = true},
				{type = "row", label = "Monnaie", plurallabel = "Monnaies", value = "monnaie", property = "P38", showsource = true},
				{type = "row", label = "Équipement", plurallabel = "Équipements", value = "équipement", property = "P912", showsource = true},
				{type = "row", label = "Employés", value = "employés", property = "P1128", showsource = true},
				{type = "row", label = "Budget", value = "budget", wikidata = {property = "P2769", showlink=true, showdate=true}, showsource = true},
				{type = "row", label = "Dépenses", value = "dépenses", wikidata = {property = "P2402", showlink=true, showdate=true}, showsource = true},
				{type = "row", label = "Dette", value = "budget", wikidata = {property = "P2133", showlink=true, showdate=true}, showsource = true},
				{type = "row", label = "Revenu fiscal", value = "revenu fiscal", wikidata = {property = "P3087", showlink=true, showdate=true}, showsource = true},
				{type = "row", label = "Économie", value = "économie", property = "P8744", showsource = true},
				building.protection(),
				{type = "row", label = "[[Propriété contributrice à un district historique|Propriété contributrice]]", plurallabel = "[[Propriété contributrice à un district historique|Propriétés contributrices]]", value = "propriété contributrice", wikidata = {property = "P527", numval = "5", showdate = true, textformat = "minimum", precision = "year", sorttype = "chronological", qualifier = "P3831", qualifiervalue = "Q1129142"}, showsource = true},
				{type = "row", label = "Contient la localité", plurallabel = "Contient les localités",value = "contient la localité", wikidata = {property = "P1383", showdate = true}, showsource = true},
				{type = "row", label = "Membre de", value = "membre de", wikidata = {property = "P463", showdate = true}, showsource = true},
				{type = "row", label = "Jumelage", plurallabel = "Jumelages", value = "jumelage", wikidata = {property = "P190", showdate = true}, showsource = true},
				{type = 'row', label = "[[Office de tourisme|Informations]]", value = "informations", wikidata = {property = 'P2872', numval = '1'}, showsource = true},
				}
			},
			{type = "table", title = "Histoire", rows = {
				{type = "row", label = "Origine du nom", value = "origine du nom", property = "P138", showsource = true},
				{type = "row", label = "Concepteur", plurallabel = "Concepteurs", value = "concepteur", property = "P287", showsource = true},
				{type = "row", label = "Fondation", value = "fondation", property = "P571", showsource = true},
				{type = "row", label = "Fondateur", plurallabel = "Fondateurs", value = "fondateur", property = "P112", showsource = true},
				{type = "row", label = "Architecte", plurallabel = "Architectes", value = "architecte", property = "P84", showsource = true},
				building.archistyle(),
				{type = "row", label = "Remplace", value = "remplace", property = "P1365", showsource = true},
				{type = "row", label = "Remplacé par", value = "remplacé par", property = "P1366", showsource = true},
				{type = "row", label = "Événement clé", plurallabel = "Événements clés", value = "événement clé", wikidata = {property = "P793", showdate = true}, showsource = true},
				{type = 'row', label = 'Histoire', value = 'histoire', wikidata = {property = 'P2184', withlink = 'frwiki', numval = '1'}, showsource = true},
				{type = "row", value = "dissolution", property = "P576", showsource = true , label = function() return localdata['intitulé dissolution'] or 'Dissolution' end, },
				{type = "row", label = "Direction des fouilles", value = "fouilles", property = "P4345", showsource = true},
				}
			},
			{type = "table", title = "Identité", rows = {
				{type = "row", label = "ISO 3166-2", value = "iso", property = "P300", showsource = true},
				{type = "row", label = "Langue officielle", plurallabel = "Langues officielles", value = "langue officielle", property = "P37", showsource = true},
				{type = "row", label = "Devise", value = function() return devise() end, showsource = true},
				{type = "row", label = "Blasonnement", value = "blasonnement", property = "P237", showsource = true},
				{type = "row", label = "Drapeau", value = "description drapeau", property = "P163", showsource = true},
				{type = 'row', label = 'Hymne', plurallabel = 'Hymnes', value = 'hymne', property = 'P85', showsource = true},
				{type = "row", label = "Symbole", plurallabel = "Symboles", value = "symbole", property = "P2238", showsource = true},
				{type = "row", label = "Fête", plurallabel = "Fêtes", value = "fête", property = "P841", showsource = true},
				{type = "row", label = "Saint patron", plurallabel = "Saints patrons", value = "saint patron", property = "P417", showsource = true},
				{type = "row", label = "Plat traditionnel", plurallabel = "Plats traditionnels", value = "plat traditionnel", property = "P868", showsource = true},
				}
			},
			{type = "table", title = "Idantifyan", rows = {
				{type = "row", label = "Kòd postal", value = "kòd postal", property = "P281", showsource = true},
				{type = 'row', label = "[[Statistisches Bundesamt|AGS]]", value = "AGS",Iproperty = 'P439'},
				{type = 'row', label = "[[Statistique Indonésie|Code de desa]]", value = "BPS", property = 'P1588'},
				{type = "row", label = "[[Federal Information Processing Standard|Code FIPS]]", value = "FIPS", property = "P774"},
				{type = "row", label = "[[Geographic Names Information System|GNIS]]", value = "GNIS", wikidata = {property = "P590", urlpattern= "https://edits.nationalmap.gov/apps/gaz-domestic/public/summary/$1"}},
				{type = 'row', label = "[[Institut national de la statistique (Espagne)|INE]]", value = "INE municipalités", property = 'P772'},
				{type = 'row', label = "[[Code Insee|INSEE]]", value = 'INSEE', property = 'P374'},
				{type = 'row', label = "[[Istituto nazionale di statistica|ISTAT]]", value = "ISTAT", property = 'P635'},
				{type = 'row', label = "Code [[Departamento Administrativo Nacional de Estadística|DANE]]", value = "DANE", property = 'P7325'},
				{type = 'row', label = "[[OKATO]]", value = "OKATO", property = 'P721'},
				{type = 'row', label = "[[Office for National Statistics|Code ONS]]", value = "ONS"},
				{type = 'row', label = "[[Classification géographique type|CGT]]", value = "statcan","CGT", property="P3012"},
				{type = 'row', label = "TGN", value = "TGN", wikidata = {property = "P1667", urlpattern= "http://vocab.getty.edu/page/tgn/$1"}},
				{type = "row", label = "[[Liste des indicatifs téléphoniques internationaux par indicatif|Indicatif téléphonique]]", value = "indicatif téléphonique", property = "P473", showsource = true},
				{type = 'row', label = "[[Plaque d'immatriculation|Immatriculation]]", value = 'immatriculation', property = 'P395', showsource = true},
				general.website(),
				{type = "row", label = "Reprezante pa", value = "Reprezante pa", property = "P1875", showsource = true},
				{type = "row", label = "Distenksyon", plurallabel = "Distenksyon", value = "distenksyon", wikidata = {property = "P166", showdate = true}, showsource = true},
				}
			},
			general.geoloc({default_zoom = 7, marker = 'village', maptype = localdata["type carte"], width = localdata["taille carte"]}),
			general.prononciation(),
	}
}