Ez a lap műszaki védett

Modul:Pozíciós térkép

A Wikipédiából, a szabad enciklopédiából
Ugrás a navigációhoz Ugrás a kereséshez

Source code project 1171.svg Pozíciós térkép[mi ez?] • [dokumentáció: mutat, szerkeszt] • [tesztek: success: 1, error: 0, skipped: 0 (részletek)]

Használat

Ez a modul a Pozíciós térkép sablon implementációja. Használatához lásd a sablon dokumentációját.

require('Modul:No globals')

local p = {}

local getArgs = require('Modul:Arguments').getArgs

local isCssAdded = false
local function getStyle()
	if isCssAdded then
		return ''
	else
		isCssAdded = true
		return mw.getCurrentFrame():extensionTag('templatestyles', nil, {src = 'Pozíciós térkép/style.css'})
	end
end

function p.getMapParams(map, frame)
	if not map then
		error('The name of the location map definition to use must be specified', 2)
	end
	if mw.title.new('Sablon:Pozíciós térkép ' .. map).exists then
		local cache = {}
		if type(frame) ~= 'table' or type(frame.expandTemplate) ~= 'function' then
			error('A frame must be provided when using a legacy location map')
		end
		return function(name, params)
			if params then
				return frame:expandTemplate{title = 'Pozíciós térkép ' .. map, args = { name, unpack(params) }}
			else
				if cache[name] == nil then
					cache[name] = frame:expandTemplate{title = 'Pozíciós térkép ' .. map, args = { name }}
				end
				return cache[name]
			end
		end
	else
		error('Unable to find the specified location map definition. "Sablon:Pozíciós térkép ' .. map .. '" doesn\'t exist', 2)
	end
end

function p.data(frame, args, map)
	if not args then
		args = getArgs(frame, {frameOnly = true})
	end
	if not map then
		map = p.getMapParams(args[1], frame)
	end
	local params = {}
	for k,v in ipairs(args) do
		if k > 2 then
			params[k-2] = v
		end
	end
	return map(args[2], #params ~= 0 and params)
end

local hemisphereMultipliers = {
	longitude = { W = -1, w = -1, E = 1, e = 1, NY = -1, Ny = -1, ny = -1, K = 1, k = 1 },
	latitude = { S = -1, s = -1, N = 1, n = 1, D = -1, d = -1, ['É'] = 1, ['é'] = 1 }
}

local function decdeg(degrees, minutes, seconds, hemisphere, decimal, direction)
	if not degrees then
		if not decimal then
			error('No value was provided for ' .. direction, 2)
		end
		local retval = tonumber(decimal)
		if retval then
			return retval
		end
		error('The value "' .. decimal .. '" provided for ' .. direction .. ' is not valid', 2)
	end
	decimal = tonumber(degrees)
	if not decimal then
		error('The degree value "' .. degrees .. '" provided for ' .. direction .. ' is not valid', 2)
	end
	if minutes and not tonumber(minutes) then
		error('The minute value "' .. minutes .. '" provided for ' .. direction .. ' is not valid', 2)
	end
	if seconds and not tonumber(seconds) then
		error('The second value "' .. seconds .. '" provided for ' .. direction .. ' is not valid', 2)
	end
	decimal = decimal + (minutes or 0)/60 + (seconds or 0)/3600
	if hemisphere then
		local multiplier = hemisphereMultipliers[direction][hemisphere]
		if not multiplier then
			-- error('The hemisphere "' .. hemisphere .. '" provided for ' .. direction .. ' is not valid', 2)
			return decimal  -- Compat
		end
		decimal = decimal * multiplier
	end
	return decimal
end

-- effectively make removeBlanks false for caption and maplink, and true for everything else
-- p.top, p.bottom, and their callers need to use this
local function valueFunc(key, value)
	if value then
		value = mw.text.trim(value)
	end
	if value ~= '' or key == 'caption' or key == 'maplink' or key == 'képaláírás' then
		return value
	end
end

local function getContainerImage(args, map)
	if args.AlternativeMap or args['alternatív térkép'] then
		return args.AlternativeMap or args['alternatív térkép']
	elseif args.relief and map('image1') ~= '' then
		return map('image1')
	else
		return map('image', {args['térképtípus']})
	end
end

function p.top(frame, args, map)
	if not args then
		args = getArgs(frame, {frameOnly = true, valueFunc = valueFunc})
	end
	if not map then
		map = p.getMapParams(args[1], frame)
	end
	local width
	if not (args.width or args['méret']) then
		width = math.floor((args.default_width or 240) * (tonumber(map('defaultscale')) or 1) + 0.5)
	elseif (args.width or args['méret']):sub(-2) == 'px' then
		width = (args.width or args['méret']):sub(1, -3)
	else
		width = args.width or args['méret']
	end
	local bordered = ((args.caption and args.caption ~= '' or args['képaláírás'] ~= '')
		and (args.border or args.keret) ~= 'none')
	local retval = getStyle() .. '<div class="poziciosTerkepDoboz' .. (bordered and ' keretes' or '')
	if (args.float or args['igazítás']) == 'left' or (args.float or args['igazítás']) == 'balra' then
		retval = retval .. ' balra'
	elseif (args.float or args['igazítás']) == 'center' or (args.float or args['igazítás']) == 'középre' then
		retval = retval .. ' center'
	elseif (args.float or args['igazítás']) ~= 'none' and (args.float or args['igazítás']) ~= 'nincs' then
		retval = retval .. ' jobbra'
	end
	retval = retval .. '" style="width:' .. (width + 2) .. 'px;'
	if bordered and (args.border or args.keret) then
		retval = retval .. ' border-color:' .. (args.border or args.keret)
	end
	retval = retval .. '">\n<div class="poziciosTerkepBelso" style="'
	if (args.border or args.keret) and (args.border or args.keret) ~= 'none' then
		retval = retval .. 'border:1px solid ' .. (args.border or args.keret) .. '; '
	end
	retval = retval .. 'width:' .. width .. 'px;">'
	local image = getContainerImage(args, map)
	retval = mw.ustring.format(
		'%s[[Fájl:%s|%spx|%s%s|class=noviewer]]',
		retval,
		image,
		width,
		args.alt or ((args.label or args.felirat or mw.title.getCurrentTitle().text) .. ' (' .. map('name') .. ')'),
		args.maplink and ('|link=' .. args.maplink) or ''
	) .. '\n'
	if args.overlay_image then
		return retval .. '<div class="overlay">[[File:' .. args.overlay_image .. '|' .. width .. 'px]]</div>'
	else
		return retval
	end
end

function p.bottom(frame, args, map)
	if not args then
		args = getArgs(frame, {frameOnly = true, valueFunc = valueFunc})
	end
	if not map then
		map = p.getMapParams(args[1], frame)
	end
	local retval = '</div>\n'

	local nevelo = map('névelő')
	if nevelo ~= '' then
		nevelo = nevelo .. ' '
	end
	local captionDiv = mw.html.create('div')
		:addClass('caption')
		:wikitext(args.caption or args['képaláírás'] or ('Pozíció ' .. nevelo .. map('name') .. ' térképén'))

	retval = retval .. getStyle() .. tostring(captionDiv) .. '\n</div>'
	return retval
end

function p.container(frame, args, map)
	if not args then
		args = getArgs(frame, {wrappers = 'Template:Location map+', valueFunc = valueFunc})
	end
	if not map then
		map = p.getMapParams(args[1], frame)
	end
	return p.top(frame, args, map) .. (args.places or '') .. p.bottom(frame, args, map)
end

local function markOuterDiv(x, y, imageDiv, labelDiv, position)
	return mw.html.create('div')
		:addClass('poziciosTerkepFelirat' .. ((position == 'left' or position == 'balra') and ' balra' or ''))
		:cssText('top:' .. y .. '%; left:' .. x .. '%;')
		:newline()
		:node(imageDiv):newline()
		:node(labelDiv):newline()
end

local function markImageDiv(mark, marksize, label, link, alt, title)
	local builder = mw.html.create('div')
		:addClass('mark')
		:cssText('left:-' .. math.floor(marksize / 2 + 0.5) .. 'px; top:-' .. math.floor(marksize / 2 + 0.5) .. 
			'px; width:' .. marksize .. 'px; font-size:' .. marksize .. 'px;')
		:attr('title', title)
	if marksize ~= 0 then
		builder:wikitext(mw.ustring.format(
			'[[Fájl:%s|%dx%dpx|%s|link=%s%s]]',
			mark,
			marksize,
			marksize,
			label,
			link,
			alt and ('|alt=' .. alt) or ''
		))
	end
	return builder
end

local function markLabelDiv(label, label_size, label_width, position, background, x, marksize)
	if position == 'balra' then position = 'left'
	elseif position == 'jobbra' then position = 'right'
	elseif position == 'fel' or position == 'fent' then position = 'top'
	elseif position == 'le' or position == 'lent' then position = 'bottom' end
	local builder = mw.html.create('div')
		:addClass('label')
		:css('font-size:', label_size .. '%')
	local distance = math.floor(marksize / 2 + 1.5)
	if position == 'top' then -- specified top
		builder:addClass('label-top')
		builder:cssText('bottom:' .. distance .. 'px; left:' .. (-label_width / 2) .. 'em; width:' .. label_width .. 'em')
	elseif position == 'bottom' then -- specified bottom
		builder:addClass('label-bottom')
		builder:cssText('top:' .. distance .. 'px; left:' .. (-label_width / 2) .. 'em; width:' .. label_width .. 'em')
	elseif position == 'left' or (tonumber(x) > 70 and position ~= 'right') then -- specified left or autodetected to left
		builder:addClass('label-left')
		builder:cssText('right:' .. distance .. 'px; min-width:' .. label_width .. 'em')
	else -- specified right or autodetected to right
		builder:addClass('label-right')
		builder:cssText('left:' .. distance .. 'px;')
	end
	builder = builder:tag('span')
		:wikitext(label)
	if background then
		builder:cssText('background-color:' .. background)
	end
	return builder:done()
end

local function getX(longitude, left, right)
	local width = (right - left) % 360
	if width == 0 then
		width = 360
	end
	local distanceFromLeft = (longitude - left) % 360
	--[[
	the distance needed past the map to the right equals distanceFromLeft - width. the distance needed past the map to 
	the left equals 360 - distanceFromLeft. to minimize page stretching, go whichever way is shorter
	--]]
	if distanceFromLeft - width / 2 >= 180 then
		distanceFromLeft = distanceFromLeft - 360
	end
	return 100 * distanceFromLeft / width
end

local function getY(latitude, top, bottom)
	return 100 * (top - latitude) / (top - bottom)
end

function p.mark(frame, args, map)
	if not args then
		args = getArgs(frame, {wrappers = 'Template:Location map~'})
	end
	if not map then
		map = p.getMapParams(args[1], frame)
	end
	local x, y, longitude, latitude
	longitude = decdeg(args.lon_deg or args['hosszúsági fok'], args.lon_min or args['hosszúsági ívperc'], 
		args.lon_sec or args['hosszúsági ívmásodperc'], args.lon_dir or args['hosszúság'], 
		args.long or args['hosszúság dec'], 'longitude')
	latitude = decdeg(args.lat_deg or args['szélességi fok'], args.lat_min or args['szélességi ívperc'], 
		args.lat_sec or args['szélességi ívmásodperc'], args.lat_dir or args['szélesség'], 
		args.lat or args['szélesség dec'], 'latitude')
	local builder = mw.html.create()
	if map('pole') ~= '' then
		x = 50 + 50 / (90 - math.abs(tonumber(map'top'))) * 
			(90 - tonumber(map'pole') / 90 * latitude) * math.sin(math.pi / 180 * longitude)
	elseif map('x') ~= '' then
		x = tonumber(mw.ext.ParserFunctions.expr(map('x', { latitude, longitude })))
	else
		x = tonumber(getX(longitude, map('left'), map('right')))
	end
	if map('pole') ~= '' then
		y = 50 + 50 / (tonumber(map'pole') - tonumber(map'top')) * 
			(90 - tonumber(map'pole') / 90 * latitude) * math.cos(math.pi / 180 * longitude)
	elseif map('y') ~= '' then
		y = tonumber(mw.ext.ParserFunctions.expr(map('y', { latitude, longitude })))
	else
		y = tonumber(getY(latitude, map('top'), map('bottom')))
	end
	if (x < 0 or x > 100 or y < 0 or y > 100) and not args.outside then
		mw.log('Mark placed outside map boundaries without outside flag set. x = ' .. x .. ', y = ' .. y)
		local parent = frame:getParent()
		if parent then
			mw.log('Parent is ' .. parent:getTitle())
		end
		mw.logObject(args, 'args')
		builder:wikitext('[[Kategória:Hibásan használt pozícióstérkép-sablonok|Outside flag not set with mark outside map]]')
	end
	local mark = args.mark or args.jel or map('mark')
	if mark == '' then
		mark = 'Red pog.svg'
	end
	local marksize = tonumber(args.marksize or args['jel mérete']) or tonumber(map('marksize')) or 8
	local imageDiv = markImageDiv(mark, marksize, args.label or args.felirat or mw.title.getCurrentTitle().text, args.link or '', 
		args.alt, args[2])
	local labelDiv
	if (args.label or args.felirat) and (args.position or args['felirat pozíciója']) ~= 'none' then
		labelDiv = markLabelDiv(args.label or args.felirat, args.label_size or args['felirat mérete'] or 90, 
			args.label_width or 16, args.position or args['felirat pozíciója'], args.background or args['háttér'], x, 
			marksize)
	end
	builder:wikitext(getStyle())
	return builder:node(markOuterDiv(x, y, imageDiv, labelDiv, args.position or args['felirat pozíciója'])):newline()
end

function p.main(frame, args, map)
	if not args then
		args = getArgs(frame, {wrappers = 'Template:Location map', valueFunc = valueFunc})
	end
	if not args[1] then
		args[1] = 'World'
	end
	if not map then
		map = p.getMapParams(args[1], frame)
	end
	return p.top(frame, args, map) .. tostring( p.mark(frame, args, map) ) .. p.bottom(frame, args, map)
end

local function manyMakeArgs(fullArgs, n)
	if n == 1 then
		return {
			fullArgs[1],
			lat = fullArgs.lat1 or fullArgs['szélesség dec1'] or fullArgs.lat or fullArgs['szélesség dec'],
			long = fullArgs.long1 or fullArgs['hosszúság dec1'] or fullArgs.long or fullArgs['hosszúság dec'],
			lat_deg = fullArgs.lat1_deg or fullArgs['szélességi fok1'] or fullArgs.lat_deg or fullArgs['szélességi fok'],
			lat_min = fullArgs.lat1_min or fullArgs['szélességi ívperc1'] or fullArgs.lat_min or fullArgs['szélességi ívperc'],
			lat_sec = fullArgs.lat1_sec or fullArgs['szélességi ívmásodperc1'] or fullArgs.lat_sec or fullArgs['szélességi ívmásodperc'],
			lat_dir = fullArgs.lat1_dir or fullArgs['szélesség1'] or fullArgs.lat_dir or fullArgs['szélesség'] or 'N',
			lon_deg = fullArgs.lon1_deg or fullArgs['hosszúsági fok1'] or fullArgs.lon_deg or fullArgs['hosszúsági fok'],
			lon_min = fullArgs.lon1_min or fullArgs['hosszúsági ívperc1'] or fullArgs.lon_min or fullArgs['hosszúsági ívperc'],
			lon_sec = fullArgs.lon1_sec or fullArgs['hosszúsági ívmásodperc1'] or fullArgs.lon_sec or fullArgs['hosszúsági ívmásodperc'],
			lon_dir = fullArgs.lon1_dir or fullArgs['hosszúság1'] or fullArgs.lon_dir or fullArgs['hosszúság'] or 'E',
			mark = fullArgs.mark1 or fullArgs.jel1 or fullArgs.mark or fullArgs.jel,
			marksize = fullArgs.mark1size or fullArgs['jel mérete1'] or fullArgs.marksize or fullArgs['jel mérete'],
			link = fullArgs.link1 or fullArgs.link,
			label = fullArgs.label1 or fullArgs.felirat1 or fullArgs.label or fullArgs.felirat,
			label_size = fullArgs.label1_size or fullArgs['felirat mérete1'] or fullArgs.label_size or fullArgs['felirat mérete'],
			position = fullArgs.position1 or fullArgs.pos1 or fullArgs['felirat pozíciója1'] or fullArgs.position or fullArgs.pos or 
				fullArgs['felirat pozíciója'],
			background = fullArgs.background1 or fullArgs.bg1 or fullArgs['háttér1'] or fullArgs.background or fullArgs.bg or 
				fullArgs['háttér']
		}
	else
		return {
			fullArgs[1],
			lat = fullArgs['lat' .. n] or fullArgs['szélesség dec' .. n],
			long = fullArgs['long' .. n] or fullArgs['hosszúság dec' .. n],
			lat_deg = fullArgs['lat' .. n .. '_deg'] or fullArgs['szélességi fok' .. n],
			lat_min = fullArgs['lat' .. n .. '_min'] or fullArgs['szélességi ívperc' .. n],
			lat_sec = fullArgs['lat' .. n .. '_sec'] or fullArgs['szélességi ívmásodperc' .. n],
			lat_dir = fullArgs['lat' .. n .. '_dir'] or fullArgs['szélesség' .. n] or fullArgs['szélesség'] or 'N',
			lon_deg = fullArgs['lon' .. n .. '_deg'] or fullArgs['hosszúsági fok' .. n],
			lon_min = fullArgs['lon' .. n .. '_min'] or fullArgs['hosszúsági ívperc' .. n],
			lon_sec = fullArgs['lon' .. n .. '_sec'] or fullArgs['hosszúsági ívmásodperc' .. n],
			lon_dir = fullArgs['lon' .. n .. '_dir'] or fullArgs['hosszúság' .. n] or fullArgs['hosszúság'] or 'E',
			outside = fullArgs['outside' .. n],
			mark = fullArgs['mark' .. n] or fullArgs['jel' .. n] or fullArgs['jel'],
			marksize = fullArgs['mark' .. n .. 'size'] or fullArgs['jel mérete' .. n] or fullArgs['jel mérete'],
			link = fullArgs['link' .. n],
			label = fullArgs['label' .. n] or fullArgs['felirat' .. n] or fullArgs['felirat'],
			label_size = fullArgs['label' .. n .. '_size'] or fullArgs['felirat mérete' .. n] or fullArgs['felirat mérete'],
			position = fullArgs['position' .. n] or fullArgs['pos' .. n] or fullArgs['felirat pozíciója' .. n],
			background = fullArgs['background' .. n] or fullArgs['bg' .. n] or fullArgs['háttér' .. n] or fullArgs['háttér']
		}
	end
end

function p.many(frame, args, map)
	if not args then
		args = getArgs(frame, {wrappers = 'Sablon:Pozíciós térkép', valueFunc = valueFunc})
	end
	if not args[1] then
		args[1] = 'Föld'
	end
	if not map then
		map = p.getMapParams(args[1], frame)
	end
	local marks = {}
	for k, v in pairs(args) do  --TODO Change to uargs once we have that
		if v then
			if string.sub(k, -4) == '_deg' then
				k = string.sub(k, 1, -5)
			end
			if string.sub(k, 1, 3) == 'lat' then
				k = tonumber(string.sub(k, 4))
				if k then
					table.insert(marks, k)
				end
			elseif mw.ustring.sub(k, 1, 14) == 'szélességi fok' then
				k = tonumber(mw.ustring.sub(k, 15))
				if k then
					table.insert(marks, k)
				end
			elseif mw.ustring.sub(k, 1, 13) == 'szélesség dec' then
				k = tonumber(mw.ustring.sub(k, 14))
				if k then
					table.insert(marks, k)
				end
			end
		end
	end
	table.sort(marks)
	if marks[1] ~= 1 and (args.lat or args['szélesség dec'] or args.lat_deg or args['szélességi fok']) then
		table.insert(marks, 1, 1)
	end
	local body = ''
	for _, v in ipairs(marks) do
		-- don't try to consolidate this into the above loop. ordering of elements from pairs() is unspecified
		body = body .. tostring( p.mark(frame, manyMakeArgs(args, v), map) )
	end
	args.label = nil -- there is no global label
	return p.top(frame, args, map) .. body .. p.bottom(frame, args, map) .. 
		((args['koordináta a cím alatt'] or args['címsor']) and p.coorTitle(frame, args) or '')
end

function p.combine(frame, args, map)
	if not args then
		args = getArgs(frame, {frameOnly = true})
	end
	local containerArgs = mw.loadData(frame.args[1]).containerArgs
	if not map then
		map = p.getMapParams(containerArgs[1], frame)
	end
	local retval = {}
	for _,modname in ipairs(frame.args) do
		for _,mark in ipairs(mw.loadData(modname).marks) do
			local markArgs = {}
			for k,v in pairs(mark) do
				markArgs[k] = v
			end
			markArgs[1] = containerArgs[1]
			retval[#retval + 1] = tostring(p.mark(frame, markArgs, map))
		end
	end
	return p.top(frame, containerArgs, map) .. table.concat(retval) .. p.bottom(frame, containerArgs, map)
end

function p.coorTitle(frame, args)
	if args.lat or args['szélesség dec'] then
		return require('Modul:Coordinate').coord(frame, {
			args.lat or args['szélesség dec'], 
			args.lon or args['hosszúság dec'], 
			args.meta, 
			display = 'title', 
			format = 'dms',
			with_pfunc = true
		})
	end
	if args.lat_deg or args['szélességi fok'] then
		return require('Modul:Infobox').coord(frame, {
			args.lat_deg or args['szélességi fok'], 
			args.lat_min or args['szélességi ívperc'], 
			args.lat_sec or args['szélességi ívmásodperc'], 
			args.lat_dir or args['szélesség'], 
			args.lon_deg or args['hosszúsági fok'], 
			args.lon_min or args['hosszúsági ívperc'], 
			args.lon_sec or args['hosszúsági ívmásodperc'], 
			args.lon_dir or args['hosszúság'], 
			args.meta, 
			display = 'title'
		})
	end
	return nil
end

return p