Vés al contingut

Mòdul:Map

De la Viquipèdia, l'enciclopèdia lliure
Icona de documentació de mòdul Documentació del mòdul [ mostra ] [ modifica el codi ] [ mostra l'historial ] [ refresca ]

Mòdul Map (codi · ús · discussió · proves · tests · casos prova | subpàgines · enllaços)

A continuació es mostra la documentació transclosa de la subpàgina /ús. [salta a la caixa de codi]


Mòdul per utilitzar les funcions de la etiqueta <mapframe> o <maplink> de l'extensió Kartographer.

Té una única funció a usar amb: {{#invoke:Map | tag | <args>}}. Recupera els paràmetres tant passats directament com indirectament via sintaxi de plantilla. Des d'un altre mòdul: require('Module:Map')._tag{<args>}.

Sintaxi

Vegeu la documentació de {{Map draw}}.

Per a depuració es disposa a més del paràmetre debug. Amb qualsevol valor mostra el codi GeoJSON generat, a usar només en previsualització.

Les pàgines amb errors les inclou a la Categoria:Pàgines amb errors en els mapes.

Dependències

Enllaços útils

-- Credits:
-- Original from Wikivoyage
-- Developed for Kartographer version on Wikipedia by Vriullop @cawiki
-- Formulae:
--    CSGNetwork at http://www.csgnetwork.com/degreelenllavcalc.html via @enwiki
--    OpenStreetMap
-- Version: 20210211

local p = {}

-- Localization on [[Module:Map/i18n]]
local i18n = {
	["coordinate-invalid"] = "Parameter $1 is an invalid value of \"latitude,longitude\".",
	["type-invalid"] = "Type $1 is invalid. Use mapframe or maplink.",
	["geotype-invalid"] = "Geotype $1 is an invalid value.",
	["ids-invalid"] = "Parameter ids $1 is invalid.",
	["polygon-required-points"] = "A polygon requires a minimum of 4 coordinate points.",
	["polygon-not-closed"] = "A closed polygon requires last point equal to first one.",
	['ids-not-found'] = "Ids not found for external data.",
	--['not-from-content-page'] = "Do not invoke from content page. Use a template or use a module subpage like /sandbox for testing .",
	-- local categories
	['cat-several-features'] = "",
	['cat-linestring-drawn'] = "",
	['cat-polygon-drawn'] = "",
}

local cat = {['cat-several-features'] = false, ['cat-linestring-drawn'] = false, ['cat-polygon-drawn'] = false}

-- Credit to http://stackoverflow.com/a/1283608/2644759, cc-by-sa 3.0
local function tableMerge(t1, t2)
	for k, v in pairs(t2) do
		if type(v) == "table" then
			if type(t1[k] or false) == "table" then
				tableMerge(t1[k] or {}, t2[k] or {})
			else
				t1[k] = v
			end
		else
			t1[k] = v
		end
	end
	return t1
end

local function loadI18n()
	local exist, res = pcall(require, "Module:Map/i18n")
	if exist and next(res) ~= nil then
		tableMerge(i18n, res.i18n)
	end
end
loadI18n()

local errormessage
local function printError(key, par)
	-- just print first error
	errormessage = errormessage or ('<span class="error">' .. (par and mw.ustring.gsub(i18n[key], "$1", par) or i18n[key]) .. '</span>')
end

-- Convert coordinates input format to geojson table
local function parseGeoSequence(data, geotype)
	local coordsGeo = {}
	for line_coord in mw.text.gsplit(data, ':', true) do -- Polygon - linearRing:linearRing...
		local coordsLine = {}
		for point_coord in mw.text.gsplit(line_coord, ';', true) do -- LineString or MultiPoint - point;point...
			local valid = false
			local val = mw.text.split(point_coord, ',', true) -- Point - lat,lon
			-- allow for elevation
			if #val >= 2 and #val <= 3 then
				local lat = tonumber(val[1])
				local lon = tonumber(val[2])
				if lat ~= nil and lon ~= nil then
					table.insert(coordsLine, {lon, lat})
					valid = true
				end
			end
			if not valid and point_coord ~= '' then printError('coordinate-invalid', point_coord) end
		end
		if geotype == 'Polygon' then
			if #coordsLine < 4 then
				printError('polygon-required-points')
			elseif table.concat(coordsLine[1]) ~= table.concat(coordsLine[#coordsLine]) then
				printError('polygon-not-closed')
			end
		end
		table.insert(coordsGeo, coordsLine)
	end
	
	if geotype == 'Point' then
		coordsGeo = coordsGeo[1][1]
	elseif geotype == "LineString" or geotype == "MultiPoint" then
		coordsGeo = coordsGeo[1]
	elseif geotype ~= 'Polygon' then
		printError('geotype-invalid', geotype)
	end
	
    return coordsGeo
end

-- data Point - {lon,lat}
-- data LineString - { {lon,lat}, {lon,lat}, ... }
-- data Polygon - { { {lon,lat}, {lon,lat} }, { {lon,lat}, {lon,lat} }, ... }
-- output as LineString format
local function mergePoints(stack, merger)
	if merger == nil then return stack end
	for _, val in ipairs(merger) do
		if type(val) == "number" then -- Point format
			stack[#stack + 1] = merger
			break
		elseif type(val[1]) == "table" then -- Polygon format
			for _, val2 in ipairs(val) do
				stack[#stack + 1] = val2
			end
		else -- LineString format
			stack[#stack + 1] = val
		end
	end
	return stack
end

-- remove duplicated points, they may affect zoom calculation
local function setUniquePoints(t)
	-- build set of unique values
	local uniqueElements = {}
	for _, point in ipairs(t) do
		if not uniqueElements[point[1]] then
			uniqueElements[point[1]] = {}
		end
		uniqueElements[point[1]][point[2]] = true
	end
	-- convert the set
	local result = {}
	for lon, _ in pairs(uniqueElements) do
		for lat, _ in pairs(uniqueElements[lon]) do
			table.insert(result, {lon, lat})
		end
	end
	
	return result
end

local function getCoordBounds(data)
	local latN, latS = -90, 90
	local lonE, lonW = -180, 180
	for i, val in ipairs(data) do
		latN = math.max(val[2], latN)
		latS = math.min(val[2], latS)
		lonE = math.max(val[1], lonE)
		lonW = math.min(val[1], lonW)
	end
	
	return latN, latS, lonE, lonW
end

local function getCoordCenter(data)
	local latN, latS, lonE, lonW = getCoordBounds(data)
	
	local latCenter = latS + (latN - latS) / 2
	local lonCenter = lonW + (lonE - lonW) / 2
	
	return lonCenter, latCenter
end

-- meters per degree by latitude
local function mxdByLat(lat)
	local latRad = math.rad(lat)
	-- see [[Geographic coordinate system#Expressing latitude and longitude as linear units]], by CSGNetwork
	local mxdLat = 111132.92 - 559.82 * math.cos(2 * latRad) + 1.175 * math.cos(4 * latRad) - 0.023 * math.cos(6 * latRad)
	local mxdLon = 111412.84 * math.cos(latRad) - 93.5 * math.cos(3 * latRad) + 0.118 * math.cos(5 * latRad)
	return mxdLat, mxdLon
end

-- Calculate zoom to fit coordinate bounds into height and width of frame
local function getZoom(data, height, width)
	local lat1, lat2, lon1, lon2 = getCoordBounds(data)
	
	local latMid = (lat1 + lat2) / 2 -- mid latitude
	local mxdLat, mxdLon = mxdByLat(latMid)
	-- distances in meters
	local distLat = math.abs((lat1 - lat2) * mxdLat)
	local distLon = math.abs((lon1 - lon2) * mxdLon)
	
	-- margin 100px in height and width, right upper icon is about 50x50px
	local validHeight = math.max(height - 100, 100)
	local validWidth = math.max(width - 100, 100)
	
	-- maximum zoom fitting all points
	local latRad = math.rad(latMid)
	for zoom = 19, 0, -1 do
		-- see https://wiki.openstreetmap.org/wiki/Zoom_levels#Metres_per_pixel_math
		-- equatorial circumference 40 075 036 m: [[Equator#Exact length]]
		local distLatFrame = 40075036 * validHeight * math.cos(latRad) / (2 ^ (zoom + 8))
		local distLonFrame = 40075036 * validWidth * math.cos(latRad) / (2 ^ (zoom + 8))
		if distLatFrame > distLat and distLonFrame > distLon then
			return zoom
		end
	end
	
	return 0
end

-- Geotype based on coordinates format pattern
local function findGeotype(coord)
	local _, semicolons = string.gsub(coord, ';', '')
	local firstcoord = string.match(coord, "[0-9%.%-]+%s*,%s*[0-9%.%-]+")
	local lastcoord = string.match(string.reverse(coord), "[0-9%.%-]+%s*,%s*[0-9%.%-]+")
	if firstcoord == nil or lastcoord == nil then
		printError('coordinate-invalid', coord)
	else
		lastcoord = string.reverse(lastcoord)
	end
	if string.find(coord, ':') or (semicolons > 2 and firstcoord == lastcoord) then
		return 'Polygon'
	elseif semicolons > 0 then
		return 'LineString' -- or MultiPoint
	else
		return 'Point'
	end
end

local function fetchWikidata(id, snak)
	-- snak is a table like {'claims', 'P625', 1, 'mainsnak', 'datavalue', 'value'}
	local value
	id = mw.text.trim(id)
	if not string.find(id, "^Q%d+$") then
		printError('ids-invalid', id)
	else
		value = mw.wikibase.getBestStatements(id, snak[2])
		for i = 3, #snak do
			if value == nil then break end
			value = value[snak[i]]
		end
	end
	
	return value
end

-- Fetch coordinates from Wikidata for a list of comma separated ids
local function getCoordinatesById(ids)
	local function roundPrec(num, prec)
		if prec == nil or prec <= 0 then return num end
		local sig = 10^math.floor(math.log10(prec)+.5) -- significant figure from sexagesimal precision: 0.00123 -> 0.001
		return math.floor(num / sig + 0.5) * sig
	end
	
	if ids == nil then return end
	local coord = {}
	local snak = {'claims', 'P625', 1, 'mainsnak', 'datavalue', 'value'}
	for idx in mw.text.gsplit(ids, '%s*,%s*') do
		local value = fetchWikidata(idx, snak)
		if value then
			local prec = value.precision
			coord[#coord+1] = roundPrec(value.latitude, prec) .. ',' .. roundPrec(value.longitude, prec)
		end
	end
	
	return #coord > 0 and table.concat(coord, ';') or nil
end

local function getBoundsById(ids, coordInput)
	if ids == nil then return {} end
	local coord = mw.text.split(coordInput, '%s*;%s*')
	local id = mw.text.split(ids, '%s*,%s*')
	if #coord ~= #id then return {} end
	local id_parent = nil
	if #id == 1 then
		id_parent = fetchWikidata(id[1], {'claims', 'P131', 1, 'mainsnak', 'datavalue', 'value', 'id'})
		if id_parent ~= nil then
			id[2] = id_parent -- P131: located in the administrative territorial entity, last try
			coord[2] = coord[1]
		end
	end
	local bounds = {}
	-- try to fetch Wikidata in this order: area, watershed area, population, and finally by administrative entity
	local snak_area = {'claims', 'P2046', 1, 'mainsnak', 'datavalue', 'value'} -- area and unit
	local snak_warea = {'claims', 'P2053', 1, 'mainsnak', 'datavalue', 'value'} -- area and unit
	local snak_pop = {'claims', 'P1082', 1, 'mainsnak', 'datavalue', 'value'} -- population
	local convert_area = {['Q712226'] = 1000000, ['Q35852'] = 10000, ['Q232291'] = 2589988.110336, ['Q81292'] = 4046.8564224,
		['Q935614'] = 1600, ['Q857027'] = 0.09290304, ['Q21074767'] = 1138100, ['Q25343'] = 1} -- to square metres
		-- query Wikidata: http://tinyurl.com/j8aez2g
	for i = 1, #id do
		if i == 2 and id[2] == id_parent and #bounds > 0 then break end -- only if not found previously
		local amount, unit, area
		local value = fetchWikidata(id[i], snak_area) or fetchWikidata(id[i], snak_warea)
		if value then
			amount = tonumber(value.amount)
			unit = string.match(value.unit, "(Q%d+)")
			if convert_area[unit] then
				area = amount * convert_area[unit]
			end
		end
		if area == nil then
			value = fetchWikidata(id[i], snak_pop)
			if value then
				amount = tonumber(value.amount)
				-- average density estimated for populated areas: 100; see [[Population density]]
				area = amount / 100 * 1000000
			end
		end
		if area then
			local radius = math.sqrt(area / math.pi) -- approximation with a circle
			local latlon = mw.text.split(coord[i], '%s*,%s*')
			local mxdLat, mxdLon = mxdByLat(latlon[1])
			bounds[#bounds+1] = {latlon[2] + (radius / mxdLon), latlon[1] + (radius / mxdLat)} -- NE bound, geoJSON format
			bounds[#bounds+1] = {latlon[2] - (radius / mxdLon), latlon[1] - (radius / mxdLat)} -- SW bound
		end
	end
	return bounds
end

local function circleToPolygon(center, radius, edges, turn)
	-- From en:Module:Mapframe, based on https://github.com/gabzim/circle-to-polygon, ISC licence
	
	local function offset(cLat, cLon, distance, bearing)
		local lat1 = math.rad(cLat)
		local lon1 = math.rad(cLon)
		local dByR = distance / 6378137 -- distance divided by 6378137 (radius of the earth) wgs84
		local lat = math.asin(
			math.sin(lat1) * math.cos(dByR) +
			math.cos(lat1) * math.sin(dByR) * math.cos(bearing)
		)
		local lon = lon1 + math.atan2(
			math.sin(bearing) * math.sin(dByR) * math.cos(lat1),
			math.cos(dByR) - math.sin(lat1) * math.sin(lat)
		)
		return math.deg(lat) .. ',' .. math.deg(lon)
	end
	
	local coords = mw.text.split(center, ',', true)
	local lat = tonumber(coords[1])
	local long = tonumber(coords[2])
	edges = edges or 32
	local move = 2 * math.pi * (turn or 0)
	local coordinates = {}
	for i = 0, edges do
		table.insert(coordinates, offset(lat, long, radius, ((2*math.pi*-i)/edges) + move))
	end
	return table.concat(coordinates, ';')
end

local function addCategories(geotype, i)
	if not mw.title.getCurrentTitle().isContentPage then return end
	
	if i > 2 and i18n["cat-several-features"] ~= '' then
		cat["cat-several-features"] = true
	end
	if geotype == "LineString" and i18n["cat-linestring-drawn"] ~= '' then
		cat["cat-linestring-drawn"] = true
	elseif geotype == "Polygon" and i18n["cat-polygon-drawn"] ~= '' then
		cat["cat-polygon-drawn"] = true
	end
	return
end

-- Recursively extract coord templates which have a name parameter.
-- from en:Module:Mapframe
local function extractCoordTemplates(wikitext)
	local output = {}
	local templates = mw.ustring.gmatch(wikitext, '{%b{}}')
	local subtemplates = {}
	for template in templates do
		local name = mw.ustring.match(template, '{{([^}|]+)') -- get the template name
		local nameParam = mw.ustring.match(template, "|%s*name%s*=%s*[^}|]+")
		if not nameParam then
			nameParam = mw.ustring.match(template, "|%s*nom%s*=%s*[^}|]+")
		end
		if mw.ustring.lower(mw.text.trim(name)) == 'coord' then
			if nameParam then table.insert(output, template) end
		elseif mw.ustring.find(template, 'coord') then
			local subOutput = extractCoordTemplates(mw.ustring.sub(template, 2))
			for _, t in pairs(subOutput) do
				table.insert(output, t)
			end
		end
	end
	-- ensure coords are not using title display
	for k, v in pairs(output) do
		output[k] = mw.ustring.gsub(v, "|%s*display%s*=[^|}]+", "|display=inline")
	end
	return output
end

-- Gets all named coordiates from a page or a section of a page.
-- dependency: Module:Transcluder
local function getNamedCoords(page)
	local parts = mw.text.split(page or "", "#", true)
	local name = parts[1] == "" and mw.title.getCurrentTitle().prefixedText or parts[1]
	local section = parts[2]
	local pageWikitext = require('Module:Transcluder').get(section and name.."#"..section or name)
	local coordTemplates = extractCoordTemplates(pageWikitext)
	local frame = mw.getCurrentFrame()
	local sep = "________"
	local expandedContent = frame:preprocess(table.concat(coordTemplates, sep))
	local expandedTemplates = mw.text.split(expandedContent, sep)
	local namedCoords = {}
	for _, expandedTemplate in pairs(expandedTemplates) do
		local coord = mw.ustring.match(expandedTemplate, "<span class=\"geo\">(.-)</span>")
		if coord then
			coord = mw.ustring.gsub(coord, ";", ",")
			local name = mw.ustring.match(expandedTemplate, "&title=(.-)<span") or coord
			name = mw.uri.decode(name)
			local description = name ~= coord and coord
			table.insert(namedCoords, {coord=coord, name=name, description=description})
		end
	end
	return namedCoords
end

-- Main function
local function main(args)
	local tagname = args.type or 'mapframe'
	if tagname ~= 'maplink' and tagname ~= 'mapframe' then printError('type-invalid', tagname) end
	
	local tagArgs = {
		text = args.text,
		zoom = tonumber(args.zoom),
		latitude = tonumber(args.latitude),
		longitude = tonumber(args.longitude)
	}
	local defaultzoom = tonumber(args.default_zoom)
	if tagname == 'mapframe' then
		tagArgs.width = args.width or 300
		tagArgs.height = args.height or 300
		tagArgs.align = args.align or 'right'
		if args.frameless ~= nil and tagArgs.text == nil then tagArgs.frameless = true end
	else
		tagArgs.class = args.class
	end
	
	local wdid = args.item or mw.wikibase.getEntityIdForCurrentPage()
	
	if args['coordinates1'] == nil and args['geotype1'] == nil then -- single feature
		args['coordinates1'] = args['coordinates'] or args[1]
		if args['coordinates1'] == nil and args['latitude'] and args['longitude'] then
			args['coordinates1'] = args['latitude'] .. ',' .. args['longitude']
		elseif args['coordinates1'] == nil then
			args['coordinates1'] = getCoordinatesById(wdid)
		end
		local par = {'title', 'image', 'description', 'geotype', 'commons', 'radius', 'radiuskm', 'edges', 'turn', 'from'}
		for _, v in ipairs(par) do
			args[v .. '1'] = args[v .. '1'] or args[v]
		end
	end
	
	local externalData = {['geoshape'] = true, ['geomask'] = true, ['geoline'] = true, ['page'] = true, ['none'] = true, ['named'] = true}
	local featureCollection = {['Point'] = true, ['MultiPoint'] = true, ['LineString'] = true, ['Polygon'] = true, ['circle'] = true}
	local myfeatures, myexternal, allpoints = {}, {}, {}
	local i, j = 1, 1
	while args['coordinates'..i] or args['ids'..i] or externalData[args['geotype'..i]] or args['commons'..i] do
		local geotypex = args['geotype'..i] or args['geotype']
		if geotypex == nil and args['commons'..i] then
			geotypex = 'page'
		end
		if geotypex ~= nil and not (featureCollection[geotypex] or externalData[geotypex]) then
			printError('geotype-invalid', geotypex)
			break
		end
		
		if geotypex == 'none' then -- skip this object
			i = i + 1
		else
			local mystack
			if geotypex == 'named' then
				local namedCoords = getNamedCoords(args['from'..i])
				mystack = myfeatures
				for _, namedCoord in pairs(namedCoords) do
					j = #mystack + 1
					mystack[j] = {}
					mystack[j]['type'] = "Feature"
					mystack[j]['geometry'] = {}
					mystack[j]['geometry']['type'] = "Point"
					mystack[j]['geometry']['coordinates'] = parseGeoSequence(namedCoord.coord, 'Point')
					allpoints = mergePoints(allpoints, mystack[j]['geometry']['coordinates'])
					mystack[j]['properties'] = {}
					mystack[j]['properties']['title'] = namedCoord.name
					mystack[j]['properties']['description'] = namedCoord.description
					mystack[j]['properties']['marker-size'] = args['marker-size'..i] or args['marker-size']
					mystack[j]['properties']['marker-symbol'] = args['marker-symbol'..i] or args['marker-symbol']
					mystack[j]['properties']['marker-color'] = args['marker-color'..i] or args['marker-color']
				end
				break
			elseif externalData[geotypex or ''] then
				mystack = myexternal
				j = #mystack + 1
				mystack[j] = {}
				mystack[j]['type'] = "ExternalData"
				mystack[j]['service'] = geotypex
				if geotypex == "page" then
					local page_name = args['commons'..i]
					if mw.ustring.find(page_name, "Data:", 1, true) == 1 then
						page_name = string.sub(page_name, 6)
					end
					if mw.ustring.find(page_name, ".map", -4, true) == nil then
						page_name = page_name .. '.map'
					end
					mystack[j]['title'] = page_name
				else
					mystack[j]['ids'] = args['ids'..i] or args['ids'] or wdid
					if mystack[j]['ids'] == nil then printError('ids-not-found'); break end
				end
				local mycoordinates = args['coordinates'..i]
				if mycoordinates == nil and (tagArgs.latitude == nil or tagArgs.longitude == nil or tagArgs.zoom == nil) then
					mycoordinates = getCoordinatesById(mystack[j]['ids'])
				end
				if mycoordinates ~= nil then
					local mypoints = getBoundsById(mystack[j]['ids'], mycoordinates)
					if #mypoints == 0 then
						mypoints = parseGeoSequence(mycoordinates, mycoordinates:find(';') and 'MultiPoint' or 'Point')
					end
					allpoints = mergePoints(allpoints, mypoints)
				end
			else
				args['coordinates'..i] = args['coordinates'..i] or getCoordinatesById(args['ids'..i])
				if geotypex == 'circle' then
					if not args['radius'..i] and args['radiuskm'..i] then
						args['radius'..i] = args['radiuskm'..i] * 1000
					end
					args['coordinates'..i] = circleToPolygon(args['coordinates'..i], args['radius'..i], args['edges'..i], args['turn'..i])
					geotypex = 'Polygon'
				end
				mystack = myfeatures
				j = #mystack + 1
				mystack[j] = {}
				mystack[j]['type'] = "Feature"
				mystack[j]['geometry'] = {}
				mystack[j]['geometry']['type'] = geotypex or findGeotype(args['coordinates'..i])
				mystack[j]['geometry']['coordinates'] = parseGeoSequence(args['coordinates'..i], mystack[j]['geometry']['type'])
				allpoints = mergePoints(allpoints, mystack[j]['geometry']['coordinates'])
				addCategories(mystack[j]['geometry']['type'], i)
			end
			mystack[j]['properties'] = {}
			mystack[j]['properties']['title'] = args['title'..i] or (geotypex and geotypex .. i) or mystack[j]['geometry']['type'] .. i
			if args['image'..i] then
				args['description'..i] = (args['description'..i] or '') .. '[[File:' .. args['image'..i] .. '|300px]]'
			end
			mystack[j]['properties']['description'] = args['description'..i]
			mystack[j]['properties']['marker-size'] = args['marker-size'..i] or args['marker-size']
			mystack[j]['properties']['marker-symbol'] = args['marker-symbol'..i] or args['marker-symbol']
			mystack[j]['properties']['marker-color'] = args['marker-color'..i] or args['marker-color']
			mystack[j]['properties']['stroke'] = args['stroke'..i] or args['stroke']
			mystack[j]['properties']['stroke-opacity'] = tonumber(args['stroke-opacity'..i] or args['stroke-opacity'])
			mystack[j]['properties']['stroke-width'] = tonumber(args['stroke-width'..i] or args['stroke-width'])
			mystack[j]['properties']['fill'] = args['fill'..i] or args['fill']
			mystack[j]['properties']['fill-opacity'] = tonumber(args['fill-opacity'..i] or args['fill-opacity'])
			
			i = i + 1
		end
	end
	
	-- calculate defaults for static mapframe; maplink is dynamic
	if (tagArgs.latitude == nil or tagArgs.longitude == nil) and #allpoints > 0 then
		if tagname == "mapframe" or tagArgs.text == nil then -- coordinates needed for text in maplink
			tagArgs.longitude, tagArgs.latitude = getCoordCenter(allpoints)
		end
	end
	if tagArgs.zoom == nil then
		if tagname == "mapframe" then
			local uniquepoints = setUniquePoints(allpoints)
			if #uniquepoints == 1 then
				local coordInput = uniquepoints[1][2] .. ',' .. uniquepoints[1][1]
				local mybounds = getBoundsById(wdid, coordInput) -- try to fetch by area
				uniquepoints = mergePoints(uniquepoints, mybounds)
			end
			if #uniquepoints <= 1 then
				tagArgs.zoom = defaultzoom or 9
			else
				tagArgs.zoom = getZoom(uniquepoints, tagArgs.height, tagArgs.width)
			end
		else
			tagArgs.zoom = defaultzoom
		end
	end
	
	local geojson = myexternal
	if #myfeatures > 0 then
		geojson[#geojson + 1] = {type = "FeatureCollection", features = myfeatures}
	end
	
	if args.debug ~= nil then
		local html = mw.text.tag{name = tagname, attrs = tagArgs, content = mw.text.jsonEncode(geojson, mw.text.JSON_PRETTY)}
		return 'syntaxhighlight', tostring(html) .. ' Arguments:' .. mw.text.jsonEncode(args, mw.text.JSON_PRETTY), {lang = 'json'}
	end
	
	if geojson and #geojson == 0 then
		errormessage = erromessage or '' -- previous message or void for no map data
	end
	
	return tagname, geojson and mw.text.jsonEncode(geojson) or '', tagArgs
end

local function addCat(cat)
	local categories = ''
	
	for k, v in pairs(cat) do
		if v then
			categories = categories .. '[[Category:' .. i18n[k] .. ']]'
		end
	end
	
	return categories
end

local function errorMessage(message)
	if message == '' then -- no map data
		return
	else
		categories = mw.message.new('Kartographer-broken-category'):inLanguage(mw.language.getContentLanguage().code):plain()
		return message .. '[[Category:' .. categories .. ']]'
	end
end

function p.tag(frame) -- entry point from invoke
	local getArgs = require('Module:Arguments').getArgs
	local args = getArgs(frame)
	local tag, geojson, tagArgs = main(args)
	
	if errormessage then return errorMessage(errormessage) end
	return frame:extensionTag(tag, geojson, tagArgs) .. addCat(cat)
end

function p._tag(args) -- entry point from require
	local tag, geojson, tagArgs = main(args)
	if errormessage then return errorMessage(errormessage) end
	return mw.getCurrentFrame():extensionTag(tag, geojson, tagArgs) .. addCat(cat)
end

return p
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy