Module:Sandbox/Yurik/Mapmask
Documentation for this module may be created at Module:Sandbox/Yurik/Mapmask/doc
local p = {}
-- If <name> is not in <params> table, set it to <default>
-- If <name> exists but is set to an empty string, delete it
-- Otherwise keep it as is
-- If <target> table is given, copy the value and remove original
function parseParam(params, target, name, default, isNumber)
if params[name] == nil then
params[name] = default
elseif params[name] == '' then
-- special case - empty string value removes the default value
params[name] = nil
elseif isNumber then
params[name] = tonumber(params[name])
end
if target ~= nil and params[name] ~= nil then
target[name] = params[name]
params[name] = nil
end
end
function parseGeoPairs(tbl, params)
local coordinates = {}
-- Parse an array of strings of number pairs "latitude, longitude" into the real number pairs
-- If key is not a number, treat it as a named parameter and save it in params (if given)
for k, v in pairs( tbl ) do
if type(k) == "number" then
local v2 = mw.text.split( v, ',', true )
if #v2 == 2 then
local lat = tonumber(v2[1])
local lon = tonumber(v2[2])
if lat ~= nil and lon ~= nil then
table.insert(coordinates, { lon, lat } )
end
end
elseif params then
params[k] = v
end
end
return coordinates
end
function toGeoJsonImpl(frameArguments, params)
local coordinates = parseGeoPairs(frameArguments, params)
local properties = {}
parseParam(params, properties, 'stroke-width', 0.5, true)
parseParam(params, properties, 'fill-opacity', 0.3, true)
parseParam(params, properties, 'stroke-opacity', nil, true)
parseParam(params, properties, 'title')
parseParam(params, properties, 'description')
parseParam(params, properties, 'fill')
parseParam(params, properties, 'stroke')
-- by default, mask the whole world, but if mask='', only highlight, without inverting
parseParam(params, nil, 'mask', true)
if params.mask then
coordinates = {
{{36000,-180}, {36000,180}, {-36000,180}, {-36000,-180}, {36000,-180}},
coordinates
}
else
coordinates = { coordinates }
end
-- Negate the above data by creating a Polygon geojson with a giant gray block minus the above data
local result = {
type = "FeatureCollection",
features = { {
type = "Feature",
properties = properties,
geometry = {
type = "Polygon",
coordinates = coordinates
}
} } }
if params.pretty ~= nil then
params.pretty = nil
return mw.text.jsonEncode(result, mw.text.JSON_PRETTY)
else
return mw.text.jsonEncode(result)
end
end
function p.toGeoJson( frame )
local f = frame:getParent()
local params = {}
local geojson = toGeoJsonImpl(f.args, params)
-- Create a hidden maplink with the needed geojson
-- Named parameters are passed as maplink parameters
parseParam(params, nil, 'text', '')
parseParam(params, nil, 'zoom', 0, true)
parseParam(params, nil, 'latitude', 0, true)
parseParam(params, nil, 'longitude', 0, true)
parseParam(params, nil, 'group', 'mask')
return frame:extensionTag( params.tag or 'maplink', params.geojson or geojson, params)
end
return p