Moodul:Kaart
Selle mooduli dokumentatsiooni saab kirjutada asukohta Moodul:Kaart/doc.
local p = {}
local coord = require( "Module:Koord" )
local function normalise(args)
local lookup_table = {
['lat']= 'latitude',
['long'] = 'longitude',
['suum'] = 'zoom',
['laius']= 'width',
['kõrgus'] = 'height',
['tekst'] = 'text',
['kirjeldus'] = 'description',
['pealkiri'] = 'title',
['raamita'] = 'frameless',
['tähis'] = 'symbol',
['värv'] = 'color',
['suurus'] = 'size',
['paksus'] = 'width',
['läbipaistvus'] = 'opacity',
['joone paksus'] = 'width',
['joone värv'] = 'color',
['joone läbipaistvus'] = 'opacity',
['täitevärv'] = 'fill_color',
['täitevärvi läbipaistvus'] = 'fill_opacity',
['kujund'] = 'contour',
['allikad'] = 'externes',
['päring'] = 'query',
}
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)
--[[phab:T214984]]
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 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], ",", true )
local geojson = {
type = "Feature",
properties = properties,
geometry = {
type = "Point",
coordinates = {
coord.dms2dec_convert(latlng[2], 'longitude'),
coord.dms2dec_convert(latlng[1], 'latitude')
}
}
}
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.width == nil and 2 or tonumber(args.width),
["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.width == nil and 2 or tonumber(args.width),
["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.contour ~= 'punkt' and args.color == nil and '#555555' or args.color,
["stroke-width"] = args.contour ~= 'punkt' and args.width == nil and 2 or tonumber(args.width),
["stroke-opacity"] = args.contour ~= 'punkt' and args.opacity == nil and 1 or tonumber(args.opacity),
["fill"] = args.contour == nil and args.fill_color == nil and '#555555' or args.fill_color,
["fill-opacity"] = args.contour == nil and 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 == 'joon' then
service = "geoline"
elseif args.contour == 'punkt' then
service = "geopoint"
properties["marker-color"] = args.color == nil and '#555555' or args.color
properties["marker-size"] = args.size == nil and 'medium' or args.size
properties["marker-symbol"] = args.symbol == nil and '' or args.symbol
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 = args[1]
end
local properties = {
["stroke"] = args.color == nil and '#555555' or args.color,
["stroke-width"] = args.width == nil and 2 or tonumber(args.width),
["stroke-opacity"] = args.opacity == nil and 1 or tonumber(args.opacity),
["fill"] = args.contour == nil and args.fill_color == nil and '#555555' or args.fill_color,
["fill-opacity"] = args.contour == nil and 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 == 'joon' 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, longitude, latitude
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 statements = entity:getBestStatements('P625')
if (statements[1] and statements[1].mainsnak.snaktype == 'value') then
longitude = statements[1].mainsnak.datavalue.value.longitude
latitude = statements[1].mainsnak.datavalue.value.latitude
end
if longitude == nil then
error('Vikiandmetes puuduvad koordinaadid')
end
geojson = {
type = "Feature",
geometry = {
type = "Point",
coordinates = {
longitude,
latitude
}
},
properties = properties
}
return mw.text.jsonEncode(geojson) .. ','
end
function p.tag(frame)
local args = normalise(frame:getParent().args)
-- Choose the tagname
local tagname = 'mapframe'
if args.lien ~= nil then
tagname = 'maplink'
end
-- Manage the basics tag params
local tagArgs = {
zoom = 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,
mapstyle = args.kaardistiil,
}
if args.max_lat ~= nil and args.max_long ~= nil and args.min_lat ~= nil and args.min_long ~= nil then
--date line
if tonumber(args.max_long) < tonumber(args.min_long) and tonumber(args.max_long) < 0 and tonumber(args.min_long) > 0 then
args.max_long = 360 + tonumber(args.max_long)
end
local long_diff = tonumber(args.max_long) - tonumber(args.min_long)
local lat_diff = tonumber(args.max_lat) - tonumber(args.min_lat)
local max_diff = long_diff > lat_diff and long_diff or lat_diff
if max_diff < 0.21 then
tagArgs.zoom = 11
elseif max_diff < 0.36 then
tagArgs.zoom = 10
elseif max_diff < 0.73 then
tagArgs.zoom = 9
elseif max_diff < 1.37 then
tagArgs.zoom = 8
elseif max_diff < 3.7 then
tagArgs.zoom = 7
elseif max_diff < 7 then
tagArgs.zoom = 6
elseif max_diff < 13 then
tagArgs.zoom = 5
elseif max_diff < 24 then
tagArgs.zoom = 4
elseif max_diff < 48 then
tagArgs.zoom = 3
elseif max_diff < 80 then
tagArgs.zoom = 2
elseif max_diff < 170 then
tagArgs.zoom = 1
else
tagArgs.zoom = 0
end
tagArgs.latitude = tonumber(args.min_lat) + (tonumber(args.max_lat) - tonumber(args.min_lat)) / 2
tagArgs.longitude = tonumber(args.min_long) + (tonumber(args.max_long) - tonumber(args.min_long)) / 2
--portrait view with max_height
if args.max_height ~= nil then
local ratio = math.rad(lat_diff) / (math.rad(long_diff) / (1 / math.cos(math.rad(tagArgs.latitude))))
if ratio < 0.7 then
tagArgs.height = 200
elseif ratio < 1 then
tagArgs.height = 250
elseif ratio < 1.2 then
tagArgs.height = 300
else
tagArgs.height = tonumber(args.max_height)
end
end
--date line
if tonumber(tagArgs.longitude) > 180 then
tagArgs.longitude = tonumber(tagArgs.longitude) - 360
end
elseif args[1] ~= nil and (args.latitude ~= nil or args.longitude ~= nil) then
error('La ou les valeurs de longitude et/ou de latitude ont été fournis via deux syntaxe différentes. Consultez la documentation du [[Modèle:Carte interactive]] pour obtenir une syntaxe correcte')
elseif args.latitude ~= nil and args.longitude ~= nil then
tagArgs.latitude = coord.dms2dec_convert(args.latitude, 'latitude')
tagArgs.longitude = coord.dms2dec_convert(args.longitude, 'longitude')
elseif args[1] ~= nil and args[2] ~= nil then
tagArgs.latitude = coord.dms2dec_convert(args[1], 'latitude')
tagArgs.longitude = coord.dms2dec_convert(args[2], 'longitude')
end
if args.frameless then
tagArgs.frameless = ''
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 then
geojson[#geojson+1] = {
type = "Feature",
geometry = {
type = "Point",
coordinates = {
tagArgs.longitude,
tagArgs.latitude
}
},
properties = {
['title'] = args.title == nil and '' or args.title,
['description'] = args.description == nil and '' or args.description,
}
}
end
if args.osm ~= nil then
local qid
if args.osm == 'jah' then
qid = mw.wikibase.getEntityIdForCurrentPage()
else
qid = args.osm
end
local service = "geoshape"
if args.contour == 'joon' 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
if args.wikidata ~= nil then
local qid, longitude, latitude
if args.wikidata == 'jah' then
qid = mw.wikibase.getEntityIdForCurrentPage()
else
qid = args.wikidata
end
local entity = mw.wikibase.getEntity( qid )
local statements = entity:getBestStatements('P625')
if (statements[1] and statements[1].mainsnak.snaktype == 'value') then
longitude = statements[1].mainsnak.datavalue.value.longitude
latitude = statements[1].mainsnak.datavalue.value.latitude
end
if longitude == nil then
error('Vikiandmetes puuduvad koordinaadid')
end
geojson[#geojson+1] = {
type = "Feature",
geometry = {
type = "Point",
coordinates = {
longitude,
latitude
}
},
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 == 'joon' then
service = "geoline"
elseif args.contour == 'punkt' then
service = "geopoint"
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.objektid ~= nil then
geojson[#geojson+1] = {
type = "FeatureCollection",
features = decodeJsonList(args.objektid)
}
end
if args.externes ~= nil then
local externes = decodeJsonList(args.externes)
for k, externe in pairs(externes) do
geojson[#geojson+1] = externe
end
end
if next(geojson) == nil and tagArgs.latitude == nil then
error('Kaardil pole punkte, jooni ega pindu, mille järgi kuvatav kaardiala määrata. Ette pole antud ka keskpunkti koordinaati. Loe malli kasutamise kohta lehelt [[Mall:Kaart]]')
end
return frame:extensionTag(tagname, mw.text.jsonEncode(geojson), tagArgs)
end
return p