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

Pozíciós térkép[mi ez?] • [dokumentáció: mutat, szerkeszt] • [tesztek: sikeres: 1, sikertelen: 0, kihagyva: 0 (részletek)]

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('strict')
local p = {}
local getArgs = require('Modul:Arguments').getArgs
local isCssAdded = false
local hasErrors = 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
			if direction == 'latitude' then
				if retval < -90 or retval > 90 then
					error('The value "' .. decimal .. '" provided for ' .. direction .. ' is not valid', 2)
				end
			elseif direction == 'longitude' then
				if retval < -180 or retval >= 360 then
					error('The value "' .. decimal .. '" provided for ' .. direction .. ' is not valid', 2)
				end
			else
				error('Invalid direction', 2)
			end
			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
	if require('Modul:Coordinate').validateDms(degrees, minutes, seconds, hemisphere, direction) then
		hasErrors = true
	end
	decimal = decimal + (tonumber(minutes) or 0)/60 + (tonumber(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

--distance logic adapted from https://wiki.openstreetmap.org/wiki/Zoom_levels#Distance_per_pixel_math
local function getHeight(map, latitude, longitude, width)
	local bottom = tonumber(map('bottom'))
	local top = tonumber(map('top'))
	local left = tonumber(map('left'))
	local right = tonumber(map('right'))
	if not bottom or not top or not left or not right then return width end
	if right < 0 and left > 0 then
		right = right + 360
	end
	local c = math.cos(math.rad(latitude)) -- variation of height in degrees
	local deg_len = 111120 -- length of a degree in many at Equator and on meridians
	local x_distance = (right - left) * deg_len * c
	local y_distance = (top - bottom) * deg_len
	local height = math.ceil(width * y_distance / x_distance)
	return height
end

-- this function returns the maximum zoom that contains the whole map
-- calculations are based on data from https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames
local function getZoomAndCenter(map, latitude, longitude, width, height)
	local bottom = tonumber(map('bottom'))
	local top = tonumber(map('top'))
	local left = tonumber(map('left'))
	local right = tonumber(map('right'))
	if not bottom or not top or not left or not right then 
		return 0, latitude, longitude --zoom 0 is the whole world
	end
	if right < 0 and left > 0 then
		right = right + 360
	end
	local tile_width = 256 -- OSM constant
	local c = math.cos(math.rad(latitude)) -- variation of height in degrees

	local x_tiles = 1.0 * width / tile_width
	local y_tiles = 1.0 * height / tile_width
	local x_zoom = math.floor(math.log(x_tiles * 360 / (right - left)) / math.log(2))
	local y_zoom = math.floor(math.log(y_tiles * 360 * c / (top - bottom)) / math.log(2))
	local x = (right + left) / 2
	local y = (top + bottom) / 2
	if x > 180 then
		x = x - 360
	end
	return math.min(x_zoom, y_zoom), y, x
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'))

	local errorDiv = hasErrors and '<div><strong class="error">Hibásan használt pozíciós térkép</strong></div>' or ''
	retval = retval .. getStyle() .. tostring(captionDiv) .. errorDiv .. '\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 args.lat and args.long and
		not args.lat_deg and not args.lon_deg and not args.lat_min and not args.lon_min and
		not args.lat_sec and not args.lon_sec and not args.lat_dir and not args.lon_dir or
		not args.lat and not args.long and
		args.lat_deg and args.lon_deg and not args.lat_min and not args.lon_min and not args.lat_sec and not args.lon_sec or
		not args.lat and not args.long and
		args.lat_deg and args.lon_deg and args.lat_min and args.lon_min and not args.lat_sec and not args.lon_sec or
		not args.lat and not args.long and
		args.lat_deg and args.lon_deg and args.lat_min and args.lon_min and args.lat_sec and args.lon_sec then
		-- Accept valid values
	else
		hasErrors = true
	end
	local lat_dir, lon_dir = mw.ustring.upper(args.lat_dir or 'N'), mw.ustring.upper(args.lon_dir or 'E')
	if (lat_dir == 'N' or lat_dir == 'S' or lat_dir == 'É' or lat_dir == 'D') and 
		(lon_dir == 'E' or lon_dir == 'W' or lon_dir == 'K' or lon_dir == 'NY') then 
		-- Accept valid values
	else
		hasErrors = true
	end
	if hasErrors then
		builder:wikitext('[[Kategória:Hibás koordináták]]')
	end
	if	args.lon_deg and not args.lon_min and not args.lon_sec and not args.lon_dir and
		args.lat_deg and not args.lat_min and not args.lat_sec and not args.lat_dir then
		-- Accept coordinates if only degrees are given
	elseif args.lon_deg and tonumber(args.lon_deg) < 0 or 
		args.lon_min and tonumber(args.lon_min) < 0 or 
		args.lon_sec and tonumber(args.lon_sec) < 0 or 
		args.lat_deg and tonumber(args.lat_deg) < 0 or 
		args.lat_min and tonumber(args.lat_min) < 0 or 
		args.lat_sec and tonumber(args.lat_sec) < 0 or 
		args['hosszúsági fok'] and tonumber(args['hosszúsági fok']) < 0 or 
		args['hosszúsági ívperc'] and tonumber(args['hosszúsági ívperc']) < 0 or 
		args['hosszúsági ívmásodperc'] and tonumber(args['hosszúsági ívmásodperc']) < 0 or 
		args['szélességi fok'] and tonumber(args['szélességi fok']) < 0 or 
		args['szélességi ívperc'] and tonumber(args['szélességi ívperc']) < 0 or 
		args['szélességi ívmásodperc'] and tonumber(args['szélességi ívmásodperc']) < 0 then
		builder:wikitext('[[Kategória:Hibásan használt pozícióstérkép-sablonok]]')
		hasErrors = true
	end
	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]]')
		hasErrors = true
	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.infoboxMapframe(frame)
	local args = getArgs(frame, { wrappers='Sablon:Infobox/Térkép' })
	if args.mapframe == 'no' or args.map == '-' then
		return nil
	end
	args.zoom = args.zoom or args[1]
	args.marker = args.marker or args['jelölő']
	args.coord = args.coord or args.koord
	if args.mapframe == 'country' then
		local itemId = mw.wikibase.getEntityIdForCurrentPage() or args.entityId
		local cst = mw.wikibase.getBestStatements(itemId, 'P625')
		if not args.coord and not next(cst) then
			return nil
		end
		local mapArgs = {}
		local function getMapArgs()
			local countryStatements = mw.wikibase.getBestStatements(itemId, 'P17')
			if #countryStatements ~= 1 then
				return
			end
			--[[
			local countryId = countryStatements[1].mainsnak.datavalue.value.id
			local mapData = {}
			mapData.top = mw.wikibase.getBestStatements(countryId, 'P1332')[1].mainsnak.datavalue.value.latitude
			mapData.bottom = mw.wikibase.getBestStatements(countryId, 'P1333')[1].mainsnak.datavalue.value.latitude
			mapData.right = mw.wikibase.getBestStatements(countryId, 'P1334')[1].mainsnak.datavalue.value.longitude
			mapData.left = mw.wikibase.getBestStatements(countryId, 'P1335')[1].mainsnak.datavalue.value.longitude
			local function map(name)
				return mapData[name]
			end
			--]]
			local map = p.getMapParams(args.map or mw.wikibase.getLabel(countryStatements[1].mainsnak.datavalue.value.id), frame)
			local coord = cst[1].mainsnak.datavalue.value
			mapArgs['frame-height'] = getHeight(map, coord.latitude, coord.longitude, 250)
			local zoom, clat, clon = getZoomAndCenter(map, coord.latitude, coord.longitude, 250, mapArgs['frame-height'])
			mapArgs.zoom = zoom
			mapArgs['frame-coord'] = ('%s_%s_%s_%s'):format(
				tostring(math.abs(clat)),
				clat < 0 and 'S' or 'N',
				tostring(math.abs(clon)),
				clon < 0 and 'W' or 'E')
		end
		getMapArgs()
		args.zoom = args.zoom or mapArgs.zoom
		args['frame-coord'] = args['frame-coord'] or mapArgs['frame-coord']
		args['frame-height'] = args['frame-height'] or mapArgs['frame-height']
	end
	if args['frame-height'] then
		local frameHeight = tonumber(args['frame-height'])
		if frameHeight < 200 then  -- default value in [[Modul:Infobox mapframe]]
			args['frame-height'] = nil
		end
		if frameHeight > 600 then  -- experimental max value limit
			args['frame-height'] = 600
		end
	end
	return frame:preprocess(require('Modul:Infobox mapframe')._main(args))
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'],
			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'],
			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'],
			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'],
			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)
	local tracking = ''
	if not args then
		args = getArgs(frame, { wrappers = 'Sablon:Pozíciós térkép', valueFunc = valueFunc })
		tracking = require('Modul:Check for unknown parameters')._check({
			['unknown']='[[Kategória:Pozíciós térkép sablont ismeretlen paraméterekkel használó lapok|_VALUE_ ]]',
			['preview']='[[Sablon:Pozíciós térkép]] sablont ismeretlen "_VALUE_" paraméterrel használja',
			['showblankpositional']='true',
			'width', 'caption', 'border', 'float', 'AlternativeMap', 'relief', 'places', 'alt', 'maplink', 'overlay_image',
			'1', regexp1='lat[%d]*', regexp2='long[%d]*',
			regexp3='lat[%d]*_deg', regexp4='lat[%d]*_min', regexp5='lat[%d]*_sec', regexp6='lat[%d]*_dir',
			regexp7='lon[%d]*_deg', regexp8='lon[%d]*_min', regexp9='lon[%d]*_sec', regexp10='lon[%d]*_dir',
			regexp11='mark[%d]*', regexp12='mark[%d]*size', regexp13='link[%d]*', regexp14='label[%d]*', regexp15='label[%d]*_size',
			regexp16='position[%d]*', regexp17='pos[%d]*', regexp18='background[%d]*', regexp19='bg[%d]*',
			'méret', 'képaláírás', 'keret', 'igazítás', 'alternatív térkép', 'térképtípus',
			regexp20='szélesség dec[%d]*', regexp21='hosszúság dec[%d]*',
			regexp22='szélességi fok[%d]*', regexp23='szélességi ívperc[%d]*', regexp24='szélességi ívmásodperc[%d]*', regexp25='szélesség[%d]*',
			regexp26='hosszúsági fok[%d]*', regexp27='hosszúsági ívperc[%d]*', regexp28='hosszúsági ívmásodperc[%d]*', regexp29='hosszúság[%d]*',
			regexp30='jel[%d]*', regexp31='jel mérete[%d]*', regexp32='felirat[%d]*', regexp33='felirat mérete[%d]*',
			regexp34='felirat pozíciója[%d]*', regexp35='háttér[%d]*', regexp36='outside[%d]*',
			'koordináta a cím alatt', 'címsor', 'meta'
		}, frame:getParent().args)
	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 '') .. tracking
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.long 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