Module:Sandbox/Yurik/Mapmask

local p = {}

-- If is not in table, set it to -- If exists but is set to an empty string, delete it -- Otherwise keep it as is -- If 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