Jump to content

Module:Pop density

Permanently protected module
From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Frietjes (talk | contribs) at 16:44, 30 December 2013. The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

--
-- This module implements {{Pop density}}
--
local p = {}
local math_module = require( "Module:Math" )
local precision = math_module._precision

local function rnd(num, digits)
	-- This function implements {{rnd}}
	return math_module._precision_format(tostring(num), tostring(digits))
end

local function unitnames(areaunit)
	if(areaunit == 'km²' or areaunit == 'sqkm' or areaunit == 'km2' ) then
		return 'km2'
	elseif( areaunit == 'mi2' or areaunit == 'sqmi') then
		return 'sqmi'
	else
		return '<span class="error">Unknown unit</span>'
	end
end

local function popdensity(pop, area1, areaunit1, areaunit2, prec, disp, flip)
	local dens1, dens1, prec1 = nil, nil, nil
	local dens2, dens2, prec2 = nil, nil, nil
	local str1, str2 = '', ''
	
	if(pop ~= '' and area1 ~= '') then
		-- pop and area are defined
		local dens1num = tonumber(pop)/tonumber(area1)
		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))
		if (unitnames(areaunit1) == 'km2') then
			str1 = '/km<sup>2</sup>'
			if(unitnames(areaunit2) == 'sqmi') then
				-- convert per km2 to per sqmi
				prec2 = prec1 - .41329777
				dens2 = rnd(dens1num*2.589988110336, math.floor(prec2 + 0.5))
				str2 = '/sq&nbsp;mi'
			end
		elseif(unitnames(areaunit1) == 'sqmi') then
			str1 = '/sq&nbsp;mi'
			if(unitnames(areaunit2) == 'km2') then
				-- convert per sqmi to per km2
				prec2 = prec1 + .41329777
				dens2 = rnd(dens1num/2.589988110336, math.floor(prec2 + 0.5))
				str2 = '/km<sup>2</sup>'
			end
		end

		-- form output
		if( str2 ~= '' ) then
			-- has a converted unit
			if( disp ~= 'num' ) then
				-- display input and output density numbers with units
				if( flip == 'on' ) then
					return dens2 .. str2 .. ' (' .. dens1 .. str1 .. ')'
				else
					return dens1 .. str1 .. ' (' .. dens2 .. str2 .. ')'
				end
			else
				-- display output density number without unit
				return dens2
			end
		else
			-- no converted unit
			if( disp ~= 'num' ) then
				-- display input density number with unit 
				return dens1 .. str1
			else
				-- display input density number without unit
				return dens1
			end
		end
	end
	return '<span class="error">Error</span>'
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