한국   대만   중국   일본 
Mo đun:Coordinates ? Wikipedia ti?ng Vi?t B??c t?i n?i dung

Mo đun : Coordinates

Trang mô đun bị khóa vô hạn
Bach khoa toan th? m? Wikipedia
Tai li?u mo đun [ t?o ]
--[=[

Mo đun nay h? tr? [[B?n m?u:Coord]] va cac b?n m?u lien quan. No cung c?p vai

ph??ng th?c, nh?t la:


{{#g?i:Coordinates | coord }} : Ham t?ng quat đ? đ?nh d?ng va hi?n th? cac gia

tr? t?a đ?.


{{#g?i:Coordinates | dec2dms }} : Ham đ?n gi?n đ? chuy?n đ?i cac gia tr? th?p

phan ra đ?nh d?ng đ?-phut-giay.


{{#g?i:Coordinates | dms2dec }} : Ham đ?n gi?n đ? chuy?n đ?i đ?nh d?ng

đ?-phut-giay ra đ?nh d?ng đ? th?p phan.


{{#g?i:Coordinates | link }} : Xu?t đ?a ch? c?a cac cong c?.


]=]


require
(
'Module:No globals'
)


local
 math_mod
 =
 require
(
"Module:Math"
)

local
 coordinates
 =
 {};


local
 current_page
 =
 mw
.
title
.
getCurrentTitle
()

local
 page_name
 =
 mw
.
uri
.
encode
(
 current_page
.
prefixedText
,
 'WIKI'
 );

local
 coord_link
 =
 '//tools.wmflabs.org/geohack/geohack.php?language=vi&pagename='
 ..
 page_name
 ..
 '&params='


-- đ?nh d?ng cac s? theo quy t?c ti?ng Vi?t (thi d? 1.234,56).

local
 lang
 =
 mw
.
getContentLanguage
()


-- Chuy?n đ?i đ?i s? thanh cac gia tr? ti?ng Anh.

local
 function
 delocalizeArguments
(
args
)

	-- Chuy?n v? b?ng đ?i s?

	local
 transposedArgs
 =
 {}

	for
 i
,
 arg
 in
 ipairs
(
args
)
 do

		transposedArgs
[
mw
.
ustring
.
upper
(
arg
)]
 =
 i

	end

	
	if
 transposedArgs
[
"B"
]
 ~=
 nil
 then

		args
[
transposedArgs
[
"B"
]]
 =
 "N"

	end

	-- “N” co th? co ngh?a h??ng nam trong ti?ng Vi?t ho?c h??ng b?c trong ti?ng Anh.

	if
 transposedArgs
[
"N"
]
 ~=
 nil
 and
 (
transposedArgs
[
"đ"
]
 ~=
 nil
 or
 transposedArgs
[
"T"
]
 ~=
 nil
)
 then

		args
[
transposedArgs
[
"N"
]]
 =
 "S"

	end

	if
 transposedArgs
[
"đ"
]
 ~=
 nil
 then

		args
[
transposedArgs
[
"đ"
]]
 =
 "E"

	end

	if
 transposedArgs
[
"T"
]
 ~=
 nil
 then

		args
[
transposedArgs
[
"T"
]]
 =
 "W"

	end

end


--[[ Ham h? tr? thay th? {{coord/display/title}} ]]

local
 function
 displaytitle
(
s
,
 notes
)

	local
 htmlTitle
 =
 '<span style="margin-right: 0.25rem;">'
 ..
 s
 ..
 notes
 ..
 '</span>'
;

	return
 mw
.
getCurrentFrame
():
extensionTag
(
'indicator'
,
 tostring
(
htmlTitle
),
 {
 name
 =
 '#coordinates'
 })

end


--[[ Ham h? tr? thay th? {{coord/display/inline}} ]]

local
 function
 displayinline
(
s
,
 notes
)

	return
 s
 ..
 notes
	
end


--[[ Ham h? tr? đ??c s? d?ng đ? nh?n ra đ?nh d?ng đ?-phut-giay. ]]

local
 function
 dmsTest
(
first
,
 second
)

	if
 type
(
first
)
 ~=
 'string'
 or
 type
(
second
)
 ~=
 'string'
 then

		return
 nil

	end

	local
 s
 =
 mw
.
ustring
.
upper
(
first
 ..
 second
)

	if
 s
 ==
 "NE"
 or
 s
 ==
 "NW"
 or
 s
 ==
 "SE"
 or
 s
 ==
 "SW"
 or

		s
 ==
 "EN"
 or
 s
 ==
 "WN"
 or
 s
 ==
 "ES"
 or
 s
 ==
 "WS"
 or

		s
 ==
 "Bđ"
 or
 s
 ==
 "BT"
 or
 s
 ==
 "Nđ"
 or
 s
 ==
 "TN"
 or

		s
 ==
 "đB"
 or
 s
 ==
 "TB"
 or
 s
 ==
 "đN"
 or
 s
 ==
 "NT"
 then

		return
 true

	end

	return
 false

end



--[[ Ham b?c đ? l?y cac tham s?; xem tai li?u c?a ham nay t?i Mo đun:Arguments. ]]

local
 function
 makeInvokeFunc
(
funcName
)

	return
 function
 (
frame
)

		local
 args
 =
 require
(
'Mo đun:Arguments'
).
getArgs
(
frame
,
 {

			wrappers
 =
 'B?n m?u:T?a đ?'

		})

		return
 coordinates
[
funcName
](
args
,
 frame
)

	end

end


--[[ Ham h? tr? đ? x? ly cac đ?i s? tuy ch?n. ]]

local
 function
 optionalArg
(
arg
,
 suplement
)

	if
 arg
 ~=
 nil
 and
 arg
 ~=
 ""
 then

		return
 arg
 ..
 suplement

	end

end


--[[ Helper function, handle optional args. ]]

local
 function
 optionalArg
(
arg
,
 supplement
)

	return
 arg
 and
 arg
 ..
 supplement
 or
 ''

end


--[[

đ?nh d?ng nh?ng thong bao l?i c?n hi?n th?.

]]

local
 function
 errorPrinter
(
errors
)

	local
 result
 =
 ""

	for
 i
,
v
 in
 ipairs
(
errors
)
 do

		local
 errorHTML
 =
 '<strong class="error">T?a đ?: '
 ..
 v
[
2
]
 ..
 '</strong>'

		result
 =
 result
 ..
 errorHTML
 ..
 "<br />"

	end

	return
 result

end


--[=[

Tinh l?p CSS c?n đ? hi?n th? t?a đ?.


B?ng ki?u CSS th??ng ?n geo-nondefault, tr? khi m?t ngu?i dung đa ghi đe thi?t l?p nay.

default la ch? đ? do ngu?i dung đ?nh ro khi nhung [[B?n m?u:coord]].

mode la ch? đ? hi?n th? (dec ho?c dms) dung đ? tinh l?p CSS.

]=]

local
 function
 displayDefault
(
default
,
 mode
)

	if
 default
 ==
 ""
 then

		default
 =
 "dec"

	end

	
	if
 default
 ==
 mode
 then

		return
 "geo-default"

	else

		return
 "geo-nondefault"

	end

end


--[[

specPrinter


Ham đ?nh d?ng gia tr? cho ra. L?y c?u truc do parseDec ho?c parseDMS t?o ra va

đ?nh d?ng no đ? nhung vao Wikipedia.

]]

local
 function
 specPrinter
(
args
,
 coordinateSpec
)

	local
 uriComponents
 =
 coordinateSpec
[
"param"
]

	if
 uriComponents
 ==
 ""
 then

		-- RETURN error, should never be empty or nil

		return
 "L?I tham s? tr?ng"

	end

	if
 args
[
"name"
]
 then

		uriComponents
 =
 uriComponents
 ..
 "&title="
 ..
 mw
.
uri
.
encode
(
coordinateSpec
[
"name"
])

	end

	
	local
 geodmshtml
 =
 '<span class="geo-dms" title="B?n đ?, khong ?nh, cung cac d? li?u khac cho v? tri nay">'

			 ..
 '<span class="latitude">'
 ..
 coordinateSpec
[
"dms-lat"
]
 ..
 '</span> '

			 ..
 '<span class="longitude">'
 ..
coordinateSpec
[
"dms-long"
]
 ..
 '</span>'

			 ..
 '</span>'


	local
 lat
 =
 tonumber
(
 coordinateSpec
[
"dec-lat"
]
 )
 or
 0

	local
 geodeclat

	if
 lat
 <
 0
 then

		-- FIXME this breaks the pre-existing precision

		geodeclat
 =
 lang
:
formatNum
(
tonumber
(
coordinateSpec
[
"dec-lat"
]:
sub
(
2
)))
 ..
 "°N"

	else

		geodeclat
 =
 lang
:
formatNum
(
tonumber
(
coordinateSpec
[
"dec-lat"
]
 or
 0
))
 ..
 "°B"

	end


	local
 long
 =
 tonumber
(
 coordinateSpec
[
"dec-long"
]
 )
 or
 0

	local
 geodeclong

	if
 long
 <
 0
 then

		-- FIXME does not handle unicode minus

		geodeclong
 =
 lang
:
formatNum
(
tonumber
(
coordinateSpec
[
"dec-long"
]:
sub
(
2
)))
 ..
 "°T"

	else

		geodeclong
 =
 lang
:
formatNum
(
tonumber
(
coordinateSpec
[
"dec-long"
]
 or
 0
))
 ..
 "°đ"

	end

	
	local
 geodechtml
 =
 '<span class="geo-dec" title="B?n đ?, khong ?nh, cung cac d? li?u khac cho v? tri nay">'

			 ..
 geodeclat
 ..
 ' '

			 ..
 geodeclong

			 ..
 '</span>'


	local
 geonumhtml
 =
 '<span class="geo">'

			 ..
 coordinateSpec
[
"dec-lat"
]
 ..
 '; '

			 ..
 coordinateSpec
[
"dec-long"
]

			 ..
 '</span>'


	local
 inner
 =
 '<span class="'
 ..
 displayDefault
(
coordinateSpec
[
"default"
],
 "dms"
 )
 ..
 '">'
 ..
 geodmshtml
 ..
 '</span>'

				..
 '<span class="geo-multi-punct">&#xfeff; / &#xfeff;</span>'

				..
 '<span class="'
 ..
 displayDefault
(
coordinateSpec
[
"default"
],
 "dec"
 )
 ..
 '">'
;


	if
 not
 args
[
"name"
]
 then

		inner
 =
 inner
 ..
 geodechtml
 
				..
 '<span style="display:none">&#xfeff; / '
 ..
 geonumhtml
 ..
 '</span></span>'

	else

		inner
 =
 inner
 ..
 '<span class="vcard">'
 ..
 geodechtml
 
				..
 '<span style="display:none">&#xfeff; / '
 ..
 geonumhtml
 ..
 '</span>'

				..
 '<span style="display:none">&#xfeff; (<span class="fn org">'

				..
 args
[
"name"
]
 ..
 '</span>)</span></span></span>'

	end


	return
 '<span class="plainlinks nourlexpansion">'
 ..
 
		'['
 ..
 coord_link
 ..
 uriComponents
 ..
 ' '
 ..
 inner
 ..
 ']'
 ..
 '</span>'

end


--[[ Ham h? tr? chuy?n đ?i s? th?p phan thanh đ?. ]]

local
 function
 convert_dec2dms_d
(
coordinate
)

	local
 d
 =
 math_mod
.
_round
(
 coordinate
,
 0
 )
 ..
 "°"

	return
 d
 ..
 ""

end


--[[ Ham h? tr? chuy?n đ?i s? th?p phan thanh đ? va phut. ]]

local
 function
 convert_dec2dms_dm
(
coordinate
)
	
	coordinate
 =
 math_mod
.
_round
(
 coordinate
 *
 60
,
 0
 );

	local
 m
 =
 coordinate
 %
 60
;

	coordinate
 =
 math.floor
(
 (
coordinate
 -
 m
)
 /
 60
 );

	local
 d
 =
 coordinate
 %
 360
 ..
"°"

	
	return
 d
 ..
 string.format
(
 "%02d′"
,
 m
 )

end


--[[ Ham h? tr? chuy?n đ?i s? th?p phan thanh đ?, phut, va giay. ]]

local
 function
 convert_dec2dms_dms
(
coordinate
)

	coordinate
 =
 math_mod
.
_round
(
 coordinate
 *
 60
 *
 60
,
 0
 );

	local
 s
 =
 coordinate
 %
 60

	coordinate
 =
 math.floor
(
 (
coordinate
 -
 s
)
 /
 60
 );

	local
 m
 =
 coordinate
 %
 60

	coordinate
 =
 math.floor
(
 (
coordinate
 -
 m
)
 /
 60
 );

	local
 d
 =
 coordinate
 %
 360
 ..
"°"


	return
 d
 ..
 string.format
(
 "%02d′"
,
 m
 )
 ..
 string.format
(
 "%02d″"
,
 s
 )

end


--[[ 

Ham h? tr? chuy?n đ?i v? đ? ho?c kinh đ? th?p phan thanh đ?nh d?ng đ?-phut-giay

theo đ? chinh xac đ??c đ?nh ro.

]]

local
 function
 convert_dec2dms
(
coordinate
,
 firstPostfix
,
 secondPostfix
,
 precision
)

	local
 coord
 =
 tonumber
(
coordinate
)

	local
 postfix

	if
 coord
 >=
 0
 then

		postfix
 =
 firstPostfix

	else

		postfix
 =
 secondPostfix

	end


	precision
 =
 precision
:
lower
();

	if
 precision
 ==
 "dms"
 then

		return
 convert_dec2dms_dms
(
 math.abs
(
 coord
 )
 )
 ..
 postfix
;

	elseif
 precision
 ==
 "dm"
 then

		return
 convert_dec2dms_dm
(
 math.abs
(
 coord
 )
 )
 ..
 postfix
;

	elseif
 precision
 ==
 "d"
 then

		return
 convert_dec2dms_d
(
 math.abs
(
 coord
 )
 )
 ..
 postfix
;

	end

end


--[[

Chuy?n đ?i đ?nh d?ng đ?-phut-giay thanh t?a đ? th?p phan B hay đ.

]]

local
 function
 convert_dms2dec
(
direction
,
 degrees_str
,
 minutes_str
,
 seconds_str
)

	local
 degrees
 =
 tonumber
(
degrees_str
)

	local
 minutes
 =
 tonumber
(
minutes_str
)
 or
 0

	local
 seconds
 =
 tonumber
(
seconds_str
)
 or
 0

	
	local
 factor
 =
 1

	direction
 =
 mw
.
ustring
.
gsub
(
direction
,
 '^ *(.-) *$'
,
 '%1'
);

	if
 direction
 ==
 "S"
 or
 direction
 ==
 "W"
 then

		factor
 =
 -
1

	end

	
	local
 precision
 =
 0

	if
 seconds_str
 then

		precision
 =
 5
 +
 math.max
(
 math_mod
.
_precision
(
seconds_str
),
 0
 );

	elseif
 minutes_str
 and
 minutes_str
 ~=
 ''
 then

		precision
 =
 3
 +
 math.max
(
 math_mod
.
_precision
(
minutes_str
),
 0
 );

	else

		precision
 =
 math.max
(
 math_mod
.
_precision
(
degrees_str
),
 0
 );

	end

	
	local
 decimal
 =
 factor
 *
 (
degrees
+
(
minutes
+
seconds
/
60
)
/
60
)
 
	return
 string.format
(
 "%."
 ..
 precision
 ..
 "f"
,
 decimal
 )
 -- not tonumber since this whole thing is string based.

end


--[[

Ki?m tra cac gia tr? cho vao đ? nh?n ra l?i khong đung ph?m vi.

]]

local
 function
 validate
(
 lat_d
,
 lat_m
,
 lat_s
,
 long_d
,
 long_m
,
 long_s
,
 source
,
 strong
 )

	local
 errors
 =
 {};

	lat_d
 =
 tonumber
(
 lat_d
 )
 or
 0
;

	lat_m
 =
 tonumber
(
 lat_m
 )
 or
 0
;

	lat_s
 =
 tonumber
(
 lat_s
 )
 or
 0
;

	long_d
 =
 tonumber
(
 long_d
 )
 or
 0
;

	long_m
 =
 tonumber
(
 long_m
 )
 or
 0
;

	long_s
 =
 tonumber
(
 long_s
 )
 or
 0
;


	if
 strong
 then

		if
 lat_d
 <
 0
 then

			table.insert
(
errors
,
 {
source
,
 "v? đ? < 0 co ch? ban c?u"
})

		end

		if
 long_d
 <
 0
 then

			table.insert
(
errors
,
 {
source
,
 "v? đ? < 0 co ch? ban c?u"
})

		end

		--[[ 

		#coordinates is inconsistent about whether this is an error.  If globe: is

		specified, it won't error on this condition, but otherwise it will.

		
		For not simply disable this check.

		
		if long_d > 180 then

			table.insert(errors, {source, "longitude degrees > 180 with hemisphere flag"})

		end

		]]

	end
	
		
	if
 lat_d
 >
 90
 then

		table.insert
(
errors
,
 {
source
,
 "v? đ? > 90"
})

	end

	if
 lat_d
 <
 -
90
 then

		table.insert
(
errors
,
 {
source
,
 "v? đ? < -90"
})

	end

	if
 lat_m
 >=
 60
 then

		table.insert
(
errors
,
 {
source
,
 "v? phut >= 60"
})

	end

	if
 lat_m
 <
 0
 then

		table.insert
(
errors
,
 {
source
,
 "v? phut < 0"
})

	end

	if
 lat_s
 >=
 60
 then

		table.insert
(
errors
,
 {
source
,
 "v? giay >= 60"
})

	end

	if
 lat_s
 <
 0
 then

		table.insert
(
errors
,
 {
source
,
 "v? giay < 0"
})

	end

	if
 long_d
 >=
 360
 then

		table.insert
(
errors
,
 {
source
,
 "kinh đ? >= 360"
})

	end

	if
 long_d
 <=
 -
360
 then

		table.insert
(
errors
,
 {
source
,
 "kinh đ? <= -360"
})

	end

	if
 long_m
 >=
 60
 then

		table.insert
(
errors
,
 {
source
,
 "kinh phut >= 60"
})

	end

	if
 long_m
 <
 0
 then

		table.insert
(
errors
,
 {
source
,
 "kinh phut < 0"
})

	end

	if
 long_s
 >=
 60
 then

		table.insert
(
errors
,
 {
source
,
 "kinh giay >= 60"
})

	end

	if
 long_s
 <
 0
 then

		table.insert
(
errors
,
 {
source
,
 "kinh giay < 0"
})

	end

	
	return
 errors
;

end


--[[

parseDec


Bi?n đ?i v? đ? va kinh đ? th?p phan thanh m?t c?u truc đ? hi?n th? t?a đ?.

]]

local
 function
 parseDec
(
 lat
,
 long
,
 format
 )

	local
 coordinateSpec
 =
 {}

	local
 errors
 =
 {}

	
	if
 not
 long
 then

		return
 nil
,
 {{
"parseDec"
,
 "Thi?u kinh đ?"
}}

	end

	
	long
 =
 long
:
gsub
(
","
,
 "."
,
 1
)

	if
 not
 tonumber
(
long
)
 then

		return
 nil
,
 {{
"parseDec"
,
 "Khong th? phan tich s? t? kinh đ?: "
 ..
 long
}}

	end

	
	errors
 =
 validate
(
 lat
,
 nil
,
 nil
,
 long
,
 nil
,
 nil
,
 'parseDec'
,
 false
 );
	
	coordinateSpec
[
"dec-lat"
]
  =
 lat
;

	coordinateSpec
[
"dec-long"
]
 =
 long
;


	local
 mode
 =
 coordinates
.
determineMode
(
 lat
,
 long
 );

	coordinateSpec
[
"dms-lat"
]
  =
 convert_dec2dms
(
 lat
,
 "B"
,
 "N"
,
 mode
)
  -- {{coord/dec2dms|{{{1}}}|B|N|{{coord/prec dec|{{{1}}}|{{{2}}}}}}}

	coordinateSpec
[
"dms-long"
]
 =
 convert_dec2dms
(
 long
,
 "đ"
,
 "T"
,
 mode
)
  -- {{coord/dec2dms|{{{2}}}|đ|T|{{coord/prec dec|{{{1}}}|{{{2}}}}}}}	

	
	if
 format
 then

		coordinateSpec
.
default
 =
 format

	else

		coordinateSpec
.
default
 =
 "dec"

	end


	return
 coordinateSpec
,
 errors

end


--[[

parseDMS


Bi?n đ?i v? đ? va kinh đ? d??i d?ng đ?-phut-giay thanh c?u truc đ? hi?n th? cac

t?a đ?.

]]

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
 =
 mw
.
ustring
.
upper
(
lat_f
);

	long_f
 =
 mw
.
ustring
.
upper
(
long_f
);

	
	-- Nh?n cac ch? ban c?u ti?ng Vi?t.

	if
 long_f
 ==
 "B"
 or
 lat_f
 ==
 "đ"
 or
 lat_f
 ==
 "T"
 then

		local
 englishFlags
 =
 {
B
 =
 "N"
,
 N
 =
 "S"
,
 T
 =
 "W"
,
 [
"đ"
]
 =
 "E"
}

		local
 lat_f
 =
 englishFlags
[
lat_f
]
 or
 lat_f

		local
 long_f
 =
 englishFlags
[
long_f
]
 or
 long_f

	end

	
	-- Check if specified backward

	if
 lat_f
 ==
 'E'
 or
 lat_f
 ==
 'W'
 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
;

	end
	
	
	errors
 =
 validate
(
 lat_d
,
 lat_m
,
 lat_s
,
 long_d
,
 long_m
,
 long_s
,
 'parseDMS'
,
 true
 );

	if
 not
 long_d
 then

		return
 nil
,
 {{
"parseDMS"
,
 "Thi?u kinh đ?"
 }}

	end

	
	long_d
 =
 long_d
:
gsub
(
","
,
 "."
,
 1
)

	if
 not
 tonumber
(
long_d
)
 then

		return
 nil
,
 {{
"parseDMS"
,
 "Khong th? phan tich s? t? kinh đ?:"
 ..
 long_d
 }}

	end

	
	if
 not
 lat_m
 and
 not
 lat_s
 and
 not
 long_m
 and
 not
 long_s
 and
 #
errors
 ==
 0
 then
 
		if
 math_mod
.
_precision
(
 lat_d
 )
 >
 0
 or
 math_mod
.
_precision
(
 long_d
 )
 >
 0
 then

			if
 lat_f
:
upper
()
 ==
 'S'
 then
 
				lat_d
 =
 '-'
 ..
 lat_d
;

			end

			if
 long_f
:
upper
()
 ==
 'W'
 then
 
				long_d
 =
 '-'
 ..
 long_d
;

			end

			
			return
 parseDec
(
 lat_d
,
 long_d
,
 format
 );

		end
		
	end
   
	
	-- Vi?t hoa cac ch? ban c?u.

	local
 vietFlags
 =
 {
N
 =
 "B"
,
 S
 =
 "N"
,
 W
 =
 "T"
,
 E
 =
 "đ"
}

	local
 viet_lat_f
 =
 vietFlags
[
lat_f
:
upper
()]
 or
 lat_f

	local
 viet_long_f
 =
 vietFlags
[
long_f
:
upper
()]
 or
 long_f

	
	-- đ?nh d?ng cac s? th?p phan.

	if
 tonumber
(
lat_s
)
 then
 lat_s
 =
 lang
:
formatNum
(
tonumber
(
lat_s
))
 end

	if
 tonumber
(
long_s
)
 then
 long_s
 =
 lang
:
formatNum
(
tonumber
(
long_s
))
 end

	
	coordinateSpec
[
"dms-lat"
]
  =
 lat_d
..
"°"
..
optionalArg
(
lat_m
,
"′"
)
 ..
 optionalArg
(
lat_s
,
"″"
)
 ..
 viet_lat_f

	coordinateSpec
[
"dms-long"
]
 =
 long_d
..
"°"
..
optionalArg
(
long_m
,
"′"
)
 ..
 optionalArg
(
long_s
,
"″"
)
 ..
 viet_long_f

	coordinateSpec
[
"dec-lat"
]
  =
 convert_dms2dec
(
lat_f
,
 lat_d
,
 lat_m
,
 lat_s
)
 -- {{coord/dms2dec|{{{4}}}|{{{1}}}|0{{{2}}}|0{{{3}}}}}

	coordinateSpec
[
"dec-long"
]
 =
 convert_dms2dec
(
long_f
,
 long_d
,
 long_m
,
 long_s
)
 -- {{coord/dms2dec|{{{8}}}|{{{5}}}|0{{{6}}}|0{{{7}}}}}


	if
 format
 then

		coordinateSpec
.
default
 =
 format

	else

		coordinateSpec
.
default
 =
 "dms"

	end
   

	return
 coordinateSpec
,
 errors
,
 backward

end


--[[

Ki?m tra cac đ?i s? cho vao đ? nh?n ra ki?u d? li?u đ??c cung c?p va x? ly đung

cach.

]]

local
 function
 formatTest
(
args
)

	local
 result
,
 errors

	local
 backward
,
 primary
 =
 false
,
 false


	local
 function
 getParam
(
args
,
 lim
)

		local
 ret
 =
 {}

		for
 i
 =
 1
,
 lim
 do

			if
 args
[
i
]
 ==
 nil
 then

				ret
[
i
]
 =
 ''

			else

				ret
[
i
]
 =
 mw
.
ustring
.
match
(
args
[
i
],
 '^%s*(.-)%s*$'
 );
  --remove whitespace

				
				-- Bi?n đ?i thanh đ?nh d?ng s? ti?ng Anh.

				-- CHO R?NG: Cac gia tr? s? khong bao gi? t?i 1.000.

				ret
[
i
]
 =
 ret
[
i
]:
gsub
(
","
,
 "."
,
 1
)

			end

		end

		return
 table.concat
(
ret
,
 '_'
)

	end

	
	if
 not
 args
[
1
]
 then

		-- no lat logic

		return
 errorPrinter
(
 {{
"formatTest"
,
 "Thi?u v? đ?"
}}
 )

	end

	
	args
[
1
]
 =
 args
[
1
]:
gsub
(
","
,
 "."
,
 1
)

	if
 not
 tonumber
(
args
[
1
])
 then

		-- bad lat logic

		return
 errorPrinter
(
 {{
"formatTest"
,
 "Khong th? phan tich s? t? v? đ?:"
 ..
 args
[
1
]}}
 )

	elseif
 not
 args
[
4
]
 and
 not
 args
[
5
]
 and
 not
 args
[
6
]
 then

		-- dec logic

		result
,
 errors
 =
 parseDec
(
args
[
1
],
 args
[
2
],
 args
.
format
)

		if
 not
 result
 then

			return
 errorPrinter
(
errors
);

		end

		result
.
param
 =
 table.concat
({
args
[
1
]:
gsub
(
","
,
 "."
,
 1
),
 'N'
,
 args
[
2
]:
gsub
(
","
,
 "."
,
 1
)
 or
 ''
,
 'E'
,
 args
[
3
]
 or
 ''
},
 '_'
)

	elseif
 dmsTest
(
args
[
4
],
 args
[
8
])
 then

		-- dms logic

		result
,
 errors
,
 backward
 =
 parseDMS
(
args
[
1
],
 args
[
2
],
 args
[
3
],
 args
[
4
],
 
			args
[
5
],
 args
[
6
],
 args
[
7
],
 args
[
8
],
 args
.
format
)

		if
 args
[
10
]
 then

			table.insert
(
errors
,
 {
'formatTest'
,
 'Tham s? d?'
})

		end

		if
 not
 result
 then

			return
 errorPrinter
(
errors
)

		end

		result
.
param
 =
 getParam
(
args
,
 9
)

	elseif
 dmsTest
(
args
[
3
],
 args
[
6
])
 then

		-- dm logic

		result
,
 errors
,
 backward
 =
 parseDMS
(
args
[
1
],
 args
[
2
],
 nil
,
 args
[
3
],
 
			args
[
4
],
 args
[
5
],
 nil
,
 args
[
6
],
 args
[
'format'
])

		if
 args
[
8
]
 then

			table.insert
(
errors
,
 {
'formatTest'
,
 'Tham s? d?'
})

		end

		if
 not
 result
 then

			return
 errorPrinter
(
errors
)

		end

		result
.
param
 =
 getParam
(
args
,
 7
)

	elseif
 dmsTest
(
args
[
2
],
 args
[
4
])
 then

		-- d logic

		result
,
 errors
,
 backward
 =
 parseDMS
(
args
[
1
],
 nil
,
 nil
,
 args
[
2
],
 
			args
[
3
],
 nil
,
 nil
,
 args
[
4
],
 args
.
format
)

		if
 args
[
6
]
 then

			table.insert
(
errors
,
 {
'formatTest'
,
 'Tham s? d?'
})

		end
	
		if
 not
 result
 then

			return
 errorPrinter
(
errors
)

		end

		result
.
param
 =
 getParam
(
args
,
 5
)

	else

		-- Error

		return
 errorPrinter
({{
"formatTest"
,
 "đ?nh d?ng đ?i s? khong ro"
}})

	end

	result
.
name
 =
 args
.
name

	
	local
 extra_param
 =
 {
'dim'
,
 'globe'
,
 'scale'
,
 'region'
,
 'source'
,
 'type'
}

	for
 _
,
 v
 in
 ipairs
(
extra_param
)
 do

		if
 args
[
v
]
 then
 
			table.insert
(
errors
,
 {
'formatTest'
,
 'Tham s?: “'
 ..
 v
 ..
 '=” c?n ph?i la “'
 ..
 v
 ..
 ':”'
 })

		end

	end

	
	local
 ret
 =
 specPrinter
(
args
,
 result
)

	if
 #
errors
 >
 0
 then

		ret
 =
 ret
 ..
 ' '
 ..
 errorPrinter
(
errors
)
 ..
 '[[Th? lo?i:Trang co th? t?a đ? h?ng]]'

	end

	return
 ret
,
 backward

end


--[[

X?p vao cac th? lo?i theo doi Wikidata.

]]

local
 function
 makeWikidataCategories
()

	local
 ret

	if
 mw
.
wikibase
 and
 current_page
.
namespace
 ==
 0
 then

		local
 entity
 =
 mw
.
wikibase
.
getEntityObject
()

		if
 entity
 and
 entity
.
claims
 and
 entity
.
claims
.
P625
 and
 entity
.
claims
.
P625
[
1
]
 then

			local
 snaktype
 =
 entity
.
claims
.
P625
[
1
].
mainsnak
.
snaktype

			if
 snaktype
 ==
 'value'
 then

				-- coordinates exist both here and on Wikidata, and can be compared.

				ret
 =
 'T?a đ? tren Wikidata'

			elseif
 snaktype
 ==
 'somevalue'
 then

				ret
 =
 'T?a đ? tren Wikidata co gia tr? khong ro'

			elseif
 snaktype
 ==
 'novalue'
 then

				ret
 =
 'T?a đ? tren Wikidata khong co gia tr?'

			end

		else

			-- We have to either import the coordinates to Wikidata or remove them here.

			ret
 =
 'T?a đ? khong co s?n tren Wikidata'

		end

	end

	if
 ret
 then

		return
 mw
.
ustring
.
format
(
'[[Th? lo?i:%s]]'
,
 ret
)

	else

		return
 ''

	end

end


--[[

link


Ham đ?n gi?n xu?t đ?a ch? t?a đ? cho nh?ng m?c đich khac.


Cach s? d?ng:

	{{ #g?i:Coordinates | link }}

	
]]

function
 coordinates
.
link
(
frame
)

	return
 coord_link
;

end


--[[

dec2dms


Ham b?c cho phep cac b?n m?u g?i dec2dms tr?c ti?p.


Cach s? d?ng:

	{{ #g?i:Coordinates | dec2dms | t?a đ? th?p phan | h?u t? cho s? d??ng | 

		h?u t? cho s? am | đ? chinh xac }}


decimal_coordinate đ??c chuy?n đ?i thanh đ?nh d?ng đ?-phut-giay. N?u la s?

d??ng, h?u t? cho s? d??ng đ??c b? sung (th??ng la N hay E); n?u la s? d??ng,

h?u t? cho s? d??ng đ??c b? sung. đ? chinh xac đ?nh ro m?c chi ti?t la m?t trong

“D”, “DM”, hay “DMS”.

]]

coordinates
.
dec2dms
 =
 makeInvokeFunc
(
'_dec2dms'
)

function
 coordinates
.
_dec2dms
(
args
)

	local
 coordinate
 =
 args
[
1
]

	local
 firstPostfix
 =
 args
[
2
]
 or
 ''

	local
 secondPostfix
 =
 args
[
3
]
 or
 ''

	local
 precision
 =
 args
[
4
]
 or
 ''


	return
 convert_dec2dms
(
coordinate
,
 firstPostfix
,
 secondPostfix
,
 precision
)

end


--[[

Ham h? tr? quy?t đ?nh s? d?ng đ?nh d?ng đ?, đ?-phut, hay đ?-phut-giay, tuy đ?

chinh xac c?a gia tr? th?p phan cho vao.

]]

function
 coordinates
.
determineMode
(
 value1
,
 value2
 )

	local
 precision
 =
 math.max
(
 math_mod
.
_precision
(
 value1
 ),
 math_mod
.
_precision
(
 value2
 )
 );

	if
 precision
 <=
 0
 then

		return
 'd'

	elseif
 precision
 <=
 2
 then

		return
 'dm'
;

	else

		return
 'dms'
;

	end

end
		

--[[

dms2dec


Ham b?c cho phep cac b?n m?u g?i dms2dec tr?c ti?p.


Cach s? d?ng:

	{{ #g?i:Coordinates | dms2dec | ch? ban c?u | đ? | 

		phut | giay }}


Chuy?n đ?i cac gia tr? đ?-phut-giay thanh đ?nh d?ng th?p phan.

direction_flag la m?t trong N, S, E, va W va đ?nh ro gia tr? cho ra la s? d??ng

(N va E) ho?c s? am (S va W).

]]

coordinates
.
dms2dec
 =
 makeInvokeFunc
(
'_dms2dec'
)

function
 coordinates
.
_dms2dec
(
args
)

	local
 direction
 =
 args
[
1
]

	local
 degrees
 =
 args
[
2
]

	local
 minutes
 =
 args
[
3
]

	local
 seconds
 =
 args
[
4
]


	return
 convert_dms2dec
(
direction
,
 degrees
,
 minutes
,
 seconds
)

end


--[=[

coord


Ch? vao chinh c?a ham Lua thay th? [[B?n m?u:Coord]].


Cach s? d?ng:

	{{ #g?i:Coordinates | coord }}

	{{ #g?i:Coordinates | coord | v? đ? | kinh đ? }}

	{{ #g?i:Coordinates | coord | v? đ? | ch? v? đ? | kinh đ? | ch? kinh đ? }}


	
	Tra c?u trang tai li?u c?a [[B?n m?u:Coord]] đ? bi?t đ?n nhi?u tham s? va

	tuy ch?n khac.


L?u y: Ham nay cung c?p cac ph?n t? hi?n th? th? giac c?a [[B?n m?u:Coord]]. đ?

cho co th? t?i cac t?a đ? len c? s? d? li?u, ham cu phap {{#t?ađ?:}} c?ng c?n

đ??c g?i. Ham nay đ??c g?i t? đ?ng trong phien b?n Lua c?a [[B?n m?u:Coord]].

]=]

coordinates
.
coord
 =
 makeInvokeFunc
(
'_coord'
)

function
 coordinates
.
_coord
(
args
)

	if
 (
not
 args
[
1
]
 or
 not
 tonumber
(
args
[
1
]))
 and
 not
 args
[
2
]
 and
 mw
.
wikibase
.
getEntityObject
()
 then

		args
[
3
]
 =
 args
[
1
];
 args
[
1
]
 =
 nil

		local
 entity
 =
 mw
.
wikibase
.
getEntityObject
()

		if
 entity
 
			and
 entity
.
claims

			and
 entity
.
claims
.
P625

			and
 entity
.
claims
.
P625
[
1
].
mainsnak
.
snaktype
 ==
 'value'

		then

			local
 precision
 =
 entity
.
claims
.
P625
[
1
].
mainsnak
.
datavalue
.
value
.
precision

			args
[
1
]
=
entity
.
claims
.
P625
[
1
].
mainsnak
.
datavalue
.
value
.
latitude

			args
[
2
]
=
entity
.
claims
.
P625
[
1
].
mainsnak
.
datavalue
.
value
.
longitude

			if
 precision
 then

				precision
=-
math_mod
.
_round
(
math.log
(
precision
)
/
math.log
(
10
),
0
)

				args
[
1
]
=
math_mod
.
_round
(
args
[
1
],
precision
)

				args
[
2
]
=
math_mod
.
_round
(
args
[
2
],
precision
)

			end

		end

	end

	
	local
 Display
 =
 args
.
display
 and
 args
.
display
:
lower
()
 or
 'inline'

	args
.
wviTitle
 =
 (
string.find
(
 Display
,
 'title'
 )
 ~=
 nil
 or
 Display
 ==
 't'
 or
 
		Display
 ==
 'it'
 or
 Display
 ==
 'ti'
)

	delocalizeArguments
(
args
)

	local
 contents
,
 backward
 =
 formatTest
(
args
)

	local
 Notes
 =
 args
.
notes
 or
 ''


	local
 function
 isInline
(
s
)

		-- Finds whether coordinates are displayed inline.

		return
 s
:
find
(
'inline'
)
 ~=
 nil
 or
 s
 ==
 'i'
 or
 s
 ==
 'it'
 or
 s
 ==
 'ti'

	end

	local
 function
 isInTitle
(
s
)

		-- Finds whether coordinates are displayed in the title.

		return
 s
:
find
(
'title'
)
 ~=
 nil
 or
 s
 ==
 't'
 or
 s
 ==
 'it'
 or
 s
 ==
 'ti'

	end

	
	local
 function
 coord_wrapper
(
in_args
)

		-- Calls the parser function {{#coordinates:}}.

		return
 mw
.
getCurrentFrame
():
callParserFunction
(
'#coordinates'
,
 in_args
)
 or
 ''

	end

	
	local
 text
 =
 ''

	if
 isInline
(
Display
)
 then

		text
 =
 text
 ..
 displayinline
(
contents
,
 Notes
)

	end

	if
 isInTitle
(
Display
)
 then

		text
 =
 text

			..
 displaytitle
(
contents
,
 Notes
)

			..
 makeWikidataCategories
()

	end

	if
 not
 args
.
nosave
 then

		local
 page_title
,
 count
 =
 mw
.
title
.
getCurrentTitle
(),
 1

		if
 backward
 then

			local
 tmp
 =
 {}

			while
 not
 mw
.
ustring
.
find
((
args
[
count
-
1
]
 or
 ''
),
 '[EWđT]'
)
 do
 tmp
[
count
]
 =
 (
args
[
count
]
 or
 ''
);
 count
 =
 count
+
1
 end

			tmp
.
count
 =
 count
;
 count
 =
 2
*
(
count
-
1
)

			while
 count
 >=
 tmp
.
count
 do
 table.insert
(
tmp
,
 1
,
 (
args
[
count
]
 or
 ''
));
 count
 =
 count
-
1
 end

			for
 i
,
 v
 in
 ipairs
(
tmp
)
 do
 args
[
i
]
 =
 v
 end

		else

			while
 count
 <=
 9
 do
 args
[
count
]
 =
 (
args
[
count
]
 or
 ''
);
 count
 =
 count
+
1
 end

		end

		if
 isInTitle
(
Display
)
 and
 not
 page_title
.
isTalkPage
 and
 page_title
.
subpageText
 ~=
 'doc'
 and
 page_title
.
subpageText
 ~=
 'tai li?u'
 and
 page_title
.
subpageText
 ~=
 'testcases'
 and
 page_title
.
subpageText
 ~=
'ki?m th?'
 then
 args
[
10
]
 =
 'primary'
 end

		args
.
notes
,
 args
.
format
,
 args
.
display
 =
 nil

		text
 =
 text
 ..
 coord_wrapper
(
args
)

	end

	return
 text

end


--[=[

coord2text


Phan tich ra m?t gia tr? t? l?n nhung [[B?n m?u:T?a đ?]].

N?U CU PHAP LIEN K?T C?A GEOHACK THAY đ?I, HAM NAY C?N đ??C THAY đ?I LUON.


Cach s? d?ng:


    {{#g?i:Coordinates | coord2text | {{T?a đ?}} | parameter }}


Gia tr? h?p l? cho tham s? th? hai la: lat (s? nguyen co d?u), long (s? nguyen co d?u), type, scale, dim, region, globe, source


]=]

function
 coordinates
.
coord2text
(
frame
)

	if
 frame
.
args
[
1
]
 ==
 ''
 or
 frame
.
args
[
2
]
 ==
 ''
 or
 not
 frame
.
args
[
2
]
 then
 return
 nil
 end

	frame
.
args
[
2
]
 =
 mw
.
text
.
trim
(
frame
.
args
[
2
])

	if
 frame
.
args
[
2
]
 ==
 'lat'
 or
 frame
.
args
[
2
]
 ==
 'long'
 then

		local
 result
,
 negative
 =
 mw
.
text
.
split
((
mw
.
ustring
.
match
(
frame
.
args
[
1
],
'[,%d]+°[BN] [,%d]+°[đT]'
)
 or
 ''
),
 ' '
)

		if
 frame
.
args
[
2
]
 ==
 'lat'
 then

			result
,
 negative
 =
 result
[
1
],
 'N'

		else

			result
,
 negative
 =
 result
[
2
],
 'T'

		end

		result
 =
 mw
.
text
.
split
(
result
,
 '°'
)

		if
 result
[
2
]
 ==
 negative
 then
 result
[
1
]
 =
 '-'
..
result
[
1
]
 end

		return
 lang
:
parseFormattedNumber
(
result
[
1
])

	else

		return
 mw
.
ustring
.
match
(
frame
.
args
[
1
],
 'params=.-_'
..
frame
.
args
[
2
]
..
':(.-)[ _]'
)

	end

end


--[=[

coordinsert


Xen v?n b?n vao lien k?t GeoHack c?a m?t l?n nhung [[B?n m?u:T?a đ?]] (n?u v?n b?n nay khong ph?i đa xu?t hi?n trong ma nhung). Tr? v? ma nhung [[B?n m?u:T?a đ?]] đa s?a đ?i.

N?U CU PHAP LIEN K?T C?A GEOHACK THAY đ?I, HAM NAY C?N đ??C THAY đ?I LUON.


Cach s? d?ng:


    {{#invoke:Coordinates | coordinsert | {{Coord}} | parameter:value | parameter:value | … }}


đ?ng lam GeoHack gay l?i b?ng cach đ?a vao gi khong đ??c noi đ?n trong tai li?u [[B?n m?u:T?a đ?]].


]=]

function
 coordinates
.
coordinsert
(
frame
)

	for
 i
,
 v
 in
 ipairs
(
frame
.
args
)
 do

		if
 i
 ~=
 1
 then

			if
 not
 mw
.
ustring
.
find
(
frame
.
args
[
1
],
 (
mw
.
ustring
.
match
(
frame
.
args
[
i
],
 '^(.-:)'
)
 or
 ''
))
 then
 
				frame
.
args
[
1
]
 =
 mw
.
ustring
.
gsub
(
frame
.
args
[
1
],
 '(params=.-)_? '
,
 '%1_'
..
frame
.
args
[
i
]
..
' '
)

			end

		end

	end

	if
 frame
.
args
.
name
 then

		if
 not
 mw
.
ustring
.
find
(
frame
.
args
[
1
],
 '<span class="vcard">'
)
 then

			local
 namestr
 =
 frame
.
args
.
name

			frame
.
args
[
1
]
 =
 mw
.
ustring
.
gsub
(
frame
.
args
[
1
],
 
				'(<span class="geo%-default">)(<span[^<>]*>[^<>]*</span><span[^<>]*>[^<>]*<span[^<>]*>[^<>]*</span></span>)(</span>)'
,
 
				'%1<span class="vcard">%2<span style="display:none">&#xfeff; (<span class="fn org">'
 ..
 namestr
 ..
 '</span>)</span></span>%3'
)

			frame
.
args
[
1
]
 =
 mw
.
ustring
.
gsub
(
frame
.
args
[
1
],
 '(&params=[^&"<>%[%] ]*) '
,
 '%1&title='
 ..
 mw
.
uri
.
encode
(
namestr
)
 ..
 ' '
)

		end

	end

	return
 frame
.
args
[
1
]

end


return
 coordinates