Module:Adresse : Différence entre versions
(+ qqes pays) |
(fullAddress : suppression variable globale entity) |
||
(15 révisions intermédiaires par 2 utilisateurs non affichées) | |||
Ligne 1 : | Ligne 1 : | ||
+ | local formats = require "Module:Adresse/Formats" | ||
+ | |||
local p = {} | local p = {} | ||
+ | local wikidata = require "Module:Interface Wikidata".fromLua | ||
+ | local linguistic = require "Module:Linguistique" | ||
+ | local countrymodule = require "Module:Country data" | ||
+ | |||
+ | local function getCountry(item) -- get country id for formatting | ||
+ | return wikidata.formatStatements{property = 'P17', entity = item, displayformat = 'raw', numvals = 1} | ||
+ | end | ||
− | local wikidata = | + | 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 | + | 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, | + | local function formatStreet(streetname, housenumber, direction, displayformat) |
− | local val = | + | 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 '') | ||
+ | val = mw.ustring.gsub(val, '$direction', direction or '') | ||
return val | return val | ||
end | end | ||
− | function | + | 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 | ||
− | local | + | function p.streetAddress(item, area) -- formate la ligne concernant la rue et le numéro de rue |
− | if | + | local streets -- châine contenant le ou les rues et numéros d'immeuble |
− | + | area = area or formats[getCountry(item)] | |
+ | |||
+ | -- 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 | end | ||
− | if | + | -- sinon : P969, type : string |
− | + | if not streets then | |
+ | streets = wikidata.formatAndCat{property = 'P969', entity = item} | ||
end | end | ||
− | return | + | return streets |
end | end | ||
− | + | function p.adminDivList(item, country) -- returns a list of admin divisions matching the criteria defined in Module:Adresse/Formats | |
− | if | + | country = country or getCountry(item) |
+ | local query = {entity = place, 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 | ||
+ | |||
+ | displayformat = formats[country] or formats.default | ||
+ | local maxdepth = 3 | ||
+ | if not divs then | ||
return nil | return nil | ||
end | end | ||
− | local | + | |
− | + | if displayformat.div1 then | |
− | table.insert( | + | 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 | end | ||
− | return | + | |
+ | return validDivs | ||
end | end | ||
− | + | function p.cityLine(item, country, divlist) -- line with list of admin divisions + optional postcode | |
− | + | country = country or getCountry(item) | |
− | return | + | |
+ | local postcode = wikidata.formatStatements{entity = item, property = 'P281'} or '' | ||
+ | local divstr = '' | ||
+ | |||
+ | divlist = divlist or p.adminDivList(item, country) | ||
+ | if not divlist then | ||
+ | return -- add a maintenance category ? | ||
end | end | ||
− | + | for i, j in pairs(divlist) do | |
− | + | 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 | end | ||
− | + | function p.fullAddress(item, country, divs, streetstr, divstr) | |
− | + | ||
− | local | + | -- 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 or p.cityLine(item, country, divs) | ||
− | + | if (not cityline) or mw.text.trim(cityline) == '' then | |
− | + | cityline = nil | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
end | end | ||
− | + | ||
− | + | -- line 3: country | |
− | + | local countryline, success = countrymodule.standarddisplay(country) | |
− | + | if not success then | |
− | + | countryline = country or wikidata.formatStatements{entity = item, property = ''} | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
end | end | ||
− | + | ||
− | local | + | local str = linguistic.conj({streetline, cityline, countryline}, '<br />') |
− | if | + | if str and (not streetstr) and (not divstr) then -- à peu près |
− | + | str = str .. '[[Category:Page utilisant une adresse fournie par Wikidata]]' | |
− | |||
− | |||
end | end | ||
− | -- | + | return str |
− | local val = p. | + | end |
− | if val then | + | |
− | val .. '[[Category:Page utilisant une adresse fournie par Wikidata]]' | + | 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 |
Version actuelle datée du 16 septembre 2016 à 08:22
La documentation pour ce module peut être créée à Module:Adresse/doc
local formats = require "Module:Adresse/Formats" local p = {} local wikidata = require "Module:Interface Wikidata".fromLua local linguistic = require "Module:Linguistique" local countrymodule = require "Module:Country data" local function getCountry(item) -- get country id for formatting return wikidata.formatStatements{property = 'P17', entity = item, displayformat = 'raw', numvals = 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 area = area or formats[getCountry(item)] -- 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 : P969, type : string if not streets then streets = wikidata.formatAndCat{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 = {entity = place, 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 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) -- line with list of admin divisions + optional postcode country = country or getCountry(item) local postcode = wikidata.formatStatements{entity = item, property = 'P281'} or '' local divstr = '' divlist = divlist or p.adminDivList(item, country) if not divlist then return -- add a maintenance category ? end for i, j in pairs(divlist) do divlist[i] = wikidata.formatEntity(j) 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) -- 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 or p.cityLine(item, country, divs) if (not cityline) or mw.text.trim(cityline) == '' then cityline = nil end -- line 3: country local countryline, success = countrymodule.standarddisplay(country) if not success then countryline = country or wikidata.formatStatements{entity = item, property = ''} 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 return str 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