Module:Football map
This module is rated as alpha. It is ready for third-party input, and may be used on a few pages to see if problems arise, but should be watched. Suggestions for new features or changes in their input and output mechanisms are welcome. |
- coordinate location (P625) (see uses)
- home venue (P115) (see uses)
- image (P18) (see uses)
- occupant (P466) (see uses)
- maximum capacity (P1083) (see uses)
Overview
[edit]This module is used with the template {{football map}} to simplify creation of maps with the <mapframe> tag provided by the Kartographer extension.
The template takes the same parameters as <mapframe> and adds a number of markers using a series of |stadiumN parameters that are used to general the JSON data for the markers. The stadium data is either taken from an internal list or using Wikidata for the coordinates.
Examples:
- Template:Football map/demo — stadia of London football clubs (using data from module list)
- Template:Football map/demo2— stadia for the Russia World Cup in 2018 (using data supplied in template)
- Template:Football map/demo3 — a selection of English stadia (using a mixture of all three data sources)
- Template:Football map/demo4 — a map of the stadia in List of football stadiums in England (using Wikidata for data parameters)
- Template:Football map/demo5 — a list of clubs and their stadium for the 2018-19 Premier League season (using Wikidata for data parameters)
- User:Jts1882/maps/stadiums — a user test page with some mapframe related information and some more examples
Usage
[edit]{{#invoke:Football map|function_name}}
Template documentation
[edit]- coordinate location (P625) (see uses)
- home venue (P115) (see uses)
- image (P18) (see uses)
- occupant (P466) (see uses)
- maximum capacity (P1083) (see uses)
This template uses <mapframe>
to display interactive maps of football stadia, using data supplied from the template, from Wikidata, and/or from lists defined in module subpages. The markers for each stadium have a popup
window with information on the stadium (e.g. image, description, capacity, etc).
Examples:
- Template:Football map/demo — stadia of London football clubs (using data from module list)
- Template:Football map/demo2— stadia for the Russia World Cup in 2018 (using data supplied in template)
- Template:Football map/List of football stadiums in England — a map of the stadia in List of football stadiums in England (using Wikidata for data parameters)
- Template:Football map/demo5 — a list of clubs and their stadium for the 2018-19 Premier League season (using Wikidata for data parameters)
Test examples
- Template:Football map/demo3 — a selection of English stadia (using a mixture of all three data sources)
- Template:Football map/demo4 — a test version of the map of the stadia in List of football stadiums in England (using Wikidata for data parameters)
- User:Jts1882/maps/stadiums — a user test page with some mapframe related information and some more examples
Usage
[edit]The simplest use of the template requires the basic mapframe parameters and a list of football stadia or football clubs.
Mapframe parameters
|width=
and|height=
— set the dimensions of the map on the page|align=
— sets the position on the page (left, right, center)|latitude=
and|longitude=
— the coordinates of the map centre|zoom=
— a zoom factor with a value between 0 (whole world) to 19 (very local). See examples for typical values|text=
— a description of the map displayed as a footer.|frameless=
— to produce a frameless map (e.g. for an infobox).
For more further information see Kartographer extension.
Stadium and club lists
A Mapframes
map can display markers for a number of geographical features, or a football stadia for this template. It takes the data in JSON format, but this template creates the JSON data from the parameters in the template. At its simplest, it needs a list of stadia or clubs set with the following parameters.
|stadiumN=
— a list of stadia with index N. The name must point to a valid Wikipedia page title.|clubN=
— a list of football clubs with index N. Wikidata is used to get the name of the home stadium.
Stadia and clubs can be mixed, but each index can only be used once. The maximum index is currently 200.
See below for more on customising the markers.
Sources of data
Each marker needs the coordinates for its location. These can be provided in the template or got automatically from a list maintained in the module or from Wikidata. Parameters provided by the template have priority, followed those in the module lists and Wikidata.
|wikidata=
— makes Wikidata the first choice for data source. Values can be overridden by those set in the template parameters.|moduledata=
— makes the lists of data in the module the first choice for data source. Values can be overridden by those set in the template parameters.|templatedata=
— only uses data provided by the template.
|latitudeN=
and|longitudeN=
— the coordinates of each stadium with the index specified|imageN=
— an image to display in the popup, entered in the form File:The Hive Stadium 3.jpg|descriptionN=
a description to display in the popup. This can contain any wiki markup, within reason.
Markers
The default markers:
|size=
— the size of the marker (small, medium, large )|color=
— the color of the marker (red, green, #0050d0, etc)|symbol=
— the marker can take numbers, letters or custom symbols- use
-number
to number the markers (default) - use
-letter
to use a sequence of letters in the markers - use **use
soccer
,museum
, etc to use a custom symbol (see mw:Help:Extension:Kartographer/IconsList of icons for more)
- use
The markers for any feature can be customised using a parameter with the index matching the feature name:
|sizeN=
— the size of the marker (small, medium, large). This is particularly useful for showing two stadia very close together (e.g. Goodison and Anfield), when making the one behind larger and/or on in front small makes them both easier to resolve. There is no control over the relative positions, which are set by<mapframe>
(more northerly ones first)|colorN=
— the color of the marker (red, green, #0050d0, etc)|symbolN=
— the marker can take numbers, letters or custom symbols.
This module has not been added to any categories. Please help out by adding categories to it so that it can be listed with similar modules. |
--require('strict')
-- All Lua modules on Wikipedia must begin by defining a variable that will hold their
-- externally accessible functions. They can have any name and may also hold data.
local p = {}
local stadiumDatabase = require( "Module:Football map/data" ) -- configuration module
-- main function callable in Wikipedia via the #invoke command.
p.main = function(frame)
str = p.getMapframeString()
return frame:preprocess(str) -- the mapframe needs to be preprocessed!!!!!
end -- End the function.
--[[ function to construct mapframe string
--]]
p.getMapframeString = function(frame)
--get mapframe arguments from calling templates
local parent = mw.getCurrentFrame():getParent()
--[[local mapParams = { width = parent.args['width'] or "400",
height = parent.args['height'] or "300",
latitude = parent.args['latitude'] or "51.5",
longitude = parent.args['longitude'] or "-0.15",
align = parent.args['align'] or "right",
text = parent.args['text'] or "",
zoom = parent.args['zoom'] or "9" }--]]
-- get JSON data for features to display
local mapData = p.getStadiumJSON()
local mapString = ""
--mapString = '<mapframe text="London football stadia" width=800 height=650 align=left zoom=11 latitude=51.530 longitude=-0.16 >'
if mapData ~= "" then
mapString = '<mapframe'
if parent.args['frameless'] then -- don't and text as this overrides frameless parameter
mapString = mapString .. ' frameless'
else
mapString = mapString .. ' text="' .. (parent.args['text'] or "") .. '"'
end
-- set width and height using noth parameters, one parameter assuming 4:3 aspect ratio, or defaults
local aspect = 4/3
local width = parent.args['width'] --or "400"
local height = parent.args['height'] or (width or 300)/aspect --or "300"
width = width or height*aspect -- if width null, use height
local align = parent.args['align'] or "right"
mapString = mapString .. ' width=' .. math.floor(width) .. ' height=' .. math.floor(height) .. ' align=' .. align
local zoom = parent.args['zoom'] --or "0" -- no longer set defaults (mapframe does automatically)
local latitude = parent.args['latitude'] --or "0"
local longitude = parent.args['longitude'] --or "0"
--set if values, otherwise allow mapframe to set automatically (TODO check if longitude and latitude are independent)
if zoom then mapString = mapString .. ' zoom=' .. zoom end
if latitude then mapString = mapString .. ' latitude=' .. latitude end
if longitude then mapString = mapString .. ' longitude=' .. longitude end
mapString = mapString .. ' >' .. mapData .. '</mapframe>' -- add data and close tag
--[[mapString = mapString
..' width=' .. (parent.args['width'] or "400" )
.. ' height=' .. (parent.args['height'] or "300")
.. ' align=' .. (parent.args['align'] or "right")
.. ' zoom=' .. (parent.args['zoom'] or "9" )
.. ' latitude=' .. (parent.args['latitude'] or "51.5")
.. ' longitude=' .. (parent.args['longitude'] or "-0.15")
.. ' >'
.. mapData
.. '</mapframe>'
]]
else
mapString = "No data for map"
end
return mapString
end -- End the function.
--[[ function to construct JSON format data for markers on map.
The information for each marker (coordinate, description and image for popup, etc)
can be set in several ways (in order of priority):
(1) using arguments in the template (|imageN=, |descriptionN=)
(2) from values in the data module (i.e. Module:Football map/data)
(3) from Wikidata
]]
p.getStadiumJSON = function(frame)
-- now we need to iterate through the stadiumN parameters and get data for the feature markers
local maxNumber = 200 -- maximum number looked for
local mapData = ""
local stadiumName = ""
local clubName = ""
--get mapframe arguments from calling templates
local parent = mw.getCurrentFrame():getParent()
--[[There are three ways of getting data about the stadium features
(1) from a list in the module subpages
(2) from wikidata
(3) from the parameters in the template (these always override other)
By default
The parameters useWikiData, useModule restrict use of source
--]]
local useWikidata = true
local useModule = true
if parent.args['wikidata'] then useWikidata = true; useModule = false end -- use wikidata or template data (no module data)
if parent.args['moduledata'] then useModule = true; useWikidata = false end -- use module of template data (no wikidata)
if parent.args['templatedata'] then useModule = false; useWikidata = false end -- only use template data
-- default parameters for marker color, size and symbol (i.e. those without index suffix)
local defaultMarker ={ color = parent.args['color'] or "0050d0",
size = parent.args['size'] or "medium",
symbol = parent.args['symbol'] or "soccer" }
local index=0
while index < maxNumber do
index = index + 1
local stadiumID = ""
-- (1) get stadium name
stadiumName = parent.args['stadium'..tostring(index)] --or ""
if not stadiumName then -- name from |stadiumN parameter,
clubName = parent.args['club'..tostring(index)] or ""
if clubName ~= "" then
stadiumName, stadiumID = p.getStadiumFromClubName(clubName)
end
end
-- if we have a valid stadium name (note:Lua has no continue statement)
if stadiumName then
local feature = {name="",alias="",latitude=0,longitude=0,description="",image="",valid=false}
local validFeatureData =true -- assume now and
-- (2) get feature parameters from module or wikidata or both
if useModule then -- get feature parameters from module data stadium list
feature = p.getModuleData(frame, stadiumName)
end
if useWikidata and feature['name'] == "" then -- get feature parameters from wikidata
feature = p.getDataFromWikiData(stadiumName,stadiumID)
if not feature['valid'] then validFeatureData =false end -- no valid coordinates
end
----------------------------------------------------
-- (3) data from template parameters will override those obtainied from a module table or wikidata
local templateArgs = {
latitude = parent.args['latitude'..tostring(index)], --or 0,
longitude= parent.args['longitude'..tostring(index)], --or 0,
description = parent.args['description'..tostring(index)], --or "",
image = parent.args['image'..tostring(index)] --or ""
}
if templateArgs['latitude'] and templateArgs['longitude'] then -- if both explicitly set
feature['latitude'] = templateArgs['latitude']
feature['longitude']= templateArgs['longitude']
feature['name'] = stadiumName -- as we have valid coordinates
validFeatureData =true
end
-- use specified description and image if provided
if templateArgs['description'] then
feature['description'] = templateArgs['description']
end
if templateArgs['image'] then
feature['image'] = templateArgs['image'] -- priority for image from template argument
end
if feature['image'] ~= "" then feature['image'] = '[[' .. mw.text.encode(feature['image']) .. ']]' end
-- wikilink - use redirect if alias
if feature['alias'] ~= '' then
feature['name'] = '[[' .. feature['name'] .. '|'.. feature['alias'] .. ']]'
else
feature['name'] = '[[' .. feature['name'] .. ']]'
end
if clubName ~= "" then
--feature['name'] = '[[' .. clubName .. ']] (' .. feature['name'] ..')'
if stadiumName ~= "" then
feature['description'] = '[[' .. stadiumName .. ']]. ' .. feature['description']
end
feature['name'] = '[[' .. clubName .. ']]'
end
if feature['image'] ~= "" then
feature['description'] = feature['image'] .. feature['description']
end
--check if current feature marker has specified color, size or symbol
local featureMarker ={
color = parent.args['color'..tostring(index)] or defaultMarker['color'],
symbol = parent.args['symbol'..tostring(index)] or defaultMarker['symbol'],
size = parent.args['size'..tostring(index)] or defaultMarker['size'] }
-- if we have a stadium with valid coordinates
if validFeatureData then
--(4) construct the json for the features
--mapData = mapStadium1
featureData = '{ "type": "Feature", '
.. ' "geometry": { "type": "Point", "coordinates": ['
.. feature['longitude'] .. ','
.. feature['latitude']
.. '] }, '
.. ' "properties": { "title": "' .. feature['name'] .. '", '
.. '"description": "' .. feature['description'] ..'", '
.. '"marker-symbol": "' .. featureMarker['symbol'] .. '", '
.. '"marker-size": "' .. featureMarker['size'] .. '", '
.. '"marker-color": "' .. featureMarker['color'] .. '" } '
.. ' } '
if index > 1 and mapData ~= "" then
mapData = mapData .. ',' .. featureData
else
mapData = featureData
end
else
--mapData = '{ "type": "Feature", "geometry": { "type": "Point", "coordinates": [-0.066417, 51.60475] }, "properties": { "title": "White Hart Lane (default)", "description": "Stadium of Tottenham Hotspur F.C.", "marker-symbol": "soccer", "marker-size": "large", "marker-color": "0050d0" } } '
end -- if valid parameters
end -- end if stadiumName
end -- end while loop
--[[ (5) check for external data (geoshape)
TODO add more than index=1 and generalise for any json feature
--]]
local geoshape = parent.args['geoshape'..tostring(1)] or ""
if geoshape ~= "" then
mapData = mapData .. ',' .. geoshape -- assumes at least one stadium
end
-- add outer bracket to json if more than one element
if index > 1 then
mapData = '[' .. mapData .. ']'
end
return mapData
end -- End the function.
--[[-------------------------------Retrieve information from wikidata-------------------------
statements of interest (datavalue element)
item = mw.wikibase.getEntity(WikidataId),
statements = item:getBestStatements('P625')[1]
"claims":
P625 coordinate location (value.longitude/latitude)
"P625":[{ "mainsnake": { ... "datavalue": { "value": {"latitude": 51.4, "longitude": -0.19] ...
statements.mainsnak.datavalue.value.latitude
P18 image on commons (value, "File:value")
"P18":[{ "mainsnake": { ... "datavalue": { "value": "Stamford Bridge Clear Skies.JPG"
P466 occupant (value.id) (use )
P1083 capacity (value.amount)
"P1083":[{ "mainsnake": { ... "datavalue": { "value": { "amount" : "+41875" ...
P571 inception (value), P576 demolished (value)
P1566 GeoNames ID (value, "geonames.org/value")
P84 architect
P137 operator, P127 owned by
P31 (instance of) Q483110 (stadium)
"P18":[{ "mainsnake": { ... "datavalue": { "value": { "id": "Q483110"
however also sports venue, olympic stadium, association football stadium
P159 headquarters location (for football club)
e..g. London
qualifier property: coordinates(P625)
page title on enwiki
mw.wikibase.getSitelink( itemId ) - gets local version
"sitelink": { "enwiki": { "title": "Stamford Bridge (stadium)"
ERROR NOTE there was an error is caused when a supposed stadium redirected to page with no coordinates
e.g Fortress Stadium, Bromley was redirecting to Bromley F.C.,
this had a valid Wiki ID and item but no coordinates
1. it is handled by setting wd['valid'] when there are valid coordinates
2. an alternative would We could check it is a stadium
if P31 (instance of ) Q483110 (stadium)
--]]
p.getDataFromWikiData=function(stadiumName,stadiumID)
local wd={name="",latitude="",longitude="",description="",image="",alias="",valid=false }
-- get wikidata id corresponding to wikipedia stadium page
local WikidataId = mw.wikibase.getEntityIdForTitle(stadiumName)
if WikidataId and mw.wikibase.isValidEntityId( WikidataId ) then -- valid id
local item = mw.wikibase.getEntity(WikidataId)
if not item then return wd end -- will test for wiki
local enwikiTitle = mw.wikibase.getSitelink( WikidataId ) -- name of local Wikipedia page
local wikidataTitle = mw.wikibase.getLabel( WikidataId ) -- name of Wikidata page
if enwikiTitle and wikidataTitle and enwikiTitle ~= wikidataTitle then
wd['alias'] = wikidataTitle
wd['name'] =stadiumName
else
wd['name'] =stadiumName
end
-- get coordinates
local statements = item:getBestStatements('P625')[1] --coordinate location
if statements ~= nil then -- check cordinates available
local coord = statements.mainsnak.datavalue.value
if type(coord.latitude) == 'number' and type(coord.longitude) == 'number' then
-- add coordinate data from wikidata for unindexed stadium
wd['latitude'] = coord.latitude
wd['longitude'] = coord.longitude
wd['valid'] = true
end
end
--get image
statements = item:getBestStatements('P18')[1] --image
if statements ~= nil then
wd['image'] = 'File:' .. statements.mainsnak.datavalue.value
end
-- get occupants --TODO check for multi-occupancy
statements = item:getBestStatements('P466')[1] --occupant (i.e football club)
if statements ~= nil then
local clubID = statements.mainsnak.datavalue.value.id
if clubID then
local clubName = mw.wikibase.getLabel( clubID )
wd['description'] = '<small>Home ground of ' .. clubName .. '</small>'
end
end
-- get capacity
statements = item:getBestStatements('P1083')[1] --mcapacity
if statements ~= nil then
local capacity = tonumber(statements.mainsnak.datavalue.value.amount)
if capacity then
wd['description'] = wd['description'] .. '<small> (capacity: ' .. capacity .. ')</small>'
end
end
end
return wd
end
----------------------------------------------
p.getStadiumFromClubName = function(clubName)
-- let us assume the club name has a wikipedia page with the extact same name
local wdId = mw.wikibase.getEntityIdForTitle(clubName)
if wdId and mw.wikibase.isValidEntityId( wdId ) then -- if valid id
local item = mw.wikibase.getEntity(wdId)
mw.logObject( mw.wikibase.getBestStatements( 'Q18721', 'P115' ) )
--local statements = mw.wikibase.getBestStatements( 'Q18721', 'P115' )[1]
local statements = item:getBestStatements('P115')[1] --home venue
if statements ~= nil then -- check cordinates available
local stadiumID = statements.mainsnak.datavalue.value.id
-- P115 doesn't seem to have the stadium name (P115 is type "Item")
--- other properties (e.g. stadium name) would need to be got from the ID
local stadiumName = mw.wikibase.getLabel( stadiumID )
--stadiumName = clubName -- if the marker is to be labelled with club name
local enwikiTitle = mw.wikibase.getSitelink( stadiumID )
return enwikiTitle, stadiumID
--return stadiumName, stadiumID
end
end
return ""
end
--------------------------------------------------------------------------------
p.getModuleData = function (frame, stadiumName)
local feature = {}
feature['name'] = ""
--feature['data'] = ""
feature['alias'] = ""
feature['description'] = ""
feature['image'] = ""
-- check the module stadium list for name match
-- set feature parameters from the module data
for _, params in pairs( stadiumDatabase.stadia ) do
if stadiumName == params[1] then -- if we have a match from the list
feature['name'] = params[1]
feature['latitude'] = params[2]
feature['longitude'] = params[3]
feature['alias'] = params[4]
feature['description'] = params[5]
feature['image'] = params[6]
break
end
end
return feature
end
-- function to construct JSON string for WHL in London map
p.getTestJSONstring = function(frame)
return '{ "type": "Feature", "geometry": { "type": "Point", "coordinates": [-0.066417, 51.60475] }, "properties": { "title": "White Hart Lane", "description": "Stadium of Tottenham Hotspur F.C.", "marker-symbol": "soccer", "marker-size": "large", "marker-color": "0050d0" } } '
end -- End the function.
-- function to construct JSON string
p.getJSONstring = function(frame)
local stadiumName = mw.getCurrentFrame():getParent().args['stadium1'] or "default name"
local str=stadiumName
local jsonString = '{ "type": "Feature", '
jsonString = jsonString .. ' "geometry": { "type": "Point", "coordinates": [-0.065833, 51.603333] }, '
jsonString = jsonString .. ' "properties": { "title": "[[White Hart Lane]]", '
jsonString = jsonString .. ' "description": "[[File:White Hart Lane Aerial.jpg|150px]]Tottenham Hotspur Football Club (1899-2017)", '
jsonString = jsonString .. ' "marker-symbol": "-number", "marker-size": "small", "marker-color": "dd50d0" } } '
--mapString = mapString .. '</mapframe>'
jsonString = '{ "type": "Feature", "geometry": { "type": "Point", "coordinates": [-0.066417, 51.60475] }, "properties": { "title": "[[Northumberland Development Project]]", "description": "[[File:NDProject2015.jpg|100px]]", "marker-symbol": "soccer", "marker-size": "large", "marker-color": "0050d0" } } '
jsonString = '{ "type": "Feature", "geometry": { "type": "Point", "coordinates": [-0.066417, 51.60475] }, "properties": { "title": "title", "description": "description", "marker-symbol": "soccer", "marker-size": "large", "marker-color": "0050d0" } } '
str = '<nowiki>' .. jsonString .. '</nowiki>'
--str = jsonString
return str
end -- End the function.
-- All modules end by returning the variable containing its functions to Wikipedia.
return p
-- We can now use this module by calling {{#invoke: HelloWorld | hello }}.
-- The #invoke command begins with the module's name, in this case "HelloWorld",
-- then takes the name of one of its functions as an argument, in this case "hello".