UWAGA
Strona jest ponownie oddana do uzytku po zabiegach konfiguracyjnych. Jeśli zobaczą Państwo na niej jakieś błedy techniczne, prosimy o ich zgłoszenie.

Większość artykułów w portalu to nasze własne teksty z kluczowych dziedzin związanych z naszą misją. Spora część materiałów pochodzi też z polskiej wersji Wikipedii, gdzie były odrzucone ze względu na politykę redaktorów (przeczytaj o krytyce Wikipedii). Są też i takie, które zostały przeniesione na nasze strony, gdyż stanowią istotne uzupełnienie merytorycznej treści naszego serwisu. Wszystkie artykuły podlegają edycji przez naszych Użytkowników, dlatego ich wersje mogą się różnić od prezentowanych na innych witrynach.

Moduł:Mapa

Z Wedapedia
Przejdź do nawigacji Przejdź do wyszukiwania

Dokumentacja dla tego modułu może zostać utworzona pod nazwą Moduł:Mapa/opis

local function getMapParams(map, frame)
	mw.logObject(map, "map")
	if not map or (#map == 0) then
		mw.log("Brak nazwy mapy lokalizacyjnej")
	end
	local moduleprefix = "Module:Mapa/dane/"
	if map then
		local moduletitle = mw.title.new(map)
		if not moduletitle or (moduletitle.namespace ~= 828) then
			moduletitle = mw.title.new(moduleprefix..map)
		end
		if not moduletitle then
			mw.log("„"..map.."” nie jest prawidłową nazwą definicji mapy lokalizacyjnej")
		elseif moduletitle.exists then
			local status, mapData = pcall(mw.loadData, moduletitle.fullText)
			if status then
				return function(name, variant)
					if name == nil then
						--mw.logObject(moduletitle.fullText, "GET module title")
						return moduletitle.fullText
					end
					
					local variants = variant and mw.text.split(variant, "%s*#%s*") or {}
					--mw.logObject(variants, "GET map variants")
					
					if name == true then
						for _, v in ipairs(variants) do
							--mw.logObject(mapData[v], "GET map variant")
							if type(mapData[v]) == "table" then
								return v
							end
						end
						
						return 1
					end
					
					for _, v in ipairs(variants) do
						if mapData[v] and mapData[v][name] ~= nil then
							--mw.logObject({variant=v, name=name, result=mapData[v][name] }, "GET")
							return mapData[v][name]
						end
					end
					
					if mapData[1][name] ~= nil then
						--mw.logObject({name=name, result=mapData[1][name] }, "GET")
						return mapData[1][name]
					end
					
					--mw.logObject({name=name}, "GET")
					return ""
				end
			end
		else
			mw.log("Nie mogę znaleźć definicji podanej mapy lokalizacyjnej. Nie istnieje „"..moduleprefix..map.."”.")
		end
	end
	
	-- default fallback
	local mapData = mw.loadData(moduleprefix.."brak")
	return function(name, variant)
		if name == nil then
			return false
		elseif name == false then
			return (map and (#map > 0)) and map or false
		elseif name == true then
			return 1
		elseif mapData[1][name] == nil then
			return ""
		elseif variant and mapData[variant] then
			return mapData[variant][name] or mapData[1][name]
		else
			return mapData[1][name]
		end
	end
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

local function formatCoordinates(parameters)
	if not parameters.coordinates then
		return false
	end
	
	local placement = parameters.placement
	if not placement then
		placement = ((parameters.linkFlag == false) or (mw.title.getCurrentTitle().namespace ~= 0)) and "w tekście" or "w tekście i na górze"
	end
	
	return require("Moduł:Współrzędne")["współrzędne"]({
		parameters.coordinates,
		parameters.geohack,
		["umieść"] = placement,
		["dokładność"] = parameters.precision,
		["linkuj"] = parameters.linkFlag == false and "nie" or "tak",
		symbol = parameters.symbol,
	})
end

local function loadMap(frame, map, variant)
	local getMapParam = getMapParams(map, frame)
	return function(param)
		return getMapParam(param, variant)
	end
end

local function decodePoints(pointsData)
	if pointsData and (#pointsData > 0) then
		local data = mw.text.jsonDecode("["..pointsData.."{\"dummy\":false}]")
		table.remove(data) -- remove last dummy
		return data
	end
end

local function estimateTextWidth(wikicode, fontSize)
	local text = mw.ustring.gsub(wikicode, "%[%[[^\n|%]%[]+|([^\n|%]%[]+)%]%]", "%1")
	text = mw.ustring.gsub(text, "%[%[([^\n|%]%[]+)%]%]", "%1")
	text = mw.ustring.gsub(text, "<[^>]*>", "")
	return mw.ustring.len(text) * fontSize
end

local function positionDescriptionCode(r)
	local d = math.abs(r - 50)
	local c = false
	if d > 40 then
		c = '3'
	elseif d > 20 then
		c = '2'
	elseif d > 10 then
		c = '1'
	else
		c = '0'
	end
	
	return r > 50 and c..'0' or '0'..c
end

local function relativePositionDescriptionCode(center, neighbour)
	local dx = neighbour.x - center.x
	local dy = neighbour.y - center.y
	local r = '0' if dx > 0 then r = '1' end
	local l = '0' if dx < 0 then l = '1' end
	local t = '0' if dy < 0 then t = '1' end
	local b = '0' if dy > 0 then b = '1' end
	local adx = math.abs(dx)
	local ady = math.abs(dy)
	if adx > (10 * ady) then
		t = '0'
		b = '0'
	elseif ady > (10 * adx) then
		r = '0'
		l = '0'
	end
	
	return r..l..t..b
end

function plainText(content)
	if content then
		local c
		content, c = mw.ustring.gsub(content, "%[%[%s*[Pp]lik%s*:.-%]%]", "")
		content, c = mw.ustring.gsub(content, "%[%[%s*[Ff]ile%s*:.-%]%]", "")
		content, c = mw.ustring.gsub(content, "%[%[%s*[Gg]rafika%s*:.-%]%]", "")
		content, c = mw.ustring.gsub(content, "%[%[%s*[Ii]mage%s*:.-%]%]", "")
		content, c = mw.ustring.gsub(content, "%[%[[^|%]]+|(.-)%]%]", "%1")
		content, c = mw.ustring.gsub(content, "%[%[(.-)%]%]", "%1")
		content, c = mw.ustring.gsub(content, "%[.- (.-)%]", "%1")
		content, c = string.gsub(content, "</?[Ss][Pp][Aa][Nn][^>]*>", "")
		content, c = string.gsub(content, "</?[Bb][Rr][^>]*>", "")
		content, c = string.gsub(content, "</?[AaBbIiPpQqSsUu][^>]*>", "")
		content, c = string.gsub(content, "[ \n\r\t]+", " ")
		content = mw.text.unstrip(content)
		content = mw.text.nowiki(content)
		return mw.text.trim(content)
	end
end

local function drawMap(builder, get, width, fontSize, data, infoboxCoordinates, customAlt)
	local reliefImage = mw.text.trim(get("mapa"))
	local reliefTitle = mw.title.new("Plik:"..reliefImage)
	if not reliefTitle.file.exists then
		reliefTitle = mw.title.new("Plik:Image of nothing.svg")
	end
	local file = reliefTitle.file
	local height = file.height *  width / file.width

	-- przeliczanie punktów na mapie
	local inside = {}
	local outside = {}
	local errors = {}
	local hoverPoints = false
	local alt = mw.loadData("Moduł:Mapa/alt")
	if data and (#data > 0) then
		local x_func = mw.text.trim(get("x"))
		local y_func = mw.text.trim(get("y"))
		local top = get("top")
		local left = get("left")
		local bottom = get("bottom")
		local right = get("right")
		if #x_func == 0 then
			x_func = false
		end
		if #y_func == 0 then
			y_func = false
		end
		for i, v in ipairs(data) do
			if v.latitude and v.longitude and v.mark and v.size then
				-- przeliczanie współrzędnych na pozycje rysowania
				if x_func then
					local expx = mw.ustring.gsub(mw.ustring.gsub(x_func, "{{{szerokość}}}", v.latitude), "{{{długość}}}", v.longitude)
					v.x = tonumber(mw.ext.ParserFunctions.expr(expx))
				else
					v.x = getX(v.longitude, left, right)
				end
				if y_func then
					local expy = mw.ustring.gsub(mw.ustring.gsub(y_func, "{{{szerokość}}}", v.latitude), "{{{długość}}}", v.longitude)
					v.y = tonumber(mw.ext.ParserFunctions.expr(expy))
				else
					v.y = getY(v.latitude, top, bottom)
				end
				
				v.rx = width * v.x / 100
				v.ry = height * v.y / 100
				v.posDesc = alt.relativeDescription[positionDescriptionCode(v.x)..positionDescriptionCode(100-v.y)]
				if not v.alt then
					v.autoAlt = alt.pointDescription[v.mark] or alt.pointDescription[false]
					local desc = plainText(v.description)
					if desc and #desc > 0 then
						v.autoAlt = v.autoAlt..mw.ustring.format(alt.describedAs, desc)
					end
				end
				
				mw.logObject(v)
				
				if (v.x < 0) or (v.x > 100) or (v.y < 0) or (v.y > 100) then
					table.insert(outside, v)
				else
					table.insert(inside, v)
					if not hoverPoints and (v.position == "hover") and v.description then
						hoverPoints = true
					end
				end
			elseif v.error then
				table.insert(errors, v)
			else
				-- TODO illegal data or "dummy: false"
				mw.logObject(v, "illegal at "..tostring(i))
			end
		end
	end
	
	-- automatyczne pozycjonowanie dwóch punktów
	if (#inside == 2) and inside[1].description and inside[2].description and not inside[1].position and not inside[2].position then
		local y1 = inside[1].ry
		local y2 = inside[2].ry
		if (math.abs(y1 - y2) < 16) and (y1 > 8) and (y2 > 8) and ((height - y1) > 8) and ((height - y2) > 8) and (math.abs(inside[1].rx - inside[2].rx) < 80) then
			inside[1].position = y2 > y1 and "top" or "bottom"
			inside[2].position = y1 > y2 and "top" or "bottom"
		end
	end
	
	local altInfo = customAlt
	if not altInfo then
		altInfo = get("alt") or ""
		if #altInfo == 0 then
			local g = get("dopełniacz")
			if g then
				altInfo = "Mapa konturowa "..g
			end
		end
	
		if (#altInfo > 0) and (#inside > 0) then
			local extAlt = inside[1].posDesc..alt.thereIs..(inside[1].alt or inside[1].autoAlt)
			if #inside == 1 then
				altInfo = altInfo..", "..extAlt
			elseif #inside == 2 then
				local extAlt2 = alt.combine2..inside[2].posDesc..alt.thereIs..(inside[2].alt or inside[2].autoAlt)
				if inside[1].posDesc == inside[2].posDesc then
					local code = relativePositionDescriptionCode(inside[1], inside[2])
					extAlt2 = (alt.relativeDescription2[code] or alt.relativeDescription2[false])..alt.thereIs2..(inside[2].alt or inside[2].autoAlt)
				end
				
				altInfo = altInfo..", "..extAlt..", "..extAlt2
			elseif (#inside > 1) and infoboxCoordinates then
				altInfo = altInfo..", "..extAlt
			end
		end
	end

	-- tło mapy
	local relief = builder:tag("div")
	relief:css({ position = "relative", border = "0 solid #aaa", padding = "0", width = tostring(width).."px" })
	relief:wikitext("[[Plik:", reliefImage, "|", width, "px|class=notpageimage|link=")
	if #altInfo > 0 then
		relief:wikitext("|alt=", altInfo)
	end
	if not hoverPoints then
		local reliefInfo = get("dopełniacz")
		if reliefInfo then
			relief:wikitext("|Mapa lokalizacyjna ", reliefInfo)
		end
	end

	relief:wikitext("]]")
	
	function showError(category, ...)
		local catLink = ""
		local known = {
			["brak mapy"] = { "'''Brak mapy:''' ''%s''", "[[Kategoria:Szablony lokalizacyjne - brak mapy]]", },
			["brak kodu mapy"] = { "'''Brak kodu mapy'''", "[[Kategoria:Szablony lokalizacyjne - brak kodu mapy]]", },
			["współrzędne spoza mapy"] = { "'''Współrzędne spoza mapy:''' ''%f %f''", "[[Kategoria:Szablony lokalizacyjne - współrzędne spoza mapy]]", },
			["brak współrzędnych"] = { "'''Brak współrzędnych'''", "[[Kategoria:Szablony lokalizacyjne – brak współrzędnych]]", },
			[true] = { "%s", false },
			[false] = { "'''''Inny błąd'''''", false, },
		}
		local k = known[category] or known[false]
		local message = mw.ustring.format(k[1], ...)
		if k[2] and (mw.title.getCurrentTitle().namespace == 0) then
			message = message..k[2]
		end
		local absolute = relief:tag("div")
			:css( { position = "absolute", ["z-index"] = 200, top = "50%", left = "50%", height = 0, width = 0, margin = 0, padding = 0, } )
		local msg = absolute:tag("div")
			:css( { ["font-size"] = "90%", ["line-height"] = "110%", position = "relative", width = "16em", ["z-index"] = 202, top = "-0.5em", left = "-8em", float = "center", ["text-align"] = "center", background = "white", color = "red", } )
			:wikitext(message)
	end
	
	-- brak mapy
	if not get() then
		local map = get(false)
		showError(map and "brak mapy" or "brak kodu mapy", map)
		if (#inside == 1) and (#outside == 0) then
			local v = inside[1]
			if (v.longitude == 0) and (v.latitude == 0) then
				--mw.log("dummy (0 0) bez mapy nie jest rysowany")
				return
			end
		end
	end
	
	-- błędy
	if (#inside == 0) and (#outside == 0) then
		showError("brak współrzędnych")
	end
	
	for i, v in ipairs(outside) do
		showError("współrzędne spoza mapy", v.latitude, v.longitude)
	end
	
	for i, v in ipairs(errors) do
		showError(true, v.error or "?")
	end
	
	-- punkty na mapie
	for i, v in ipairs(inside) do
		local hsize = tostring(v.size/2).."px"
		local size = tostring(v.size).."px"
		local absolute = relief:tag("div")
			:attr("aria-hidden", "true")
			:css( { position = "absolute", ["z-index"] = 2, top = tostring(v.y).."%", left = tostring(v.x).."%", height = 0, width = 0, margin = 0, padding = 0, } )
		local file = absolute:tag("div")
			:css( { position = "relative", ["text-align"] = "center", left = "-"..hsize, top = "-"..hsize, width = size, ["font-size"] = size, ["line-height"] = size, } )
		file:wikitext("[[Plik:", v.mark, "|", v.size, "x", size, "|link=", v.link)
		if v.description then
			file:wikitext("|", v.description)
		end
		file:wikitext("]]")
		-- TODO description
		if v.description and (v.position ~= "hover") then
			
			function descriptionWidth(availableWidth)
				return availableWidth <= 0 and "auto" or (math.min(availableWidth, 120).."px")
			end
			
			local descw = "auto"
			local css = {}
			if v.position == "right" then
				descw = descriptionWidth(math.floor(width - v.rx - (v.size / 2) - 5))
				css = { top = "-0.5em", left = tostring((v.size / 2) + 2).."px", ["text-align"] = "left", float = "left" }
			elseif v.position == "left" then
				descw = descriptionWidth(math.floor(v.rx - (v.size / 2) - 5))
				css = { top = "-0.5em", right = tostring((v.size / 2) + 2).."px", ["text-align"] = "right", float = "right" }
			elseif v.position == "top" then
				descw = "10em"
				css = { bottom = tostring((v.size / 4) + 2).."px", left = "-5em", ["text-align"] = "center", float = "center" }
			elseif v.position == "bottom" then
				descw = "10em"
				css = { top = tostring((v.size / 4) + 2).."px", left = "-5em", ["text-align"] = "center", float = "center" }
			else -- auto
				local textWidth = estimateTextWidth(v.description, fontSize) * 0.6
				if (v.x < 50) or ((v.rx + textWidth + (v.size / 2) + 2) < width) then -- right
					descw = descriptionWidth(math.floor(width - v.rx - (v.size / 2) - 5))
					css = { top = "-0.5em", left = tostring((v.size / 2) + 2).."px", ["text-align"] = "left", float = "left" }
				elseif ((v.rx - (v.size / 2) - 2) > textWidth) or (v.x > 70) then -- left
					descw = descriptionWidth(math.floor(v.rx - (v.size / 2) - 5))
					css = { top = "-0.5em", right = tostring((v.size / 2) + 2).."px", ["text-align"] = "right", float = "right" }
				elseif (v.y > 50) then -- top
					descw = "10em"
					css = { bottom = tostring((v.size / 4) + 2).."px", left = "-5em", ["text-align"] = "center", float = "center" }
				else -- bottom
					descw = "10em"
					css = { top = tostring((v.size / 4) + 2).."px", left = "-5em", ["text-align"] = "center", float = "center" }
				end
			end

			local desc = absolute:tag("div")
				:css( { ["font-size"] = tostring(fontSize).."px", ["line-height"] = tostring(1.2*fontSize).."px", ["z-index"] = "90", ["position"] = "absolute", ["width"] = descw, } )
			desc:css(css)
			desc:tag("span")
				:css({ padding = "1px", ["text-shadow"] = "0 0 5px white;" })
				:wikitext(v.description)
		end
	end
end

local function makeTrackingLinks(get, group)
	local linkAlias = get("link alias")
	local mapVariant = get(true)
	if not linkAlias or (#linkAlias == 0) then
		return
	end
	
	local trackingLink = "Moduł:Mapa/linkujące/"..linkAlias.."/"..group
	_ = mw.title.new(trackingLink).id
	_ = mw.title.new(trackingLink.."/"..mapVariant).id
end

local function adjustPointParams(points, mapgeohack)
	for i, p in ipairs(points) do
		local link = p.link
		if link then
			if mapgeohack==false then
				p.link = ""
			elseif mapgeohack then
				p.link = link.."_"..mapgeohack
			elseif p.geohack then
				p.link = link.."_"..p.geohack
			end
		end
	end
end

local function tryGetMapFor(property)
	local id = mw.wikibase.getEntityIdForCurrentPage()
	if not id then
		return
	end
	
	local props = mw.wikibase.getBestStatements(id, property)
	if not props or (#props <= 0) then
		return
	end
	
	local maps = {}
	for i, v in ipairs(props) do
		if v.mainsnak and (v.mainsnak.snaktype == "value") and (v.mainsnak.datatype == "wikibase-item") then
			local name = mw.wikibase.getLabelByLang(v.mainsnak.datavalue.value.id, "pl")
			if name then
				table.insert(maps, name)
			end
		end
	end
	
	if #maps <= 0 then
		return
	end
	
	local result = table.concat(maps,'#')
	mw.logObject(result,"tryGetMapFor("..property..")")
	return result
end

local function isKartographerZoom(map, size)
	if not map then
		return false
	end
	
	if string.match(map,"^[1-9]$") or string.match(map, "^1[0-9]$") then
		return map
	end
	
	local w = tonumber(size)
	if w and (w > 0) then
		local d, k = string.match(map, "^([0-9]+) ?(k?)m$")
		local d = tonumber(d)
		if d and (d > 0) then
			if k == "k" then
				d = d * 1000
			end
			
			local z = (math.log(96000) + math.log(w) - math.log(d)) / math.log(2)
			local zoom = math.min(math.max(math.floor(z), 1),19)
			mw.logObject({w = w, d = d, z=z, zoom=zoom}, "zoom calc")
			return zoom
		end
	end

	return false
end

return {
	
	["Wartość"] = function(frame)
		local f = frame.args[1] and frame or frame:getParent()
		return getMapParams(f.args[1], frame)(f.args[2], f.args[3])
	end,
	
	["Infobox"] = function(frame)
		-- log wskazujący na początek wywołania funkcji
		mw.log("{{#invoke:Moduł:Mapa|Infobox}}")
		local args = require('Module:Arguments').getArgs(frame, {
			trim = true,
			removeBlanks = true,
			wrappers = "Szablon:Infobox mapa lokalizacyjna",
		})
		local defaultIcon = "[[Plik:Geographylogo.svg|20px|alt=Ziemia|link=Ziemia]]"
		local map = args["mapa"]
			or tryGetMapFor("P17") -- państwo
			or tryGetMapFor("P706") -- region geograficzny
			or tryGetMapFor("P30") -- kontynent
			or "brak" -- poddaję się
		local variant = args["wariant"]
		local description = args["opis"]
		local mark = args["znak na mapie"] or "Red pog.svg"
		local markSize = tonumber(args["wielkość znaku"]) or 6
		local coordinates = args["współrzędne"]
		local markalt = args["alt znaku na mapie"]
		if not coordinates then
			mw.log("infobox może wyszukać współrzędne w wikidanych")
		else
			mw.log("współrzędne: "..coordinates)
		end
		local precision = args["dokładność"]
		local twoMaps = args["dwie mapy"]
		local category = args["kategoria"]
		local geohack = args["opcje geohack"]
		local position = args["pozycja opisu"]
		local points = args["punkty mapy"]
		mw.logObject({precision = precision, twoMaps = twoMaps, category = category, geohack = geohack, position = position, points = points}, "argumenty")
		if points and not string.match(points, "%s*{") then
			mw.log("załączone punkty do mapy są w nieodpowiednim formacie")
			return
		end
		if not points and not coordinates then
			if args["wikidane"] == "nie" then
				mw.log("brak punktów na mapę, a nie ma pozwolenia na Wikidane")
			elseif map ~= "pusta" then
				mw.log("brak punktów na mapę i współrzędnych, nadszedł czas na Wikidane")
				local display = true
				if (map ~= "osobna") and (map ~= "niedostępna") then
					display = "#coordinates"
				end
				local p = require("Moduł:Współrzędne").punkt({
					["opcje geohack"] = geohack,
					["znak"] = mark,
					["rozmiar znaku"] = markSize,
					["opis"] = description,
					["pozycja"] = position,
					["dokładność"] = precision,
					["alt"] = markalt,
					display = display,
					symbol = false,
				})
				if not p then
					mw.log("brak punktów na mapę nawet w Wikidanych")
				end
				
				points = p
			end
		end
		if not points and not coordinates and (mw.title.getCurrentTitle().fullText == frame:getParent():getTitle()) and (type(frame.getParent) == "function") then
			--TEST ANY ARG
			local any = false
			for k, v in pairs(frame:getParent().args) do
				any = true
				break
			end
			
			if not any then
				-- brak jakichkolwiek argumentów w szablonie to tryb demo
				points = require("Moduł:Współrzędne").punkt({ "0 0", display = true, symbol = false, })
				map = "brak"
			end
		end
		if not points and not coordinates then
			if not category or (mw.title.getCurrentTitle().namespace ~= 0) or (map == "żadna") or (map == "osobna") or (map == "pusta") or (map == "niedostępna") then
				return
			end

			return '|- style="display:none;"\n!colspan="2"|brak współrzędnych[[Kategoria:Szablony lokalizacyjne – brak współrzędnych – '..category..']]\n|-'
		end
		
		local result = {}
		local coords = false
		if (map == "żadna") or (map == "none") then
			_ = mw.title.new("Moduł:Mapa/linkujące/żadna").id
			-- TODO współrzędne, geohack, linkuj=tak, dokładność=kątowo, umieść=w tekście (i na górze)
			coords = formatCoordinates({
				coordinates = coordinates,
				geohack = geohack,
				linkFlag = true,
			})
		elseif map == "osobna" then
			_ = mw.title.new("Moduł:Mapa/linkujące/osobna").id
			-- TODO współrzędne, geohack, linkuj=tak, dokładność=kątowo, umieść=w tekście
			coords = formatCoordinates({
				coordinates = coordinates,
				geohack = geohack,
				linkFlag = true,
				placement = "w tekście",
			})
		elseif map == "pusta" then
			_ = mw.title.new("Moduł:Mapa/linkujące/pusta").id
			-- no map nor coordinates
		elseif map == "niedostępna" then
			_ = mw.title.new("Moduł:Mapa/linkujące/niedostępna").id
			-- TODO współrzędne, globe:none, linkuj=nie, dokładność=dziesiętnie, normalizacja=auto, ikona=
			coords = formatCoordinates({
				coordinates = coordinates,
				linkFlag = false,
				precision = precision or "dziesiętnie",
			})
		elseif (map == "dynamiczna") or isKartographerZoom(map, 240) then
			_ = mw.title.new("Moduł:Mapa/kartographer").id
			_ = mw.title.new("Moduł:Mapa/kartographer/"..map).id
			coords = formatCoordinates({
				coordinates = coordinates,
				geohack = geohack or "",
				linkFlag = true,
				precision = precision or "kątowo",
				symbol = icon,
			})
			local primaryPoint = false
			if coordinates  then
				local p = require("Moduł:Współrzędne").punkt({
					coordinates,
					["znak"] = mark,
					["rozmiar znaku"] = markSize,
					["opis"] = description,
					symbol = false,
				})
				primaryPoint = true
				points = points and (p..points) or p
			end

			local pointsData = decodePoints(points)
			mw.logObject(pointsData, "pointsData")

			if not coords and pointsData and (#pointsData > 0) then
				icon = false
				coords = pointsData[1].display
			end

			longitude = 0
			latitude = 0
			for i, v in ipairs(pointsData) do
				longitude = longitude + v.longitude
				latitude = latitude + v.latitude
			end
			longitude = longitude / #pointsData
			latitude = latitude / #pointsData
			
			local mapWidth = 238
			local map1 = mw.html.create("div")
				:css( { margin="0 auto", ["text-align"]="center", width=tostring(mapWidth+4).."px" } )
			map1:tag("div")
				:css( { ["font-weight"]= "bold", color="gray" } )
				:wikitext("Położenie na mapie")
			local content = {}
			if #pointsData == 1 then
				content.type = "Feature"
				content.properties = {}
				content.properties["marker-color"] = "f00"
				content.properties["marker-size"] = "medium"
				content.properties.description = description
				content.geometry = {
					type = "Point",
					coordinates = {longitude, latitude},
				}
			else
				content.type = "FeatureCollection"
				content.features = {}
				for i, v in ipairs(pointsData) do
					p = {}
					p.type = "Feature"
					p.properties = {}
					p.properties["marker-size"] = (primaryPoint and (i == 1)) and "medium" or "small"
					p.properties["marker-color"] = (primaryPoint and (i == 1)) and "f00" or "00f"
					p.geometry = {
						type = "Point",
						coordinates = {v.longitude, v.latitude},
					}
					table.insert(content.features, p)
				end
			end
			mw.logObject(content, "content")
			local contentJson = mw.text.jsonEncode(content, mw.text.JSON_PRETTY)
			mw.logObject(contentJson, "contentJson")
			local zoom = isKartographerZoom(map, 240)
			if not zoom then
				zoom = (#pointsData > 1)
					and nil -- zoom się sam ustali (TODO sprawdź czy punkty są różne)
					or 12 -- jeden punkt wymaga konkretnej skali
			end
			
			local kartographer = frame:extensionTag('mapframe', contentJson, {
				width = mapWidth,
				height = mapWidth,
				zoom = zoom,
				longitude = longitude,
				latitude = latitude,
				align = "center",
				lang = "local",
				frameless = 1
			})
			map1:wikitext(kartographer)
			table.insert(result, '|- class="infobox-locationmap" style="background-color:white; text-align:center; border-top:1px solid #aaa;"\n|colspan="2"|')
			table.insert(result, tostring(map1:allDone()))
			table.insert(result, "\n")
			
		else
			local maps = {}
			local list = string.match(map, "#")
			for v in mw.ustring.gmatch(map, "[^#]+") do
				table.insert(maps, mw.text.trim(v))
			end
			if #maps == 0 then
				table.insert(maps, map)
			end
			if not list and (twoMaps ~= "nie") then
				while #map > 0 do
					local get = loadMap(frame, map, variant)
					map = mw.text.trim(get("nadrzędna") or "")
					if #map > 0 then
						table.insert(maps, 2, map)
					end
				end
			end

			local mapIndex = 1
			local map = maps[mapIndex]
			local get = loadMap(frame, map, variant)
			-- prepare coordinates under the map
			local icon = mw.text.trim(get("ikona") or "")
			if #icon == 0 then
				icon = defaultIcon
			end
			
			local mapPrecision = get("dokładność")
			if mapPrecision and (#mapPrecision <= 0) then
				mapPrecision = nil
			end
			
			coords = formatCoordinates({
				coordinates = coordinates,
				geohack = geohack or get("globe") or "",
				linkFlag = get("globe") ~= false,
				precision = precision or mapPrecision or "kątowo",
				symbol = icon,
			})
		
			if coordinates  then
				local p = require("Moduł:Współrzędne").punkt({
					coordinates,
					["opcje geohack"] = geohack,
					["znak"] = mark,
					["rozmiar znaku"] = markSize,
					["opis"] = description,
					["pozycja"] = position,
					alt = markalt,
					symbol = false,
				})
				--primaryPoint = true
				points = points and (p..points) or p
			end

			local pointsData = decodePoints(points)
			if pointsData then
				adjustPointParams(pointsData, get("globe"))
			end
		
			if not coords and pointsData and (#pointsData > 0) then
				icon = false
				coords = pointsData[1].display
			end
			
			-- tracking link, pseudo reference to primary map
			makeTrackingLinks(get, "primary")
			
			-- draw maps
			while map do
				map = nil
				-- draw map
				local mapWidth = tonumber(get("rozmiar")) or 238
				if mapWidth > 238 then
					mapWidth = 238
				elseif mapWidth < 100 then
					mapWidth = 100
				end
				local map1 = mw.html.create("div")
					:css( { margin="0 auto", ["text-align"]="center", width=tostring(mapWidth+4).."px" } )
				map1:tag("div")
					:css( { ["font-weight"]= "bold", color="gray" } )
					:wikitext("Położenie na mapie ", get("dopełniacz"))
				drawMap(map1:tag("div"):addClass("mapa-lokalizacyjna"), get, mapWidth, 12.6, pointsData, coordinates, false)
				table.insert(result, '|- class="infobox-locationmap" style="background-color:white; text-align:center; border-top:1px solid #aaa;"\n|colspan="2"|')
				table.insert(result, tostring(map1:allDone()))
				table.insert(result, "\n")
				-- next parent
				if mapIndex < #maps then
					mapIndex = mapIndex + 1
					map = maps[mapIndex]
					get = loadMap(frame, map, variant)
				end
			end
		end
		
		if coords then
			table.insert(result, '|-\n|colspan="2" style="background-color:white; text-align:center; border-bottom:1px solid #aaa;"|')
			table.insert(result, coords)
			table.insert(result, "\n")
		end
		
		if #result > 0 then
			table.insert(result, "|-")
		end
		
		return table.concat(result)
	end,
	
	["Thumb"] = function(frame)
		local args = require('Module:Arguments').getArgs(frame, {
			trim = true,
			removeBlanks = false,
			wrappers = "Szablon:Mapa lokalizacyjna",
		})
		local map = args["mapa"] or args[1] or "{{{1}}}"
		if #map == 0 then
			map = nil
		end
		local variant = args["wariant"]
		local width = tonumber(args["rozmiar"]) or 238
		local fontSize = tonumber(args["font-size"]) or 12.6
		local align = args["wyrównanie"] or "right"
		local footer = args["podpis"]
		local alt = args["alt"]
		local pointsData = decodePoints(args["punkty mapy"])
		
		local get = loadMap(frame, map, variant)
		if pointsData then
			adjustPointParams(pointsData, get("globe"))
		end

		-- tracking link, pseudo reference to this map
		makeTrackingLinks(get, "standalone")

		local positionClass = {
			["center"] = "center",
			["right"] = "tright",
			["left"] = "tleft",
			[""] = "tnone",
		}
		local thumb = mw.html.create("div")
			:addClass("thumb")
			:addClass(positionClass[align] or align)
			:addClass("panel-with-scroll")
			:wikitext('\n')
		local thumbinner = thumb:tag("div")
			:addClass("thumbinner")
			:css({ width = tostring(width + 2).."px" })
			:wikitext('\n')
		local border = thumbinner:tag("div")
			:css({ border = "1px solid #ccc", width = tostring(width).."px !important" })
		local builder = border:tag("div")
			--:addClass("mapa-lokalizacyjna")
			:css({ margin = "0 auto", width = tostring(width).."px" })
		drawMap(builder, get, width, fontSize, pointsData, false, alt)
		if pointsData and (#pointsData == 1) and (mw.title.getCurrentTitle().namespace == 0) then
			builder:wikitext("[[Kategoria:Mapa lokalizacyjna z jednym punktem]]")
		end
		thumbinner
			:wikitext('\n')
		local thumbcaption = thumbinner:tag("div")
			:addClass("thumbcaption")
		thumbcaption:tag("div")
			:addClass("magnify")
			:wikitext("[[Plik:Geographylogo.svg|16x16px|link=Wikiprojekt:Szablony lokalizacyjne]]")
		if footer and (#footer > 0) then
			thumbcaption:wikitext(footer)
		else
			thumbcaption:wikitext("Położenie na mapie ", mw.text.nowiki(get("dopełniacz") or ""))
		end
		thumbinner
			:wikitext('\n')
		thumb
			:wikitext('\n')
		return thumb:allDone()
	end,
	
	["Inline"] = function(frame)
		local args = require('Module:Arguments').getArgs(frame, {
			trim = true,
			removeBlanks = false,
			wrappers = "Szablon:Mapa lokalizacyjna",
		})
		local map = args["mapa"] or args[1] or "{{{1}}}"
		if #map == 0 then
			map = nil
		end
		local variant = args["wariant"]
		local width = tonumber(args["rozmiar"]) or 238
		local fontSize = tonumber(args["font-size"]) or 12.6
		local alt = args["alt"]
		local pointsData = decodePoints(args["punkty mapy"])
		
		local get = loadMap(frame, map, variant)
		if pointsData then
			adjustPointParams(pointsData, get("globe"))
		end
			
		-- tracking link, pseudo reference to this map
		makeTrackingLinks(get, "standalone")

		local builder = mw.html.create("div")
			:addClass("mapa-lokalizacyjna")
			:css({ margin ="0 auto", width = tostring(width + 2).."px", padding = "3px", margin = "3px" })
		drawMap(builder, get, width, fontSize, pointsData, false, alt)
		if pointsData and (#pointsData == 1) and (mw.title.getCurrentTitle().namespace == 0) then
			builder:wikitext("[[Kategoria:Mapa lokalizacyjna z jednym punktem]]")
		end
		return builder:allDone()
	end,

}