Module:CarouselMap

From OpenStreetMap Wiki
Jump to navigation Jump to search
[Edit] [Purge] Documentation

This module inserts an interactive map that cycles daily among locations specified in a configuration module.

Configuration

Each of the functions below relies on a subpage of Module:CarouselMap to determine the map's contents on a given day. Each subpage is a Lua module that returns a table of places specifying the map's parameters. When embedding a carousel in a new article, create a corresponding configuration module based on an existing module (as well as a /doc page containing any relevant documentation):

slippymap

Inserts an interactive Leaflet map based on the given configuration module. Appropriate for raster tile layers.

Parameters:

|1 =
The configuration module's subpage name. Defaults to the current page's subpage name.
|height =
The map's height in pixels.
|width =
The map's width in pixels, or |width = full to fill the available space.

vectormap

Inserts an interactive MapLibre GL map based on the given configuration module. Similar to slippymap, but with support for rendering vector tiles on the client side. Displays an interactive comparison between two maps if either |layer2 = or |date2 = is specified.

Parameters:

|1 =
The configuration module's subpage name. Defaults to the current page's subpage name.
|height =
The map's height in pixels.
|width =
The map's width in pixels, or |width = full to fill the available space.
|layer2 =
The layer ID on the right-hand side of the map comparison, overriding the layer field in the configuration.
|date2 =
The ISO 8601-1 date to filter the right-hand side of the map comparison, overriding the date field in the configuration.

description

Inserts the description field of the configuration.

Parameters:

|1 =
The configuration module's subpage name. Defaults to the current page's subpage name.

externalURL

Inserts a URL to the full version of the embedded map.

Parameters:

|1 =
The configuration module's subpage name. Defaults to the current page's subpage name.
|site =
The ID of the website to link to.

See also

local p = {}

local siteURLFormats = {
	americana = "https://americanamap.org/#{vectorZoom}/{lat}/{lon}",
	openhistoricalmap = "https://www.openhistoricalmap.org/#map={zoom}/{lat}/{lon}&layers={layer}&date={date}",
	osm = "https://www.openstreetmap.org/#map={zoom}/{lat}/{lon}&layers={layer}",
	["wikimedia:vi"] = "https://www.mediawiki.org/wiki/User:Mxn/mapframe#/map/0/{zoom}/{lat}/{lon}",
}

local layerCodesByName = {
	cycle = "C",
	humanitarian = "H",
	mapnik = "M",
	standard = "M",
	transport = "T",
	historic = "O",
	woodblock = "W",
	["japanese scroll"] = "J",
}

function p.place(frame)
	local configName = frame.args[1] or mw.title.getCurrentTitle().subpageText
	local config = mw.loadJsonData("Module:CarouselMap/config/" .. configName .. ".json")
	assert(config, "No configuration JSON file found at Module:CarouselMap/config/" .. configName .. ".json")
	
	local placeNumber = os.date("*t").yday
	-- For some reason, the # operator isn’t available on the return value of mw.loadJsonData().
	local size = 0
	for i, place in ipairs(config) do
		size = i
	end
	return config[((placeNumber - 1) % size) + 1]
end

function p.slippymap(frame)
	local place = p.place(frame)
	local layer = place.layer
	if place.layer == "standard" or place.layer == "mapnik" then layer = "leaflet" end
	
	return frame:extensionTag {
		name = "mapframe",
		args = {
			width = frame.args.width and #frame.args.width > 0 and frame.args.width or "full",
			height = frame.args.height and #frame.args.height > 0 and frame.args.height or 200,
			zoom = place.zoomLevel or 12,
			bearing = place.bearing or 0,
			pitch = place.pitch or 0,
			latitude = place.latitude,
			longitude = place.longitude,
			service = layer,
		},
	}
end

function p.vectormap(frame)
	local place = p.place(frame)
	local layer = place.layer
	if place.layer == "standard" or place.layer == "mapnik" then layer = "leaflet" end
	
	local template = "Vector map"
	local width = frame.args.width and #frame.args.width > 0 and frame.args.width or "full"
	local height = frame.args.height and #frame.args.height > 0 and frame.args.height or 200
	local args = {
		width = width,
		height = height,
		zoom = place.zoomLevel or 11,
		lat = place.latitude,
		lon = place.longitude,
		bearing = place.bearing,
		pitch = place.pitch,
		date = place.date,
		layer = layer,
		marker = "no",
	}
	
	if place.layer2 or frame.args.layer2 or place.date2 or frame.args.date2 then
		template = "Map compare"
		args["date2"] = place.date2 or frame.args.date2 or place.date
		args["layer2"] = place.layer2 or frame.args.layer2 or place.layer
	end
	
	return frame:expandTemplate {
		title = template,
		args = args,
	}
end

function p.description(frame)
	local place = p.place(frame)
	local lang = frame.args.lang or mw.getContentLanguage()
	return place.description and (place.description[lang] or place.description.en) or place.name
end

function p.externalURL(frame)
	local place = p.place(frame)
	
	local site = frame.args.site and siteURLFormats[frame.args.site]
	return site and site:gsub("{(%w+)}", {
		zoom = place.zoomLevel or 12,
		vectorZoom = (place.zoomLevel or 12) - 1,
		lat = place.latitude,
		lon = place.longitude,
		date = place.date,
		layer = place.layer and layerCodesByName[place.layer],
	})
end

return p