Modul:Coordinate
Megjelenés
Coordinate[mi ez?] • [dokumentáció: mutat, ] • [tesztek: sikeres: 8, sikertelen: 0, kihagyva: 1 (részletek)]
TemplateStylest használ: |
Koordinátákkal kapcsolatos funkciók gyűjteménye, a koordinátasablonok megvalósítása.
Az infoboxok az {{infobox/Pozíciós térkép}}
és {{infobox/Koordináta}}
sablonokkal használják, a Modul:Infobox modulon keresztül.
Használat
A sablonok kiváltásához szükséges működés: en:Template:Coord#Usage.
Regressziós tesztelés: Sablon:Koord/regressziós tesztelés.
Lásd még
-------------------------------------------------------------------------------
-- Coordinate processing functions
-------------------------------------------------------------------------------
require('strict')
local lang = mw.getContentLanguage()
local current_page = mw.title.getCurrentTitle()
local page_name = mw.uri.encode(current_page.prefixedText, 'WIKI')
local coord_link = 'https://geohack.toolforge.org/geohack.php?language=hu&pagename=' .. page_name .. '¶ms='
-- The class used to internally represent a single coordinate
local Coordinate = {}
local getArgs = require('Modul:Arguments').getArgs
local bit32 = require( 'bit32' )
--Internal functions
--[[
Normalize cardinal direction
@param string cardDir Cardinal direction, English or Hungarian
@return string
--]]
local function normCardDir(cardDir)
if lang:uc(cardDir) == 'É' then return 'N' end
if cardDir:upper() == 'D' then return 'S' end
if cardDir:upper() == 'K' then return 'E' end
if cardDir:upper() == 'NY' then return 'W' end
return cardDir
end
local function mfloor(float)
local result = math.floor(float)
return result + 1 < float + 1e-12 and result + 1 or result
end
--[[ Helper function, used in detecting DMS formatting ]]
local function dmsTest(first, second)
first = normCardDir(first or '')
second = normCardDir(second or '')
local concatenated = first:upper() .. second:upper()
if concatenated == "NE" or concatenated == "NW" or concatenated == "SE" or concatenated == "SW" or
concatenated == "EN" or concatenated == "WN" or concatenated == "ES" or concatenated == "WS" then
return true
end
return false
end
--[[
Try to find the relevant precision for a latitude or longitude as float
@param float float
@return number the precision
--]]
local function detectPrecisionForFloat(float)
local parts = mw.text.split(tostring(float), '%.')
if parts[2] then
return math.pow(10, -1 * math.min(#parts[2], 6))
else
return 1
end
end
--[[
Validate DMS coordinates
@return string|nil Error message
--]]
function Coordinate.validateDms(degrees, minutes, seconds, hemisphere, direction)
if not degrees then
return 'Missing degrees'
end
local d = tonumber(degrees)
if not d then
return 'Invalid degrees'
end
if not direction or direction ~= 'latitude' and direction ~= 'longitude' then
error('Invalid direction', 2)
end
if direction == 'latitude' and d > 90 or direction == 'longitude' and d >= 360 then
return 'Invalid degrees'
end
if not minutes and not seconds then
-- Allow decimal format
if direction == 'latitude' then
if d < -90 or d < 0 and hemisphere == 'S' then
return 'Invalid degrees'
end
elseif direction == 'longitude' then
if d < -180 or d < 0 and hemisphere == 'W' then
return 'Invalid degrees'
end
end
end
if not minutes and seconds then
return 'Missing minutes'
end
if minutes then
if d < 0 or select(2, math.modf(d)) ~= 0 then
return 'Invalid degrees'
end
local m = tonumber(minutes)
if not m or m < 0 or m >= 60 then
return 'Invalid minutes'
end
if seconds then
if select(2, math.modf(m)) ~= 0 then
return 'Invalid minutes'
end
local s = tonumber(seconds)
if not s or s < 0 or s >= 60 then
return 'Invalid seconds'
end
end
end
end
--[[
Transform degrees, minutes, seconds format latitude and longitude
into the a structure to be used in displaying coordinates
--]]
local function parseDMS(lat_d, lat_m, lat_s, lat_f, long_d, long_m, long_s, long_f)
lat_f = normCardDir(lat_f):upper()
long_f = normCardDir(long_f):upper()
-- Check if specified backward
if lat_f == 'E' or lat_f == 'W' then
local t_d, t_m, t_s, t_f
t_d = lat_d
t_m = lat_m
t_s = lat_s
t_f = lat_f
lat_d = long_d
lat_m = long_m
lat_s = long_s
lat_f = long_f
long_d = t_d
long_m = t_m
long_s = t_s
long_f = t_f
end
local errm = Coordinate.validateDms(lat_d, lat_m, lat_s, lat_f, 'latitude')
if errm then
return nil, { { 'parseDMS', errm } }
end
errm = Coordinate.validateDms(long_d, long_m, long_s, long_f, 'longitude')
if errm then
return nil, { { 'parseDMS', errm } }
end
local lat = (lat_f:upper() == 'S' and -1 or 1) * ((tonumber(lat_d) or 0) + (tonumber(lat_m) or 0) / 60
+ (tonumber(lat_s) or 0) / 3600)
local long = (long_f:upper() == 'W' and -1 or 1) * ((tonumber(long_d) or 0) + (tonumber(long_m) or 0) / 60
+ (tonumber(long_s) or 0) / 3600)
local prec = math.min(detectPrecisionForFloat(lat_d), detectPrecisionForFloat(long_d))
if lat_m ~= nil or long_m ~= nil then
if prec < 1 then
return nil, {{'parseDMS', 'Nem értelmezhető adatok'}}
else
prec = math.min(detectPrecisionForFloat(lat_m), detectPrecisionForFloat(long_m))
if prec < 0.0001 then
prec = 1e-6
elseif prec < 1 then
prec = prec / 100
else
prec = Coordinate.PRECISION.M
end
end
end
if lat_s ~= nil or long_s ~= nil then
if prec == Coordinate.PRECISION.M then
prec = math.max(math.min(detectPrecisionForFloat(lat_s), detectPrecisionForFloat(long_s)), 0.001) * Coordinate.PRECISION.S
else
return nil, {{'parseDMS', 'Nem értelmezhető adatok'}}
end
end
local coord = Coordinate:new{latitude = lat, longitude = long, precision = prec}
return coord, coord and {} or {{'parseDMS', 'Nem értelmezhető adatok'}}
end
--[[
Format any error messages generated for display
--]]
local function errorPrinter(errors)
return nil, nil, nil, errors
--[[
local result = ""
for _, v in ipairs(errors) do
local errorHTML = '<strong class="error">Coordinates: ' .. v[2] .. '</strong>'
result = result .. errorHTML .. '<br>'
end
return result
--]]
end
Coordinate.DISPLAY_TYPE = {
INLINE = 1, -- 2^0
TITLE = 2 -- 2^1
}
Coordinate.PRECISION = {
MS = 1 / 3600 / 1000, -- to 1/1000 of an arcsecond
D000001 = 1e-6, -- ±0.000001°
MS10 = 1 / 3600 / 100, -- to 1/100 of an arcsecond
D00001 = 1e-5, -- ±0.00001°
MS100 = 1 / 3600 / 10, -- to 1/10 of an arcsecond
D0001 = 0.0001, -- ±0.0001°
S = 1 / 3600, -- to an arcsecond
D001 = 0.001, -- ±0.001°
D01 = 0.01, -- ±0.01°
M = 1 / 60, -- to an arcminute
D1 = 0.1, -- ±0.1°
D = 1, -- to a degree
D10 = 10 -- ±10°
}
local orderedPrecisions = {
Coordinate.PRECISION.MS,
Coordinate.PRECISION.MS10,
Coordinate.PRECISION.MS100,
Coordinate.PRECISION.S,
Coordinate.PRECISION.M,
Coordinate.PRECISION.D10
}
local function detectWikidataPrecision(float)
local precision
for _, v in ipairs(orderedPrecisions) do
local m = tonumber(float) / v
if math.abs(mfloor(m + 0.5) - m) < 1e-8 / v + 1e-12 then
precision = v
end
end
local s = tostring(float)
local i = s:find('%.')
if precision == Coordinate.PRECISION.MS and i and #s - i > 6 then
return precision
end
local decPrecision = detectPrecisionForFloat(float)
return precision and decPrecision < precision and precision or decPrecision
end
--[[
Check the input arguments for coord to determine the kind of data being provided
and then make the necessary processing.
--]]
local function formatTest(args)
local errors, result, format, coordParams = {}
if not args[1] then
-- no lat logic
return errorPrinter{{"formatTest", "Missing latitude"}}
elseif not args[4] and not args[5] and not args[6] then
-- dec logic
if args.precision == 'wikidata' then
result = Coordinate:new{latitude = tonumber(args[1]), longitude = tonumber(args[2])}
if not result then
return errorPrinter{{'formatTest', 'Nem értelmezhető adatok'}}
end
local logPrec = -1 * math.log10(result.precision)
format = logPrec == math.floor(logPrec) and 'dec' or 'dms'
else
result = Coordinate:new{latitude = tonumber(args[1]), longitude = tonumber(args[2]),
precision = math.min(detectPrecisionForFloat(args[1]), detectPrecisionForFloat(args[2]))}
if not result then
return errorPrinter{{'formatTest', 'Nem értelmezhető adatok'}}
end
format = 'dec'
end
coordParams = args[3]
elseif dmsTest(args[4], args[8]) then
-- dms logic
result, errors = parseDMS(args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8])
format = 'dms'
coordParams = args[9]
if args[10] then
table.insert(errors, {'formatTest', 'Extra unexpected parameters'})
end
elseif dmsTest(args[3], args[6]) then
-- dm logic
result, errors = parseDMS(args[1], args[2], nil, args[3], args[4], args[5], nil, args[6])
format = 'dms'
coordParams = args[7]
if args[8] then
table.insert(errors, {'formatTest', 'Extra unexpected parameters'})
end
elseif dmsTest(args[2], args[4]) then
-- d logic
result, errors = parseDMS(args[1], nil, nil, args[2], args[3], nil, nil, args[4])
format = result and result.precision < 1 and 'dec' or 'dms'
coordParams = args[5]
if args[6] then
table.insert(errors, {'formatTest', 'Extra unexpected parameters'})
end
else
-- Error
return errorPrinter{{"formatTest", "Unknown argument format"}}
end
return result, format, coordParams, errors
end
--[[
Check if a value is a number in the given range
@param mixed value
@param number min
@param number max
@return boolean
--]]
local function validateNumberInRange(value, min, max)
return type(value) == 'number' and value >= min and value <= max
end
--[[
Validate precision
--]]
local function validatePrecision(precision)
for _, v in pairs(Coordinate.PRECISION) do
if v == precision then
return true
end
end
return false
end
--[[
Validate a Coordinate defintion
@param table definition data
@return boolean
--]]
local function validate(definition)
--Validate precision
if not validatePrecision(definition.precision) then
return false
end
--Validate latitude and longitude
if not validateNumberInRange(definition.latitude, -180, 360) or not validateNumberInRange(definition.longitude, -180, 360) then
return false
end
return true
end
--[[
Try to find the relevant precision for a GlobeCoordinate definition
@param table GlobeCoordinate definition
@return number the precision
--]]
local function guessPrecision(definition)
return math.min(detectWikidataPrecision(definition.latitude), detectWikidataPrecision(definition.longitude))
end
-------------------------------------------------------------------------------
-- Creates a new Coordinate
-- @param float latitude Latitude ("vertical" position) as a signed floating-point value (North is positive, South is negative)
-- @param float longitude Longitude ("horizontal" position) as a signed floating-point value (East is positive, West is negative)
-- @example Coordinate.create(12.3456, -98.7654)
--
function Coordinate.create(latitude, longitude)
local coord = {}
setmetatable(coord, Coordinate)
coord.latitude = latitude
coord.longitude = longitude
return coord
end
-------------------------------------------------------------------------------
-- Build a new Coordinate
-- @param table definition Definition of the coordinate
-- @return Coordinate|nil
-- @example Coordinate:new{latitude = 12.3456, longitude = -98.7654}
--
function Coordinate:new(definition)
--Default values
if definition.precision == nil then
definition.precision = guessPrecision(definition)
else
for _, v in pairs(Coordinate.PRECISION) do
if math.abs(definition.precision - v) < 1e-12 then
definition.precision = v
end
end
end
if not validate(definition) then
return nil
end
local coord = {
latitude = definition.latitude,
longitude = definition.longitude,
precision = definition.precision or 0
}
setmetatable(coord, self)
self.__index = self
return coord
end
-------------------------------------------------------------------------------
-- == operator
-- (note that this is a naive implementation which requires exact equality if floating-point values;
-- this probably does not work very well in practice)
function Coordinate.__eq(coord1, coord2)
return math.abs(coord1.latitude - coord2.latitude) < 1e-6 and math.abs(coord1.longitude - coord2.longitude) < 1e-6
end
-------------------------------------------------------------------------------
-- Transform coordinate to string
-- @param string format
-- Special characters in the format string:
-- %L latitude as a signed float
-- %U latitude as an unsigned float
-- %D degree part of latitude (i.e. floor(latitude))
-- %M minute part of latitude
-- %S second part of latitude (including fractional part)
-- %C cardinal direction for latitude as shortcut (N/S)
-- %I internationalized cardinal direction for latitude as shortcut (currently always in in Hungarian: É/D)
-- ... same with lowercase for longitude
function Coordinate:format(format)
local d, rem = math.modf(self.latitude) -- splits number into integer and fractional part
local m, rem = math.modf(rem * 60)
local s = math.floor(rem * 60 * 100 + 0.5) / 100
format = format:gsub('%%L', lang:formatNum(self.latitude))
format = format:gsub('%%U', lang:formatNum(math.abs(self.latitude)))
format = format:gsub('%%D', d)
format = format:gsub('%%M', m)
format = format:gsub('%%S', s)
format = format:gsub('%%C', (self.latitude >= 0) and 'N' or 'S')
format = format:gsub('%%I', (self.latitude >= 0) and 'É' or 'D')
local d, rem = math.modf(self.longitude) -- splits number into integer and fractional part
local m, rem = math.modf(rem * 60)
local s = math.floor(rem * 60 * 100 + 0.5) / 100
format = format:gsub('%%l', lang:formatNum(self.longitude))
format = format:gsub('%%u', lang:formatNum(math.abs(self.longitude)))
format = format:gsub('%%d', d)
format = format:gsub('%%m', m)
format = format:gsub('%%s', s)
format = format:gsub('%%c', (self.longitude >= 0) and 'E' or 'W')
format = format:gsub('%%i', (self.longitude >= 0) and 'K' or 'Ny')
return format
end
-------------------------------------------------------------------------------
-- These elements can be used in stringPatterns between $ marks
-- E.g. "$int$° $int$′ $int$″"
local patternElements = {
uint = "[0-9]+",
int = "[-+]?[0-9]+",
ufloat = "[0-9]*[.,]?[0-9]+", -- english or hungarian separator notation
float = "[-+]?[0-9]*[.,]?[0-9]+", -- english or hungarian separator notation
cd = "[NSEWÉDK][Yy]?" -- cardinal directions in english or hungarian
}
-------------------------------------------------------------------------------
-- FIXME move this to an intl module
-- string to number, handle english and hungarian separator
local function num(s)
if type(s) == 'string' then
s = s:gsub(",", ".")
return tonumber(s)
else
return s
end
end
-------------------------------------------------------------------------------
-- cardinal direction to sign of coordinate (+1/-1), handles english and hungarian shortcuts
local directionMap = {N = 1, S = -1, E = 1, W = -1, ["É"] = 1, D = -1, K = 1, Ny = -1, NY = -1}
local function dirsign(s) return directionMap[s] end
-------------------------------------------------------------------------------
-- Contains regexp - callback pairs. The regexp describes a possible human-readable representation of a coordinate,
-- the callback receives the match results and transforms them into a latitude-longitude pair (a pair of signed floats).
-- Can use patternElement keys for syntatic sugar.
local stringPatterns = {
{"($float$), ($float$)", function(lat, long) return num(lat), num(long) end}, -- 12.3456, -98.7654
{"($cd$) ($float$), ($cd$) ($float$)",
function(lath, lat, longh, long)
return dirsign(lath) * num(lat), dirsign(longh) * num(long)
end}, -- É 48,621667, K 16,871528
{"($int$)° ($int$)['′] ($float$)[\"″] ($cd$), ($int$)° ($int$)['′] ($float$)[\"″] ($cd$)",
function(latd, latm, lats, lath, longd, longm, longs, longh)
local lat = dirsign(lath) * (num(latd) + num(latm) / 60 + num(lats) / 3600)
local long = dirsign(longh) * (num(longd) + num(longm) / 60 + num(longs) / 3600)
return lat, long
end}, -- 12° 20' 44" N, 98° 45' 55" W
{"($cd$) ($int$)° ($int$)['′] ($float$)[\"″], ($cd$) ($int$)° ($int$)['′] ($float$)[\"″]",
function(lath, latd, latm, lats, longh, longd, longm, longs)
local lat = dirsign(lath) * (num(latd) + num(latm) / 60 + num(lats) / 3600)
local long = dirsign(longh) * (num(longd) + num(longm) / 60 + num(longs) / 3600)
return lat, long
end}, -- N 12° 20' 44", W 98° 45' 55"
}
local stringPatternsOld, stringPatterns = stringPatterns, {}
for i, pair in ipairs(stringPatternsOld) do
local pattern, callback = pair[1], pair[2]
for key, value in pairs(patternElements) do
pattern = pattern:gsub('%$' .. key .. '%$', value)
end
table.insert(stringPatterns, {pattern, callback})
end
-------------------------------------------------------------------------------
-- Creates a Coordinate object from a human-readable string representation.
-- @param string s
-- @return Coordinate|nil
-- @example
--
function Coordinate.fromString(s)
for i, pair in ipairs(stringPatterns) do
local pattern, callback = pair[1], pair[2]
if mw.ustring.match(s, pattern) then
local lat, long = callback(mw.ustring.match(s, pattern))
return Coordinate:new{latitude = lat, longitude = long}
end
end
return nil
end
-------------------------------------------------------------------------------
-- Returns coordinate in standard text format - two signed floats (12.3456, -98.7654)
-- @return string
--
function Coordinate:__tostring()
return self:format('%L, %l')
end
--[[
Build params uri component and link text for GeoHack link
@param string format dec|dms
@return string, string|nil, nil
@example coord:toGeoHack('dms')
--]]
function Coordinate:toGeoHack(format)
if format ~= 'dec' and format ~= 'dms' then return nil, nil end
local params = ''
local text = ''
local logPrec = -1 * math.log10(self.precision)
local decimalPrecision = logPrec == math.floor(logPrec)
if decimalPrecision then
params = math.floor(self.latitude * 1e+6 + 0.5) / 1e+6 .. ';' .. math.floor(self.longitude * 1e+6 + 0.5) / 1e+6
end
if format == 'dec' then
local decimals = math.floor(logPrec)
if decimals < 1 then decimals = 0 end
text = mw.text.tag('span', { class = 'latitude' }, (self.latitude >= 0 and 'é. sz.' or 'd. sz.') .. ' ' ..
string.format('%.' .. decimals .. 'f', math.abs(self.latitude)):gsub('%.', ',') .. '°') .. ', ' ..
mw.text.tag('span', { class = 'longitude' }, (self.longitude >= 0 and 'k. h.' or 'ny. h.') .. ' ' ..
string.format('%.' .. decimals .. 'f', math.abs(self.longitude)):gsub('%.', ',') .. '°')
end
if format == 'dms' or not decimalPrecision then
local d, m, s, ctext, decimals
if decimalPrecision then
local float = math.abs(self.latitude)
d = mfloor(float)
m = mfloor(float * 60 - d * 60)
decimals = math.floor(logPrec) - 3
if decimals < 0 then decimals = 0 end
s = mfloor((float * 3600 - d * 3600 - m * 60) * 10^decimals + 0.5) / 10^decimals
if s == 60 then s = 0; m = m + 1 end
if m == 60 then m = 0; d = d + 1 end
else
local intToPrecision = mfloor(math.abs(self.latitude) / self.precision + 0.5)
d = mfloor(intToPrecision * self.precision)
m = mfloor(intToPrecision * (self.precision * 60) - d * 60)
decimals = math.floor(-1 * math.log10(self.precision * 3600))
if decimals < 1 then decimals = 0 end
s = mfloor(intToPrecision - d / self.precision - m / (self.precision * 60) + 0.5) * (self.precision * 3600)
end
if not decimalPrecision then params = params .. d end
if format == 'dms' then ctext = (self.latitude >= 0 and 'é. sz.' or 'd. sz.') .. ' ' .. d .. '°' end
if self.precision < Coordinate.PRECISION.D then
if not decimalPrecision then params = params .. '_' .. m end
if format == 'dms' then ctext = ctext .. ' ' .. string.format('%02d′', m) end
if self.precision < Coordinate.PRECISION.M then
if not decimalPrecision then params = params .. '_' .. s end
if format == 'dms' then ctext = ctext .. ' ' .. ('0%.0f'):format(s):sub(-2) .. '″' end
end
end
if not decimalPrecision then params = params .. '_' .. (self.latitude >= 0 and 'N' or 'S') .. '_' end
if format == 'dms' then text = text .. mw.text.tag('span', { class = 'latitude' }, ctext) .. ', ' end
local d, m, s, ctext, decimals
if decimalPrecision then
local float = math.abs(self.longitude)
d = mfloor(float)
m = mfloor(float * 60 - d * 60)
decimals = math.floor(logPrec) - 3
if decimals < 0 then decimals = 0 end
s = mfloor((float * 3600 - d * 3600 - m * 60) * 10^decimals + 0.5) / 10^decimals
if s == 60 then s = 0; m = m + 1 end
if m == 60 then m = 0; d = d + 1 end
else
local intToPrecision = mfloor(math.abs(self.longitude) / self.precision + 0.5)
d = mfloor(intToPrecision * self.precision)
m = mfloor(intToPrecision * (self.precision * 60) - d * 60)
decimals = math.floor(-1 * math.log10(self.precision * 3600))
if decimals < 1 then decimals = 0 end
s = mfloor(intToPrecision - d / self.precision - m / (self.precision * 60) + 0.5) * (self.precision * 3600)
end
if not decimalPrecision then params = params .. d end
if format == 'dms' then ctext = (self.longitude >= 0 and 'k. h.' or 'ny. h.') .. ' ' .. d .. '°' end
if self.precision < Coordinate.PRECISION.D then
if not decimalPrecision then params = params .. '_' .. m end
if format == 'dms' then ctext = ctext .. ' ' .. string.format('%02d′', m) end
if self.precision < Coordinate.PRECISION.M then
if not decimalPrecision then params = params .. '_' .. s end
if format == 'dms' then ctext = ctext .. ' ' .. ('0%.0f'):format(s):sub(-2) .. '″' end
end
end
if not decimalPrecision then params = params .. '_' .. (self.longitude >= 0 and 'E' or 'W') end
if format == 'dms' then text = text .. mw.text.tag('span', { class = 'longitude' }, ctext) end
end
return params, text
end
function Coordinate:geodecHtml()
return ('<span class="geo-dec" title="Maps, aerial photos, and other data for this location">%f°%s %f°%s</span>'):format(
math.abs(self.latitude),
(self.latitude >= 0) and 'N' or 'S',
math.abs(self.longitude),
(self.longitude >= 0) and 'E' or 'W'
)
end
--[[
Get the display type as a binary number, to be processed using bitwise operators.
@param string|number text User input text or type already stored as a binary number
@return number The recognized types
--]]
local function getDisplay(text)
if type(text) == 'number' then
return text
elseif text == nil then
-- default
return Coordinate.DISPLAY_TYPE.INLINE
elseif type(text) ~= 'string' then
return 0
end
local display = 0
text = text:lower()
if string.find(text, 'inline') ~= nil or text == 'i' or text == 'it' or text == 'ti' then
display = Coordinate.DISPLAY_TYPE.INLINE
end
if string.find(text, 'title') ~= nil or text == 't' or text == 'it' or text == 'ti' then
display = display + Coordinate.DISPLAY_TYPE.TITLE
end
return display
end
--[[
Process {{#coordinates:}} parser function and return eventual error message.
@param Coordinate coord The coordinate to process
@param boolean|nil primary Whether it's the primary coordinate tag for the page
@param string|nil geohack GeoHack parameters
@param table|nil params Additional parameters
@return string Error message wikitext, or empty string if there was no error
--]]
local function getParserFunction(coord, primary, geohack, params)
params = params or {}
table.insert(params, 1, coord.latitude)
table.insert(params, 2, coord.longitude)
if primary then
table.insert(params, 3, 'primary')
end
if geohack then
table.insert(params, 4, geohack)
end
return mw.getCurrentFrame():callParserFunction('#coordinates', params)
end
--[[
Return a GlobeCoordinate in HTMl (with a <GlobeCoordinate> node)
@param mw.language|string|nil language to use. By default the content language.
@param table|nil attributes table of attributes to add to the <GlobeCoordinate> node.
@return string
--]]
function Coordinate.coord(frame, args)
if not args then
args = getArgs(frame)
end
local coord, inputFormat, coordParams, errors = formatTest(args)
if #errors > 0 then
local result = ""
for _, v in ipairs(errors) do
local errorHTML = '<strong class="error">Coordinate: ' .. v[2] .. '</strong>'
result = result .. errorHTML .. '<br>'
end
return result .. '[[Kategória:Hibás koordináták]]'
end
local format = args.format or inputFormat
local params, linkText = coord:toGeoHack(format)
if coordParams then params = params .. '_' .. coordParams end
local title = args.name and '&title=' .. mw.uri.encode(args.name) or ''
local inlineLink = mw.text.tag(
'span', {
class = 'plainlinks nourlexpansion'
},
'[' .. coord_link .. params .. title .. ' ' .. linkText ..
mw.text.tag(
'span', {
["class"] = "h-geo geo",
["style"] = "display:none;"
},
mw.text.tag( 'span', {
["class"] = "p-latitude latitude"
},
coord.latitude
) ..
', ' ..
mw.text.tag( 'span', {
["class"] = "p-longitude longitude"
},
coord.longitude
)
) ..
mw.text.tag('span', { class = 'geo-nondefault' }, mw.text.tag('span', { class = 'vcard' },
coord:geodecHtml() ..
mw.text.tag('span', {class = 'fn org'}, args.name or '')
)) .. ']'
) .. (args.notes or '')
local display = getDisplay(args.display)
local text = ''
if bit32.btest(display, Coordinate.DISPLAY_TYPE.INLINE) then
text = inlineLink
end
if bit32.btest(display, Coordinate.DISPLAY_TYPE.TITLE) then
text = text .. ('<span id="coordinates">[[Földrajzi koordináta-rendszer|Koordináták]]: %s</span>'):format(inlineLink)
end
text = mw.getCurrentFrame():extensionTag {
name = 'templatestyles', args = { src = 'Modul:Coordinate/styles.css' }
} .. text
if args.with_pfunc then
text = text .. getParserFunction(coord, bit32.btest(display, Coordinate.DISPLAY_TYPE.TITLE), coordParams, {name = args.name})
end
return text
end
return Coordinate