Mô đun:Bdtt

local p = {}
local coord = require( "Module:Coordinates" )

local function normalise(args)
local lookup_table = {
['vĩ_độ'] = 'latitude',
['kinh_độ'] = 'longitude',
['mức_phóng_đại'] = 'zoom',
['rộng'] = 'width',
['cao'] = 'height',
['chú_thích'] = 'text',
['mô_tả'] = 'description',
['tiêu_đề'] = 'title',
['bỏ_khung'] = 'frameless',
['ký_hiệu'] = 'symbol',
['màu'] = 'color',
['cỡ'] = 'size',
['mức_trong_suốt'] = 'opacity',
['màu'] = 'color',
['màu_nền'] = 'fill_color',
['đường_cao_độ'] = 'contour',
['truy_vấn'] = 'query',
['ngôn_ngữ'] = 'lang',
['đánh_dấu'] = 'marker';
['mẫu'] = 'form';
}

for k, v in pairs(lookup_table) do
if args[k] ~= nil then
args[v] = args[k]
end
end

return args
end

local function decodeJsonList(value)
local trimmedValue = mw.text.trim(value, ',')
return mw.text.jsonDecode('[' .. trimmedValue .. ']')
end

function p.marker(frame)
local args = normalise(frame:getParent().args)

if args[1] nil and args.latlng nil then --One coordinate is mandatory
return
end

local properties = {
['marker-color'] = args.color == nil and '555555' or args.color,
['marker-size'] = args.size == nil and 'medium' or args.size,
['marker-symbol'] = args.symbol == nil and or args.symbol,
['title'] = args.title == nil and or args.title,
['description'] = args.description == nil and or args.description,
}

local latlng = mw.text.split( (args[1] == nil and args.latlng or args[1]), ",", true )

if args.randomise ~= nil then
latlng[1] = latlng[1] + math.random(-tonumber(args.randomise), tonumber(args.randomise))/100000
latlng[2] = latlng[2] + math.random(-tonumber(args.randomise), tonumber(args.randomise))/100000
end

local geojson = {
type = "Feature",
properties = properties,
geometry = {
type = "Point",
coordinates = {
tonumber(latlng[2]),
tonumber(latlng[1]),
}
}
}
return mw.text.jsonEncode(geojson) .. ','
end

function p.line(frame)
local args = normalise(frame:getParent().args)

if args[2] == nil then --At least two coordinates are mandatory
return
end

local properties = {
["stroke"] = args.color == nil and '555555' or args.color,
["stroke-width"] = args.size == nil and 2 or tonumber(args.size),
["stroke-opacity"] = args.opacity == nil and 1 or tonumber(args.opacity),
['title'] = args.title == nil and or args.title,
['description'] = args.description == nil and or args.description,
}

local coordinates = {}
local i = 1
while args[i] ~= nil do
local latlng = mw.text.split( args[i], ",", true )
coordinates[i] = {
tonumber(latlng[2]),
tonumber(latlng[1]),
}
i = i+1
end

local geojson = {
type = "Feature",
properties = properties,
geometry = {
type = "LineString",
coordinates = coordinates
}
}
return mw.text.jsonEncode(geojson) .. ','
end

function p.polygon(frame)
local args = normalise(frame:getParent().args)

if args[3] == nil then --At least three coordinates are mandatory
return
end

local properties = {
["stroke"] = args.color == nil and '555555' or args.color,
["stroke-width"] = args.size == nil and 2 or tonumber(args.size),
["stroke-opacity"] = args.opacity == nil and 1 or tonumber(args.opacity),
["fill"] = args.fill_color == nil and '555555' or args.fill_color,
["fill-opacity"] = args.fill_opacity == nil and 0.3 or tonumber(args.fill_opacity),
['title'] = args.title == nil and or args.title,
['description'] = args.description == nil and or args.description,
}

local coordinates = {}
local i = 1
while args[i] ~= nil do
local latlng = mw.text.split( args[i], ",", true )
coordinates[i] = {
tonumber(latlng[2]),
tonumber(latlng[1]),
}
i = i+1
end
local latlng = mw.text.split( args[1], ",", true )
coordinates[i] = {
tonumber(latlng[2]),
tonumber(latlng[1]),
}

local geojson = {
type = "Feature",
properties = properties,
geometry = {
type = "Polygon",
coordinates = { coordinates }
}
}
return mw.text.jsonEncode(geojson) .. ','
end

function p.query(frame)
local args = normalise(frame:getParent().args)

local query
if args[1] ~= nil then
query = args[1]
else
return
end

local properties = {
["stroke"] = args.color == nil and '555555' or args.color,
["stroke-width"] = args.size == nil and 2 or tonumber(args.size),
["stroke-opacity"] = args.opacity == nil and 1 or tonumber(args.opacity),
["fill"] = args.fill_color == nil and '555555' or args.fill_color,
["fill-opacity"] = args.fill_opacity == nil and 0.3 or tonumber(args.fill_opacity),
['title'] = args.title == nil and or args.title,
['description'] = args.description == nil and or args.description,
}

local service = "geoshape"
if args.contour ~= nil then
service = "geoline"
end

local geojson = {
type = "ExternalData",
service = service,
query = query,
properties = properties,
}
return mw.text.jsonEncode(geojson) .. ','
end

function p.osm(frame)
local args = normalise(frame:getParent().args)

local qid
if args[1] == nil then
qid = mw.wikibase.getEntityIdForCurrentPage()
else
qid = mw.text.trim(args[1])
end

local properties = {
["stroke"] = args.color == nil and '555555' or args.color,
["stroke-width"] = args.size == nil and 2 or tonumber(args.size),
["stroke-opacity"] = args.opacity == nil and 1 or tonumber(args.opacity),
["fill"] = args.fill_color == nil and '555555' or args.fill_color,
["fill-opacity"] = args.fill_opacity == nil and 0.3 or tonumber(args.fill_opacity),
['title'] = args.title == nil and or args.title,
['description'] = args.description == nil and or args.description,
}

local service = "geoshape"
if args.contour ~= nil then
service = "geoline"
end

local geojson = {
type = "ExternalData",
service = service,
ids = qid,
properties = properties,
}
return mw.text.jsonEncode(geojson) .. ','
end

function p.commons(frame)
local args = normalise(frame:getParent().args)

if args[1] == nil then
return
end

local page_name = args[1]
if mw.ustring.find(page_name, "Data:", 1, true) == 1 then
page_name = string.sub(page_name, 6)
end
if mw.ustring.find(page_name, ".map", -4, true) == nil then
page_name = page_name .. '.map'
end

local geojson = {
type = "ExternalData",
service = "page",
title = page_name
}
return mw.text.jsonEncode(geojson) .. ','
end

function p.wikidata(frame)
local args = normalise(frame:getParent().args)
local qid

local properties = {
['marker-color'] = args.color == nil and '555555' or args.color,
['marker-size'] = args.size == nil and 'medium' or args.size,
['marker-symbol'] = args.symbol == nil and or args.symbol,
['title'] = args.title == nil and or args.title,
['description'] = args.description nil and or args.description,
}

if args[1] nil then
qid = mw.wikibase.getEntityIdForCurrentPage()
else
qid = args[1]
end

local entity = mw.wikibase.getEntity( qid )
local value = entity:formatPropertyValues( 'P625', { mw.wikibase.entity.claimRanks.RANK_NORMAL, mw.wikibase.entity.claimRanks.RANK_PREFERRED, mw.wikibase.entity.claimRanks.RANK_TRUTH } ).value
if value == nil then
error('Thông số P625 "toạ độ địa lý" không có ở Wikidata')
end
latlng = mw.text.split( mw.text.decode(value), ", ", true )
geojson = {
type = "Feature",
geometry = {
type = "Point",
coordinates = {
coord._dms2dec(coord._parsedmsstring(latlng[2])),
coord._dms2dec(coord._parsedmsstring(latlng[1]))
}
},
properties = properties
}

return mw.text.jsonEncode(geojson) .. ','
end

function p.tag(frame)
local args = ( frame.getParent and normalise(frame:getParent().args) ) or frame

-- Choose the tagname
local tagname = 'mapframe'
if args.lien ~= nil then
tagname = 'maplink'
end

-- Manage the basics tag params
local tagArgs = {
zoom = args.zoom nil and args.commons nil and 14 or tonumber(args.zoom),
height = args.height == nil and 420 or tonumber(args.height),
width = args.width == nil and 420 or tonumber(args.width),
align = args.align == nil and 'right' or args.align,
text = args.text,
}

if args[1] ~= nil and (args.latitude ~= nil or args.longitude ~= nil) then
error('Kinh độ và vĩ độ được cung cấp theo hai cú pháp khác nhau. Xem hướng dẫn của Bản mẫu:Bản đồ tương tác để biết cú pháp phù hợp.')
elseif args.latitude ~= nil and args.latitude ~=
and args.longitude ~= nil and args.longitude ~= then
tagArgs.latitude = args.latitude
tagArgs.longitude = args.longitude
elseif args[1] ~= nil and args[2] ~= nil then
tagArgs.latitude = args[1]
tagArgs.longitude = args[2]
elseif args.commons nil and args.wikidata nil
and args.form nil and args.query nil and args.external == nil then --The only exceptions allowed to put latitude and longitude away are when using an external map stored on commons, coord from wikidata, form, query or external
error('Thiếu kinh độ & vĩ độ')
end

if tagArgs.latitude ~= nil and tagArgs.longitude ~= nil then
if tonumber(tagArgs.latitude) then
tagArgs.latitude = tonumber(tagArgs.latitude)
else
tagArgs.latitude = coord._dms2dec(coord._parsedmsstring(tagArgs.latitude))
end
if tonumber(tagArgs.longitude) then
tagArgs.longitude = tonumber(tagArgs.longitude)
else
tagArgs.longitude = coord._dms2dec(coord._parsedmsstring(tagArgs.longitude))
end
end

if args.frameless then
tagArgs.frameless =
end

if args.lang ~= nil then
tagArgs.lang = args.lang
end

-- Manage the basics GeoJSON params
local geojson = {}

if args.commons ~= nil then
geojson[geojson+1] = {
type = "ExternalData",
service = "page",
title = args.commons,
}
end

if args.marker ~= nil and args.marker ~= then
geojson[geojson+1] = {
type = "Feature",
geometry = {
type = "Point",
coordinates = {
tagArgs.longitude,
tagArgs.latitude
}
},
properties = {
['marker-color'] = (args.color nil or args.color ) and '555555' or args.color,
['marker-size'] = (args.size nil or args.size ) and 'medium' or args.size,
['marker-symbol'] = args.symbol == nil and or args.symbol,
['title'] = args.title == nil and or args.title,
['description'] = args.description == nil and or args.description,
}
}
end

if args.osm ~= nil and args.osm ~= then
local qid
if args.osm == 'oui' then
qid = mw.wikibase.getEntityIdForCurrentPage()
if qid == nil then
qid = "Q1"
end
else
qid = args.osm
end

local service = "geoshape"
if args.contour ~= nil then
service = "geoline"
end

geojson[geojson+1] = {
type = "ExternalData",
service = service,
ids = qid,
properties = {
title = args.title == nil and or args.title,
description = args.description == nil and or args.description,
}
}
end

local qid = args.wikidata
if qid and not mw.wikibase.isValidEntityId( qid ) then
qid = mw.wikibase.getEntityIdForCurrentPage()
end
if qid and mw.wikibase.isValidEntityId( qid ) then
local entity = mw.wikibase.getEntity( qid )
local value = entity:formatPropertyValues( 'P625', { mw.wikibase.entity.claimRanks.RANK_NORMAL, mw.wikibase.entity.claimRanks.RANK_PREFERRED, mw.wikibase.entity.claimRanks.RANK_TRUTH } ).value
if value == then
error('Thông số P625 "toạ độ địa lý" không có ở Wikidata')
end
latlng = mw.text.split( mw.text.decode(value), ", ", true )
geojson[geojson+1] = {
type = "Feature",
geometry = {
type = "Point",
coordinates = {
coord._dms2dec(coord._parsedmsstring(latlng[2])),
coord._dms2dec(coord._parsedmsstring(latlng[1]))
}
},
properties = {
title = args.title == nil and or args.title,
description = args.description == nil and or args.description,
}
}
end

if args.query ~= nil then
local service = "geoshape"
if args.contour ~= nil then
service = "geoline"
end

geojson[geojson+1] = {
type = "ExternalData",
service = service,
query = args.query,
properties = {
title = args.title == nil and or args.title,
description = args.description == nil and or args.description,
}
}
end

--Manage external GeoJSON datas included through models
if args.form ~= nil then
geojson[geojson+1] = {
type = "FeatureCollection",
features = decodeJsonList(args.form)
}
end

if args.external ~= nil and args.external ~= then
local external = decodeJsonList(args.external)
for k, externe in pairs(external) do
geojson[geojson+1] = externe
end
end

return frame:extensionTag(tagname, mw.text.jsonEncode(geojson), tagArgs)
end

return p