Module:Carte interactive
La documentation pour ce module peut être créée à Module:Carte interactive/doc
local p = {}
local coord = require( "Module:Coordinates" )
local function normalise(args)
local lookup_table = {
['largeur'] = 'width',
['hauteur'] = 'height',
['texte'] = 'text',
['legende'] = 'text',
['légende'] = 'text',
['déscription'] = 'description',
['titre'] = 'title',
['sans_cadre'] = 'frameless',
['symbole'] = 'symbol',
['couleur'] = 'color',
['taille'] = 'size',
['epaisseur'] = 'size',
['épaisseur'] = 'size',
['opacite'] = 'opacity',
['opacité'] = 'opacity',
['epaisseur contour'] = 'outline_size',
['épaisseur contour'] = 'outline_size',
['couleur contour'] = 'outline_color',
['opacite contour'] = 'opacity',
['opacité contour'] = 'opacity',
['couleur fond'] = 'fill_color',
['opacite fond'] = 'fill_opacity',
['opacité fond'] = 'fill_opacity',
['geoline'] = 'contour',
['requête'] = 'query',
['requete'] = 'query',
['request'] = 'query',
['langue'] = 'lang',
}
for k, v in pairs(lookup_table) do
if args[k] ~= nil then
args[v] = args[k]
end
end
return args
end
local function decodeJsonList(value)
--[[ Plusieurs modèles, dont {{Carte interactive/Marqueur}}, ajoutent des
virgules à la fin des représentations JSON des objets. Cela fonctionne avec
le parsing JSON relaxé de HHVM, mais pas PHP7. Ce bug est détaillé ici:
https://phabricator.wikimedia.org/T214984
Cette fonction retire donc les virgules finales et initiales, avant
d'appeler mw.text.jsonDecode sur la liste.
]]
local trimmedValue = mw.text.trim(value, ',')
return mw.text.jsonDecode('[' .. trimmedValue .. ']')
end
function p.marker(frame)
local args = normalise(frame:getParent().args)
if args[1] == nil and args.latlng == nil then --One coordinate is mandatory
return
end
local properties = {
['marker-color'] = args.color == nil and '#555555' or args.color,
['marker-size'] = args.size == nil and 'medium' or args.size,
['marker-symbol'] = args.symbol == nil and '' or args.symbol,
['title'] = args.title == nil and '' or args.title,
['description'] = args.description == nil and '' or args.description,
}
local latlng = mw.text.split( (args[1] == nil and args.latlng or args[1]), ",", true )
if args.randomise ~= nil then
latlng[1] = latlng[1] + math.random(-tonumber(args.randomise), tonumber(args.randomise))/100000
latlng[2] = latlng[2] + math.random(-tonumber(args.randomise), tonumber(args.randomise))/100000
end
local geojson = {
type = "Feature",
properties = properties,
geometry = {
type = "Point",
coordinates = {
tonumber(latlng[2]),
tonumber(latlng[1]),
}
}
}
return mw.text.jsonEncode(geojson) .. ','
end
function p.line(frame)
local args = normalise(frame:getParent().args)
if args[2] == nil then --At least two coordinates are mandatory
return
end
local properties = {
["stroke"] = args.color == nil and '#555555' or args.color,
["stroke-width"] = args.size == nil and 2 or tonumber(args.size),
["stroke-opacity"] = args.opacity == nil and 1 or tonumber(args.opacity),
['title'] = args.title == nil and '' or args.title,
['description'] = args.description == nil and '' or args.description,
}
local coordinates = {}
local i = 1
while args[i] ~= nil do
local latlng = mw.text.split( args[i], ",", true )
coordinates[i] = {
tonumber(latlng[2]),
tonumber(latlng[1]),
}
i = i+1
end
local geojson = {
type = "Feature",
properties = properties,
geometry = {
type = "LineString",
coordinates = coordinates
}
}
return mw.text.jsonEncode(geojson) .. ','
end
function p.polygon(frame)
local args = normalise(frame:getParent().args)
if args[3] == nil then --At least three coordinates are mandatory
return
end
local properties = {
["stroke"] = args.color == nil and '#555555' or args.color,
["stroke-width"] = args.size == nil and 2 or tonumber(args.size),
["stroke-opacity"] = args.opacity == nil and 1 or tonumber(args.opacity),
["fill"] = args.fill_color == nil and '#555555' or args.fill_color,
["fill-opacity"] = args.fill_opacity == nil and 0.3 or tonumber(args.fill_opacity),
['title'] = args.title == nil and '' or args.title,
['description'] = args.description == nil and '' or args.description,
}
local coordinates = {}
local i = 1
while args[i] ~= nil do
local latlng = mw.text.split( args[i], ",", true )
coordinates[i] = {
tonumber(latlng[2]),
tonumber(latlng[1]),
}
i = i+1
end
local latlng = mw.text.split( args[1], ",", true )
coordinates[i] = {
tonumber(latlng[2]),
tonumber(latlng[1]),
}
local geojson = {
type = "Feature",
properties = properties,
geometry = {
type = "Polygon",
coordinates = { coordinates }
}
}
return mw.text.jsonEncode(geojson) .. ','
end
function p.query(frame)
local args = normalise(frame:getParent().args)
local query
if args[1] ~= nil then
query = args[1]
else
return
end
local properties = {
["stroke"] = args.color == nil and '#555555' or args.color,
["stroke-width"] = args.size == nil and 2 or tonumber(args.size),
["stroke-opacity"] = args.opacity == nil and 1 or tonumber(args.opacity),
["fill"] = args.fill_color == nil and '#555555' or args.fill_color,
["fill-opacity"] = args.fill_opacity == nil and 0.3 or tonumber(args.fill_opacity),
['title'] = args.title == nil and '' or args.title,
['description'] = args.description == nil and '' or args.description,
}
local service = "geoshape"
if args.contour ~= nil then
service = "geoline"
end
local geojson = {
type = "ExternalData",
service = service,
query = query,
properties = properties,
}
return mw.text.jsonEncode(geojson) .. ','
end
function p.osm(frame)
local args = normalise(frame:getParent().args)
local qid
if args[1] == nil then
qid = mw.wikibase.getEntityIdForCurrentPage()
else
qid = mw.text.trim(args[1])
end
local properties = {
["stroke"] = args.color == nil and '#555555' or args.color,
["stroke-width"] = args.size == nil and 2 or tonumber(args.size),
["stroke-opacity"] = args.opacity == nil and 1 or tonumber(args.opacity),
["fill"] = args.fill_color == nil and '#555555' or args.fill_color,
["fill-opacity"] = args.fill_opacity == nil and 0.3 or tonumber(args.fill_opacity),
['title'] = args.title == nil and '' or args.title,
['description'] = args.description == nil and '' or args.description,
}
local service = "geoshape"
if args.contour ~= nil then
service = "geoline"
end
local geojson = {
type = "ExternalData",
service = service,
ids = qid,
properties = properties,
}
return mw.text.jsonEncode(geojson) .. ','
end
function p.commons(frame)
local args = normalise(frame:getParent().args)
if args[1] == nil then
return
end
local page_name = args[1]
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
local geojson = {
type = "ExternalData",
service = "page",
title = page_name
}
return mw.text.jsonEncode(geojson) .. ','
end
function p.wikidata(frame)
local args = normalise(frame:getParent().args)
local qid
local properties = {
['marker-color'] = args.color == nil and '#555555' or args.color,
['marker-size'] = args.size == nil and 'medium' or args.size,
['marker-symbol'] = args.symbol == nil and '' or args.symbol,
['title'] = args.title == nil and '' or args.title,
['description'] = args.description == nil and '' or args.description,
}
if args[1] == nil then
qid = mw.wikibase.getEntityIdForCurrentPage()
else
qid = args[1]
end
local entity = mw.wikibase.getEntity( qid )
local value = entity:formatPropertyValues( 'P625', { mw.wikibase.entity.claimRanks.RANK_NORMAL, mw.wikibase.entity.claimRanks.RANK_PREFERRED, mw.wikibase.entity.claimRanks.RANK_TRUTH } ).value
if value == nil then
error('La propriété P625 "coordonnées géographiques" n\'est pas renseigné sur Wikidata')
end
latlng = mw.text.split( mw.text.decode(value), ", ", true )
geojson = {
type = "Feature",
geometry = {
type = "Point",
coordinates = {
coord._dms2dec(coord._parsedmsstring(latlng[2])),
coord._dms2dec(coord._parsedmsstring(latlng[1]))
}
},
properties = properties
}
return mw.text.jsonEncode(geojson) .. ','
end
function p.tag(frame)
local args = ( frame.getParent and normalise(frame:getParent().args) ) or frame
-- Choose the tagname
local tagname = 'mapframe'
if args.lien ~= nil then
tagname = 'maplink'
end
-- Manage the basics tag params
local tagArgs = {
zoom = args.zoom == nil and args.commons == nil and 14 or tonumber(args.zoom),
height = args.height == nil and 420 or tonumber(args.height),
width = args.width == nil and 420 or tonumber(args.width),
align = args.align == nil and 'right' or args.align,
text = args.text,
}
if args[1] ~= nil and (args.latitude ~= nil or args.longitude ~= nil) then
error('La ou les valeurs de longitude et/ou de latitude ont été fournis via deux syntaxe différentes. Consultez la documentation du [[Modèle:Carte interactive]] pour obtenir une syntaxe correcte')
elseif args.latitude ~= nil and args.latitude ~= ''
and args.longitude ~= nil and args.longitude ~= '' then
tagArgs.latitude = args.latitude
tagArgs.longitude = args.longitude
elseif args[1] ~= nil and args[2] ~= nil then
tagArgs.latitude = args[1]
tagArgs.longitude = args[2]
elseif args.commons == nil and args.wikidata == nil
and args.formes == nil and args.query == nil and args.externes == nil then --The only exceptions allowed to put latitude and longitude away are when using an external map stored on commons, coord from wikidata, formes, query or externes
error('Les paramètres de latitude et/ou de longitude sont absent')
end
if tagArgs.latitude ~= nil and tagArgs.longitude ~= nil then
if tonumber(tagArgs.latitude) then
tagArgs.latitude = tonumber(tagArgs.latitude)
else
tagArgs.latitude = coord._dms2dec(coord._parsedmsstring(tagArgs.latitude))
end
if tonumber(tagArgs.longitude) then
tagArgs.longitude = tonumber(tagArgs.longitude)
else
tagArgs.longitude = coord._dms2dec(coord._parsedmsstring(tagArgs.longitude))
end
end
if args.frameless then
tagArgs.frameless = ''
end
if args.lang ~= nil then
tagArgs.lang = args.lang
end
-- Manage the basics GeoJSON params
local geojson = {}
if args.commons ~= nil then
geojson[#geojson+1] = {
type = "ExternalData",
service = "page",
title = args.commons,
}
end
if args.marqueur ~= nil and args.marqueur ~= '' then
geojson[#geojson+1] = {
type = "Feature",
geometry = {
type = "Point",
coordinates = {
tagArgs.longitude,
tagArgs.latitude
}
},
properties = {
['marker-color'] = (args.color == nil or args.color == '') and '#555555' or args.color,
['marker-size'] = (args.size == nil or args.size == '') and 'medium' or args.size,
['marker-symbol'] = args.symbol == nil and '' or args.symbol,
['title'] = args.title == nil and '' or args.title,
['description'] = args.description == nil and '' or args.description,
}
}
end
if args.osm ~= nil and args.osm ~= '' then
local qid
if args.osm == 'oui' then
qid = mw.wikibase.getEntityIdForCurrentPage()
if qid == nil then
qid = "Q1"
end
else
qid = args.osm
end
local service = "geoshape"
if args.contour ~= nil then
service = "geoline"
end
geojson[#geojson+1] = {
type = "ExternalData",
service = service,
ids = qid,
properties = {
['title'] = args.title == nil and '' or args.title,
['description'] = args.description == nil and '' or args.description,
['stroke'] = args.outline_color == nil and '#555555' or args.outline_color,
['stroke-width'] = args.outline_size == nil and 2 or tonumber(args.outline_size),
}
}
end
local qid = args.wikidata
if qid and not mw.wikibase.isValidEntityId( qid ) then
qid = mw.wikibase.getEntityIdForCurrentPage()
end
if qid and mw.wikibase.isValidEntityId( qid ) then
local entity = mw.wikibase.getEntity( qid )
local value = entity:formatPropertyValues( 'P625', { mw.wikibase.entity.claimRanks.RANK_NORMAL, mw.wikibase.entity.claimRanks.RANK_PREFERRED, mw.wikibase.entity.claimRanks.RANK_TRUTH } ).value
if value == '' then
error('La propriété P625 "coordonnées géographiques" n\'est pas renseigné sur Wikidata')
end
latlng = mw.text.split( mw.text.decode(value), ", ", true )
geojson[#geojson+1] = {
type = "Feature",
geometry = {
type = "Point",
coordinates = {
coord._dms2dec(coord._parsedmsstring(latlng[2])),
coord._dms2dec(coord._parsedmsstring(latlng[1]))
}
},
properties = {
title = args.title == nil and '' or args.title,
description = args.description == nil and '' or args.description,
}
}
end
if args.query ~= nil then
local service = "geoshape"
if args.contour ~= nil then
service = "geoline"
end
geojson[#geojson+1] = {
type = "ExternalData",
service = service,
query = args.query,
properties = {
title = args.title == nil and '' or args.title,
description = args.description == nil and '' or args.description,
}
}
end
--Manage external GeoJSON datas included through models
if args.formes ~= nil then
geojson[#geojson+1] = {
type = "FeatureCollection",
features = decodeJsonList(args.formes)
}
end
if args.externes ~= nil and args.externes ~= '' then
local externes = decodeJsonList(args.externes)
for k, externe in pairs(externes) do
geojson[#geojson+1] = externe
end
end
return frame:extensionTag(tagname, mw.text.jsonEncode(geojson), tagArgs)
end
return p