خانه
تصادفی
ورود
تنظیمات
دربارهٔ ویکی حج
جستجو
در حال ویرایش
پودمان:Coordinates2
هشدار:
شما وارد نشدهاید. نشانی آیپی شما برای عموم قابل مشاهده خواهد بود اگر هر تغییری ایجاد کنید. اگر
وارد شوید
یا
یک حساب کاربری بسازید
، ویرایشهایتان به نام کاربریتان نسبت داده خواهد شد، همراه با مزایای دیگر.
بررسی ضدهرزنگاری. این قسمت را پر
نکنید
!
--[[ * Modulo per implementare le funzionalità di Coord * * Traduce in lua: * Template:Coord * Template:Coord/input/dec * Template:Coord/input/d * Template:Coord/input/dm * Template:Coord/input/dms * Template:Coord/input/ERROR * Template:Coord/input/error2 * Template:Coord/link * Template:Coord/prec dec * Template:Coord/dms2dec * Template:Coord/dec2dms * Template:Coord/dec2dms/d * Template:Coord/dec2dms/d1 * Template:Coord/dec2dms/dm * Template:Coord/dec2dms/dm1 * Template:Coord/dec2dms/dms * Template:Coord/dec2dms/dms1 * Template:Precision1 ]] -- Variabili globali local p = {} -- per l'esportazione delle funzioni del modulo local args = {} -- argomenti passati al template local errorTable = {} -- table per contenere gli errori da ritornare -- Configurazione local cfg = mw.loadData("Module:Coord2/config") ------------------------------------------------------------------------------- -- Funzioni di utilità ------------------------------------------------------------------------------- -- Ritorna il numero arrotondato al numero di cifre decimali richiesto local function round(num, idp) local mult = 10^(idp or 0) return math.floor(num * mult + 0.5) / mult end -- Ritorna la stringa "0 + numero" quando il numero è di una sola cifra, altrimenti lo stesso numero local function padleft0(num) return (num < 10 and "0" or "") .. num end -- Converte un numero in stringa senza usare la notazione scientifica, esempio tostring(0.00001) local function numberToString(num) -- la parentesi () extra serve per non ritornare anche il gsub.count return (string.format("%f", num):gsub("%.?0+$", "")) end -- Ritorna latitudine e longitudine della [[d:property:p625]] -- o nil nel caso non siano presenti local function getWikidataCoordinates() local entity, value, lat, long entity = mw.wikibase.getEntityObject() if entity and entity.claims and entity.claims.P625 and #entity.claims.P625 > 0 and entity.claims.P625[1].mainsnak.snaktype == "value" then value = entity.claims.P625[1].mainsnak.datavalue.value lat = round(value.latitude, 6) long = round(value.longitude, 6) end return lat, long end ------------------------------------------------------------------------------- -- Parsing parametri ------------------------------------------------------------------------------- -- Error handler per xpcall, formatta l'errore -- nel namespace principale aggiunge una categoria di warning local function errhandler(msg) local cat = "" if mw.title.getCurrentTitle().namespace == 0 then cat = "[[Categoria:" .. cfg.categorie["warning"] .. "]]\n" end return string.format("%s<span style=\"color:red;\">Il template {{Coord}} ha riscontrato degli errori " .. "([[Template:Coord|istruzioni]]):\n%s</span>\n", cat, msg:match(".+%d:%s(.+)$")) end -- Raccoglie più messaggi di errore in un'unica table prima di usare error() local function dumpError(...) local arg = {...} table.insert(errorTable, "* ") for _, val in ipairs(arg) do table.insert(errorTable, val) end table.insert(errorTable, "\n") end -- Parsifica il parametro "display" local function getDisplay() local display = {} display.inline = not args["display"] or args["display"] == "inline" or args["display"] == "inline,title" display.title = args["display"] == "title" or args["display"] == "inline,title" display.debug = args["display"] == "debug" return display end -- Con le richieste "dm" e "dms" verifica se ci sono -- parametri lasciati vuoti in modo valido. -- Ritorna il tipo di richiesta dopo la eventuale semplificazione. local function paramsEmpty(reqFormat) if reqFormat == "dms" then -- {{coord|1|2||N|5|6||E}} valido if args[3] == "" and args[7] == "" then table.remove(args, 7) table.remove(args, 3) reqFormat = "dm" -- {{coord|1|2|3|N|5|6||E}} non valido elseif args[3] == "" or args[7] == "" then error("* lat e long hanno diversa precisione") -- {{coord|1||3|N|5||7|E}} valido elseif args[2] == "" and args[6] == "" then args[2], args[6] = 0, 0 -- {{coord|1|2|3|N|5||7|E}} non valido elseif args[2] == "" or args[6] == "" then error("* lat e long hanno diversa precisione") end end if reqFormat == "dm" then -- {{coord|1||N|4||E}} valido if args[2] == "" and args[5] == "" then table.remove(args, 5) table.remove(args, 2) reqFormat = "d" -- {{coord|1|2|N|4||E}} non valido elseif args[2] == "" or args[5] == "" then error("* lat e long hanno diversa precisione") end end return reqFormat end -- Riconosce il tipo di richiesta ("dec", "d", "dm" o "dms") e parsifica i parametri posizionali -- Ritorna il tipo di richiesta. local function paramsParse() local reqFormat, globe, earth, prefix, num, str local param = {} -- riconoscimento tipo di richiesta if #args < 2 then error("* coordinate non specificate") elseif #args < 4 then reqFormat = "dec" elseif #args < 6 then reqFormat = "d" elseif #args < 8 then reqFormat = "dm" elseif #args < 10 then reqFormat = "dms" else error("* errato numero di parametri") end -- valida i parametri che possono essere lasciati vuoti reqFormat = paramsEmpty(reqFormat) -- validazione parametri posizionali currFormat = cfg.params[reqFormat] globe = args[#args]:match("globe:(%w+)") earth = not globe or globe == "earth" for k, v in ipairs(args) do if currFormat[k] then param.type = currFormat[k][1] param.name = currFormat[k][2] param.min = currFormat[k][3] param.max = currFormat[k][4] prefix = reqFormat .. " format: " .. param.name -- valida un parametro di tipo numero if param.type == "number" then num = tonumber(v) if num then if earth and num < param.min then dumpError(prefix, " < ", param.min) elseif earth and math.floor(num) > param.max then dumpError(prefix, " > ", param.max) end else dumpError(prefix, " non è un numero") end -- valida un parametro di tipo stringa elseif param.type == "string" then if v ~= param.min and v ~= param.max then dumpError(prefix, " diverso da ", param.min, " e da ", param.max) end end end end if #errorTable > 0 then error(table.concat(errorTable)) end return reqFormat end ------------------------------------------------------------------------------- -- classi DecCoord e DmsCoord ------------------------------------------------------------------------------- -- Rappresenta una coordinata (lat o long) in gradi decimali local DecCoord = {} -- Rappresenta una coordinata (lat o long) in gradi/minuti/secondi local DmsCoord = {} -- Costruttore di DecCoord -- deg: gradi decimali, positivi o negativi, se negativi viene cambiato il segno e -- la direzione cardinale eventualmente invertita -- card: direzione cardinale (N|S|E|W) function DecCoord:new(deg, card) local self = {} setmetatable(self, { __index = DecCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) if self.deg < 0 then self.card = card == "N" and "S" or (card == "E" and "W" or card) self.deg = -self.deg else self.card = card end return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DecCoord:__tostring() return numberToString(self.deg) .. "°" .. self.card end -- Ritorna i gradi con segno function DecCoord:getDeg() local deg = self.deg * ((self.card == "N" or self.card =="E") and 1 or -1) return numberToString(deg) end -- Ritorna un nuovo oggetto DmsCoord, convertendo in gradi/minuti/secondi function DecCoord:toDms() local deg, min, sec deg = round(self.deg * 3600, 2) sec = round(math.floor(deg) % 60 + deg - math.floor(deg), 2) deg = math.floor((deg - sec) / 60) min = deg % 60 deg = math.floor((deg - min) / 60) % 360 return DmsCoord:new(deg, min, sec, self.card) end -- Costruttore di DmsCoord -- deg: gradi -- min: minuti, può essere nil -- sec: secondi, può essere nil -- card: direzione cardinale (N|S|E|W) function DmsCoord:new(deg, min, sec, card) local self = {} setmetatable (self, { __index = DmsCoord, __tostring = function(t) return self:__tostring() end, __concat = function(t, t2) return tostring(t) .. tostring(t2) end }) self.deg = tonumber(deg) self.min = min and tonumber(min) self.sec = sec and tonumber(sec) self.card = card return self end -- Richiamata automaticamente ogni volta che è richiesto un tostring o un concatenamento function DmsCoord:__tostring() return self.deg .. "°" .. (self.min and (padleft0(self.min) .. "′") or "") .. (self.sec and (padleft0(self.sec) .. "″") or "") .. self.card end -- Ritorna un nuovo oggetto DecCoord, convertendo in gradi decimali function DmsCoord:toDec() local deg = round((self.deg + ((self.min or 0) + (self.sec or 0) / 60) / 60), 6) return DecCoord:new(deg, self.card) end ------------------------------------------------------------------------------- -- Coord ------------------------------------------------------------------------------- -- Nel namespace principale e con display.title legge la [[d:property:p625]] -- e la utilizza come latitudine e longitudine se non fornite dall'utente. -- Ritorna la categoria appropriata per [[Categoria:Wikidata]], altrimenti una stringa vuota local function checkWikidata(display) local wdLat, wdLong, cat if mw.title.getCurrentTitle().namespace == 0 and display.title then wdLat, wdLong = getWikidataCoordinates() if wdLat and wdLong then -- se l'utente non ha fornito lat e long usa quelli di Wikidata if #args == 0 or (#args == 1 and not tonumber(args[1])) then table.insert(args, numberToString(wdLat)) table.insert(args, numberToString(wdLong)) if #args == 3 then table.insert(args, table.remove(args, 1)) end cat = "Coordinate assenti ma presenti su Wikidata" end else cat = "Coordinate non presenti su Wikidata" end end return cat and ("[[Categoria:" .. cat .. "]]") or "" end -- Crea l'HTML ritornato da Coord local function buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat, display) local root, text, url, htmlTitle, noprint -- geohack url e parametri url = cfg.geohackUrl .. "&pagename=" .. mw.uri.encode(mw.title.getCurrentTitle().prefixedText, "WIKI") .. "¶ms=" .. geohackParams .. (args["name"] and ("&title=" .. mw.uri.encode(args["name"])) or "") root = mw.html.create("") root :tag("span") :addClass("plainlinks nourlexpansion") :wikitext("[" .. url) :tag("span") :addClass(defaultFormat == "dec" and "geo-nondefault" or "geo-default") :tag("span") :addClass("geo-dms") :attr("title", "Mappe, foto aeree e altri dati per questa posizione") :tag("span") :addClass("latitude") :wikitext(tostring(dmsLat)) :done() :wikitext(" ") :tag("span") :addClass("longitude") :wikitext(tostring(dmsLong)) :done() :done() :done() :tag("span") :addClass("geo-multi-punct") :wikitext(" / ") :done() :tag("span") :addClass(defaultFormat == "dec" and "geo-default" or "geo-nondefault") :wikitext(args["name"] and "<span class=\"vcard\">" or "") :tag("span") :addClass("geo-dec") :attr("title", "Mappe, foto aeree e altri dati per questa posizione") :wikitext(decLat .. " " .. decLong) :done() :tag("span") :attr("style", "display:none") :tag("span") :addClass("geo") :wikitext(decLat:getDeg() .. "; " .. decLong:getDeg()) :done() :done() :wikitext(args["name"] and ("<span style=\"display:none\"> (<span class=\"fn org\">" .. args["name"] .. "</span>)</span></span>") or "") :done() :wikitext("]") :done() -- formatta il risultato a seconda di args["display"] (nil, "inline", "title", "inline,title") text = tostring(root) .. (args["notes"] or "") -- se inline e title, in stampa deve apparire solo il primo noprint = display.inline and "class=\"noprint\" " or "" htmlTitle = "<span style=\"font-size: small;\"><span " .. noprint .. "id=\"coordinates\">[[مختصات جغرافیایی|مختصات]]: " return (display.inline and text or "") .. (display.title and (htmlTitle .. text .. "</span></span>") or "") end -- Dato un input fino a 9 parametri posizionali e 4 con nome, ritorna un html -- contenente le coordinate in formato dec e dms come collegamento esterno a geohack.php. local function coord() local decLat, degLong, dmsLat, dmsLong local reqFormat, defaultFormat, geohackParams, display, wdCat, gdStr, gdRet, ret -- parsifica il parametro "display" display = getDisplay() -- legge [[d:property:p625]] ed eventualmente la utilizza wdCat = checkWikidata(display) -- parsifica i parametri posizionali ret, reqFormat = xpcall(paramsParse, errhandler) if not ret then return reqFormat end if reqFormat == "dec" then -- {{coord|1.111|2.222}} decLat = DecCoord:new(args[1], "N") decLong = DecCoord:new(args[2], "E") elseif reqFormat == "d" then -- {{coord|1.111|N|3.333|W}} decLat = DecCoord:new(args[1], args[2]) decLong = DecCoord:new(args[3], args[4]) elseif reqFormat == "dm" then -- {{coord|1|2|N|4|5|W}} dmsLat = DmsCoord:new(args[1], args[2], nil, args[3]) dmsLong = DmsCoord:new(args[4], args[5], nil, args[6]) elseif reqFormat == "dms" then -- {{coord|1|2|3|N|5|6|7|W}} dmsLat = DmsCoord:new(args[1], args[2], args[3], args[4]) dmsLong = DmsCoord:new(args[5], args[6], args[7], args[8]) end -- conversioni dec <=> dms if reqFormat == "dec" or reqFormat == "d" then dmsLat = decLat:toDms() dmsLong = decLong:toDms() -- rimuove secondi e minuti se zero e presenti in lat e long if dmsLat.sec == 0 and dmsLong.sec == 0 then dmsLat.sec, dmsLong.sec = nil, nil if dmsLat.min == 0 and dmsLong.min == 0 then dmsLat.min, dmsLong.min = nil, nil end end elseif reqFormat == "dm" or reqFormat == "dms" then decLat = dmsLat:toDec() decLong = dmsLong:toDec() end if args["format"] then defaultFormat = args["format"] elseif reqFormat == "dec" then defaultFormat = "dec" else defaultFormat = "dms" end -- crea la stringa param per geohack.php if reqFormat == "dec" then geohackParams = args[1] .. "_N_" .. args[2] .. "_E" .. (args[3] and ("_" .. args[3]) or "") else -- concatena solo i posizionali geohackParams = table.concat(args, "_") end -- utilizza l'estensione [[:mw:Extension:GeoData]] gdStr = string.format("{{#coordinates:%s|%s|name=%s}}", table.concat(args, "|"), (display.title and mw.title.getCurrentTitle().namespace == 0) and "primary" or "", args["name"] or "") gdRet = mw.getCurrentFrame():preprocess(gdStr) return display.debug and (decLat .. " " .. decLong .. " " .. dmsLat .. " " .. dmsLong) or wdCat .. buildHTML(decLat, decLong, dmsLat, dmsLong, geohackParams, defaultFormat, display) .. gdRet end -- Entry-point per eventuale {{dms2dec}} function p.dms2dec(frame) local args = frame.args -- {{dms2dec|N|2|3|4}} return DmsCoord:new(args[2], args[3], args[4], args[1]):toDec():getDeg() end -- Entry-point per eventuale {{dec2dms}} function p.dec2dms(frame) local args = frame.args -- {{dec2dms|1.111|N|S}} return DecCoord:new(args[1], tonumber(args[1]) >= 0 and args[2] or args[3]):toDms() end -- Entry-point per {{coord}} function p.coord(frame) -- copia i parametri ricevuti, eccetto quelli con nome valorizzati a stringa vuota for k, v in pairs(frame:getParent().args) do if v ~= "" or tonumber(k) then args[k] = string.gsub(v, "^%s*(.-)%s*$", "%1") end end -- retrocompatibilità con una funzionalità nascosta del precedente template: -- ignorava qualunque parametro posizionale vuoto dopo longitudine e parametri geohack for i = #args, 1, -1 do if args[i] == "" then table.remove(args, i) else break end end -- rimuove i parametri posizionali vuoti front to back fermandosi al primo non vuoto while args[1] == "" do table.remove(args, 1) end return coord() end return p
خلاصه:
لطفاً توجه داشتهباشید که همهٔ مشارکتها در ویکی حج منتشرشده تحت Creative Commons Attribution-NonCommercial-ShareAlike در نظر گرفتهمیشوند (برای جزئیات بیشتر
ویکی حج:حق تکثیر
را ببینید). اگر نمیخواهید نوشتههایتان بیرحمانه ویرایش و توزیع شوند؛ بنابراین، آنها را اینجا ارائه نکنید.
شما همچنین به ما تعهد میکنید که خودتان این را نوشتهاید یا آن را از یک منبع با مالکیت عمومی یا مشابه آزاد آن برداشتهاید (برای جزئیات بیشتر
ویکی حج:حق تکثیر
را ببینید).
کارهای دارای حق تکثیر را بدون اجازه ارائه نکنید!
لغو
راهنمای ویرایشکردن
(در پنجرهٔ تازه باز میشود)
الگوی بهکاررفته در این صفحه:
پودمان:Coordinates2/توضیحات
(
ویرایش
)