Module:Gemeente in Nederland

Moduledocumentatie​[bekijk] [bewerk] [ververs] [geschiedenis]

Deze module maakt een tabel aan met de woonplaatsen in een Nederlandse gemeente, inclusief inwoneraantallen, peildatums en de hoofdplaats(en) van de gemeente gemarkeerd. Deze module is onderdeel van het Wikiproject WikidataOpWikipedia/Inwoneraantal en valt onder het deelproject "Tabel woonplaatsen Nederlandse gemeente".

Parameters bewerken

Sjabloonparameters bewerken

  • wikidataid (optioneel): Wikidata-ID van de gemeente.
  • wikidatalinks (optioneel): Indien "ja" zal de tabel links bevatten naar de Wikidata-items van de woonplaatsen. Gebruik dit alleen in de "Toon bewerking ter controle"-modus.

Moduleparameters bewerken

  • reference_date: De gewenste peildatum.

Werking bewerken

  • De module probeert een tabel te maken voor de gemeente behorend bij het opgegeven Wikidata-ID. Als die niet gegeven is, wordt geprobeerd een tabel te maken voor de pagina waarin het sjabloon wordt aangeroepen. In beide gevallen werkt het pas als het bijbehorende Wikidata-item als is een (P31) een Nederlandse gemeente (Q2039348) is. Wanneer een foutieve waarde als Wikidata-ID is opgegeven, wordt niet in plaats daarvan geprobeerd het Wikidata-item behorend bij de Wikipedia-pagina te gebruiken.
  • Voor de hoofdplaatsen wordt hoofdplaats (P36) gebruikt, de woonplaatsen komen van omvat plaats (P1383). Alleen woonplaatsen met een is een (P31) van woonplaats in Nederland (Q1852859) worden gebruikt.
  • Voor de naam van de gemeente en de naam van de woonplaatsen worden de Nederlandse labels uit Wikidata gebruikt.
  • Voor het verkrijgen van de inwoneraantallen, inwoneraantallen met bron en bijbehorende peildatums van de gemeente en woonplaatsen wordt het sjabloon {{Inwonertal}} gebruikt, namelijk {{Inwonertal|id=...|soort=waardepuur}}, {{Inwonertal|id=...}} en {{Inwonertal|id=...|soort=datum}}. Als er een inwonertal (P1082) staat met als van toepassing op deel (P518) de gemeente, dan wordt dat inwoneraantal gebruikt en de daarbij behorende bron.
  • Indien de tabel links moet bevatten naar de Wikidata-items, wordt daarvoor {{Inwonertal|id=...|soort=wdlink}} gebruikt.
  • De sortering van de woonplaatsen is als volgt: bovenaan staan de hoofdplaatsen op alfabetische volgorde en dikgedrukt, daaronder staan de overige woonplaatsen op alfabetische volgorde. De sortering kan door de lezer veranderd worden met de pijltjes boven in de tabel.

Beheercategorieën bewerken

Deze module kan pagina's toevoegen aan vier beheercategorieën. Zie voor extra uitleg de documentatie in de beheercategorie:

--Variabele die alle modulefuncties bevat
local p = {}

--Modulefunctie "settlements_table", voert functie "settlements_table" uit
function p.settlements_table(frame)
	local ok, result = pcall(settlements_table, frame)
	--Als er geen errors optraden tijdens de uitvoering van de functie, wordt de tabel (het resultaat) geretourneerd
	if ok == true then
		return result
	--Als er wel een error optrad, wordt een foutmelding geretourneerd en wordt de pagina in een beheercategorie geplaatst
	else
		return frame:expandTemplate{ title = 'Error', args = {'De module gaf een foutmelding (klik [[Overleg Wikipedia:Wikiproject/WikidataOpWikipedia/Inwoneraantal#Tabel woonplaatsen Nederlandse gemeente|hier]] voor hulp):<br />' .. result .. '[[Categorie:Wikipedia:Tabel woonplaatsen Nederlandse gemeente/Directe actie nodig]]'} }
	end
end

--Functie "settlements_table", maakt een tabel met alle woonplaatsen in een gemeente en de bijbehorende inwoneraantallen en markeert de hoofdplaats(en)
function settlements_table(frame)
	result = ''

	--Parameters die meegegeven worden aan het sjabloon ophalen
	parent_args = frame:getParent().args
	--Parameters die meegegeven worden aan de module (vanuit het sjabloon) ophalen
	args = frame.args

	--Als de sjabloonparameter "wikidataid" gegeven is, wordt een tabel gemaakt voor het Wikidata-item met dat ID
	if parent_args.wikidataid then
		municipality_id = parent_args.wikidataid
		--Als het ID niet op een Wikidata-ID lijkt, wordt een foutmelding geretourneerd
		if string.sub(municipality_id, 1, 1) ~= 'Q' then
			error('Het opgegeven Wikidata-ID, <code>' .. municipality_id .. '</code>, is niet geldig. Een geldig Wikidata-ID is in de vorm "Qx", met een of meer cijfers op de plaats van x.')
		end
	--Anders wordt het Wikidata-item behorend bij de pagina zelf gebruikt
	else
		municipality_id = mw.wikibase.getEntityIdForCurrentPage()
	end

	--Als de pagina geen Wikidata-ID heeft en ook geen Wikidata-ID is opgegeven, wordt een foutmelding geretourneerd
	if municipality_id == nil then
		error('Er kon geen tabel gemaakt worden omdat deze pagina geen Wikidata-ID heeft en er geen Wikidata-ID is opgegeven als parameter (zie [[Sjabloon:Tabel woonplaatsen Nederlandse gemeente#Parameters|hier]] welke parameters gebruikt kunnen worden).')
	end

	--Als het bijbehorende Wikidata-item niet een instantie is van "municipality of the Netherlands" (Q2039348), wordt een foutmelding geretourneerd
	local municipality_instance = 'Q2039348'
	if not is_instance(municipality_id, municipality_instance) then
		error('Er kon geen tabel gemaakt worden omdat het [[:d:' .. municipality_id .. '|Wikidata-item]] ' .. (parent_args.wikidataid and 'van het opgegeven Wikidata-ID' or 'van deze pagina') .. ' niet een instantie is van "municipality of the Netherlands" ([[d:' .. municipality_instance .. '|' .. municipality_instance .. ']]).')
	end

	--De hoofdplaatsen van, woonplaatsen in, het totale inwoneraantal van en de naam van de gemeente worden opgehaald uit Wikidata
	local capitals = mw.wikibase.getBestStatements(municipality_id, 'P36')
	local settlements = mw.wikibase.getBestStatements(municipality_id, 'P1383')
	local municipality_data = get_population(frame, municipality_id)
	local municipality_name = mw.wikibase.getLabelByLang(municipality_id, 'nl')

	--De Wikidata-ID's van de hoofdplaatsen worden in een table gezet
	local capital_ids = {}
	for k in pairs(capitals) do
		capital_ids[k] = capitals[k].mainsnak.datavalue.value.id
	end

	--Voor iedere woonplaats in de gemeente worden gegevens opgehaald
	local settlements_data = {}
	local municipality_population_sum = 0
	local n = 1
	for k in pairs(settlements) do
		local id = settlements[k].mainsnak.datavalue.value.id

		--Alleen als de woonplaats een instantie is van "populated place in the Netherlands" (Q1852859) wordt deze meegenomen
		if is_instance(id, 'Q1852859') then
			--Het inwoneraantal wordt opgehaald, alsmede het inwoneraantal met bron erachter en de bijbehorende peildatum
			local settlement_data = get_population(frame, id)

			--De naam van de woonplaats wordt opgehaald
			local settlement_name = mw.wikibase.getLabelByLang(id, 'nl')

			--Voor de woonplaatsnamen worden links naar artikelen gemaakt, als er geen pagina over bestaat wordt er niet gelinkt
			local settlement_table_name = frame:expandTemplate{ title = 'Wikidata', args = {'label', 'short', 'linked', id} }

			--Als de woonplaats een hoofdplaats van de gemeente is, wordt hij gemarkeerd
			local settlement_is_capital = contains(capital_ids, id)
			if settlement_is_capital then
				settlement_table_name = '\'\'\'' .. settlement_table_name .. '\'\'\''
			end

			--Gegevens over de woonplaats worden opgeslagen in een table
			settlement_data_combined = {name=settlement_name, table_name=settlement_table_name, is_capital=settlement_is_capital}
			for k,v in pairs(settlement_data) do
				settlement_data_combined[k] = v
			end
			settlements_data[n] = settlement_data_combined
			n = n + 1

			--De som van alle inwoneraantallen wordt berekend
			municipality_population_sum = municipality_population_sum + settlement_data_combined.population
		end
	end

	--De table wordt gesorteerd volgens de functie "order_settlements"
	table.sort(settlements_data, order_settlements)

	for k, row in pairs(settlements_data) do
		--De tabel wordt gemaakt met de gegevens uit de table "settlements_data". Merk op dat hier "row.population_with_source_sortable" wordt gebruikt, het inwoneraantal mét bron erachter
		result = result .. '\n|-\n|' .. row.table_name .. '||' .. row.population_with_source_sortable .. '||' .. row.population_date
	end

	--Als de som van de inwoneraantallen niet gelijk is aan de waarde gegeven op Wikidata, wordt het verschil toegevoegd aan de tabel
	local population_difference = municipality_data.population - municipality_population_sum
	if population_difference ~= 0 then
		--Het Sjabloon:Sorteer wordt gebruikt om het overige inwoneraantal sorteerbaar te maken
		local population_difference_sortable = frame:expandTemplate{ title = 'Sorteer', args = {population_difference, format_thousand(population_difference)} }
		--Als het verschil binnen de marge van een afrondingsverschil ligt (aantal woonplaatsen vermenigvuldigd met 2) heet de tabelrij "Afrondingsverschil", anders "Overig"
		if math.abs(population_difference) > #settlements_data * 2 then
			--Als het verschil te groot is, wordt de pagina in een beheercategorie geplaatst
			population_difference_title = 'Overig[[Categorie:Wikipedia:Tabel woonplaatsen Nederlandse gemeente/Te veel overig]]'
		else
			population_difference_title = 'Afrondingsverschil'
		end
		result = result .. '\n|-class="sortbottom"\n|' .. population_difference_title .. '||' .. population_difference_sortable .. '||'
	end

	--Het totale inwoneraantal van de gemeente uit Wikidata wordt onderaan de tabel gezet. Merk op dat hier "municipality_data.population_with_source_sortable" wordt gebruikt, het inwoneraantal mét bron erachter
	result = '{| class="wikitable sortable"\n|+ Woonplaatsen in de gemeente ' .. municipality_name .. '\n|-\n!Woonplaats!!Inwoneraantal!!Peildatum' .. result .. '\n|-class="sortbottom"\n|Totaal:||' .. municipality_data.population_with_source_sortable .. '||' .. municipality_data.population_date .. '\n|+ align="bottom" style="caption-side:bottom; text-align:right;" class="noprint" | <small>[[Overleg Wikipedia:Wikiproject/WikidataOpWikipedia/Inwoneraantal#Tabel woonplaatsen Nederlandse gemeente|Meld een fout]]</small>\n|}'

	--Het resultaat wordt geretourneerd
	return result
end

--Functie "is_instance", kijkt of een Wikidata-item een instantie is van een ander Wikidata-item
function is_instance(id, instance)
	local instances = mw.wikibase.getBestStatements(id, 'P31')
	for index, value in pairs(instances) do
		if value.mainsnak.datavalue.value.id == instance then
			return true
		end
	end
	return false
end

--Functie "get_population", haalt het inwoneraantal, inwoneraantal met bron en de peildatum van het inwoneraantal op uit Wikidata
function get_population(frame, id)
	--Als de woonplaats een inwoneraantal heeft waarvan "van toepassing op deel" (P518) de gemeente zelf is, dan wordt dat inwoneraantal gebruikt
	population_partial = frame:expandTemplate{ title = 'Wikidata', args = {'property', id, 'P1082', P518=municipality_id} }:gsub('%.', '')
	if population_partial ~= '' then
		population = population_partial
		population_with_source = frame:expandTemplate{ title = 'Wikidata', args = {'property', 'qualifier', 'references', 'normal+', id, 'P1082', P518=municipality_id} }
		population_date = frame:expandTemplate{ title = 'Wikidata', args = {'properties', 'qualifier', 'normal+', id, 'P1082', P518=municipality_id, 'P585', format='%q'} }
	else
		--Anders worden met Sjabloon:Inwonertal het "gewone" inwoneraantal en bijbehorende gegevens van Wikidata gehaald, die gemarkeerd zijn als voorkeurswaarde
		population = frame:expandTemplate{ title = 'Inwonertal', args = {id=id, soort='waardepuur'} }:gsub('%.', '')
		population_with_source = frame:expandTemplate{ title = 'Inwonertal', args = {id=id} }
		population_date = frame:expandTemplate{ title = 'Inwonertal', args = {id=id, soort='datum'} }
	end

	--Als de peildatum 4 karakters of korter is (een jaartal), wordt deze via het Sjabloon:Sorteer voor de sortering omgezet naar 1 januari van dat jaar
	if string.len(population_date) <= 4 then
		population_date = frame:expandTemplate{ title = 'Sorteer', args = {'1 januari', population_date} }
	end

	--Als het inwoneraantal niet bekend is, wordt deze vervangen door een vraagteken en wordt de pagina in een beheercategorie geplaatst
	if population == '' then
		--Voor de sortering wordt het inwoneraantal op 0 gezet, terwijl "population_with_source" wordt weergegeven als een vraagteken
		population = 0
		population_with_source = '?'
		result = result .. '[[Categorie:Wikipedia:Tabel woonplaatsen Nederlandse gemeente/Ontbrekend inwoneraantal]]'
	end

	--Als de peildatum niet gelijk is aan de gewenste peildatum, wordt de pagina in een beheercategorie geplaatst
	if population_date ~= args.reference_date then
		result = result .. '[[Categorie:Wikipedia:Tabel woonplaatsen Nederlandse gemeente/Onjuiste peildatum]]'
	end

	--Als de moduleparameter "wikidatalinks" gelijk is aan "ja", wordt bij ieder inwoneraantal een link geplaatst naar de Wikidata-locatie van dat gegeven
	if parent_args.wikidatalinks == 'ja' then
		local wikidatalink = frame:expandTemplate{ title = 'Inwonertal', args = {id=id, soort='wdlink'} }
		--Alleen als het het inwoneraantal van de gemeente betreft, wordt de pagina in een beheercategorie geplaatst (zodat die categorietoewijzing maar een keer gebeurt)
		if id == municipality_id then
			wikidatalink = wikidatalink .. '[[Categorie:Wikipedia:Tabel woonplaatsen Nederlandse gemeente/Directe actie nodig]]'
		end
		population_with_source = population_with_source .. ' ' .. wikidatalink
	end

	--Het Sjabloon:Sorteer wordt gebruikt om de inwoneraantallen sorteerbaar te maken
	local population_with_source_sortable = frame:expandTemplate{ title = 'Sorteer', args = {population, population_with_source} }

	return {population=population, population_with_source_sortable=population_with_source_sortable, population_date=population_date}
end

--Functie "contains", kijkt of een table een bepaalde waarde bevat
function contains(tab, val)
	for index, value in pairs(tab) do
		if value == val then
			return true
		end
	end
	return false
end

--Functie "order_settlements", retourneert welke rij boven en welke onder de andere moet staan: op alfabetische volgorde van woonplaatsnamen, waarbij de hoofdplaats(en) bovenaan staat/staan (alfabetisch gesorteerd indien meer dan één)
function order_settlements(a, b)
	if a.is_capital == b.is_capital then
		return a.name < b.name
	end
	return a.is_capital
end

--Functie "format_thousand", voegt scheidingstekens voor duizendtallen (punten) toe aan een getal
--Credits: remiX (04-01-2013), van http://www.computercraft.info/forums2/index.php?/topic/8065-lua-thousand-separator/
--Aangepast om ook te werken voor negatieve getallen
function format_thousand(v)
	if v < 0 then
		negative = true
		v = -v
	end
	local s = string.format('%d', math.floor(v))
	local pos = string.len(s) % 3
	if pos == 0 then pos = 3 end
	local formatted = string.sub(s, 1, pos) .. string.gsub(string.sub(s, pos+1), '(...)', '.%1')
	if negative == true then formatted = '-' .. formatted end
	return formatted
end

return p