Ce module fournit des paramètres d'entrée pour les fonctions map et maplink prises en charge par Extension:Kartographer.

Utilisation

[modifier]
{{#invoke:map|tag|type=|text=|geotype=|title=|latitude=|longitude=|zoom=|marker-symbol=|marker-size=|marker-color=|group=|show=|data=|image=|width=|height=}} 
Paramètre Utilisation Syntaxe
type maplink ou mapframe selon la fonction qui doit être invoquée
text Texte qui apparaîtra dans le coin inférieur gauche de la carte ou en lieu et place des coordonnées
geotype Point pour les points individuels, Polygon pour les polygones
title Nom de l'objet
latitude et longitude
zoom Niveau de zoom de la carte Le niveau par défaut est de « 13 »
marker-symbol Symbole, lettre ou numéro à afficher sur la carte comme marqueur
  • Symboles les plus courants : town-hall hôtel de ville, information bureau d'information, aiport aéroport, harbor, rail, bus bus, rail-metro, museum , castle, restaurant restaurant, lodging, campsite, bar bar, theatre théâtre, bank banque, hospital hôpital, embassy ambassade (liste complète des icônes dans la section « Voir aussi »)
  • Lettres : -letter
  • Numéros : -number
marker-size Taille du symbole, lettre ou numéro à afficher sur la carte comme marqueur
  • Vide par défaut
  • large pour une plus grande taille
marker-color Couleur du marqueur de carte
  • 808080 couleur par défaut si le paramètre est vide
  • 008000 pour le symbole « town-hall » (ou 4682B4 s'il est dans la section « Voir ») ainsi que les symboles « information », « bank » et « hospital »
  • 8B0000 pour les symboles « airport », « harbor », « rail » et « bus » ainsi que les lettres et chiffres de la section « Aller »
  • 800080 pour les symboles « bus » et « rail-metro » ainsi que les lettres et chiffres de la section « Circuler »
  • 4682B4 pour les symboles « museum » et « castle » ainsi que les lettres et chiffres de la section « Voir »
  • FF4500 pour le symbole « restaurant » et les lettres et chiffres de la section « Manger »
  • 000000 pour les symboles « bar » et « theatre » ainsi que les lettres et chiffres de la section « Boire un verre / Sortir »
  • 000080 pour les symboles « lodging » et « campsite » ainsi que les lettres et chiffres de la section « Dormir »
  • FFD700 pour le symbole « embassy » ainsi que les lettres et chiffres de la section « Ambassades et consulats »
  • A0522D pour les lettres et chiffres des sections « Autres destinations » et « Aux environs »
group Groupe du marqueur (voir, manger, boire, etc.)
show Quels groupes de marqueurs afficher (par défaut, les groupes les plus courants comme voir, manger, boire, etc.)
data data=values remplit le polygone donné par data
data=world;;values remplit la zone à l'extérieur du polygone
image Nom de l'image affichée dans la vignette
width et height Largeur et hauteur de la carte en px ou % de la largeur de l'écran (uniquement pour mapframe)

Exemple

[modifier]

Avec maplink :

Avec mapframe :

{{#invoke:map|tag|type=mapframe|text=Carte de [[Liège]]|geotype=Point|title=Musée du Grand Curtius|latitude=50.64709 |longitude=5.58370 |zoom=15|image=LIEGE Palais Curtius - actuel Musée Curtius quai de Maestricht 13 (13-2013).JPG|marker-symbol=museum|marker-size=large|marker-color=4682B4|group=voir}} 
Carte
Carte de Liège

Voir aussi

[modifier]

require('strict') local getArgs = require('Module:Arguments').getArgs local p = {} local insert = table.insert local concat = table.concat local split = mw.text.split  local function dbg(v, msg)     mw.log((msg or '') .. mw.text.jsonEncode(v)) end  -- See http://geojson.org/geojson-spec.html -- Each geotype expects a certain array depth: --   Point           - array of 2 or 3 numbers: [lon, lat] or [lon, lat, elevation] --                     all other types use Point as the basic type --   MultiPoint      - array of 0 or more Points: [Point, ... ] --   LineString      - array of 2 or more Points: [Point, Point, ... ] --   MultiLineString - array of 1 or more LineStrings: [[Point, Point, ...], ...] --   Polygon         - array of 1 or more LinearRings: [[Point, Point, Point, Point, ... ], ...] --                     each LinearRing is an array of 4 or more Points, where the first and last Points must be the same --                     first LinearRing is the exterior ring, subsequent rings are holes in it --   MultiPolygon    - array of 1 or more Polygons: [[[Point, Point, Point, Point, ...], ...], ...] local allGeotypes = { 	-- how many nested array levels until we get to the Point, 	-- second is the minimum number of values each Points array must have 	Point = {1, 1}, 	MultiPoint = {1, 0}, 	LineString = {1, 2}, 	MultiLineString = {2, 2}, 	Polygon = {2, 4}, 	MultiPolygon = {3, 4}, }  -- Parse all unnamed string parameters in a form of “latitude,longitude” (or “latitude,longitude,elevation”) into the real number pairs local function getSequence(args)     local coords = {}     for ind, val in pairs(args) do         if type(ind) == 'number' then             local valid = false             local val2 = split(val, ',', true)             if #val2 >= 2 and #val2 <= 3 then -- allow for elevation (ignored here)                 local lat = tonumber(val2[1])                 local lon = tonumber(val2[2])                 if lat ~= nil and lon ~= nil then                     insert(coords, {lon, lat})                     valid = true                 end             end             if not valid then                 error('Le paramètre non nommée #' .. ind .. ' « ' .. val .. ' » n’est pas reconnu en tant que valeur « latitude,longitude » valide')             end         end     end     return coords end  -- Convert a comma and semicolon separated numbers into geojson coordinate arrays -- For example, for the LineString, data "p1;p2;p3" would be converted to [p1,p2,p3] (each "p" is a [lon,lat] value) -- LineString has the depth of "1" -- array of points (each point being a two value array) -- For Polygon, the same sequence "p1;p2;p3" would be converted to [[p1,p2,p3]] -- Which is an array of array of points. But sometimes we need to specify two subarrays of points: -- [[p1,p2],[p3]] (last point is in a separate array), and we do it with "p1;p2;;p3" -- Similarly, for MultiPolygon, "p1;p2;;;p3" would generate [[[p1,p2]],[[p3]]] function p._parseGeoSequence(args)     if not allGeotypes[args.geotype] then         return 'Géotype « ' .. args.geotype .. ' » inconnu.'     end     local levels, min = unpack(allGeotypes[args.geotype])     local result = {}      -- Example for levels==3, converting “p1 ; p2 ; ; ; p3 ; ; p4” => [[[p1, p2]], [[p3],[p4]]]     -- This function will be called after each gap, and all values are done, so the above will call:     -- before p3:  gap=2, [],[],[p1,p2]            => [[[p1,p2]]],[],[]     -- before p4:  gap=1, [[[p1,p2]]],[],[p3]      => [[[p1,p2]]],[[p3]]],[]     -- the end,    gap=2, [[[p1,p2]]],[[p3]]],[p4] => [[[p1,p2]],[[p3],[p4]]],[],[]     -- Here, convert at “p1 ; ; ” from [[],[p1]]     local function closeArrays(gap)         if #result[levels] < min then             error('Chaque tableau de points doit contenir au moins ' .. min .. ' points.')         elseif min == 1 and #result[levels] ~= 1 then -- Point             error('Un point doit indiquer exactement un point de données')         end         -- attach arrays in reverse order to the higher order ones         for i = levels, levels - gap + 1, -1 do             insert(result[i - 1], result[i])             result[i] = {}         end         return 0     end      for i = 1, levels do result[i] = {} end     local gap = 0     local usedSequence = false     for val in mw.text.gsplit(args.data, ';', true) do         local val2 = mw.text.split(val, ',', true)         -- allow for elevation         if #val2 >= 2 and #val2 <= 3 and not usedSequence then             if gap > 0 then                 gap = closeArrays(gap)             end             local lat = tonumber(val2[1])             local lon = tonumber(val2[2])             if lat == nil or lon == nil then                 return 'Valeur de données « ' .. val .. ' » erronée.'              end             insert(result[levels], {lon, lat})         else             val = mw.text.trim(val)             if val == '' then                 usedSequence = false                 gap = gap + 1                 if gap >= levels then                     return 'Les données ne doivent pas sauter plus de ' .. (levels - 1) .. ' valeurs.'                 end             elseif usedSequence then                 return 'Les coordonnées ne doivent pas être ajoutées juste après la séquence nommée.'             else                 if gap > 0 then                     gap = closeArrays(gap)                 elseif #result[levels] > 0 then                     return 'La séquence nommée « ' .. val .. ' » ne peut pas être utilisée au milieu de la séquence.'                 end                 -- Parse value as a sequence name. Eventually we can load data from external data sources                 if val == 'values' then                     val = getSequence(args)                 elseif min == 4 and val == 'world' then                     val = {{360, -180}, {360, 180}, {-360, 180}, {-360, -180}, {360, -180}}                 elseif tonumber(val) ~= nil then                     return 'Pas une coordonnée valide ni un nom de séquence : « ' .. val .. ' ».'                 else                     return 'La séquence « ' .. val .. '» est inconnue. Essayez « values » ou « world » (pour les polygones) ou spécifiez les valeurs comme une liste de paires « lat,lon;lat,lon;... »'                 end                 result[levels] = val                 usedSequence = true             end         end     end     -- allow one empty last value (some might close the list with an extra semicolon)     if gap > 1 then         return 'Les données ne doivent pas avoir de blancs multiples à la fin'     end     closeArrays(levels-1)     return args.geotype == 'Point' and result[1][1] or result[1] end  function p.parseGeoSequence(args)     local result = p._parseGeoSequence(args)     if type(result) == 'string' then         error(result)     end     return result end  -- Run this function to check that the above works ok function p.parseGeoSequenceTest()     local testSeq = function(data, expected)         local result = getSequence(data)         if type(result) == 'table' then              result = mw.text.jsonEncode(result)         end         return result == expected and '' or             'Erreur :\n données = « ' .. mw.text.jsonEncode(data) .. ' »,\n résultat = « ' .. result .. ' »,\n attendu = « ' .. expected .. ' ».'     end     local test = function(geotype, data, expected, values)         values = values or {}         values.geotype = geotype         values.data = data         local result = p._parseGeoSequence(values)         if type(result) == 'table' then             result = mw.text.jsonEncode(result)         end         return result == expected and '' or             'Erreur :\n geotype = « ' .. geotype .. ' », données = « ' .. mw.text.jsonEncode(data) .. ' »,\n résultat = « ' .. result .. ' »,\n attendu = « ' .. expected .. ' ».'     end     local values = {' 9 , 8 ', '7,6'}     local result = ''         .. testSeq({}, '[]')         .. testSeq({'\t\n 1 \r,-10'}, '[[-10,1]]')         .. testSeq(values, '[[8,9],[6,7]]')         .. test('Point', '1,2', '[2,1]')         .. test('MultiPoint', '1,2;3,4;5,6', '[[2,1],[4,3],[6,5]]')         .. test('LineString', '1,2;3,4', '[[2,1],[4,3]]')         .. test('MultiLineString', '1,2;3,4', '[[[2,1],[4,3]]]')         .. test('MultiLineString', '1,2;3,4;;5,6;7,8', '[[[2,1],[4,3]],[[6,5],[8,7]]]')         .. test('Polygon', '1,2;3,4;5,6;1,2', '[[[2,1],[4,3],[6,5],[2,1]]]')         .. test('MultiPolygon', '1,2;3,4;5,6;1,2', '[[[[2,1],[4,3],[6,5],[2,1]]]]')         .. test('MultiPolygon', '1,2;3,4;5,6;1,2;;11,12;13,14;15,16;11,12', '[[[[2,1],[4,3],[6,5],[2,1]],[[12,11],[14,13],[16,15],[12,11]]]]')         .. test('MultiPolygon', '1,2;3,4;5,6;1,2;;;11,12;13,14;15,16;11,12', '[[[[2,1],[4,3],[6,5],[2,1]]],[[[12,11],[14,13],[16,15],[12,11]]]]')         .. test('MultiPolygon', '1,2;3,4;5,6;1,2;;;11,12;13,14;15,16;11,12;;21,22;23,24;25,26;21,22', '[[[[2,1],[4,3],[6,5],[2,1]]],[[[12,11],[14,13],[16,15],[12,11]],[[22,21],[24,23],[26,25],[22,21]]]]')         .. test('MultiLineString', 'values;;1,2;3,4', '[[[8,9],[6,7]],[[2,1],[4,3]]]', values)         .. test('Polygon', 'world;;world', '[[[360,-180],[360,180],[-360,180],[-360,-180],[360,-180]],[[360,-180],[360,180],[-360,180],[-360,-180],[360,-180]]]')     return result ~= '' and result or 'Tests réussis' end  function p._tag(args)     local tagname = args.type or 'maplink'     if tagname ~= 'maplink' and tagname ~= 'mapframe' then         error('Type de balise « ' .. tagname .. ' » inconnu (essayez « maplink » ou « mapframe »)')     end     local tagArgs = {         text = args.text,         zoom = tonumber(args.zoom),         latitude = tonumber(args.latitude),         longitude = tonumber(args.longitude),         group = args.group,         show = args.show,         class = args.class,         url = args.url,         alt = args.alt,         image = args.image,     }     if args.wikidata ~= nil then         local e = mw.wikibase.getEntity(args.wikidata)         if e.claims ~= nil then             if (not tagArgs.latitude or not tagArgs.longitude) then                 if e.claims.P625 ~= nil then                     tagArgs.latitude = e.claims.P625[1].mainsnak.datavalue.value.latitude                     tagArgs.longitude = e.claims.P625[1].mainsnak.datavalue.value.longitude                 end             end             if not args.title then                 -- always try to fetch title, to get a reference in 'Wikidata entities used in this page'                 if e.labels.fr ~= nil then                     args.title = e.labels.fr.value                 elseif e.labels.en ~= nil then                     args.title = e.labels.en.value                 end             end             --if not tagArgs.url then             --    if e.claims.P856 ~= nil then             --        tagArgs.url = e.claims.P856[1].mainsnak.datavalue.value             --    end             --end             if not tagArgs.image then                 if e.claims.P18 ~= nil then                     tagArgs.image = e.claims.P18[1].mainsnak.datavalue.value                 end             end         end     end     args.title = args.title or ''     tagArgs.title = args.title     tagArgs.alt = tagArgs.alt or ''     tagArgs.url = tagArgs.url or ''     tagArgs.image = tagArgs.image or ''     if tagArgs.image ~= '' then         args.description = '[[File:' .. tagArgs.image .. '|300px|]]'             .. (args.description and '<br /> <small>' .. args.description .. '</small>' or '')     end     if args.ismarker and (args.latitude == 'NA' or args.longitude == 'NA' or not tagArgs.latitude or not tagArgs.longitude) then         return 'nowiki', '', tagArgs     end     if tagname == 'mapframe' then         tagArgs.width = args.width or 420         tagArgs.height = args.height or 420         tagArgs.align = args.align or 'right'     elseif not args.class and (args.text == '' or args.text == '""') then         tagArgs.class = 'no-icon' -- Hide pushpin icon in front of an empty text link     end     if args.data == '' then         args.data = nil     end     if (not args.geotype) ~= (not args.data) then         -- one is given, but not the other         if args.data then             error('Le paramètre « data » est fourni, mais « geotype » ne l’est pas (utilisez un de ces types : Point, MultiPoint, LineString, MultiLineString, Polygon, MultiPolygon)')         elseif args.geotype == 'Point' and tagArgs.latitude ~= nil and tagArgs.longitude ~= nil then             -- For Point geotype, it is enough to set latitude and logitude, and data will be set up automatically             args.data = tagArgs.latitude .. ',' .. tagArgs.longitude         else             error('Le paramètre « data » doit être défini. Utiliser « values » pour utiliser tous les paramètres non nommés en tant que coordonnées (lat,lon|lat,lon|...), « world » pour le monde entier, une combinaison comme  « world;values » pour créer un masque, ou bien directement des coordonnées « lat,lon;lat,lon... » avec « ; » comme séparateur de points')         end     end     local geojson     -- Kartographer can now automatically calculate the needed latitude/longitude/zoom, based on the data provided.     -- Current version ignores mapmasks, but that will also be fixed soon. Leaving this for now, but can be removed if all is good.     --tagArgs.latitude = tagArgs.latitude or 0     --tagArgs.longitude = tagArgs.longitude or 0     --tagArgs.zoom = tagArgs.zoom or 14     if args.geotype then         geojson = {             type = 'Feature',             properties = {                 title = args.title,                 description = args.description,                 alt = args.alt,                 ['marker-size'] = args['marker-size'],                 ['marker-symbol'] = args['marker-symbol'],                 ['marker-color'] = args['marker-color'],                 stroke = args.stroke,                 ['stroke-opacity'] = tonumber(args['stroke-opacity']),                 ['stroke-width'] = tonumber(args['stroke-width']),                 fill = args.fill,                 ['fill-opacity'] = tonumber(args['fill-opacity']),             },             geometry = {                 type = args.geotype,                 coordinates = p.parseGeoSequence(args)             }         }     end     if args.debug ~= nil then         local html = mw.html.create(tagname, not geojson and {selfClosing=true} or nil):attr(tagArgs)         if geojson then             html:wikitext(mw.text.jsonEncode(geojson, mw.text.JSON_PRETTY))         end         return 'syntaxhighlight', tostring(html) .. mw.text.jsonEncode(args, mw.text.JSON_PRETTY),             {lang = 'json', latitude = 0, longitude = 0, title = '', url = ''}     end     return tagname, geojson and mw.text.jsonEncode(geojson) or '', tagArgs end  local listingMarkerTypes = {'see', 'eat', 'buy', 'drink', 'sleep'} local regionMarkerTypes = {'city', 'vicinity'}  function p.tag(frame)     local args = getArgs(frame)     local tag, geojson, tagArgs = p._tag(args)     local out = {}      local function has_value(tab, val)         for index, value in ipairs(tab) do             if value == val then                 return true             end         end         return false     end      if args.ismarker == 'yes' then         if mw.title.getCurrentTitle().namespace == 0         and has_value({'do', unpack(listingMarkerTypes)}, string.lower(args.group)) -- prepend to copy of listingMarkerTypes         then            insert(out, '[[Category:Has ' .. string.lower(args.group) .. ' listing]]')         end         if geojson ~= '' then            -- local coordargs = { tagArgs.latitude, tagArgs.longitude, ['title'] = tagArgs.title }            insert(out, '<span class="noprint listing-coordinates" style="display:none">'                 ..   '<span class="geo">'                 ..     '<abbr class="latitude">' .. tagArgs.latitude .. '</abbr>'                 ..     '<abbr class="longitude">' .. tagArgs.longitude .. '</abbr>'                 ..   '</span>'                 .. '</span>'                 .. '<span title="Carte pour le marqueur « '.. args.group ..' »">' -- TODO                 .. frame:extensionTag(tag, geojson, tagArgs)                 .. '&#32;</span>')             if mw.title.getCurrentTitle().namespace == 0 then                 insert(out, '[[Category:Article avec marqueur]]')             end         else             if mw.title.getCurrentTitle().namespace == 0 and has_value(listingMarkerTypes, string.lower(args.group))             and (args.latitude ~= 'NA' and args.longitude ~= 'NA') then                 insert(out, '[[Category:' .. string.lower(args.group).. ' listing with no coordinates]]')             end         end         if mw.title.getCurrentTitle().namespace == 0 and has_value(regionMarkerTypes, string.lower(args.group))         then              if args.wikidata == nil or args.wikidata == '' then                  insert(out, '[[Category:Region markers without wikidata]]')              end              if args.image == nil or args.image == '' then                 insert(out, '[[Category:Region markers without image]]')             end         end         if tagArgs.title ~= '' then             --title = '<b id="' .. mw.uri.anchorEncode(tagArgs.title) .. '" class="fn org listing-name">' .. tagArgs.title .. '</b>'             insert(out, '<b class="fn org listing-name">' .. tagArgs.title .. '</b>')         end         if tagArgs.alt ~= '' then             insert(out, ' <em>(' .. tagArgs.alt .. ')</em>')         end         return concat(out, '')     else         return frame:extensionTag(tag, geojson, tagArgs)     end end  return p