Moduuli:Koordinaatit
Siirry navigaatioon
Siirry hakuun
Tämän moduulin ohjeistuksen voi tehdä sivulle Moduuli:Koordinaatit/ohje
-- This module is for sorting out coordinates in {{M|Coord}} and
-- aim is to allow using them with location maps when they are made to use modules
-- (currently they have various issues).
local p = {}
-- flags for where coordinates will be displayed: inline or title
local g_displaytitle = false
local g_displayinline = false
-- dd|mm|ss.s|N/S|ddd|mm|ss.s|E/W|
local function isvalid8(listItems)
local latd = tonumber(listItems[1])
local latm = tonumber(listItems[2])
local lats = tonumber(listItems[3])
local lond = tonumber(listItems[5])
local lonm = tonumber(listItems[6])
local lons = tonumber(listItems[7])
if (latd ~= nil and latm ~= nil and lats ~= nil
and lond ~= nil and lonm ~= nil and lons ~= nil) then
-- also values should be in sensible range
-- (dd > 90 dec, m/s > 60, ddd > 180)
if (math.abs(latd) > 90 or math.abs(latm) > 60 or math.abs(lats) > 60
or math.abs(lond) > 180 or math.abs(lonm) > 60 or math.abs(lons) > 60) then
return false
end
if ((listItems[4] == 'N' or listItems[4] == 'S') and (listItems[8] == 'E' or listItems[8] == 'W')) then
return true
end
end
return false
end
-- dd|mm.m|N/S|ddd|mm.m|E/W|
local function isvalid6(listItems)
local latd = tonumber(listItems[1])
local latm = tonumber(listItems[2])
local lond = tonumber(listItems[4])
local lonm = tonumber(listItems[5])
if (latd ~= nil and latm ~= nil
and lond ~= nil and lonm ~= nil) then
-- also values should be in sensible range
-- (dd > 90 dec, m/s > 60, ddd > 180)
if (math.abs(latd) > 90 or math.abs(latm) > 60
or math.abs(lond) > 180 or math.abs(lonm) > 60) then
return false
end
if ((listItems[3] == 'N' or listItems[3] == 'S') and (listItems[6] == 'E' or listItems[6] == 'W')) then
return true
end
end
return false
end
-- dd.d|N/S|ddd.d|E/W|
local function isvalid4(listItems)
local lat = tonumber(listItems[1])
local lon = tonumber(listItems[3])
if (lat ~= nil and lon ~= nil) then
-- also values should be in sensible range
-- (dd > 90 dec, m/s > 60, ddd > 180)
if (math.abs(lat) > 90 or math.abs(lon) > 180) then
return false
end
if ((listItems[2] == 'N' or listItems[2] == 'S') and (listItems[4] == 'E' or listItems[4] == 'W')) then
return true
end
end
return false
end
-- dd.d|ddd.d|
local function isvalid2(listItems)
local lat = tonumber(listItems[1])
local lon = tonumber(listItems[2])
if (lat ~= nil and lon ~= nil) then
-- also values should be in sensible range
-- (dd > 90 dec, m/s > 60, ddd > 180)
if (math.abs(lat) > 90 or math.abs(lon) > 180) then
return false
end
return true
end
return false
end
-- region:
local function isregion( par )
if par == nil then
return false
end
if not type( par ) == 'string' then
return false
end
i, j = string.find(par, "region:")
if (i >= 0 and j >= 0 and j < string.len(par)) then
return true
end
end
-- d/m/s format to decimal
local function dmstodec()
end
-- decimal format to d/m/s
local function dectodms()
end
-- 22.90361°S, 43.20972°W
local function makestringdec(lat, lon)
local ns ="N"
local we ="W"
local _lat = tonumber(lat)
local _lon = tonumber(lon)
if (_lat < 0) then
ns = "S"
end
if (_lon < 0) then
we = "E"
end
return mw.ustring.format( '%s°%s, %s°%s', lat, ns, lon, we )
end
-- combine parameters to single displayable string
-- 22°54′13″S, 43°12′35″W
local function makestringdms(listItems, count)
if (count >= 8) then
return mw.ustring.format( '%s°%s′%s″%s, %s°%s′%s″%s',
listItems[1], listItems[2], listItems[3], listItems[4],
listItems[5], listItems[6], listItems[7], listItems[8] )
end
if (count >= 6) then
return mw.ustring.format( '%s°%s′%s, %s°%s′%s',
listItems[1], listItems[2], listItems[3],
listItems[4], listItems[5], listItems[6] )
end
if (count >= 4) then
return mw.ustring.format( '%s°%s, %s°%s',
listItems[1], listItems[2],
listItems[3], listItems[4] )
end
if (count >= 2) then
return makestringdec(listItems[1], listItems[2])
end
end
-- https://geohack.toolforge.org/geohack.php?language=fi&pagename=Malline:Coord¶ms=60_10_10_N_24_57_09_E_region:FI-18_type:landmark&title=Senaatintori
local function makegeohacklink(listItems, name, count)
local link = 'https://geohack.toolforge.org/geohack.php?language=fi&pagename=Malline:Coord¶ms='
-- TODO: if coordinates are given in decimal format, convert to dms for use in the link?
local k = 1
while (k <= #listItems and k <= count) do
link = link .. listItems[k]
k = k + 1
if (k <= count) then
link = link .. "_"
end
end
if (string.len(name) > 0) then
link = link .. "&title=" .. name
end
return link
end
-- tags for displaying in title
local function maketitle(coordstring)
-- does not work on a user-page?
return '<span id="coordinatespan" class="plainlinksneverexpand">Koordinaatit: ' .. coordstring ..'</span>'
end
-- title,inline,rivi,otsikko,t,it,i,ti,o,ro,r,or,primary
local function parsedisplay(dispstring)
local i = 0
local j = 0
local len = string.len(dispstring)
while (i < len) do
i = string.find(dispstring, ",", i)
if (i == nil) then
i = len
end
if (i == j) then
break
end
local par = ''
if (i < len) then
par = string.sub(dispstring, j, i-1)
else
par = string.sub(dispstring, j, len)
end
-- check par match
if (par == "primary") then
g_displaytitle = true
end
if (par == "title" or par == "otsikko" or par == "t" or par == "o") then
g_displaytitle = true
end
if (par == "inline" or par == "rivi" or par == "i" or par == "r") then
g_displayinline = true
end
if (par == "it" or par == "ti" or par == "ro" or par == "or") then
g_displaytitle = true
g_displayinline = true
end
i = i + 1
j = i
end
end
local function buildCoords( args )
-- Get the list items.
local listItems = args
if #listItems == 0 then
return '<span class="error">Parametrit puuttuvat</span>'
end
-- parameters can have various combinations without named fields:
-- dd|mm|ss.s|N/S|ddd|mm|ss.s|E/W|
-- dd|mm.m|N/S|ddd|mm.m|E/W|
-- dd.d|N/S|ddd.d|E/W|
-- dd.d|ddd.d|
--
-- by number of parameters, validate that parameters are of correct type
-- and within sensible range
local formatting = args['muoto'] or args['format'] or '' -- dms/dec
local name = args['nimi'] or args['name'] or ''
local notes = args['huom'] or args['notes'] or ''
local display = args['näyttö'] or args['display'] or '' -- title,inline,rivi,otsikko,t,it,i,ti,o,ro,r,or,primary
parsedisplay(display)
-- TODO: there may be two or more extra fields after the actual coordinates.. detect that too
-- try these in descending order
local isvalid = false
if (#listItems >= 8) then
isvalid = isvalid8(listItems)
end
if (#listItems >= 6 and isvalid == false) then
isvalid = isvalid6(listItems)
end
if (#listItems >= 4 and isvalid == false) then
isvalid = isvalid4(listItems)
end
if (#listItems >= 2 and isvalid == false) then
isvalid = isvalid2(listItems)
end
if (isvalid == false) then
return '<span class="error">Virheelliset koordinaatit</span>[[Luokka:Virheellisiä koordinaatteja sisältävät sivut]]'
end
local coords = makestringdms(listItems, #listItems)
local link = makegeohacklink(listItems, name, #listItems)
local coordstring = '[' .. link .. ' ' .. coords ..']'
if (g_displaytitle == true and g_displayinline == true) then
return coordstring .. maketitle(coordstring)
end
if (g_displaytitle == true) then
return maketitle(coordstring)
end
if (g_displayinline == true) then
return coordstring
end
-- no known display format
return ""
end
function p.main( frame )
local origArgs
if frame == mw.getCurrentFrame() then
origArgs = frame:getParent().args
for k, v in pairs( frame.args ) do
origArgs = frame.args
break
end
else
origArgs = frame
end
local args = {}
for k, v in pairs( origArgs ) do
if type( k ) == 'number' or v ~= '' then
args[ k ] = v
end
end
return buildCoords( args )
end
return p