Module:Pop density: Difference between revisions
Content added Content deleted
No edit summary |
Vivaporius (talk | contribs) m (1 revision imported) |
||
(2 intermediate revisions by 2 users not shown) | |||
Line 5: | Line 5: | ||
local math_module = require( "Module:Math" ) |
local math_module = require( "Module:Math" ) |
||
local precision = math_module._precision |
local precision = math_module._precision |
||
local sortkey = require( "Module:Sortkey" ) |
|||
local function rnd(num, digits) |
local function rnd(num, digits) |
||
Line 42: | Line 43: | ||
local function popdensity(pop, area1, areaunit1, areaunit2, prec, disp, flip) |
local function popdensity(pop, area1, areaunit1, areaunit2, prec, disp, flip) |
||
local dens1, |
local dens1, dens1sort, prec1 |
||
local dens2, |
local dens2, dens2sort, prec2 |
||
local str1, str2 = '', '' |
local str1, str2 = '', '' |
||
local uniterror = '<sup>[[Template:Pop density|?Unknown unit?]]</sup>[[Category:Pop density using unsupported units]]' |
local uniterror = '<sup>[[Template:Pop density|?Unknown unit?]]</sup>[[Category:Pop density using unsupported units]]' |
||
Line 62: | Line 63: | ||
local unit2 = unitnames[areaunit2] or nil |
local unit2 = unitnames[areaunit2] or nil |
||
prec1 = (prec ~= '') and tonumber(prec) |
prec1 = (prec ~= '') and tonumber(prec) |
||
or (1+math.log10(2*area1/(1/10^precision(pop)+pop/area1/10^precision(area1)))) |
|||
dens1 = rnd(dens1num, math.floor(prec1 + 0.5)) |
dens1 = rnd(dens1num, math.floor(prec1 + 0.5)) |
||
dens1sort = '<span style="display:none" data-sort-value="' |
|||
.. sortkey._sortKeyForNumber(dens1num) .. '♠"></span>' |
|||
if (unit1) then |
if (unit1) then |
||
str1 = '/' .. unitstr[unit1] |
str1 = '/' .. unitstr[unit1] |
||
Line 71: | Line 75: | ||
prec2 = prec1 - math.log10(mult) |
prec2 = prec1 - math.log10(mult) |
||
dens2 = rnd(dens1num*mult, math.floor(prec2 + 0.5)) |
dens2 = rnd(dens1num*mult, math.floor(prec2 + 0.5)) |
||
dens2sort = '<span style="display:none" data-sort-value="' |
|||
.. sortkey._sortKeyForNumber(dens1num*mult) .. '♠"></span>' |
|||
str2 = '/' .. unitstr[unit2] |
str2 = '/' .. unitstr[unit2] |
||
elseif(areaunit2 ~= '') then |
elseif(areaunit2 ~= '') then |
||
Line 100: | Line 106: | ||
-- display input and output density numbers with units |
-- display input and output density numbers with units |
||
if( flip == 'on' ) then |
if( flip == 'on' ) then |
||
return dens2 .. str2 .. ' (' .. dens1 .. str1 .. ')' |
return (dens2sort or '') .. dens2 .. str2 .. ' (' .. dens1 .. str1 .. ')' |
||
else |
else |
||
return dens1 .. str1 .. ' (' .. dens2 .. str2 .. ')' |
return (dens1sort or '') .. dens1 .. str1 .. ' (' .. dens2 .. str2 .. ')' |
||
end |
end |
||
elseif( disp == 'table') then |
elseif( disp == 'table') then |
||
dens1 = (dens1sort or '') .. dens1 |
|||
dens2 = (dens2sort or '') .. dens2 |
|||
return pop .. '||' .. area1 .. '||' .. dens1 .. '||' .. dens2 |
return pop .. '||' .. area1 .. '||' .. dens1 .. '||' .. dens2 |
||
else |
else |
||
Line 114: | Line 122: | ||
if( disp ~= 'num' and disp ~= 'table' ) then |
if( disp ~= 'num' and disp ~= 'table' ) then |
||
-- display input density number with unit |
-- display input density number with unit |
||
return dens1 .. str1 |
return (dens1sort or '') .. dens1 .. str1 |
||
elseif( disp == 'table') then |
elseif( disp == 'table') then |
||
return pop .. '||' .. area1 .. '||' .. dens1 |
return pop .. '||' .. area1 .. '||' ..(dens1sort or '') .. dens1 |
||
else |
else |
||
-- display input density number without unit |
-- display input density number without unit |
||
Line 128: | Line 136: | ||
function p.density(frame) |
function p.density(frame) |
||
local args = (frame.args[3] ~= nil) and frame.args or frame:getParent().args |
local args = (frame.args[3] ~= nil) and frame.args or frame:getParent().args |
||
return popdensity( |
|||
args[1] or '', args[2] or '', args[3] or '', args[4] or '', |
|||
args['prec'] or '', args['disp'] or '', args['flip'] or '' |
|||
) |
|||
end |
end |
||
Latest revision as of 03:25, 12 May 2022
Documentation for this module may be created at Module:Pop density/doc
--
-- This module implements {{Pop density}}
--
local p = {}
local math_module = require( "Module:Math" )
local precision = math_module._precision
local sortkey = require( "Module:Sortkey" )
local function rnd(num, digits)
-- This function implements {{rnd}}
return math_module._precision_format(tostring(num), tostring(digits))
end
local unitnames = {
["km²"] = "km2",
["sqkm"] = "km2",
["km2"] = "km2",
["mi2"] = "sqmi",
["sqmi"] = "sqmi",
["acres"] = "acre",
["acre"] = "acre",
["ha"] = "ha",
["dunam"] = "dunam",
["m²"] = "m2",
["sqm"] = "m2",
["m2"] = "m2"
}
local unitmult = {
["km2"] = 1000000,
["sqmi"] = 2589988.110336,
["acre"] = 4046.8564224,
["ha"] = 10000,
["dunam"] = 1000,
["m2"] = 1
}
local unitstr = {
["km2"] = 'km<sup>2</sup>',
["sqmi"] = 'sq mi',
["acre"] = 'acre',
["ha"] = 'ha',
["dunam"] = 'dunam',
["m2"] = 'm<sup>2</sup>'
}
local function popdensity(pop, area1, areaunit1, areaunit2, prec, disp, flip)
local dens1, dens1sort, prec1
local dens2, dens2sort, prec2
local str1, str2 = '', ''
local uniterror = '<sup>[[Template:Pop density|?Unknown unit?]]</sup>[[Category:Pop density using unsupported units]]'
if(pop ~= '' and area1 ~= '') then
-- pop and area are defined
local popnum = tonumber(pop)
if not popnum then
error(string.format('Unable to convert population "%s" to a number', pop), 2)
end
local area1num = tonumber(area1)
if not area1num then
error(string.format('Unable to convert area "%s" to a number', area1), 2)
end
local dens1num = popnum/area1num
local unit1 = unitnames[areaunit1] or nil
local unit2 = unitnames[areaunit2] or nil
prec1 = (prec ~= '') and tonumber(prec)
or (1+math.log10(2*area1/(1/10^precision(pop)+pop/area1/10^precision(area1))))
dens1 = rnd(dens1num, math.floor(prec1 + 0.5))
dens1sort = '<span style="display:none" data-sort-value="'
.. sortkey._sortKeyForNumber(dens1num) .. '♠"></span>'
if (unit1) then
str1 = '/' .. unitstr[unit1]
if(unit2) then
-- convert
local mult = unitmult[unit2]/unitmult[unit1]
prec2 = prec1 - math.log10(mult)
dens2 = rnd(dens1num*mult, math.floor(prec2 + 0.5))
dens2sort = '<span style="display:none" data-sort-value="'
.. sortkey._sortKeyForNumber(dens1num*mult) .. '♠"></span>'
str2 = '/' .. unitstr[unit2]
elseif(areaunit2 ~= '') then
if( disp ~= 'num' ) then
dens2 = '?'
else
dens2 = '?' .. uniterror
end
str2 = '/' .. areaunit2 .. uniterror
end
elseif(areaunit1 ~= '') then
if( disp ~= 'num' ) then
dens2 = '?'
else
dens2 = '?' .. uniterror
end
if(unit2) then
str2 = '/' .. unitstr[unit2]
elseif(areaunit2 ~= '') then
str2 = '/' .. areaunit2 .. uniterror
end
str1 = '/' .. areaunit1 .. uniterror
end
-- form output
if( str2 ~= '' ) then
-- has a converted unit
if( disp ~= 'num' and disp ~= 'table' ) then
-- display input and output density numbers with units
if( flip == 'on' ) then
return (dens2sort or '') .. dens2 .. str2 .. ' (' .. dens1 .. str1 .. ')'
else
return (dens1sort or '') .. dens1 .. str1 .. ' (' .. dens2 .. str2 .. ')'
end
elseif( disp == 'table') then
dens1 = (dens1sort or '') .. dens1
dens2 = (dens2sort or '') .. dens2
return pop .. '||' .. area1 .. '||' .. dens1 .. '||' .. dens2
else
-- display output density number without unit
return dens2
end
else
-- no converted unit
if( disp ~= 'num' and disp ~= 'table' ) then
-- display input density number with unit
return (dens1sort or '') .. dens1 .. str1
elseif( disp == 'table') then
return pop .. '||' .. area1 .. '||' ..(dens1sort or '') .. dens1
else
-- display input density number without unit
return dens1
end
end
end
return ''
end
function p.density(frame)
local args = (frame.args[3] ~= nil) and frame.args or frame:getParent().args
return popdensity(
args[1] or '', args[2] or '', args[3] or '', args[4] or '',
args['prec'] or '', args['disp'] or '', args['flip'] or ''
)
end
return p