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 argsk ~= nil then
			argsv = argsk
		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 args1 == 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( (args1 == nil and args.latlng or args1), ",", true )
	
	if args.randomise ~= nil then
		latlng1 = latlng1 + math.random(-tonumber(args.randomise), tonumber(args.randomise))/100000
		latlng2 = latlng2 + math.random(-tonumber(args.randomise), tonumber(args.randomise))/100000
	end
	
	local geojson = {
type = "Feature",
properties = properties,
geometry = {
type = "Point",
coordinates = {
	tonumber(latlng2), 
	tonumber(latlng1),
}
}
}
return mw.text.jsonEncode(geojson) .. ','
end
function p.line(frame)
	local args = normalise(frame:getParent().args)
	
	if args2 == 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 argsi ~= nil do
		local latlng = mw.text.split( argsi, ",", true )
		coordinatesi = {
	tonumber(latlng2), 
	tonumber(latlng1),
}
		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 args3 == 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 argsi ~= nil do
		local latlng = mw.text.split( argsi, ",", true )
		coordinatesi = {
	tonumber(latlng2), 
	tonumber(latlng1),
}
		i = i+1
	end
	local latlng = mw.text.split( args1, ",", true )
	coordinatesi = {
	tonumber(latlng2), 
	tonumber(latlng1),
}
	
	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 args1 ~= nil then
		query = args1
	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 args1 == nil then
		qid = mw.wikibase.getEntityIdForCurrentPage()
	else
		qid = mw.text.trim(args1)
	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 args1 == nil then
		return
	end
	
	local page_name = args1
	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 args1 == nil then
		qid = mw.wikibase.getEntityIdForCurrentPage()
	else
		qid = args1
	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(latlng2)), 
				coord._dms2dec(coord._parsedmsstring(latlng1))
			}
		},
		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 args1 ~= 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 args1 ~= nil and args2 ~= nil then
		tagArgs.latitude = args1
		tagArgs.longitude = args2
	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(latlng2)), 
					coord._dms2dec(coord._parsedmsstring(latlng1))
				}
			},
			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