Przejdź do zawartości

Moduł:Koordynaty

Z Encyklopedia Warmii i Mazur

local m = {}

local geoformatdata = { supportedFormats = { { prec = "10st", precision = 10.00000000000000000000, dms = false, secondsFormat = nil, format = "%0.0f%s" }, { prec = "st", precision = 1.00000000000000000000, dms = false, secondsFormat = nil, format = "%0.0f%s" }, { prec = "1", precision = 0.10000000000000000000, dms = false, secondsFormat = nil, format = "%0.1f%s" }, { prec = "min", precision = 0.01666666666666670000, dms = true, secondsFormat = "%02.0f", format = "%0.0f%s%02.0f%s" }, { prec = "2", precision = 0.01000000000000000000, dms = false, secondsFormat = nil, format = "%0.2f%s" }, { prec = "3", precision = 0.00100000000000000000, dms = false, secondsFormat = nil, format = "%0.3f%s" }, { prec = "sek", precision = 0.00027777777777777800, dms = true, secondsFormat = "%02.0f", format = "%0.0f%s%02.0f%s%02.0f%s" }, { prec = "4", precision = 0.00010000000000000000, dms = false, secondsFormat = nil, format = "%0.4f%s" }, { prec = "sek+", precision = 0.00002777777777777780, dms = true, secondsFormat = "%04.1f", format = "%0.0f%s%02.0f%s%04.1f%s" }, { prec = "5", precision = 0.00001000000000000000, dms = false, secondsFormat = nil, format = "%0.5f%s" }, { prec = "sek2", precision = 0.00000277777777777778, dms = true, secondsFormat = "%05.2f", format = "%0.0f%s%02.0f%s%05.2f%s" }, { prec = "6", precision = 0.00000100000000000000, dms = false, secondsFormat = nil, format = "%0.6f%s" }, { prec = "sek3", precision = 0.00000027777777777778, dms = true, secondsFormat = "%06.3f", format = "%0.0f%s%02.0f%s%06.3f%s" }, { prec = "7", precision = 0.00000010000000000000, dms = false, secondsFormat = nil, format = "%0.7f%s" }, { prec = "sek4", precision = 0.00000002777777777778, dms = true, secondsFormat = "%07.4f", format = "%0.0f%s%02.0f%s%07.4f%s" }, },

displayGlobes = { earth = "EW", moon = "EW", mercury = "W", mars = "W", phobos = "W", deimos = "W", ganymede = "W", callisto = "W", io = "W", europa = "W", mimas = "W", enceladus = "W", tethys = "W", dione = "W", rhea = "W", titan = "W", lapetus = "W", phoebe = "W", venus = "E", ceres = "E", vesta = "E", miranda = "E", ariel = "E", umbriel = "E", titania = "E", oberon = "E", triton = "E", pluto = "E", },

latitudeLinkMarkers = { degree="_", minute="_", second="_", positivePrefix="", positiveSuffix="N", negativePrefix="", negativeSuffix="S", }, longitudeLinkMarkers = { degree="_", minute="_", second="_", positivePrefix="", positiveSuffix="E", negativePrefix="", negativeSuffix="W", }, latitudeGlobeMarkers = { degree="°", minute="′", second="″", positivePrefix="", positiveSuffix="N", negativePrefix="", negativeSuffix="S", }, longitudeGlobeMarkers = { degree="°", minute="′", second="″", positivePrefix="", positiveSuffix="E", negativePrefix="", negativeSuffix="W", },

displayDecimalSeparator = ",", coordinatesSeparator = "\194\160", topPrefix = "Na mapach: ", documentationSubpage = "opis",

geohack_link = "//tools.wmflabs.org/geohack/geohack.php?language=pl&pagename=%s&params=%s", geohack_hint = "Mapy, zdjęcia satelitarne i inne informacje dotyczące miejsca o współrzędnych geograficznych %s %s",

-- template API data apiTemplateName = "szablon", apiMicroName = "mikro", apiAutoName = "auto", apiLatitude = "szerokość", apiLongitude = "długość",

argLocation = "umieść", valLocationTop = "na górze", valLocationInline = "w tekście", valLocationTopAndInline = "w tekście i na górze",

argPrecision = "dokładność", valPrecisionAutoDecimal = "dziesiętnie", valPrecisionAutoDMS = "kątowo",

argLink = "linkuj", valLinkYes = "tak", valLinkNo = "nie",

argName = "nazwa",

argGlobe = "glob", -- for 'auto'

-- categories errorCategory = "",

-- error messages errorTooManyPositionalArguments = "Za dużo parametrów", errorExpectedIntegerDegree = "Oczekiwana liczba stopni bez kropki dziesiętnej jeśli podawane są minuty (%s°%s')", errorInvalidMinutes = "Wartość minut jest nieprawidłowa (%s°%s')", errorExpectedIntegerMinutes = "Oczekiwana liczba minut bez kropki dziesiętnej jeśli podawane są sekundy (%s°%s'%s”)", errorInvalidSeconds = "Wartość sekund jest nieprawidłowa (%s°%s'%s”)", errorInvalidPositionalArguments = "Nieprawidłowe parametry", errorExpectedNonNegativeLatitude = "Oczekiwana nieujemna wartość szerokości geograficznej: %f", errorLatitudeOutOfRange = "Przekroczony zakres szerokości geograficznej (%f)", errorExpectedNonNegativeLongitude = "Oczekiwana nieujemna wartość długości geograficznej: %f", errorLongitudeOutOfRange = "Przekroczony zakres długości geograficznej (%f)", errorUnrecognizedLinkOption = "Niedozwolona wartość parametru link: %s", errorUnrecognizedLocationOption = "Niedozwolona wartość parametru umieść: %s", }

local function create()

-- initialize default data local result = { latitude = 0, longitude = 0, precision = 1, params = nil, inline = false, top = false, link = true, }

function result:parseCoordinates(args)

local function isInt(s) -- up to 3 digits is enough for coordinates return s:match"^-?%d%d?%d?$" end

local lang = mw.getContentLanguage()

local function parseTypes() local types = {} for i = 1, 9 do local arg = mw.text.trim(args[i] or "") if #arg==0 then table.insert(types, "_") elseif arg == "N" or arg=="E" or arg=="S" or arg=="W" then table.insert(types, arg) elseif lang:parseFormattedNumber(arg) then local scientific = arg:match"[eE]" table.insert(types, scientific and "X" or "#") else table.insert(types, "X") end end

return table.concat(types, "") end

local function calculateDecimalPrecision(s) local s1 = string.gsub(s,"%d","0") local s2 = string.gsub(s1,"^-","0") local s3 = string.gsub(s2,"0$","1") local result = lang:parseFormattedNumber(s3) return result > 0 and result or 1.0 end

local function selectAutoPrecision(p1, p2) local dms = nil if (args[geoformatdata.argPrecision] == geoformatdata.valPrecisionAutoDecimal) then dms = false elseif not args[geoformatdata.argPrecision] or (args[geoformatdata.argPrecision] == geoformatdata.valPrecisionAutoDMS) then dms = true else -- precision is selected explicit in the parameter return end

-- select automatic precision local precision = p1 < p2 and p1 or p2

-- find best DMS or decimal precision if precision < 1 then local eps = precision / 1024 for i,v in ipairs(geoformatdata.supportedFormats) do if (v.dms == dms) and ((v.precision - precision) < eps) then precision = v.precision break end end end

self.precision = precision end

local function parseAngle(index, extra)

local degree = mw.text.trim(args[index]) local result = lang:parseFormattedNumber(degree) if extra == 0 then return true, result, calculateDecimalPrecision(degree) end

local minutes = mw.text.trim(args[index+1]) if not isInt(degree) then return false, string.format(geoformatdata.errorExpectedIntegerDegree, degree, minutes) end

local precision = isInt(minutes) and 0.01666666666666670000 or 0.00027777777777777800

local value = lang:parseFormattedNumber(minutes) if value < 0 or value >= 60 then return false, string.format(geoformatdata.errorInvalidMinutes, degree, minutes) end

if result < 0 then result = result * 60 - value else result = result * 60 + value end

if extra == 1 then return true, result / 60, precision end

local seconds = mw.text.trim(args[index+2]) if not isInt(minutes) then return false, string.format(geoformatdata.errorExpectedIntegerMinutes, degree, minutes, seconds) end

precision = 0.00027777777777777800 * calculateDecimalPrecision(seconds) local value = lang:parseFormattedNumber(seconds) if value < 0 or value >= 60 then return false, string.format(geoformatdata.errorInvalidSeconds, degree, minutes, seconds) end

if result < 0 then result = result * 60 - value else result = result * 60 + value end

return true, result / 3600, precision end

local function analyzeAngle(degree, minutes, seconds) local result = lang:parseFormattedNumber(degree) if not result then return false, geoformatdata.errorInvalidPositionalArguments end

if not string.match(degree, "^%d+$") then if (#minutes > 0) or (#seconds > 0) then -- expected empty minutes and empty seconds if float degree is given return false, geoformatdata.errorInvalidPositionalArguments end

return true, result, calculateDecimalPrecision(degree) end

if #minutes == 0 then if #seconds > 0 then -- expected empty seconds if minute is not given return false, geoformatdata.errorInvalidPositionalArguments end

return true, result, calculateDecimalPrecision(degree) end

local minute = lang:parseFormattedNumber(minutes) if not minute or (minute >= 60) then return false, string.format(geoformatdata.errorInvalidMinutes, degree, minutes) end

result = result * 60 + minute if not string.match(minutes, "^%d+$") then if #seconds > 0 then return false, string.format(geoformatdata.errorExpectedIntegerMinutes, degree, minutes, seconds) end

return true, result/60, 0.00027777777777777800 end

if #seconds == 0 then return true, result/60, 0.01666666666666670000 end

local second = lang:parseFormattedNumber(seconds) if not second or (second >= 60) then return false, string.format(geoformatdata.errorInvalidSeconds, degree, minutes, seconds) end

result = result*60 + second return true, result/3600, calculateDecimalPrecision(seconds)*0.00027777777777777800 end

assert(args, "Missing template arguments") if not args[1] then -- display nothing if no positional arguments are provided return false, nil end

if args[10] then return false, geoformatdata.errorTooManyPositionalArguments end

local types = parseTypes()

local function parseSimpleText() local arg = mw.text.trim(args[1]) if types == "XX_______" then self.params = mw.text.trim(args[2]) end

local d1, m1, s1, h1, d2, m2, s2, h2 = mw.ustring.match(arg, "^([0-9,.]+)[°_]?%s*([0-9,.]*)['′_]?%s*([0-9,.]*)[\"″_]?%s*([NSEW])[,;]?%s+([0-9,.]+)[°_]?%s*([0-9,.]*)['′_]?%s*([0-9,.]*)[\"″_]?%s*([EWNS])$") if d1 then if (((h1 == "N") or (h1 == "S")) and ((h2 == "N") or (h2 == "S"))) or (((h1 == "E") or (h1 == "W")) and ((h2 == "E") or (h2 == "W"))) then return geoformatdata.errorInvalidPositionalArguments end

local status1, v1, p1 = analyzeAngle(d1, m1, s1) if not status1 then return v1 end

local status2, v2, p2 = analyzeAngle(d2, m2, s2) if not status2 then return v2 end

if (h1 == "S") or (h1 == "W") then v1 = -v1; end if (h2 == "S") or (h2 == "W") then v2 = -v2; end

self.latitude = ((h1 == "N") or (h1 == "S")) and v1 or v2 self.longitude = ((h1 == "E") or (h1 == "W")) and v1 or v2 selectAutoPrecision(p1, p2) return nil end

local lat, lon = string.match(arg, "^(-?[0-9.,]+)%s+(-?[0-9.,]+)$") if lat then local latitude = lang:parseFormattedNumber(lat) local longitude = lang:parseFormattedNumber(lon) if latitude and longitude then self.latitude = latitude self.longitude = longitude selectAutoPrecision(calculateDecimalPrecision(lat), calculateDecimalPrecision(lon)) return nil end end

return geoformatdata.errorInvalidPositionalArguments end

if (types == "X________") or (types == "XX_______") then local errorMessage = parseSimpleText() if errorMessage then return false, errorMessage end else local mapping = mw.loadData("Module:Koordynaty/parserData")[types] if not mapping then return false, geoformatdata.errorInvalidPositionalArguments end

if mapping[7] ~= 0 then self.params = mw.text.trim(args[mapping[7]]) end

local status1, latitude, latPrecision = parseAngle(mapping[1], mapping[2]) if not status1 then return false, latitude end

if mapping[3] ~= 0 then assert(mapping[3] == 1 or mapping[3] == -1, "Invalid adjust mode: " .. mapping[3]); if latitude < 0 then return false, string.format(geoformatdata.errorExpectedNonNegativeLatitude, latitude) end latitude = mapping[3] * latitude end

local status2, longitude, lonPrecision = parseAngle(mapping[4], mapping[5]) if not status2 then return false, longitude end

if mapping[6] ~= 0 then assert(mapping[6] == 1 or mapping[6] == -1, "Invalid adjust mode: " .. mapping[6]); if longitude < 0 then return false, string.format(geoformatdata.errorExpectedNonNegativeLongitude, longitude) end longitude = mapping[6] * longitude end

self.latitude = latitude self.longitude = longitude selectAutoPrecision(latPrecision, lonPrecision) end

if self.latitude < -90 or self.latitude > 90 then return false, string.format(geoformatdata.errorLatitudeOutOfRange, self.latitude) end

if self.longitude < -360 or self.longitude > 360 then return false, string.format(geoformatdata.errorLongitudeOutOfRange, self.longitude) end

return true, nil end

function result:normalize() assert(self,"Did you use '.' instead of ':' while calling the function?") local mode = false if self.params then for i, v in ipairs(mw.text.split( self.params, '_', true )) do if mode then -- more than one globe, display as given return end

local globe = string.match(v, "^globe:(%a+)$") if globe then mode = geoformatdata.displayGlobes[string.lower(globe)] if not mode then -- unrecognized display as given return end end end end

if mode == "?" then -- unrecognized left as given elseif mode == "W" then if self.longitude > 0 then self.longitude = self.longitude - 360 end elseif mode == "E" then if self.longitude < 0 then self.longitude = self.longitude + 360 end elseif self.longitude < -180 then self.longitude = self.longitude + 360 elseif self.longitude > 180 then self.longitude = self.longitude - 360 end end

function result:parseOptions(args) -- TODO process notation in conjuction with precision local precision = args[geoformatdata.argPrecision] if precision and (precision ~= geoformatdata.valPrecisionAutoDecimal) and (precision ~= geoformatdata.valPrecisionAutoDMS) then self.precision = precision end

self.name = args[geoformatdata.argName]

local link = args[geoformatdata.argLink] if link == geoformatdata.valLinkYes then self.link = true elseif link == geoformatdata.valLinkNo then self.link = false elseif link then return false, string.format(geoformatdata.errorUnrecognizedLinkOption, link) else -- default is yes self.link = true end

local location = args[geoformatdata.argLocation] if location == geoformatdata.valLocationTop then self.top = true self.inline = false elseif location == geoformatdata.valLocationInline then self.top = false self.inline = true elseif location == geoformatdata.valLocationTopAndInline then self.top = true self.inline = true elseif location then return false, string.format(geoformatdata.errorUnrecognizedLocationOption, location) elseif mw.title.getCurrentTitle().isTalkPage then -- an exception for talk pages self.top = false self.inline = true else -- default if not given self.top = true self.inline = false end

return true, nil end

function result:format()

local function selectFormat(precision) local supportedFormats = geoformatdata.supportedFormats local precisionType = type(precision) if precisionType == "string" then -- find wikipedia template precision for i, v in ipairs(supportedFormats) do if (precision == v.prec) then return true, v end end elseif precisionType == "number" then -- find wikidata precision for i, v in ipairs(supportedFormats) do local prec = v.precision local eps = prec / 64 local minPrec = prec - eps local maxPrec = prec + eps if (minPrec < precision) and (precision < maxPrec) then return true, v end end end

-- use the last one with highest precision return false, supportedFormats[#supportedFormats] end

local function formatAngle(value, format, markers, decimalSeparator) assert(type(value) == "number") local prefix = value < 0 and markers.negativePrefix or markers.positivePrefix local suffix = value < 0 and markers.negativeSuffix or markers.positiveSuffix

value = math.abs(value)

local result = nil

if not format.dms then -- format decimal value if format.precision > 1 then -- round the value value = math.floor(value / format.precision) * format.precision end

result = string.format(format.format, value, markers.degree) else -- format dms value local angle = math.floor(value) local minutes = math.floor((value - angle) * 60) local seconds = tonumber(string.format(format.secondsFormat, (value - angle) * 3600 - minutes * 60))

-- fix rounded seconds if seconds == 60 then minutes = minutes + 1 seconds = 0 if minutes == 60 then angle = angle + 1 minutes = 0 end end

if format.precision > 0.01 then -- round the value if seconds >= 30 then minutes = minutes + 1 end seconds = 0 if minutes == 60 then angle = angle + 1 minutes = 0 end end

result = string.format(format.format, angle, markers.degree, minutes, markers.minute, seconds, markers.second) end

if decimalSeparator then result = string.gsub(result, "%.", decimalSeparator) end

return prefix .. result .. suffix end

local function formatDegree(value, decimalSeparator) local result = string.format("%f", value)

if decimalSeparator then result = string.gsub(result, "%.", decimalSeparator) end

return result end

local function fullpagenamee() local title = mw.title.getCurrentTitle() return title.namespace == 0 and title:partialUrl() or title.nsText .. ":" .. title:partialUrl() end

local status, format = selectFormat(self.precision) assert(format)

local prettyLatitude = formatAngle(self.latitude, format, geoformatdata.latitudeGlobeMarkers, geoformatdata.displayDecimalSeparator) local prettyLongitude = formatAngle(self.longitude, format, geoformatdata.longitudeGlobeMarkers, geoformatdata.displayDecimalSeparator)

if not self.link then return mw.text.nowiki(prettyLatitude .. geoformatdata.coordinatesSeparator .. prettyLongitude) end

local params = { formatAngle(self.latitude, format, geoformatdata.latitudeLinkMarkers), formatAngle(self.longitude, format, geoformatdata.longitudeLinkMarkers), }

if self.params then table.insert(params, self.params) end

local degreeLatitude = formatDegree(self.latitude, geoformatdata.displayDecimalSeparator) local degreeLongitude = formatDegree(self.longitude, geoformatdata.displayDecimalSeparator)

local geohack_link = string.format(geoformatdata.geohack_link, fullpagenamee(), table.concat(params,"_")) if self.name then geohack_link = geohack_link .. "&title=" .. mw.uri.encode(self.name) end

local pretty_hint = string.format(geoformatdata.geohack_hint, prettyLatitude, prettyLongitude) local degree_hint = string.format(geoformatdata.geohack_hint, degreeLatitude, degreeLongitude) local separator = mw.text.nowiki(geoformatdata.coordinatesSeparator)

local node = false local result = mw.html.create():wikitext("[", geohack_link, " ") node = result:tag("span"):attr("class", "geo-default") :tag("span"):attr("class", "geo-dms"):attr("title", mw.text.nowiki(pretty_hint)) node:tag("span"):attr("class", "latitude"):wikitext(mw.text.nowiki(prettyLatitude)) node:wikitext(separator) node:tag("span"):attr("class", "longitude"):wikitext(mw.text.nowiki(prettyLongitude)) result:tag("span"):attr("class", "geo-multi-punct"):wikitext("/") node = result:tag("span"):attr("class", "geo-nondefault") :tag("span"):attr("class", "geo-dms"):attr("title", mw.text.nowiki(degree_hint)) node:tag("span"):attr("class", "latitude"):wikitext(mw.text.nowiki(degreeLatitude)) node:wikitext(separator) node:tag("span"):attr("class", "longitude"):wikitext(mw.text.nowiki(degreeLongitude)) result:wikitext("]")

return tostring(result) end

function result:display(inlinePrefix) local text = self:format()

if not self.top and not self.inline then return text end

local result = mw.html.create()

if self.top then local indicator = mw.html.create("span") :attr("id", "coordinates") :attr("class", "coordinates plainlinks") :wikitext(geoformatdata.topPrefix, text) result:wikitext(mw.getCurrentFrame():extensionTag{name = 'indicator', content = tostring(indicator), args = { name='coordinates' } } or "") end

if self.inline then result:wikitext(inlinePrefix or "") :tag("span") :attr("class", self.top and "coordinates inline inline-and-top plainlinks" or "coordinates inline plainlinks") :wikitext(text) end

return tostring(result) end

function result:extensionGeoData() local params = {}

local title = mw.title.getCurrentTitle() if self.top and not title.isTalkPage and (title.subpageText ~= geoformatdata.documentationSubpage) then table.insert(params, "primary") end

if self.latitude >= 0 then table.insert(params, string.format("%f", self.latitude)) table.insert(params, "N") else table.insert(params, string.format("%f", -self.latitude)) table.insert(params, "S") end

if mode == "W" then if self.longitude > 0 then table.insert(params, string.format("%f", 360-self.longitude)) else table.insert(params, string.format("%f", -self.longitude)) end table.insert(params, "W") elseif mode == "E" then if self.longitude >= 0 then table.insert(params, string.format("%f", self.longitude)) else table.insert(params, string.format("%f", 360+self.longitude)) end table.insert(params, "E") elseif self.longitude >= 0 then table.insert(params, string.format("%f", self.longitude)) table.insert(params, "E") else table.insert(params, string.format("%f", -self.longitude)) table.insert(params, "W") end

if self.params then table.insert(params, self.params) end

if self.name then params.name = self.name end

-- https://bugzilla.wikimedia.org/show_bug.cgi?id=50863 RESOLVED return mw.getCurrentFrame():callParserFunction("#coordinates", params) or "" end

return result; end

local function showError(message, args) if not message then return geoformatdata.errorCategory end

local result = {} table.insert(result, "") assert(type(message) == "string", "Expected string message") table.insert(result, message) local i = 1 while args[i] do if i == 1 then table.insert(result, ": {") else table.insert(result, "|") end

table.insert(result, args[i]) i = i + 1 end if i > 1 then table.insert(result, "}") end

table.insert(result, "")

if mw.title.getCurrentTitle().namespace == 0 then table.insert(result, geoformatdata.errorCategory) end

return table.concat(result, "") end

local function parse(frame, link) local coordinates = create() local args = frame.args local status, errorMessage = coordinates:parseCoordinates(args) if not status then return showError(errorMessage, args) end

local status, errorMessage = coordinates:parseOptions(args) if not status then return showError(errorMessage, args) end

coordinates.link = link coordinates:normalize() return coordinates:display()..coordinates:extensionGeoData() end

function m.format(frame) return parse(frame, false) end

function m.link(frame) return parse(frame, true) end

m[geoformatdata.apiTemplateName] = function (frame) local coordinates = create() local args = frame:getParent().args local status, errorMessage = coordinates:parseCoordinates(args) if not status then return showError(errorMessage, args) end

local status, errorMessage = coordinates:parseOptions(args) if not status then return showError(errorMessage, args) end

coordinates:normalize() return coordinates:display()..coordinates:extensionGeoData() end

m[geoformatdata.apiMicroName] = function (frame) local coordinates = create() local args = frame:getParent().args local status, errorMessage = coordinates:parseCoordinates(args) if not status then return showError(errorMessage, args) end

-- the only available option coordinates.name = args[geoformatdata.argName]

-- options are implied in micro variant if coordinates.precision > 0.00027777777777777800 then coordinates.precision = 0.00027777777777777800 -- seconds elseif coordinates.precision < 0.00002777777777777780 then coordinates.precision = 0.00002777777777777780 -- seconds with one decimal digit end

if not coordinates.params then coordinates.params = "scale:5000" -- bonus end

coordinates.inline = true coordinates.top = false coordinates.link = true

-- simple link without geodata extension coordinates:normalize() return coordinates:display() end

m[geoformatdata.apiAutoName] = function(frame)

local entity = mw.wikibase.getEntityObject() if not entity then mw.log("missing entity") return nil end -- missing entity local claims = entity.claims if not claims then mw.log("missing claims") return nil end -- missing claims

local function selectProperty(pid) local prop = claims[pid] if not prop then return false end -- missing property

-- load preferred statements local result = {} for _, v in ipairs(prop) do if v.rank == "preferred" then table.insert(result, v) end end

if #result ~= 0 then return true, result end

for _, v in ipairs(prop) do if v.rank == "normal" then table.insert(result, v) end end

if #result ~= 0 then return true, result end

mw.log("empty property table") return false -- empty property table end

local function selectValue(prop, expectedType) if not prop then return false end if prop.type ~= "statement" then return false end local snak = prop.mainsnak if not snak or snak.snaktype ~= "value" then return false end local datavalue = snak.datavalue if not datavalue or datavalue.type ~= expectedType then return false end local value = datavalue.value if not value then return false end return true, value end

function selectGlobe(globe) local globes = { ["http://www.wikidata.org/entity/Q2"] = { symbol="Ziemia ", link="" }, ["http://www.wikidata.org/entity/Q405"] = { symbol="Błąd przy generowaniu miniatury: ", link="globe:Moon" }, ["http://www.wikidata.org/entity/Q111"] = { symbol="Błąd przy generowaniu miniatury: ", link="globe:Mars" }, ["http://www.wikidata.org/entity/Q308"] = { symbol="Merkury ", link="globe:Mercury" }, ["http://www.wikidata.org/entity/Q313"] = { symbol="Wenus ", link="globe:Venus" }, }

mw.log("GLOBE: "..(globe or "http://www.wikidata.org/entity/Q2")) return globes[globe or "http://www.wikidata.org/entity/Q2"] end

function selectType() local types = { unknownType = "type:city", { property = "P300", [150093] = "type:adm1st", [247073] = "type:adm2nd", [925381] = "type:adm2nd", [3504085] = "type:adm3rd", [3491915] = "type:adm3rd", [2616791] = "type:adm3rd", }, { property = "P31", [515] = "type:city", [6256] = "type:country", [5107] = "type:satellite", [165] = "type:satellite", }, }

for _, pset in ipairs(types) do local status, classes = selectProperty(pset.property) if status then for _, p in ipairs(classes) do local status2, v = selectValue(p, "wikibase-entityid") if status2 and v["entity-type"] == "item" then local result = pset[v["numeric-id"]] if result then return result end end end end end

return types.unknownType end

local status1, coordinates = selectProperty("P" .. (frame.args[1] or "625")) if not status1 then return nil end local status2, autocoords = selectValue(coordinates[1], "globecoordinate") if not status2 then return nil end local argGlobe = frame.args[geoformatdata.argGlobe] local globe = argGlobe == "" and { symbol="", link="" } or selectGlobe(argGlobe or autocoords.globe) or { symbol="", link=false } if not globe.link then return nil end -- not supported globe

local params = { selectType(), } if #globe.link > 0 then table.insert(params, globe.link) end

local coords = create() coords:parseOptions(frame.args) coords.latitude = autocoords.latitude coords.longitude = autocoords.longitude coords.precision = autocoords.precision or 1 coords.params = table.concat(params,"_")

coords:normalize() return coords:display(globe.symbol) end

m[geoformatdata.apiLatitude] = function (frame) local coordinates = create() local status = coordinates:parseCoordinates(frame.args) return status and coordinates.latitude or "" end

m[geoformatdata.apiLongitude] = function (frame) local coordinates = create() local status = coordinates:parseCoordinates(frame.args) return status and coordinates.longitude or "" end

return m