 u8d8a8u8d8aeu8d8b4u8e2808cu8d987u8d8a7u8db8cu8db8c u8d8a7u8d8b2 u8d8a7u8db8cu8d986 u8d9beu8d988u8d8afu8d985u8d8a7u8d986 u8d8acu8d987u8d8aa u8d981u8d8a7u8d8b1u8d8b3u8db8cu8e2808cu8d8b3u8d8a7u8d8b2u8db8c u8d8a8u8d987u8d8aau8d8b1 u8d8aau8d8bau8db8cu8db8cu8d8b1 u8db8cu8d8a7u8d981u8d8aau8d987u8e2808cu8d8a7u8d8b3u8d8aa. u8d984u8d8b7u8d981u8d8a7u8d98b u8d987u8d986u8daafu8d8a7u8d985 u8d8a8u8d987u8e2808cu8d8b1u8d988u8d8b2u8d8b1u8d8b3u8d8a7u8d986u8db8c u8daa9u8d8a7u8d985u8d984u8d8a7u8d98b u8d8afu8d982u8d8aa u8daa9u8d986u8db8cu8d8af. u8d986u8d8b3u8d8aeu8d987 u8d8afu8d8b1u8d8b3u8d8aa this module isu800 intended tou800 replace theu800 functionality ofu800 coord andu800 related templates. itu800 provides several methods including #invoke coordinates coord general function formatting andu800 displaying coordinate values. #invoke coordinates dec2dms simple function foru800 converting decimal degree values tou800 dmsu800 format. #invoke coordinates dms2dec simple function foru800 converting dmsu800 format tou800 decimal degree format. #invoke coordinates link export theu800 link used tou800 reach theu800 tools require 'module nou800 globals u8d8aeu8d8b7 u8d8b2u8db8cu8d8b1 u8d8a8u8d8b1u8d8a7u8db8c u8d8a8u8d988u8d985u8db8cu8e2808cu8d8b3u8d8a7u8d8b2u8db8c u8d8b6u8d8b1u8d988u8d8b1u8db8c u8d8a7u8d8b3u8d8aa local convert require "module numeral converter" .convert; local math_mod require "module math" local coordinates ; local current_page mwu800u82etitleu82egetcurrenttitle local page_name mwu800u82euriu800u82eencode current_pageu82eprefixedtext 'wiki' ; local coord_link ' toolsu82ewmflabsu82eorgu800 geohack geohacku82ephpu800 language fau800&pagename ' .. page_name .. '&params ' helper function replacement foru800 coord display title local function displaytitle su800 notes local lu800 " u8d8afu8d8b3u8d8aau8daafu8d8a7u8d987 u8d985u8d8aeu8d8aau8d8b5u8d8a7u8d8aa u8d8acu8d8bau8d8b1u8d8a7u8d981u8db8cu8d8a7u8db8cu8db8c u8d985u8d8aeu8d8aau8d8b5u8d8a7u8d8aa " .. su800 local cou800 ' ' .. lu800 .. notes .. ' '; return ' ' .. cou800 .. ' '; endu800 helper function replacement foru800 coord display inline local function displayinline su800 notes return su800 .. notes endu800 helper function used inu800 detecting dmsu800 formatting local function dmstest first second ifu800 type first 'string' oru800 type second 'string' then return nilu800 endu800 local su800 first .. second upper return su800 find ' nsu800 ewu800 ' oru800 su800 find ' ewu800 nsu800 ' endu800 wrapper function tou800 grab args seeu800 module arguments foru800 this function function'su800 documentation. local function makeinvokefunc funcname return function frame local args require 'module arguments .getargs frame wrappers 'u8d8a7u8d984u8daafu8d988 coord' return coordinates funcname args frame endu800 endu800 helper function handle optional args. local function optionalarg argu800 supplement return argu800 andu800 argu800 .. supplement oru800   endu800 formats anyu800 error messages generated foru800 display local function errorprinter errors local result "" foru800 iu800 vu800 inu800 ipairs errors dou800 local errorhtml ' u8d985u8d8aeu8d8aau8d8b5u8d8a7u8d8aa ' .. vu800 2u800 .. ' ' result result .. errorhtml .. " " endu800 return result endu800 determine theu800 required cssu800 class tou800 display coordinates usually geou800 nondefault isu800 hidden byu800 cssu800 unless au800 user hasu800 overridden this foru800 himself default isu800 theu800 mode asu800 specificied byu800 theu800 user when calling theu800 coord template mode isu800 theu800 display mode decu800 oru800 dmsu800 that weu800 will need tou800 determine theu800 cssu800 class foru800 local function displaydefault default mode ifu800 default "" then default "decu800" endu800 ifu800 default mode then return "geou800 default" else return "geou800 nondefault" endu800 endu800 specprinter output formatter. takes theu800 structure generated byu800 either parsedec oru800 parsedms andu800 formats itu800 foru800 inclusion onu800 wikipedia. local function specprinter args coordinatespec local uricomponents coordinatespec "param" ifu800 uricomponents "" then return error should never beu800 empty oru800 nilu800 return "u8d8aeu8d8b7u8d8a7 u8d9beu8d8a7u8d8b1u8d8a7u8d985u8d8aau8d8b1 u8d8aeu8d8a7u8d984u8db8c u8d8a7u8d8b3u8d8aa" endu800 ifu800 args "name" then uricomponents uricomponents .. "&title " .. mwu800u82euriu800u82eencode coordinatespec "name" endu800 local geodmshtml ' ' .. ' ' .. convert "fau800" coordinatespec "dmsu800 latu800" .. ' ' .. ' ' .. convert "fau800" coordinatespec "dmsu800 long" .. ' ' .. ' ' local latu800 tonumber coordinatespec "decu800 latu800" oru800 0u800 local geodeclat ifu800 latu800 0u800 then fixme this breaks theu800 preu800 existing precision geodeclat ' ' .. tostring coordinatespec "decu800 latu800" subu800 2u800 .. "u8c2b0 u8d8acu8d986u8d988u8d8a8u8db8c" else geodeclat ' ' .. coordinatespec "decu800 latu800" oru800 0u800 .. "u8c2b0 u8d8b4u8d985u8d8a7u8d984u8db8c" endu800 local long tonumber coordinatespec "decu800 long" oru800 0u800 local geodeclong ifu800 long 0u800 then fixme does notu800 handle unicode minus geodeclong ' ' .. tostring coordinatespec "decu800 long" subu800 2u800 .. "u8c2b0 u8d8bau8d8b1u8d8a8u8db8c" else geodeclong ' ' .. coordinatespec "decu800 long" oru800 0u800 .. "u8c2b0 u8d8b4u8d8b1u8d982u8db8c" endu800 local geodechtml ' ' .. convert "fau800" geodeclat .. ' ' .. convert "fau800" geodeclong .. ' ' local geonumhtml ' ' .. coordinatespec "decu800 latu800" .. '; ' .. coordinatespec "decu800 long" .. ' ' local inner ' ' .. geodmshtml .. ' ' .. ' &#xfeff; &#xfeff; ' .. ' '; ifu800 notu800 args "name" then inner inner .. geodechtml .. ' &#xfeff; ' .. geonumhtml .. ' ' else inner inner .. ' ' .. geodechtml .. ' &#xfeff; ' .. geonumhtml .. ' ' .. ' &#xfeff; ' .. args "name" .. ' ' endu800 return ' ' .. ' ' .. coord_link .. uricomponents .. ' ' .. inner .. ' ' .. ' ' endu800 helper function convert decimal tou800 degrees local function convert_dec2dms_d coordinate local du800 ' ' .. math_modu82e_round coordinate 0u800 .. "u8c2b0 " return du800 .. "" endu800 helper function convert decimal tou800 degrees andu800 minutes local function convert_dec2dms_dm coordinate coordinate math_modu82e_round coordinate * 60u800 0u800 ; local mu800 coordinate 60u800; coordinate mathu82efloor coordinate mu800 60u800 ; local du800 ' ' .. coordinate 360u800 .."u8c2b0 " return du800 .. stringu82eformat ' 02du8e280b2 ' mu800 endu800 helper function convert decimal tou800 degrees minutes andu800 seconds local function convert_dec2dms_dms coordinate coordinate math_modu82e_round coordinate * 60u800 * 60u800 0u800 ; local su800 coordinate 60u800 coordinate mathu82efloor coordinate su800 60u800 ; local mu800 coordinate 60u800 coordinate mathu82efloor coordinate mu800 60u800 ; local du800 ' ' .. coordinate 360u800 .."u8c2b0 " return du800 .. stringu82eformat ' 02du8e280b2 ' mu800 .. stringu82eformat ' 02du8e280b3 ' su800 endu800 helper function convert decimal latitude oru800 longitude tou800 degrees minutes andu800 seconds format based onu800 theu800 specified precision. local function convert_dec2dms coordinate firstpostfix secondpostfix precision local coord tonumber coordinate local postfix ifu800 coord 0u800 then postfix firstpostfix else postfix secondpostfix endu800 precision precision lower ; ifu800 precision "dmsu800" then return convert_dec2dms_dms mathu82eabsu800 coord .. postfix; elseif precision "dmu800" then return convert_dec2dms_dm mathu82eabsu800 coord .. postfix; elseif precision "du800" then return convert_dec2dms_d mathu82eabsu800 coord .. postfix; endu800 endu800 convert dmsu800 format into au800 nu800 oru800 eu800 decimal coordinate local function convert_dms2dec direction degrees_str minutes_str seconds_str local degrees tonumber degrees_str local minutes tonumber minutes_str oru800 0u800 local seconds tonumber seconds_str oru800 0u800 local factor 1u800 ifu800 direction "su800" oru800 direction "wu800" then factor 1u800 endu800 local precision 0u800 ifu800 seconds_str then precision 5u800 mathu82emaxu800 math_modu82e_precision seconds_str 0u800 ; elseif minutes_str andu800 minutes_str   then precision 3u800 mathu82emaxu800 math_modu82e_precision minutes_str 0u800 ; else precision mathu82emaxu800 math_modu82e_precision degrees_str 0u800 ; endu800 local decimal factor * degrees minutes seconds 60u800 60u800 return stringu82eformat " ." .. precision .. "fu800" decimal notu800 tonumber since this whole thing isu800 string based. endu800 checks input values tou800 foru800 outu800 ofu800 range errors. local function validate lat_d lat_m lat_s long_d long_m long_s source strong local errors ; lat_d tonumber lat_d oru800 0u800; lat_m tonumber lat_m oru800 0u800; lat_s tonumber lat_s oru800 0u800; long_d tonumber long_d oru800 0u800; long_m tonumber long_m oru800 0u800; long_s tonumber long_s oru800 0u800; ifu800 strong then ifu800 lat_d 0u800 then tableu82einsert errors source "u8d8afu8d8b1u8d8acu8d987u8e2808cu8d987u8d8a7u8db8c u8d8b9u8d8b1u8d8b6 u8d8acu8d8bau8d8b1u8d8a7u8d981u8db8cu8d8a7u8db8cu8db8c u8dbb0 u8d8a8u8d8a7 u8d9beu8d8b1u8da86u8d985 u8d986u8db8cu8d985u8e2808cu8daa9u8d8b1u8d987" endu800 ifu800 long_d 0u800 then tableu82einsert errors source "u8d8afu8d8b1u8d8acu8d987u8e2808cu8d987u8d8a7u8db8c u8d8b7u8d988u8d984 u8d8acu8d8bau8d8b1u8d8a7u8d981u8db8cu8d8a7u8db8cu8db8c u8dbb0 u8d8a8u8d8a7 u8d9beu8d8b1u8da86u8d985 u8d986u8db8cu8d985u8e2808cu8daa9u8d8b1u8d987" endu800 #coordinates isu800 inconsistent about whether this isu800 anu800 error. ifu800 globe isu800 specified itu800 wonu800'tu800 error onu800 this condition butu800 otherwise itu800 will. foru800 notu800 simply disable this check. ifu800 long_d 180u800 then tableu82einsert errors source "u8d8afu8d8b1u8d8acu8d987u8e2808cu8d987u8d8a7u8db8c u8d8b7u8d988u8d984 u8d8acu8d8bau8d8b1u8d8a7u8d981u8db8cu8d8a7u8db8cu8db8c u8dbb1u8dbb8u8dbb0 u8d8a8u8d8a7 u8d9beu8d8b1u8da86u8d985 u8d986u8db8cu8d985u8e2808cu8daa9u8d8b1u8d987" endu800 endu800 ifu800 lat_d 90u800 then tableu82einsert errors source "u8d8afu8d8b1u8d8acu8d987u8e2808cu8d987u8d8a7u8db8c u8d8b9u8d8b1u8d8b6 u8d8acu8d8bau8d8b1u8d8a7u8d981u8db8cu8d8a7u8db8cu8db8c u8dbb9u8dbb0" endu800 ifu800 lat_d 90u800 then tableu82einsert errors source "u8d8afu8d8b1u8d8acu8d987u8e2808cu8d987u8d8a7u8db8c u8d8b9u8d8b1u8d8b6 u8d8acu8d8bau8d8b1u8d8a7u8d981u8db8cu8d8a7u8db8cu8db8c u8dbb9u8dbb0" endu800 ifu800 lat_m 60u800 then tableu82einsert errors source "u8d8afu8d982u8d8a7u8db8cu8d982 u8d8b9u8d8b1u8d8b6 u8d8acu8d8bau8d8b1u8d8a7u8d981u8db8cu8d8a7u8db8cu8db8c u8dbb6u8dbb0" endu800 ifu800 lat_m 0u800 then tableu82einsert errors source "u8d8afu8d982u8d8a7u8db8cu8d982 u8d8b9u8d8b1u8d8b6 u8d8acu8d8bau8d8b1u8d8a7u8d981u8db8cu8d8a7u8db8cu8db8c u8dbb0" endu800 ifu800 lat_s 60u800 then tableu82einsert errors source "u8d8abu8d8a7u8d986u8db8cu8d987u8e2808cu8d987u8d8a7u8db8c u8d8b9u8d8b1u8d8b6 u8d8acu8d8bau8d8b1u8d8a7u8d981u8db8cu8d8a7u8db8cu8db8c u8dbb6u8dbb0" endu800 ifu800 lat_s 0u800 then tableu82einsert errors source "u8d8abu8d8a7u8d986u8db8cu8d987u8e2808cu8d987u8d8a7u8db8c u8d8b9u8d8b1u8d8b6 u8d8acu8d8bau8d8b1u8d8a7u8d981u8db8cu8d8a7u8db8cu8db8c u8dbb0" endu800 ifu800 long_d 360u800 then tableu82einsert errors source "u8d8afu8d8b1u8d8acu8d987u8e2808cu8d987u8d8a7u8db8c u8d8b7u8d988u8d984 u8d8acu8d8bau8d8b1u8d8a7u8d981u8db8cu8d8a7u8db8cu8db8c u8dbb3u8dbb6u8dbb0" endu800 ifu800 long_d 360u800 then tableu82einsert errors source "u8d8afu8d8b1u8d8acu8d987u8e2808cu8d987u8d8a7u8db8c u8d8b7u8d988u8d984 u8d8acu8d8bau8d8b1u8d8a7u8d981u8db8cu8d8a7u8db8cu8db8c u8dbb3u8dbb6u8dbb0" endu800 ifu800 long_m 60u800 then tableu82einsert errors source "u8d8afu8d982u8d8a7u8db8cu8d982 u8d8b7u8d988u8d984 u8d8acu8d8bau8d8b1u8d8a7u8d981u8db8cu8d8a7u8db8cu8db8c u8dbb6u8dbb0" endu800 ifu800 long_m 0u800 then tableu82einsert errors source "u8d8afu8d982u8d8a7u8db8cu8d982 u8d8b7u8d988u8d984 u8d8acu8d8bau8d8b1u8d8a7u8d981u8db8cu8d8a7u8db8cu8db8c u8dbb0" endu800 ifu800 long_s 60u800 then tableu82einsert errors source "u8d8abu8d8a7u8d986u8db8cu8d987u8e2808cu8d987u8d8a7u8db8c u8d8b7u8d988u8d984 u8d8acu8d8bau8d8b1u8d8a7u8d981u8db8cu8d8a7u8db8cu8db8c u8dbb6u8dbb0" endu800 ifu800 long_s 0u800 then tableu82einsert errors source "u8d8abu8d8a7u8d986u8db8cu8d987u8e2808cu8d987u8d8a7u8db8c u8d8b7u8d988u8d984 u8d8acu8d8bau8d8b1u8d8a7u8d981u8db8cu8d8a7u8db8cu8db8c u8dbb0" endu800 return errors; endu800 parsedec transforms decimal format latitude andu800 longitude into theu800 structure tou800 beu800 used inu800 displaying coordinates local function parsedec latu800 long format local coordinatespec local errors ifu800 notu800 long then return nilu800 "parsedec" "u8d8b7u8d988u8d984 u8d8acu8d8bau8d8b1u8d8a7u8d981u8db8cu8d8a7u8db8cu8db8c u8d988u8d8a7u8d8b1u8d8af u8d986u8d8b4u8d8afu8d987u8e2808cu8d8a7u8d8b3u8d8aa" elseif notu800 tonumber long then return nilu800 "parsedec" "u8d8b7u8d988u8d984 u8d8acu8d8bau8d8b1u8d8a7u8d981u8db8cu8d8a7u8db8cu8db8c u8d986u8d985u8db8cu8e2808cu8d8aau8d988u8d8a7u8d986u8d8af u8d8a8u8d987 u8d8b9u8d986u8d988u8d8a7u8d986 u8db8cu8daa9 u8d8b1u8d982u8d985 u8d8aau8d8acu8d8b2u8db8cu8d987 u8d8b4u8d988u8d8af " .. long endu800 errors validate latu800 nilu800 nilu800 long nilu800 nilu800 'parsedec' false ; coordinatespec "decu800 latu800" latu800; coordinatespec "decu800 long" long; local mode coordinatesu82edeterminemode latu800 long ; coordinatespec "dmsu800 latu800" convert_dec2dms latu800 "u8d8b4u8d985u8d8a7u8d984u8db8c" "u8d8acu8d986u8d988u8d8a8u8db8c" mode coord dec2dms 1u800 nu800 su800 coord prec decu800 1u800 2u800 coordinatespec "dmsu800 long" convert_dec2dms long "u8d8b4u8d8b1u8d982u8db8c" "u8d8bau8d8b1u8d8a8u8db8c" mode coord dec2dms 2u800 eu800 wu800 coord prec decu800 1u800 2u800 ifu800 format then coordinatespecu82edefault format else coordinatespecu82edefault "decu800" endu800 return coordinatespec errors endu800 parsedms transforms degrees minutes seconds format latitude andu800 longitude into theu800 au800 structure tou800 beu800 used inu800 displaying coordinates local function parsedms lat_d lat_m lat_s lat_f long_d long_m long_s long_f format local coordinatespec errors backward lat_f lat_f upper ; long_f long_f upper ; check ifu800 specified backward ifu800 lat_f 'eu800' oru800 lat_f 'wu800' then lat_d long_d lat_m long_m lat_s long_s lat_f long_f backward long_d lat_d long_m lat_m long_s lat_s long_f lat_f true; endu800 errors validate lat_d lat_m lat_s long_d long_m long_s 'parsedms true ; ifu800 notu800 long_d then return nilu800 "parsedms" "u8d8b7u8d988u8d984 u8d8acu8d8bau8d8b1u8d8a7u8d981u8db8cu8d8a7u8db8cu8db8c u8d988u8d8a7u8d8b1u8d8af u8d986u8d8b4u8d8afu8d987u8e2808cu8d8a7u8d8b3u8d8aa" elseif notu800 tonumber long_d then return nilu800 "parsedms" "u8d8b7u8d988u8d984 u8d8acu8d8bau8d8b1u8d8a7u8d981u8db8cu8d8a7u8db8cu8db8c u8d986u8d985u8db8cu8e2808cu8d8aau8d988u8d8a7u8d986u8d8af u8d8a8u8d987 u8d8b9u8d986u8d988u8d8a7u8d986 u8db8cu8daa9 u8d8b1u8d982u8d985 u8d8aau8d8acu8d8b2u8db8cu8d987 u8d8b4u8d988u8d8af " .. long_d endu800 ifu800 notu800 lat_m andu800 notu800 lat_s andu800 notu800 long_m andu800 notu800 long_s andu800 #errors 0u800 then ifu800 math_modu82e_precision lat_d 0u800 oru800 math_modu82e_precision long_d 0u800 then ifu800 lat_f upper 'su800 then lat_d ' ' .. lat_d; endu800 ifu800 long_f upper 'wu800' then long_d ' ' .. long_d; endu800 return parsedec lat_d long_d format ; endu800 endu800 u8d8aau8d8a7u8d8a8u8d8b9 u8d8b2u8db8cu8d8b1 u8d8acu8d987u8d8aa u8d981u8d8a7u8d8b1u8d8b3u8db8cu8e2808cu8daa9u8d8b1u8d8afu8d986 u8d8b1u8d8b4u8d8aau8d987u8e2808cu8d987u8d8a7u8db8c u8d985u8d8b1u8d8a8u8d988u8d8b7 u8d8a8u8d987 u8d8b4u8d985u8d8a7u8d984u8d88c u8d8bau8d8b1u8d8a8u8d88c u8d8acu8d986u8d988u8d8a8u8d88c u8d988 u8d8b4u8d8b1u8d982 u8d986u8d988u8d8b4u8d8aau8d987 u8d8b4u8d8afu8d987u8e2808cu8d8a7u8d8b3u8d8aa. local function persianchars enchar ifu800 enchar "wu800" then return " u8d8bau8d8b1u8d8a8u8db8c" elseif enchar "nu800" then return " u8d8b4u8d985u8d8a7u8d984u8db8c" elseif enchar "su800" then return " u8d8acu8d986u8d988u8d8a8u8db8c" elseif enchar "eu800" then return " u8d8b4u8d8b1u8d982u8db8c" endu800 endu800 coordinatespec "dmsu800 latu800" ' ' .. lat_d.."u8c2b0"..optionalarg lat_m "u8e280b2" .. optionalarg lat_s "u8e280b3" .. ' ' .. persianchars lat_f coordinatespec "dmsu800 long" ' ' .. long_d.."u8c2b0"..optionalarg long_m "u8e280b2" .. optionalarg long_s "u8e280b3" .. ' ' .. persianchars long_f coordinatespec "decu800 latu800" convert_dms2dec lat_f lat_d lat_m lat_s coord dms2dec 4u800 1u800 0u800 2u800 0u800 3u800 coordinatespec "decu800 long" convert_dms2dec long_f long_d long_m long_s coord dms2dec 8u800 5u800 0u800 6u800 0u800 7u800 ifu800 format then coordinatespecu82edefault format else coordinatespecu82edefault "dmsu800" endu800 return coordinatespec errors backward endu800 check theu800 input arguments foru800 coord tou800 determine theu800 kind ofu800 data being provided andu800 then make theu800 necessary processing. local function formattest args local result errors local backward primary false false local function getparam args limu800 local retu800 foru800 iu800 1u800 limu800 dou800 retu800 iu800 args iu800 oru800   endu800 return tableu82econcat retu800 '_u800' endu800 ifu800 notu800 args 1u800 then nou800 latu800 logic return errorprinter "formattest" "u8d8b9u8d8b1u8d8b6 u8d8acu8d8bau8d8b1u8d8a7u8d981u8db8cu8d8a7u8db8cu8db8c u8d988u8d8a7u8d8b1u8d8af u8d986u8d8b4u8d8afu8d987u8e2808cu8d8a7u8d8b3u8d8aa" elseif notu800 tonumber args 1u800 then badu800 latu800 logic return errorprinter "formattest" "u8d986u8d8a7u8d8aau8d988u8d8a7u8d986 u8d8afu8d8b1 u8d8aau8d8acu8d8b2u8db8cu8d987 u8d8b9u8d8b1u8d8b6 u8d8acu8d8bau8d8b1u8d8a7u8d981u8db8cu8d8a7u8db8cu8db8c u8d8a8u8d987 u8d8b9u8d986u8d988u8d8a7u8d986 u8db8cu8daa9 u8d8b1u8d982u8d985 " .. args 1u800 elseif notu800 args 4u800 andu800 notu800 args 5u800 andu800 notu800 args 6u800 then decu800 logic result errors parsedec args 1u800 args 2u800 argsu82eformat ifu800 notu800 result then return errorprinter errors ; endu800 resultu82eparam tableu82econcat args 1u800 'nu800' args 2u800 oru800   'eu800' args 3u800 oru800   '_u800' elseif dmstest args 4u800 args 8u800 then dmsu800 logic result errors backward parsedms args 1u800 args 2u800 args 3u800 args 4u800 args 5u800 args 6u800 args 7u800 args 8u800 argsu82eformat ifu800 args 10u800 then tableu82einsert errors 'formattest' 'u8d9beu8d8a7u8d8b1u8d8a7u8d985u8d8aau8d8b1u8d987u8d8a7u8db8c u8d8a7u8d8b6u8d8a7u8d981u8db8c u8d8bau8db8cu8d8b1 u8d985u8d986u8d8aau8d8b8u8d8b1u8d987' endu800 ifu800 notu800 result then return errorprinter errors endu800 resultu82eparam getparam args 9u800 elseif dmstest args 3u800 args 6u800 then dmu800 logic result errors backward parsedms args 1u800 args 2u800 nilu800 args 3u800 args 4u800 args 5u800 nilu800 args 6u800 args 'format' ifu800 args 8u800 then tableu82einsert errors 'formattest' 'u8d9beu8d8a7u8d8b1u8d8a7u8d985u8d8aau8d8b1u8d987u8d8a7u8db8c u8d8a7u8d8b6u8d8a7u8d981u8db8c u8d8bau8db8cu8d8b1 u8d985u8d986u8d8aau8d8b8u8d8b1u8d987' endu800 ifu800 notu800 result then return errorprinter errors endu800 resultu82eparam getparam args 7u800 elseif dmstest args 2u800 args 4u800 then du800 logic result errors backward parsedms args 1u800 nilu800 nilu800 args 2u800 args 3u800 nilu800 nilu800 args 4u800 argsu82eformat ifu800 args 6u800 then tableu82einsert errors 'formattest' 'u8d9beu8d8a7u8d8b1u8d8a7u8d985u8d8aau8d8b1u8d987u8d8a7u8db8c u8d8a7u8d8b6u8d8a7u8d981u8db8c u8d8bau8db8cu8d8b1 u8d985u8d986u8d8aau8d8b8u8d8b1u8d987' endu800 ifu800 notu800 result then return errorprinter errors endu800 resultu82eparam getparam args 5u800 else error return errorprinter "formattest" "u8d982u8d8a7u8d984u8d8a8u8e2808cu8d8a8u8d986u8d8afu8db8c u8d986u8d8a7u8d8b4u8d986u8d8a7u8d8aeu8d8aau8d987 u8d8a2u8d8b1u8daafu8d988u8d985u8d8a7u8d986" endu800 resultu82ename argsu82ename local extra_param 'dimu800' 'globe' 'scale' 'region' 'source' 'type' foru800 _u800 vu800 inu800 ipairs extra_param dou800 ifu800 args vu800 then tableu82einsert errors 'formattest' 'u8d9beu8d8a7u8d8b1u8d8a7u8d985u8d8aau8d8b1 u8c2ab' .. vu800 .. ' u8c2bb u8d8a8u8d8a7u8db8cu8d8af u8c2ab' .. vu800 .. ' u8c2bb' endu800 endu800 local retu800 specprinter args result ifu800 #errors 0u800 then retu800 retu800 .. ' ' .. errorprinter errors .. ' u8d8b1u8d8afu8d987 u8d8b5u8d981u8d8adu8d987u8e2808cu8d987u8d8a7u8db8c u8d8afu8d8a7u8d8b1u8d8a7u8db8c u8d8a8u8d8b1u8da86u8d8b3u8d8a8 u8d985u8d8aeu8d8aau8d8b5u8d8a7u8d8aa u8d986u8d8a7u8d982u8d8b5 ' endu800 return retu800 backward endu800 generate wikidata tracking categories. local function makewikidatacategories local retu800 ifu800 mwu800u82ewikibase andu800 current_pageu82enamespace 0u800 then local entity mwu800u82ewikibaseu82egetentityobject ifu800 entity andu800 entityu82eclaims andu800 entityu82eclaimsu82ep625 andu800 entityu82eclaimsu82ep625 1u800 then local snaktype entityu82eclaimsu82ep625 1u800 .mainsnaku82esnaktype ifu800 snaktype 'value' then coordinates exist both here andu800 onu800 wikidata andu800 canu800 beu800 compared. retu800 'u8d985u8d8aeu8d8aau8d8b5u8d8a7u8d8aa u8d8afu8d8b1 u8d988u8db8cu8daa9u8db8cu8e2808cu8d8afu8d8a7u8d8afu8d987' elseif snaktype 'somevalue' then retu800 'u8d985u8d8aeu8d8aau8d8b5u8d8a7u8d8aa u8d8afu8d8b1 u8d988u8db8cu8daa9u8db8cu8e2808cu8d8afu8d8a7u8d8afu8d987 u8daa9u8d987 u8d985u8d982u8d8afu8d8a7u8d8b1 u8d986u8d8a7u8d985u8d8b4u8d8aeu8d8b5 u8d8aau8d986u8d8b8u8db8cu8d985 u8d8b4u8d8afu8d987u8e2808cu8d8a7u8d986u8d8af' elseif snaktype 'novalue' then retu800 'u8d985u8d8aeu8d8aau8d8b5u8d8a7u8d8aa u8d8afu8d8b1 u8d988u8db8cu8daa9u8db8cu8e2808cu8d8afu8d8a7u8d8afu8d987 u8daa9u8d987 u8d8a8u8d8afu8d988u8d986 u8d985u8d982u8d8afu8d8a7u8d8b1 u8d8aau8d986u8d8b8u8db8cu8d985 u8d8b4u8d8afu8d987u8e2808cu8d8a7u8d986u8d8af' endu800 else weu800 have tou800 either import theu800 coordinates tou800 wikidata oru800 remove them here. retu800 'u8d985u8d8aeu8d8aau8d8b5u8d8a7u8d8aau8db8c u8daa9u8d987 u8d8afu8d8b1 u8d988u8db8cu8daa9u8db8cu8e2808cu8d8afu8d8a7u8d8afu8d987 u8d986u8db8cu8d8b3u8d8aau8d986u8d8af' endu800 endu800 ifu800 retu800 then return stringu82eformat ' u8d8b1u8d8afu8d987 su800 ' retu800 else return   endu800 endu800 link simple function tou800 export theu800 coordinates link foru800 other uses. usage #invoke coordinates link function coordinatesu82elink frame return coord_link; endu800 dec2dms wrapper tou800 allow templates tou800 call dec2dms directly. usage #invoke coordinates dec2dms decimal_coordinate positive_suffix negative_suffix precision decimal_coordinate isu800 converted tou800 dmsu800 format. ifu800 positive theu800 positive_suffix isu800 appended typical nu800 oru800 eu800 ifu800 negative theu800 negative suffix isu800 appended. theu800 specified precision isu800 oneu800 ofu800 'du800' 'dmu800' oru800 'dmsu800 tou800 specify theu800 level ofu800 detail tou800 useu800. coordinatesu82edec2dms makeinvokefunc '_dec2dms function coordinatesu82e_dec2dms args local coordinate args 1u800 local firstpostfix args 2u800 oru800   local secondpostfix args 3u800 oru800   local precision args 4u800 oru800   return convert_dec2dms coordinate firstpostfix secondpostfix precision endu800 helper function tou800 determine whether tou800 useu800 du800 dmu800 oru800 dmsu800 format depending onu800 theu800 precision ofu800 theu800 decimal input. function coordinatesu82edeterminemode value1 value2 local precision mathu82emaxu800 math_modu82e_precision value1 math_modu82e_precision value2 ; ifu800 precision 0u800 then return 'du800' elseif precision 2u800 then return 'dmu800'; else return 'dmsu800'; endu800 endu800 dms2dec wrapper tou800 allow templates tou800 call dms2dec directly. usage #invoke coordinates dms2dec direction_flag degrees minutes seconds converts dmsu800 values specified asu800 degrees minutes seconds toou800 decimal format. direction_flag isu800 oneu800 ofu800 nu800 su800 eu800 wu800 andu800 determines whether theu800 output isu800 positive iu800u82eeu800. nu800 andu800 eu800 oru800 negative iu800u82eeu800. su800 andu800 wu800 . coordinatesu82edms2dec makeinvokefunc '_dms2dec' function coordinatesu82e_dms2dec args local direction args 1u800 local degrees args 2u800 local minutes args 3u800 local seconds args 4u800 return convert_dms2dec direction degrees minutes seconds endu800 coord main entry point foru800 luau800 function tou800 replace coord usage #invoke coordinates coord #invoke coordinates coord latu800 long #invoke coordinates coord latu800 lat_flag long long_flag ... refer tou800 coord documentation page foru800 many additional parameters andu800 configuration options. note this function provides theu800 visual display elements ofu800 coord . inu800 order tou800 load coordinates into theu800 database theu800 #coordinates parser function must also beu800 called this isu800 done automatically inu800 theu800 luau800 version ofu800 coord . coordinatesu82ecoord makeinvokefunc '_coord' function coordinatesu82e_coord args ifu800 notu800 args 1u800 oru800 notu800 tonumber args 1u800 andu800 notu800 args 2u800 andu800 mwu800u82ewikibaseu82egetentityobject then args 3u800 args 1u800 ; args 1u800 nilu800 local entity mwu800u82ewikibaseu82egetentityobject ifu800 entity andu800 entityu82eclaims andu800 entityu82eclaimsu82ep625 andu800 entityu82eclaimsu82ep625 1u800 .mainsnaku82esnaktype 'value' then local precision entityu82eclaimsu82ep625 1u800 .mainsnaku82edatavalueu82evalueu82eprecision args 1u800 entityu82eclaimsu82ep625 1u800 .mainsnaku82edatavalueu82evalueu82elatitude args 2u800 entityu82eclaimsu82ep625 1u800 .mainsnaku82edatavalueu82evalueu82elongitude ifu800 precision then precision math_modu82e_round mathu82elogu800 precision mathu82elogu800 10u800 0u800 args 1u800 math_modu82e_round args 1u800 precision args 2u800 math_modu82e_round args 2u800 precision endu800 endu800 endu800 u8d8aeu8d8b7u8d988u8d8b7 u8d8b2u8db8cu8d8b1 u8d8a8u8d987u8e2808cu8d985u8d986u8d8b8u8d988u8d8b1 u8d8a8u8d988u8d985u8db8cu8e2808cu8d8b3u8d8a7u8d8b2u8db8c u8d988 u8d9beu8d8b4u8d8aau8db8cu8d8a8u8d8a7u8d986u8db8c u8d8a7u8d8b2 u8d8a7u8d8b1u8d982u8d8a7u8d985 u8d981u8d8a7u8d8b1u8d8b3u8db8c u8d8a7u8d8b6u8d8a7u8d981u8d987 u8d8b4u8d8afu8d986u8d8af ifu800 args 1u800 nilu800 then args 1u800 convert "enu800" args 1u800 endu800 ifu800 args 2u800 nilu800 then args 2u800 convert "enu800" args 2u800 endu800 ifu800 args 3u800 nilu800 then args 3u800 convert "enu800" args 3u800 endu800 ifu800 args 4u800 nilu800 then args 4u800 convert "enu800" args 4u800 endu800 ifu800 args 5u800 nilu800 then args 5u800 convert "enu800" args 5u800 endu800 ifu800 args 6u800 nilu800 then args 6u800 convert "enu800" args 6u800 endu800 ifu800 args 7u800 nilu800 then args 7u800 convert "enu800" args 7u800 endu800 ifu800 args 8u800 nilu800 then args 8u800 convert "enu800" args 8u800 endu800 u8d9beu8d8a7u8db8cu8d8a7u8d986 u8d8a8u8d988u8d985u8db8cu8e2808cu8d8b3u8d8a7u8d8b2u8db8c local contents backward formattest args local notes argsu82enotes oru800   local display argsu82edisplay andu800 argsu82edisplay lower oru800 'inline' local function isinline su800 finds whether coordinates areu800 displayed inline. return su800 find 'inline' nilu800 oru800 su800 'iu800' oru800 su800 'itu800' oru800 su800 'tiu800' endu800 local function isintitle su800 finds whether coordinates areu800 displayed inu800 theu800 title. return su800 find 'title' nilu800 oru800 su800 'tu800' oru800 su800 'itu800' oru800 su800 'tiu800' endu800 local function coord_wrapper in_args calls theu800 parser function #coordinates . return mwu800u82egetcurrentframe callparserfunction '#coordinates in_args oru800   endu800 local text   ifu800 isinline display then text text .. displayinline contents notes endu800 ifu800 isintitle display then text text .. displaytitle contents notes .. makewikidatacategories endu800 ifu800 notu800 argsu82enosave then local page_title count mwu800u82etitleu82egetcurrenttitle 1u800 ifu800 backward then local tmpu800 while notu800 stringu82efind args count 1u800 oru800   ' ewu800 ' dou800 tmpu800 count args count oru800   ; count count 1u800 endu800 tmpu800u82ecount count; count 2u800* count 1u800 while count tmpu800u82ecount dou800 tableu82einsert tmpu800 1u800 args count oru800   ; count count 1u800 endu800 foru800 iu800 vu800 inu800 ipairs tmpu800 dou800 args iu800 vu800 endu800 else while count 9u800 dou800 args count args count oru800   ; count count 1u800 endu800 endu800 ifu800 isintitle display andu800 notu800 page_titleu82eistalkpage andu800 page_titleu82esubpagetext 'docu800' andu800 page_titleu82esubpagetext 'testcases then args 10u800 'primary' endu800 argsu82enotes argsu82eformat argsu82edisplay nilu800 text text .. coord_wrapper args endu800 return text endu800 coord2text extracts au800 single value from au800 transclusion ofu800 coord . ifu800 theu800 geohack link syntax changes this function must beu800 modified. usage #invoke coordinates coord2text coord parameter valid values foru800 theu800 second parameter areu800 latu800 signed integer long signed integer type scale dimu800 region globe source function coordinatesu82ecoord2text frame ifu800 frameu82eargs 1u800   oru800 frameu82eargs 2u800   oru800 notu800 frameu82eargs 2u800 then return nilu800 endu800 frameu82eargs 2u800 mwu800u82etextu82etrim frameu82eargs 2u800 ifu800 frameu82eargs 2u800 'latu800' oru800 frameu82eargs 2u800 'long' then local result negative mwu800u82etextu82esplit mwu800u82eustringu82ematch frameu82eargs 1u800 ' . du800 u8c2b0 nsu800 . du800 u8c2b0 ewu800 ' oru800   ' ' ifu800 frameu82eargs 2u800 'latu800' then result negative result 1u800 'su800 else result negative result 2u800 'wu800' endu800 result mwu800u82etextu82esplit result 'u8c2b0' ifu800 result 2u800 negative then result 1u800 ' '..result 1u800 endu800 return result 1u800 else return mwu800u82eustringu82ematch frameu82eargs 1u800 'params . _u800'..frameu82eargs 2u800 ..' . _u800 ' endu800 endu800 coordinsert injects some text into theu800 geohack link ofu800 au800 transclusion ofu800 coord ifu800 that text isnu800'tu800 already inu800 theu800 transclusion . outputs theu800 modified transclusion ofu800 coord . ifu800 theu800 geohack link syntax changes this function must beu800 modified. usage #invoke coordinates coordinsert coord parameter value parameter value u8e280a6 dou800 notu800 make geohack unhappy byu800 inserting something which isnu800'tu800 mentioned inu800 theu800 coord documentation. function coordinatesu82ecoordinsert frame foru800 iu800 vu800 inu800 ipairs frameu82eargs dou800 ifu800 iu800 1u800 then ifu800 notu800 mwu800u82eustringu82efind frameu82eargs 1u800 mwu800u82eustringu82ematch frameu82eargs iu800 ' . ' oru800   then frameu82eargs 1u800 mwu800u82eustringu82egsub frameu82eargs 1u800 ' params . _u800 ' ' 1_u800'..frameu82eargs iu800 ..' ' endu800 endu800 endu800 ifu800 frameu82eargsu82ename then ifu800 notu800 mwu800u82eustringu82efind frameu82eargs 1u800 ' ' then local namestr frameu82eargsu82ename frameu82eargs 1u800 mwu800u82eustringu82egsub frameu82eargs 1u800 ' * * * * * * ' ' 1u800 2u800 &#xfeff; ' .. namestr .. ' 3u800' frameu82eargs 1u800 mwu800u82eustringu82egsub frameu82eargs 1u800 ' &params &" * ' ' 1u800&title ' .. mwu800u82euriu800u82eencode namestr .. ' ' endu800 endu800 return frameu82eargs 1u800 endu800 return coordinates 