Module:Sandbox/Ahecht/coords
< Module:Sandbox | Ahecht
File:Test Template Info-Icon - Version (2).svg Module documentation[create] [purge]
p = {}
function p._split(text)
text = mw.ustring.gsub(mw.text.trim(text), "[*′″]", {['*'] = '°', ['′'] = "'", ['″'] = '"'})
local lat, long
local regexes = {
"^([+%-%d.°'\"NS%s]+),%s*([+%-%d.°'\"EW%s]+)$", --split by commas
"^([+%-%d.°'\"%s]+[NS])%s*([+%-%d.°'\"%s]+[EW])$", --split by N/S
"^([+%-%d.°'%s]+\")%s*([+%-%d.°'%s]+\")$", --split by "
"^([+%-%d.°%s]+')%s*([+%-%d.°%s]+')$", --split by '
"^([+%-%d.%s]+°)%s*([+%-%d.%s]+°)$", --split by °
"^([+%-%d.]+)%s*([+%-%d.]+)$" --split by space
}
for _, regex in ipairs(regexes) do
lat, long = string.match(text, regex)
if lat and long then return {mw.text.trim(lat), mw.text.trim(long)} end
end
end
function p._parse(text)
local parts = p._split(text)
local errmsg = '<strong class="error">Unable to parse "' .. text .. '" as coordinates.</strong>'
if not parts then return errmsg end
local coords = {}
for k, v in ipairs(parts) do
local count, number
-- Convert N, S, E, and W
v, count = string.gsub(v, '(%s*[SW])$', '')
if count > 0 and v:sub(1,1) ~= '-' then
v = '-' .. v
else
v = string.gsub(v, '(%s*[NE])$', '')
end
-- attempt to convert text to number
coords[k] = tonumber(v)
-- attempt to convert dms to decimal
if not coords[k] and string.match(v, "[°'\"]") then
number = tonumber(string.match(v, "^[^'\"]+'%s*([%d.]+)%s*\"[^'\"]*$"))
if number and tonumber(number) then
coords[k] = (coords[k] or 0) + (number/3600)
end
number = tonumber(string.match(v, "^[^°']+°%s*([%d.]+)%s*'[^°']*$"))
if number and tonumber(number) then
coords[k] = (coords[k] or 0) + (number/60)
end
number = tonumber(string.match(v, "^%s*([+%-%d.]+)%s*°[^°]*$"))
if number and tonumber(number) then
coords[k] = (coords[k] or 0) + number
end
end
if not coords[k] then return errmsg end
end
return coords
end
function p.parse(frame)
parsed = p._parse(frame.args[1])
if not parsed then
return '<strong class="error">Unable to parse "' .. (frame.args[1] or '') .. '" as coordinates.</strong>'
end
if parsed[1] < 0 then
parsed[1] = (-1 * parsed[1]) .. "_S"
else
parsed[1] = parsed[1] .. "_N"
end
if parsed[2] < 0 then
parsed[2] = (-1 * parsed[2]) .. "_W"
else
parsed[2] = parsed[2] .. "_E"
end
return parsed[1] .. '_' .. parsed[2]
end
return p