Модуль:WikidataCoords
Выгляд
Дакументацыю да гэтага модуля можна стварыць у Модуль:WikidataCoords/Дакументацыя
local p = {}
-- Значэнні прадвызначаных аргументаў
local defaultArgs = {
['lat_deg'] = '',
['lat_min'] = '0',
['lat_sec'] = '0',
['lat_dir'] = 'N',
['lon_deg'] = '',
['lon_min'] = '0',
['lon_sec'] = '0',
['lon_dir'] = 'E'
}
-- Дадатковыя прадвызначаныя аргументы для *_wikidata
local defaultArgsWikidata = {
['lat_deg_wikidata'] = '',
['lat_min_wikidata'] = '0',
['lat_sec_wikidata'] = '0',
['lat_dir_wikidata'] = 'N',
['lon_deg_wikidata'] = '0',
['lon_min_wikidata'] = '0',
['lon_sec_wikidata'] = '0',
['lon_dir_wikidata'] = 'E'
}
-- Суадносіны найменных і лікавых параметраў
local argsMap = {
'lat_deg','lat_min','lat_sec','lat_dir',
'lon_deg','lon_min','lon_sec','lon_dir'
}
-- === Дапаможныя функцыі ===
local function trimUnits(v)
if v == nil then return v end
return mw.text.trim(v, '°′″ ')
end
local function trimUnitsForKeys(tbl, keys)
for _, k in ipairs(keys) do
if tbl[k] ~= nil and tbl[k] ~= '' then
tbl[k] = trimUnits(tbl[k])
end
end
end
-- Вяртае lat, lon або nil, nil калі няма
local function fetchCoordsFromWD(frame, property)
local moduleWikidata = require('Module:Wikidata')
-- Падтрымка параметра propertyFilter; прадвызначана P625
local prop = property or 'p625'
frame.args = {
['property'] = prop,
['plain'] = true,
['subvalue'] = 'plain'
}
local coords = moduleWikidata.formatProperty(frame)
if not coords or coords == '' then
return nil, nil
end
-- Замена HTML-сутнасцей
coords = tostring(coords)
coords = string.gsub(coords, ''', '′')
coords = string.gsub(coords, '"', '″')
-- Выдаляем усё, што не лічбы/знакі раздзялення
coords = mw.ustring.gsub(coords, '[^%d.,-]', '')
local parts = mw.text.split(coords, ',', true)
local lat = tonumber(parts[1])
local lon = tonumber(parts[2])
return lat, lon
end
-- === Асноўныя функцыі ===
-- Зваротна сумяшчальная версія: калі няма lat/coord — падцягваем ВД у базавыя палі;
-- калі lat зададзены, з ВД дадаём *_wikidata
function p.execTplAddCoords(frame)
local pFrame = frame:getParent()
local args = mw.clone(pFrame.args)
setmetatable(args, nil)
local template = mw.text.trim(args[1])
-- Калі базавыя параметры пустыя — нічога не робім
if not args.lat_deg or args.lat_deg == '' then
return ''
end
-- Атрыманне каардынат з Вікіданых у *_wikidata
local propertyFilter = args.propertyFilter or 'p625'
local lat, lon = fetchCoordsFromWD(frame, propertyFilter)
if lat ~= nil then
args.lat_deg_wikidata = math.abs(lat)
args.lat_dir_wikidata = (lat >= 0) and 'N' or 'S'
end
if lon ~= nil then
args.lon_deg_wikidata = math.abs(lon)
args.lon_dir_wikidata = (lon >= 0) and 'E' or 'W'
end
-- Прадвызначаныя значэнні і абрэзка адзінак
for name, value in pairs(defaultArgsWikidata) do
if not args[name] or args[name] == '' then
args[name] = value
end
args[name] = trimUnits(args[name])
end
for name, value in pairs(defaultArgs) do
if not args[name] or args[name] == '' then
args[name] = value
end
args[name] = trimUnits(args[name])
end
return frame:expandTemplate{ title = template, args = args }
end
-- Метад выклікае шаблон, дадаючы да параметраў каардынаты з Вікіданых
function p.execTplWithCoords(frame)
local pFrame = frame:getParent()
local args = mw.clone(pFrame.args)
setmetatable(args, nil)
local template = mw.text.trim(args[1]); args[1] = nil
-- Фармат вываду
local outType = args[2]
if outType then outType = mw.text.trim(outType) end
-- Перавызначэнне 1 і 2 параметра
args[1] = args['01']; args['01'] = nil
args[2] = args['02']; args['02'] = nil
local isWikidata = false
-- Калі няма ні coord, ні lat_deg — спрабуем ВД,
-- але з падтрымкай propertyFilter
if (not args.lat_deg or args.lat_deg == '') and (not args.coord or args.coord == '') then
isWikidata = true
local propertyFilter = args.propertyFilter or 'p625'
local lat, lon = fetchCoordsFromWD(frame, propertyFilter)
-- Калі ВД нічога не вярнуў — не выклікаем шаблон (палепшаны ранні выхад)
if lat == nil and lon == nil then
return ''
end
if lat ~= nil then
args.lat_deg = math.abs(lat)
args.lat_dir = (lat >= 0) and 'N' or 'S'
end
if lon ~= nil then
args.lon_deg = math.abs(lon)
args.lon_dir = (lon >= 0) and 'E' or 'W'
end
end
-- Устаноўка прадвызначаных значэнняў
for name, value in pairs(defaultArgs) do
if not args[name] or args[name] == '' then
args[name] = value;
end
end
-- Абрэзка адзінак ва ўваходных значэннях (стар. паводзіны)
trimUnitsForKeys(args, {
'lat_deg','lat_min','lat_sec','lat_dir',
'lon_deg','lon_min','lon_sec','lon_dir'
})
-- Калі параметры пустыя, шаблон не выклікаецца
if (args.lat_deg == '' and args.lon_deg == '') and (not args.coord or args.coord == '') then
return '';
end
-- Апрацоўка фармату вываду
if outType and (not args.coord or args.coord == '') then
-- Нумараваныя параметры, пачынаючы з n-га
if outType == '12345678' or outType == '23456789' or outType == '345678910' then
local n = 0;
if outType == '23456789' then
n = 1;
elseif outType == '345678910' then
n = 2;
end
for i, name in ipairs(argsMap) do
args[i + n] = args[name];
args[name] = nil;
end
end
if outType == 'coord' then
args['coord'] = args.lat_deg ..
'/' ..
args.lat_min ..
'/' ..
args.lat_sec ..
'/' ..
args.lat_dir .. '/' .. args.lon_deg .. '/' .. args.lon_min .. '/' .. args.lon_sec .. '/' .. args.lon_dir
end
end
local out = frame:expandTemplate{ title = template, args = args }
if (not isWikidata) and not (args.display and args['display'] == 'title') then
out = '<span class="no-wikidata" data-wikidata-property-id="P625">' .. out .. '</span>'
end
return out
end
return p;