Aller au contenu

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

De Wreck
Modèle:Infobox>Zolo
mAucun résumé des modifications
m 59 versions importées
 
(46 versions intermédiaires par 7 utilisateurs non affichées)
Ligne 1 : Ligne 1 :
local formats = require "Module:Adresse/Formats"
local p = {}
local p = {}
local wikidata = require "Module:Wikidata"
local linguistic = require "Module:Linguistique"
local countrymodule = require "Module:Country data"


local wikidata =require('Module:Wikidata')
local function getCountry(item) -- get country id for formatting
 
local country = wikidata.getIds(item, {property = "P17"})
local street = {
if (not country) then
-- identifant wikipédia = regex pour le format de l'adresse
-- $number : le numéro de l'immeuble
-- $ street : le nom de la rue
-- questions :
-- utiliser des noms plutôt que des ID wikidata ?
-- si problème de performance, utiliser des fonctions plutôt que des regex ?
Q16 = '$number $street $direction',-- Canada
Q30 = '$number $street $direction',-- Etats-Unis
Q31 = '$number $street',-- Belgique
Q40 = '$street $number', -- Autriche
Q148 = '$number $street $direction', -- si l'on met les noms de rue en français
Q183 = '$street $number', -- Allemagne
Q39 = '$street $number', -- Suisse
Q142 = '$number $street',-- France
Q145 = '$number $street',-- UK
Q218 = '$street $number', --  Roumanie
default = '$number $street $direction',
}
 
local direction = { -- directions affichées dans les noms des rues
Q16 = {Q659 = 'Nord', Q679 = 'Ouest', Q684 = 'Est', Q667 = 'Sud'}, -- au Canada, on peut avoir des noms de rue en français
Q30 = {Q659 = 'North', Q679 = 'West', Q684 = 'East', Q667 = 'South'}, -- Etats-Unis seulement la première lettre ?
}
 
function p.formatAddress(streets, postcode, city, formattingarea)
-- streets est une table de {streetname, number, }quarge que "city" qui détermine le formatage de la rue et du code postal
if (not streets) and (not postcode) and (not city) then  
return nil
return nil
end
end
 
if #country > 1 then
local addresslines = {} -- lignes à mettre dans l'adresse : rue, codepostal + ville etc.
return nil
if streets then
table.insert(addresslines, streets)
end
if postcode or formattingarea then
table.insert(addresslines, (postcode or '') .. ' ' .. (formattingarea or ''))
end
end
 
return country[1]
return table.concat(addresslines, '<br />')
end
end


Ligne 63 : Ligne 34 :
local str = ''
local str = ''
for i, snak in pairs(claim.qualifiers.P560) do
for i, snak in pairs(claim.qualifiers.P560) do
str = str .. wikidata.formatSnak(snak,  {speciallabels = direction[area]})
local directionlabels = area.directions or formats.default.directions
str = str .. wikidata.formatSnak(snak,  {speciallabels = directionlabels})
end
end
return str
return str
end
end


local function streetFromClaims(claim, formattingarea) -- réupère le nom de la rue à partir d'une affirmation P669 Wikidata
local function streetFromClaims(claim) -- réupère le nom de la rue à partir d'une affirmation P669 Wikidata
return wikidata.formatStatement(claim)
return wikidata.formatStatement(claim)
end
end


local function formatStreet(streetname, housenumber, direction, area)
local function formatStreet(streetname, housenumber, direction, displayformat)
local val = street[area] or street.default
local val = displayformat.streetline or formats.default.streetline
val = mw.ustring.gsub(val, '$number', housenumber or '')
val = mw.ustring.gsub(val, '$number', housenumber or '')
val = mw.ustring.gsub(val, '$street', streetname or '')
val = mw.ustring.gsub(val, '$street', streetname or '')
Ligne 81 : Ligne 53 :


local function wikidatastreet(claim, area) --formate des données sur la rue à partir d'une affirmation Wikidata
local function wikidatastreet(claim, area) --formate des données sur la rue à partir d'une affirmation Wikidata
local streetname = streetFromClaims(claim)
local streetname = streetFromClaims(claim, area)
local housenumber =  numberFromClaim(claim)
local housenumber =  numberFromClaim(claim, area)
local direction = directionFromClaim(claim, area)
local direction = directionFromClaim(claim, area)
return formatStreet(streetname, housenumber, direction, area)
return formatStreet(streetname, housenumber, direction, area)
end
end


function p.wikidataAddress(item) -- fprùate l'intégralité d'une adresse à partir des données contenues dans une élément Wikidata
function p.streetAddress(item, area) -- formate la ligne concernant la rue et le numéro de rue
 
local streets -- châine contenant le ou les rues et numéros d'immeuble
-- définit la zone dans laquelle on se trouve pour choisir le format à utilier
local area = wikidata.formatStatements({item = item, property = 'P17', numval = 1, displayformat = 'raw'}) -- = pays
if not area then
local country = getCountry(item)
if country and formats[country] then
area = formats[country]
else
area = formats.default
end
end
local streets -- châine contenant le ou les rues et numéros d'immeuble
-- essaye de remplir street, en priorité avec P669, type : élément
-- essaye de remplir street, en priorité avec P669, type : élément
local streetclaims = wikidata.getClaims{item=item, property = 'P669', item=item}
local streetclaims = wikidata.getClaims{entity = item, property = 'P669'}
if streetclaims then
if streetclaims then
for i, j in pairs(streetclaims) do
for i, j in pairs(streetclaims) do
streetclaims[i] = wikidatastreet(j, area)  
streetclaims[i] = wikidatastreet(j, area)
end
end
streets = mw.text.listToText(streetclaims)
streets = mw.text.listToText(streetclaims)
streets = wikidata.addLinkback(streets, item, 'P669')
streets = wikidata.formatAndCat{value = streets, entity = item, property = 'P669'}
-- faut-il ajouter Category:Page utilisant des données de Wikidata/P969 ?
end
end
-- sinon : P969, type : string
-- sinon : P6375, type : string -- remplace P969
if not streets then
streets = wikidata.formatAndCat{linkback = true, property = 'P6375', entity = item, isinlang = 'fr'}
end
-- sinon : P969, type : string -- propriété obsolète
if not streets then  
if not streets then  
streets =  wikidata.formatAndCat{property = 'P969', item=item}
streets =  wikidata.formatAndCat{linkback = true, property = 'P969', entity = item}
end
return streets
end
 
function p.adminDivList(item, country) -- returns a list of admin divisions matching the criteria defined in Module:Adresse/Formats
country = country or getCountry(item)
local query = {property = 'P131'}
local divs = wikidata.transitiveVals(item, query, 0, 10, country)
local validDivs = {}
-- solution 1: looks for divs of a certain type
local function setValue(targetclasses, depth)
local test = {}
for _, d in pairs(divs) do
for j, divtype in pairs(targetclasses) do
if (divtype == '-') then
if #validDivs > 0 then
divs = wikidata.addVals(divs, query, 0, 1, country)
end
if divs[#divs] == country then
return nil
end
return divs[#divs]
end
if wikidata.isInstance(divtype, d, 3) then
-- restrain list to new value, will be expanded only if needed
divs = {d}
return d
end
end
end
if depth >= 0 then
local num = #divs
divs = wikidata.addVals(divs, query, 0, 10, country)
if #divs > num then return setValue(targetclasses, depth) end
end
end
 
-- solution2: looks for divs that are part of a closed list (way more efficient for big items)
local function findInList(list, depth)
for i, j in pairs(divs) do
for k, l in pairs(list) do
if j == l then
divs = {l}
return l
end
end
end
if depth >= 0 then
local num = #divs
divs = wikidata.addVals(divs, query, 0, 10, country)
if #divs > num then return findInList(list, depth) end
end
end
local displayformat = formats[country] or formats.default
local maxdepth = 3
if not divs then
return nil
end
 
if displayformat.div1 then
local val = setValue(displayformat.div1, maxdepth)
if val and val ~= validDivs[#validDivs] then
table.insert(validDivs, val)
end
end
end


--[[ code postal, peu utile pour l'instant
if displayformat.div2 then
local postcode = wikidata.getClaims{property= 'P281', item=item}
local val = setValue(displayformat.div2, maxdepth)
if postcode and #postcode > 1 then -- s'il y a plusieurs codes postaux, il y a sans doute plusieurs adresses différentes, c'est difficile de savoir lequel correspond à laquelle
if val and val ~= validDivs[#validDivs] then
postcode = nil
table.insert(validDivs, val)
elseif postcode then
end
postcode = wikidata.formatStatement(postcode[1])
elseif displayformat.div2vals then
local val = findInList(displayformat.div2vals, 1)
if val and val ~= validDivs[#validDivs] then
table.insert(validDivs, val)
end
end
end
]]--
-- faaut-il essayer d'ajouter la ville par P131 ? Souvent on en veut pas (par exemple en infobox)
if displayformat.div3 then
local val = p.formatAddress(streets, postcode)
local val = setValue(displayformat.div3, maxdepth)
if val then return
if val and val ~= validDivs[#validDivs] then
val .. '[[Category:Page utilisant une adresse fournie par Wikidata]]'
table.insert(validDivs, val)
end
elseif displayformat.div3vals then
local val =  findInList(displayformat.div3vals, 0)
if val and val ~= validDivs[#validDivs] then
table.insert(validDivs, val)
end
end
return validDivs
end
 
function p.cityLine(item, country, divlist, postcode) -- line with list of admin divisions + optional postcode
country = country or getCountry(item)
local postcode = postcode or wikidata.formatStatements{entity = item, property = 'P281'} or ''
if postcode == '-' then -- can be disabled when it is not useful
postcode = ''
end
local divstr = ''
if (not divlist) or (#divlist == 0) then
divlist = p.adminDivList(item, country)
end
if (not divlist) or (#divlist == 0) then
return -- add a maintenance category ?
end
for i, j in pairs(divlist) do
if string.find(j, '^Q[0-9]+$') then
divlist[i] = wikidata.formatEntity(j)
end
end
local divstr = linguistic.conj(divlist, 'comma')
 
local formatting = formats[country] or formats.default
local str = formatting.cityline or formats.default.cityline
str = str:gsub("$postcode", postcode or '')
str = str:gsub("$admindivs", divstr or '')
return str
end
 
function p.fullAddress(item, country, divs, streetstr, divstr, showcountry, postcode)
-- country id used for formatting
country = country or getCountry(item)
local displayformat = formats[country] or formats.default
 
-- line 1 street
local streetline = streetstr or p.streetAddress(item, country)
-- line 2: administrative divisions, postcodes
local cityline = divstr
if not cityline then cityline = p.cityLine(item, country, divs, postcode) end
if (not cityline) or mw.text.trim(cityline) == '' then
cityline = nil
end
 
-- line 3: country
local countryline, success
if (showcountry ~= '-') then
countryline, success = countrymodule.standarddisplay(country)
if not success then
if (type(country) == 'string') and string.find(country, "^Q[0-9]+$") then
countryline = wikidata.formatEntity(country)
else
countryline = country or wikidata.formatStatements{entity = item, property = 'P17'}
end
end
end
local str = linguistic.conj({streetline, cityline, countryline}, '<br />')
if str and (not streetstr) and (not divstr) then -- à peu près
str = str .. '[[Category:Page utilisant une adresse fournie par Wikidata]]'
end
local hasstreetline
if streetline then hasstreetline = true else hasstreetline = false end
 
return str, hasstreetline
end
 
function p.wikidataAddress(item, country) -- fonction de transition
local area = formats[country] or formats.default
local val = p.streetAddress(item, area)
if val then
return val .. '[[Category:Page utilisant une adresse fournie par Wikidata]]'
end
end
end
end
return p
return p

Dernière version du 22 février 2026 à 00:17

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

local formats = require "Module:Adresse/Formats"

local p = {}
local wikidata = require "Module:Wikidata"
local linguistic = require "Module:Linguistique"
local countrymodule = require "Module:Country data"

local function getCountry(item) -- get country id for formatting
	local country = wikidata.getIds(item, {property = "P17"})
	if (not country) then
		return nil
	end
	if #country > 1 then
		return nil
	end
	return country[1] 
end

local function numberFromClaim(claim) -- récupère le numéro de l'immeuble à partir d'un qualificatif P670 d'une affirmation Wikidata
	if not claim.qualifiers or not claim.qualifiers.P670 then
		return nil
	end
	local vals = {}
	for i, j in pairs(claim.qualifiers.P670) do
		table.insert(vals, wikidata.formatSnak(j))
	end
	return table.concat(vals, '-')
end

local function directionFromClaim(claim, area) -- par exemple rue Sherbrooke Ouest
	if not claim.qualifiers or not claim.qualifiers.P560 then
		return nil
	end
	local str = ''
	for i, snak in pairs(claim.qualifiers.P560) do
		local directionlabels = area.directions or formats.default.directions
		str = str .. wikidata.formatSnak(snak,  {speciallabels = directionlabels})
	end
	return str
end

local function streetFromClaims(claim) -- réupère le nom de la rue à partir d'une affirmation P669 Wikidata
	return wikidata.formatStatement(claim)
end

local function formatStreet(streetname, housenumber, direction, displayformat)
	local val = displayformat.streetline or formats.default.streetline
	val = mw.ustring.gsub(val, '$number', housenumber or '')
	val = mw.ustring.gsub(val, '$street', streetname or '')
	val = mw.ustring.gsub(val, '$direction', direction or '')
	return val
end

local function wikidatastreet(claim, area) --formate des données sur la rue à partir d'une affirmation Wikidata
	local streetname = streetFromClaims(claim, area)
	local housenumber =  numberFromClaim(claim, area)
	local direction = directionFromClaim(claim, area)
	return formatStreet(streetname, housenumber, direction, area)
end

function p.streetAddress(item, area) -- formate la ligne concernant la rue et le numéro de rue
	local streets -- châine contenant le ou les rues et numéros d'immeuble
	
	if not area then
		local country = getCountry(item)
		if country and formats[country] then
			area = formats[country]
		else
			area = formats.default
		end
	end
	
	-- essaye de remplir street, en priorité avec P669, type : élément
	local streetclaims = wikidata.getClaims{entity = item, property = 'P669'}
	if streetclaims then
		for i, j in pairs(streetclaims) do
			streetclaims[i] = wikidatastreet(j, area)
		end
		streets = mw.text.listToText(streetclaims)
		streets = wikidata.formatAndCat{value = streets, entity = item, property = 'P669'}
	end
	
	-- sinon : P6375, type : string -- remplace P969
	if not streets then
		streets = wikidata.formatAndCat{linkback = true, property = 'P6375', entity = item, isinlang = 'fr'}
	end
	
	-- sinon : P969, type : string -- propriété obsolète
	if not streets then 
		streets =  wikidata.formatAndCat{linkback = true, property = 'P969', entity = item}
	end
	
	return streets
end

function p.adminDivList(item, country) -- returns a list of admin divisions matching the criteria defined in Module:Adresse/Formats
	country = country or getCountry(item)
	local query = {property = 'P131'}
	local divs = wikidata.transitiveVals(item, query, 0, 10, country)
	local validDivs = {}	
	
	-- solution 1: looks for divs of a certain type
	local function setValue(targetclasses, depth)
		local test = {}
		for _, d in pairs(divs) do
			for j, divtype in pairs(targetclasses) do
				if (divtype == '-') then
					if #validDivs > 0 then
						divs = wikidata.addVals(divs, query, 0, 1, country)
					end
					if divs[#divs] == country then
						return nil
					end
					return divs[#divs]
				end
				if wikidata.isInstance(divtype, d, 3) then
					 -- restrain list to new value, will be expanded only if needed
					divs = {d}
					return d
				end
			end
		end
		if depth >= 0 then
			local num = #divs
			divs = wikidata.addVals(divs, query, 0, 10, country)
			if #divs > num then return setValue(targetclasses, depth) end
		end
	end

	-- solution2: looks for divs that are part of a closed list (way more efficient for big items)
	local function findInList(list, depth) 
		for i, j in pairs(divs) do
			for k, l in pairs(list) do
				if j == l then
					divs = {l}
					return l
				end
			end
		end
		if depth >= 0 then
			local num = #divs
			divs = wikidata.addVals(divs, query, 0, 10, country)
			if #divs > num then return findInList(list, depth) end
		end
	end
					
	local displayformat = formats[country] or formats.default
	local maxdepth = 3
	if not divs then
		return nil
	end

	if displayformat.div1 then
		local val = setValue(displayformat.div1, maxdepth)
		if val and val ~= validDivs[#validDivs] then
			table.insert(validDivs, val)
		end
	end

	if displayformat.div2 then
		local val = setValue(displayformat.div2, maxdepth)
		if val and val ~= validDivs[#validDivs] then
			table.insert(validDivs, val)
		end
	elseif displayformat.div2vals then
		local val =  findInList(displayformat.div2vals, 1)
		if val and val ~= validDivs[#validDivs] then
			table.insert(validDivs, val)
		end
	end
	
	if displayformat.div3 then
		local val = setValue(displayformat.div3, maxdepth)
		if val and val ~= validDivs[#validDivs] then
			table.insert(validDivs, val)
		end
	elseif displayformat.div3vals then
		local val =  findInList(displayformat.div3vals, 0)
		if val and val ~= validDivs[#validDivs] then
			table.insert(validDivs, val)
		end
	end
	
	return validDivs
end

function p.cityLine(item, country, divlist, postcode) -- line with list of admin divisions + optional postcode
	country = country or getCountry(item)
	
	local postcode = postcode or wikidata.formatStatements{entity = item, property = 'P281'} or ''
	if postcode == '-' then -- can be disabled when it is not useful
		postcode = ''
	end
	local divstr = ''
	
	if (not divlist) or (#divlist == 0) then
		divlist = p.adminDivList(item, country)
	end
	if (not divlist) or (#divlist == 0) then
		return -- add a maintenance category ?
	end
	for i, j in pairs(divlist) do
		if string.find(j, '^Q[0-9]+$') then
			divlist[i] = wikidata.formatEntity(j)
		end
	end
	local divstr = linguistic.conj(divlist, 'comma')

	local formatting = formats[country] or formats.default
	local str = formatting.cityline or formats.default.cityline
	str = str:gsub("$postcode", postcode or '')
	str = str:gsub("$admindivs", divstr or '')
	return str
end

function p.fullAddress(item, country, divs, streetstr, divstr, showcountry, postcode)
	 -- country id used for formatting
	country = country or getCountry(item)
	local displayformat = formats[country] or formats.default

	-- line 1 street
	local streetline = streetstr or p.streetAddress(item, country)
	
	-- line 2: administrative divisions, postcodes
	local cityline = divstr
	if not cityline then cityline = p.cityLine(item, country, divs, postcode) end
	if (not cityline) or mw.text.trim(cityline) == '' then
		cityline = nil
	end

	-- line 3: country
	local countryline, success
	if (showcountry ~= '-') then
		countryline, success = countrymodule.standarddisplay(country)
		if not success then
			if (type(country) == 'string') and string.find(country, "^Q[0-9]+$") then
				countryline = wikidata.formatEntity(country)
			else
				countryline = country or wikidata.formatStatements{entity = item, property = 'P17'}
			end
		end
	end
	local str = linguistic.conj({streetline, cityline, countryline}, '<br />')
	if str and (not streetstr) and (not divstr) then -- à peu près
		str = str .. '[[Category:Page utilisant une adresse fournie par Wikidata]]'
	end
	
	local hasstreetline
	if streetline then hasstreetline = true else hasstreetline = false end

	return str, hasstreetline
end

function p.wikidataAddress(item, country) -- fonction de transition
	local area = formats[country] or formats.default
	local val = p.streetAddress(item, area)
	if val then
		return val .. '[[Category:Page utilisant une adresse fournie par Wikidata]]'
	end
end
return p