Module:CarouselMap

From OpenStreetMap Wiki
Jump to navigation Jump to search

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