Module:Sandbox/Matroc/Mapdraw2

-- This is an experimental module by Matroc - 1/11/2018 -- Used in conjunction with template that is making use of and -- Will change name as more shapes further developed.... -- Conversion of some of the Mapshapes for general use and further development probably desired by more skilled -- Scribunto - Lua programmers -- Shapes built using different coding approaches thus need to combine and simplify as much as possible -- Probably change coordinates to data or something like that. -- NEED TO WORK OUT USING lat and long if lat and long not found in wikidata in Module and template as well -- Latitude and Longitude are recalculated to position correctly for mercator type maps - thus can draw shapes -- without curvature distortion.

-- 26 Aug -- many wikidata entries do not have lat long - if lat and long are provided as parameters then -- going to get around getting the coordinates by putting those parameters 1st then wikidata lat long -- JSON errors will still happen - at least this is a work around getting so that they can be corrected

local p = {} -- CONVERT NEWLATITTUDE

local function newlat(a) newlatitude = 180/math.pi * (2 * math.atan(math.exp( a * math.pi/180)) - math.pi/2 ) if newlatitude > 89.5 then point = 89.5 end -- END if   if newlatitude < -89.5 then point = -89.5 end -- END if    return newlatitude end

-- GET LATITUDE

local function latitude(wikidata) local latitude = "" local entity = mw.wikibase.getEntityObject(wikidata) if entity == nil then error("Wikidata ID " .. wikidata .. " not found!") end local claims = entity.claims if claims == nil then error("Wikidata ID found No Data!") end if claims.P625 ~= nil then latitude = entity.claims.P625[1].mainsnak.datavalue.value.latitude return latitude end if latitude == "" then error("Latitude not found in Wikidata!") end return latitude end

-- GET LONGITUDE -- P625

local function longitude(wikidata) local longitude = "" local entity = mw.wikibase.getEntityObject(wikidata) if entity == nil then error("Wikidata ID " .. wikidata .. " not found!") end local claims = entity.claims if claims == nil then error("Wikidata ID found No Data!") end if claims.P625 ~= nil then longitude = entity.claims.P625[1].mainsnak.datavalue.value.longitude return longitude end if longitude == "" then error("Longitude not found in Wikidata!") end return longitude end

-- TEST ADD LEFT _ RIGHT _ CENTER for Description local function aligndesc(description,descattr) if description ~= nil and description ~= "" then if descattr == "l" then description = " " .. description .. " "	elseif descattr == "r" then description = " " .. description .. " "	elseif descattr == "c" then description = " " .. description .. " "	else description = description end end description = string.gsub(description,'"','\\"')  -- change " to \" for Kartographer return description end

-- NEW FUNCTION TO BE TESTED

local function latlongcheck(lat,long) if lat == nil then error("Missing argument lat!") end if long == nil then error("Missing argument long!") end if tonumber(lat) > 90 or tonumber(lat) < -90 then error("Latitude must be between 90 and -90!") end if tonumber(long) > 180 or tonumber(long) < -180 then error("Longitude must be between 180 and -180!") end return "" end

-- TESTING ADDING fillopacity,strokeopacity and strokewidth FUTURE local function partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity)

-- Maplink content LineString local part1a = '\n{"type": "Feature","geometry": {"type":"LineString", "coordinates":\n' local part1b = '\n\t"properties":{\n\t\t"title": "' .. title .. '",\n' local part1b = part1b .. '\t\t"description": "' .. description .. '",\n' local part1b = part1b .. '\t\t"stroke-opacity":' .. strokeopacity .. ',\n' local part1b = part1b .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":' .. strokewidth .. '\n}}\n'

-- Maplink content Polygon local part2a = '\n{"type": "Feature","geometry": { "type":"Polygon", \t"coordinates":\n' local part2b = '\n\t"properties":{\n\t\t"title": "' .. title .. '",\n' local part2b = part2b .. '\t\t"description": "' .. description .. '",\n\t\t"fill": "' .. fill .. '",\n' local part2b = part2b .. '\t\t"fill-opacity":' .. fillopacity .. ',\n' local part2b = part2b .. '\t\t"stroke-opacity":' .. strokeopacity .. ',\n' local part2b = part2b .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":' .. strokewidth .. '\n}}\n'

-- Mapframe content LineString local part3a = '\n{"type": "FeatureCollection",\n\t"features": [\n\t\t{\n\t\t"type": "Feature",\n\t\t"geometry": {\n\t\t"type":"LineString", "coordinates":\n' local part3b = '\n\t"properties":{\n\t\t"title": "' .. title .. '",\n' local part3b = part3b .. '\t\t"description": "' .. description .. '",\n' local part3b = part3b .. '\t\t"stroke-opacity":' .. strokeopacity .. ',\n' local part3b = part3b .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":' .. strokewidth .. '\n}\n}]}\n'

-- Mapframe content Polygon local part4a = '\n{"type": "FeatureCollection",\n\t"features": [\n\t\t{\n\t\t"type": "Feature",\n\t\t"geometry": {\n\t\t"type":"Polygon", "coordinates":\n' local part4b = '\n\t"properties": {\n\t\t"title": "' .. title .. '",\n' local part4b = part4b .. '\t\t"description": "' .. description .. '",\n\t\t"fill": "' .. fill .. '",\n' local part4b = part4b .. '\t\t"fill-opacity":' .. fillopacity .. ',\n' local part4b = part4b .. '\t\t"stroke-opacity":' .. strokeopacity .. ',\n' local part4b = part4b .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":' .. strokewidth .. '\n}\n}]}\n'

return part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b end

local function parts(lat,long,group,title,description,fill,stroke) --       local xprogcomment = '\n\t\t"__xprogcomment__" : "Mapdraw",\n\t\t"__xprogcomment__date__" : "' .. os.date("%m/%d/%Y -- %I:%M:%S") .. '",\n' -- ERROR SPOT PART1A MAYBE AS THIS WAS MISSING PIECE PROBABLY DELETED SOMEWHERE DURING DEVELOPMENT -- WILL HAVE TO TEST VARIOUS PIECES TO INSURE THIS HAS BEEN CORRECTED -- Put together content for template

-- Maplink content LineString local part1a = '\n{"type": "Feature","geometry": {"type":"LineString", "coordinates":\n' local part1b = '\n\t"properties":{\n\t\t"title": "' .. title .. '",\n' local part1b = part1b .. '\t\t"description": "' .. description .. '",\n' local part1b = part1b .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":1\n}}\n'

-- Maplink content Polygon local part2a = '\n{"type": "Feature","geometry": { "type":"Polygon", \t"coordinates":\n' local part2b = '\n\t"properties":{\n\t\t"title": "' .. title .. '",\n' local part2b = part2b .. '\t\t"description": "' .. description .. '",\n\t\t"fill": "' .. fill .. '",\n' local part2b = part2b .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":1\n}}\n'

-- Mapframe content LineString local part3a = '\n{"type": "FeatureCollection",\n\t"features": [\n\t\t{\n\t\t"type": "Feature",\n\t\t"geometry": {\n\t\t"type":"LineString", "coordinates":\n' local part3b = '\n\t"properties":{\n\t\t"title": "' .. title .. '",\n' local part3b = part3b .. '\t\t"description": "' .. description .. '",\n' local part3b = part3b .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":1\n}\n}]}\n'

-- Mapframe content Polygon local part4a = '\n{"type": "FeatureCollection",\n\t"features": [\n\t\t{\n\t\t"type": "Feature",\n\t\t"geometry": {\n\t\t"type":"Polygon", "coordinates":\n' local part4b = '\n\t"properties": {\n\t\t"title": "' .. title .. '",\n' local part4b = part4b .. '\t\t"description": "' .. description .. '",\n\t\t"fill": "' .. fill .. '",\n' local part4b = part4b .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":1\n}\n}]}\n'

return part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b end

-- For other functions if to be added from original Module Mapdraw -- table of positions for specific shapes local function positions(shape) local positions = {}

positions['star6'] = {30,60,90,120,150,180,210,240,270,300,330,360} positions['star2'] = {36,72,108,144,180,216,252,288,324,360} positions['cross'] = {15,45,75,105,135,165,195,225,255,285,315,345} positions['xshape'] = {30,60,90,120,150,180,210,240,270,300,330,360} positions['bar'] = {90,270} positions['keystone'] = {35,26,55,160,200,305,334,325} positions['cog'] = {45,90,135,180,225,270,315,360} positions['quad'] = {360,90,180,270} positions['arrow'] = {360,45,90,135,180,225,270,315} positions['pentagram'] = {360,144,288,72,216} return positions[shape]

end

-- FUTURE CHANGE TO CHECK AND IF NEED BE CREATE DEFAULT fill AND stroke local function checkhex(fill,stroke) if string.len(fill) ~= 7 then error("Incorrect length for argument fill!") end if string.gsub(fill,"#[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]","") ~= "" then error("Incorrect hexidecimal format for argument fill!") end if string.len(stroke) ~= 7 then error("Incorrect length for argument stroke!") end if string.gsub(stroke,"#[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]","") ~= "" then error("Incorrect hexidecimal format for argument stroke!") end end

local function checkid(id) id = string.gsub(id,"q","Q") id = string.gsub(id,"%s+","") if string.gsub(id,"^[Q]%d+$","") ~= "" then error("Bad format for parameter id!") end --   return id end

-- Several variants of code being concatted depending upon the shape - only used for p.arrow right now -- -3600,90], [3600, 90], [3600,-90], [-3600,-90], [-3600,90, future to add shaded area around shape -- Need to add 'shading' if we want this shaded area local function putittogether(mapframe,type,part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b,coordinates) if mapframe == "y" or mapframe == "yes" then if type == "poly" then coordinates = '' .. coordinates .. '},' coordinates = part4a .. coordinates .. part4b else coordinates = '[' .. coordinates .. ']},'                       coordinates = part3a .. coordinates .. part3b end else if type == "poly" then coordinates = '' .. coordinates .. '},' coordinates = part2a .. coordinates .. part2b else coordinates = '[' .. coordinates .. ']},'                       coordinates = part1a .. coordinates .. part1b end end

return coordinates end

function p.id(frame) --   if frame.args[1]~=nil and frame.args[1]~='' then --       return frame.args[1] --   end local arg1 = frame.args[1] local entity = mw.wikibase.getEntityObject(arg1) --	local entity = mw.wikibase.getEntityObject if entity == nil then return end return entity.id end

-- GET LATITUDE -- P625 as standalone function

function p.latitude(frame) --   if frame.args[1]~=nil and frame.args[1]~='' then --       return frame.args[1] --   end local latitude = "" local arg1 = frame.args[1] local entity = mw.wikibase.getEntityObject(arg1) --	local entity = mw.wikibase.getEntityObject if entity == nil then return latitude end local claims = entity.claims if claims == nil then return latitude end if claims.P625 ~= nil then latitude = entity.claims.P625[1].mainsnak.datavalue.value.latitude return latitude end return latitude end

-- GET LONGITUDE -- P625 as standalone function

function p.longitude(frame) --   if frame.args[1]~=nil and frame.args[1]~='' then --       return frame.args[1] --   end local longitude = "" local arg1 = frame.args[1] local entity = mw.wikibase.getEntityObject(arg1) --	local entity = mw.wikibase.getEntityObject if entity == nil then return longitude end local claims = entity.claims if claims == nil then return longitude end if claims.P625 ~= nil then longitude = entity.claims.P625[1].mainsnak.datavalue.value.longitude return longitude end return longitude end

-- ARROW -- only creates a Polygon with a stroke thickness of 3 and fill-opacity of 1.0

function p.arrow(frame) local shape = "arrow" local id = frame.args['id']	or "" local lat=frame.args['lat'] or "" local long=frame.args['long'] or "" if lat == "" or lat == nil or long == "" or long == nil then id = checkid(id) lat = latitude(id) long = longitude(id) end

local latitude = lat -- for marker points to       local longitude = long -- for marker points to        local direction = frame.args['direction'] or "1" if direction == nil or direction == "" then direction = "1" end --          if string.gsub(direction,"[1-8]","") ~= "" then error("Numbers 1-8 only in direction!") end if string.gsub(direction,"^[1-8]$","") ~= "" then direction="1" end if tonumber(direction) < 1 or tonumber(direction) > 8 then direction = "1" end direction = tonumber(direction) local group = frame.args['group'] or 'arrow' local title = frame.args['title'] or 'An arrow' local description = frame.args['desc'] or '' local descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) local r = frame.args['radius'] or ".5" r = tonumber(r) if r > 10 then error("10 for length is MAX") end  -- exception for bar only if r <= 0 then error("r has to be greater than 0") end local r2 = r * .50 local r3 = r * .475 local fill = frame.args['fill'] or "#000000"            -- fill arg - default is black if fill == nil or fill == "" then fill = "#000000" end local stroke = frame.args['stroke'] or "#000000"        -- stroke arg - default is black if stroke == nil or stroke == "" then stroke = fill end local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end local coordinates = "" local type = frame.args['type'] or "poly" -- default is polygon if type ~= "poly" then type = "line" end

local angle,ptx,pty = 0,0,0

local compass = positions(shape) local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) --       local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke)

lat = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180) angle = (compass[direction]) * math.pi / 180 ptx = lat - (r*1.05) * math.cos( angle ) pty = long - (r*1.05) * math.sin( angle ) lat,long = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty)

lat = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180)

local matrix = {} -- 1         angle = (compass[direction] - 18) * math.pi / 180 ptx = lat + r2 * math.cos( angle ) pty = long + r2 * math.sin( angle ) ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) matrix[1] = "[" .. pty .. "," .. ptx .. "]@@@@@" -- 2         angle = compass[direction] * math.pi / 180 ptx = lat + r * math.cos( angle ) pty = long + r * math.sin( angle ) ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) matrix[2] = "[" .. pty .. "," .. ptx .. "]@@@@@" --3         angle = (compass[direction] + 18) * math.pi / 180 ptx = lat + r2 * math.cos( angle ) pty = long + r2 * math.sin( angle ) ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) matrix[3] = "[" .. pty .. "," .. ptx .. "]@@@@@"

-- 4         angle = (compass[direction] - 2) * math.pi / 180 ptx = lat + r3 * math.cos( angle ) pty = long + r3 * math.sin( angle ) ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) matrix[4] = "[" .. pty .. "," .. ptx .. "]@@@@@"

-- 5         angle = (compass[direction] + 181) * math.pi / 180 ptx = lat + r * math.cos( angle ) pty = long + r * math.sin( angle ) ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) matrix[5] = "[" .. pty .. "," .. ptx .. "]@@@@@" -- 6         angle = (compass[direction] + 179) * math.pi / 180 ptx = lat + r * math.cos( angle ) pty = long + r * math.sin( angle ) ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) matrix[6] = "[" .. pty .. "," .. ptx .. "]@@@@@" -- 7         angle = (compass[direction] + 2) * math.pi / 180 ptx = lat + r3 * math.cos( angle ) pty = long + r3 * math.sin( angle ) ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) matrix[7] = "[" .. pty .. "," .. ptx .. "]@@@@@"

for i=1,table.getn(matrix),1 do               coordinates = coordinates .. matrix[i] end coordinates = coordinates .. matrix[1] coordinates = string.gsub(coordinates,'@@@@@$','') coordinates = string.gsub(coordinates,'@@@@@',',')

lat = string.format("%.6f",newlat(lat))

coordinates = putittogether(mapframe,type,part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b,coordinates)

-- Make thickness of 3

coordinates = string.gsub(coordinates,'stroke%-width%":1','fill-opacity": 1.0,\n\t\t"stroke-width":4')

return coordinates

end

-- BOX - Square

function p.box(frame) local shape = frame.args['box'] or "box" local id = frame.args['id']	or "" local lat=frame.args['lat'] or "" local long=frame.args['long'] or "" if lat == "" or lat == nil or long == "" or long == nil then id = checkid(id) lat = latitude(id) long = longitude(id) end -- Future : local shading = frame.args['shading'] or 'n' local group = frame.args['group'] or 'box' local title = frame.args['title'] or 'A box' local description = frame.args['desc'] or '' local descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) local name = frame.args['name'] or "A Center Box" local r = frame.args['radius'] or ".5" r = tonumber(r) if r > 10 then error("10 for radius is MAX") end if r <= 0 then error("r has to be greater than 0") end local fill = frame.args['fill'] or "#ccef64" local stroke = frame.args['stroke'] or "#0000ff" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end local coordinates = "" local type = frame.args['type'] or "line" -- default line for LineString if type ~= "line" then type = "poly" end local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) --       local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke) lat = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180)

local angle1,angle2,angle3,angle4 = 0,0,0,0 local ptx,ptx2,ptx3,ptx4 = 0,0,0,0 local pty,pty2,pty3,pty4 = 0,0,0,0 local a = 45 local b = 135 local c = 225 local d = 315 angle1 = a * math.pi / 180 ptx = lat + r * math.cos( angle1 ) pty = long + r * math.sin( angle1 )

angle2 = b * math.pi /180 ptx2 = lat + r * math.cos( angle2 ) pty2 = long + r * math.sin( angle2 )

angle3 = c * math.pi /180 ptx3 = lat + r * math.cos( angle3 ) pty3 = long + r * math.sin( angle3 ) angle4 = d * math.pi /180 ptx4 = lat + r * math.cos( angle4 ) pty4 = long + r * math.sin( angle4 ) ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) ptx2,pty2 = string.format("%.6f",newlat(ptx2)),string.format("%.6f",pty2) ptx3,pty3 = string.format("%.6f",newlat(ptx3)),string.format("%.6f",pty3) ptx4,pty4 = string.format("%.6f",newlat(ptx4)),string.format("%.6f",pty4) lat,long = string.format("%.6f",newlat(lat)),string.format("%.6f",long)

coordinates = "[" .. pty .. "," .. ptx .. "],[" .. pty2 .. "," .. ptx2 .. "],[" .. pty3 .. "," .. ptx3 .. "],[".. pty4 .. "," .. ptx4 .. "],[" .. pty .. "," .. ptx .. "]"

-- ADD SHADING to call coordinates = putittogether(mapframe,type,part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b,coordinates)

return coordinates

end

-- EQUITRI

function p.equitri(frame) local shape = "equitri" local id = frame.args['id']	or "" local lat=frame.args['lat'] or "" local long=frame.args['long'] or "" if lat == "" or lat == nil or long == "" or long == nil then id = checkid(id) lat = latitude(id) long = longitude(id) end

local group = frame.args['group'] or 'equitri' local title = frame.args['title'] or 'An equilateral triangle' local description = frame.args['desc'] or '' local descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) local r = frame.args['radius'] or ".5" r = tonumber(r) if r > 10 then error("10 for radius is MAX") end if r <= 0 then error("r has to be greater than 0") end r = r * 2 local fill = frame.args['fill'] or "#ccef64" local stroke = frame.args['stroke'] or "#0000ff" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end local coordinates = ""

local type = frame.args['type'] or "line" -- default line for LineString if type ~= "line" then type = "poly" end

local direction = frame.args['direction'] or "1" if direction == nil or direction == "" then direction="1" end if string.gsub(direction,"^[1-4]$","") ~= "" then direction="1" end --             direction = string.gsub(direction,"%..*","") direction = tonumber(direction) if direction <= 0 or direction >=5 then error("direction should be a number from 1 to 4!") end

local factors = {} factors[1] = "360,120,240" factors[2] = "90,210,330" factors[3] = "180,300,60" factors[4] = "270,150,30"

local points = factors[direction] a = string.gsub(points,'%,.*$','') b = string.gsub(points,'(%d+%,)(%d+)(%,%d+)',"%2") c = string.gsub(points,'^.*,','') local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) --       local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke)

lat = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180)

angle1 = a * math.pi / 180 ptx = lat + r * math.cos( angle1 ) pty = long + r * math.sin( angle1 )

angle2 = b * math.pi /180 ptx2 = lat + r * math.cos( angle2 ) pty2 = long + r * math.sin( angle2 )

angle3 = c * math.pi /180 ptx3 = lat + r * math.cos( angle3 ) pty3 = long + r * math.sin( angle3 )

ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) ptx2,pty2 = string.format("%.6f",newlat(ptx2)),string.format("%.6f",pty2) ptx3,pty3 = string.format("%.6f",newlat(ptx3)),string.format("%.6f",pty3)

lat,long = string.format("%.6f",newlat(lat)),string.format("%.6f",long)

coordinates = "[" .. pty .. "," .. ptx .. "],[" .. pty2 .. "," .. ptx2 .. "],[" .. pty3 .. "," .. ptx3 .. "],[" .. pty .. "," .. ptx .. "]"

coordinates = putittogether(mapframe,type,part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b,coordinates)

return coordinates

end

-- STAR -- to be reworked for vertical placement of top of star

function p.star(frame) local shape = "star" local id = frame.args['id']	or "" local lat=frame.args['lat'] or "" local long=frame.args['long'] or "" if lat == "" or lat == nil or long == "" or long == nil then id = checkid(id) lat = latitude(id) long = longitude(id) end

local latitude = string.format("%.6f",lat) local longitude = string.format("%.6f",long) local group = frame.args['group'] or 'star' local title = frame.args['title'] or 'A star' local description = frame.args['desc'] or '' local descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) local radius = frame.args['radius'] or ".5" radius = tonumber(radius) if radius > 10 then error("10 for radius is MAX") end if radius <= 0 then error("radius has to be greater than 0") end local radius2 = radius * 3; local fill = frame.args['fill'] or "#ccef64" local stroke = frame.args['stroke'] or "#0000ff" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke)

local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end -- FUTURE USE latitude = math.log(math.tan((90 + latitude) * math.pi/360)) / (math.pi/180) local ra,angle = 0,0 local points = {} local coordinates = "" local type = frame.args['type'] or "line" -- default line for LineString if type ~= "line" then type = "poly" end local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) --       local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke) for i = 1,10, 1 do        mod = math.mod(i,2) if mod == 1 then ra = radius else ra = radius2 end angle = ((2 * math.pi / 10)) * i         points[i] =  '[' .. string.format("%.6f",longitude + (ra * math.cos(angle))) .. ","        points[i] = points[i] .. string.format("%.6f",newlat(latitude + (ra * math.sin(angle)))) .. "],"     end

for i = 1,10, 1 do        coordinates = coordinates .. points[i] .. "\n" end

coordinates = coordinates .. points[1]

if mapframe == "y" or mapframe == "yes" then if type == "poly" then coordinates = string.gsub(coordinates,'%]%,$',']]]},') coordinates = part4a .. string.gsub(coordinates,'^%[','[') .. part4b          else                coordinates  = string.gsub(coordinates,'%]%,},')                ,'},') coordinates = part3a .. string.gsub(coordinates,'^%[','') .. part3b          end	   else           if type == "poly" then                coordinates  = string.gsub(coordinates,'%]%,]},')                ,']},') coordinates = part2a .. string.gsub(coordinates,'^%[','[') .. part2b          else                coordinates  = string.gsub(coordinates,'%]%,},')                ,'},') coordinates = part1a .. string.gsub(coordinates,'^%[','[[') .. part1b          end	   	   end

return coordinates

end -- STAR2 -- reworked star pointing North

function p.star2(frame) local shape = "star2" local id = frame.args['id']	or "" local lat=frame.args['lat'] or "" local long=frame.args['long'] or "" if lat == "" or lat == nil or long == "" or long == nil then id = checkid(id) lat = latitude(id) long = longitude(id) end

local x = tonumber(lat) local y = tonumber(long) local latitude = string.format("%.6f",lat) local longitude = string.format("%.6f",long) local group = frame.args['group'] or 'star2' local title = frame.args['title'] or 'A star(2)' local description = frame.args['desc'] or '' local descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) local radius = frame.args['radius'] or ".5" radius = tonumber(radius) if radius > 10 then error("10 for radius is MAX") end if radius <= 0 then error("radius has to be greater than 0") end local radius2 = radius * 3; local fill = frame.args['fill'] or "#ccef64" local stroke = frame.args['stroke'] or "#0000ff" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end -- FUTURE USE local ra,angle,ptx,pty = 0,0,0,0 local compass = {} local points = {} local coordinates = "" local type = frame.args['type'] or "line" -- default line for LineString if type ~= "line" then type = "poly" end local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) --       local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke)

x = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180) compass = positions(shape)

for i = 1,table.getn(compass), 1 do       mod = math.mod(i,2) if mod == 1 then r = radius else r = radius2 end angle = compass[i] * math.pi / 180 ptx = x + r * math.cos( angle ) pty = y + r * math.sin( angle ) ptx = newlat(ptx) -- TEST BELOW FIX       points[i] = '[' .. string.format("%.6f",pty) .. pty .. "," .. string.format("%.6f",ptx) .. "],"       points[i] = '[' .. string.format("%.6f",pty) .. "," .. string.format("%.6f",ptx) .. "],"

end

for i = 1,table.getn(points), 1 do        coordinates = coordinates .. points[i] .. "\n" end

coordinates = coordinates .. points[1]

if mapframe == "y" or mapframe == "yes" then if type == "poly" then coordinates = string.gsub(coordinates,'%]%,$',']]]},') coordinates = part4a .. string.gsub(coordinates,'^%[','[') .. part4b          else                coordinates  = string.gsub(coordinates,'%]%,},')                ,'},') coordinates = part3a .. string.gsub(coordinates,'^%[','') .. part3b          end	   else           if type == "poly" then                coordinates  = string.gsub(coordinates,'%]%,]},')                ,']},') coordinates = part2a .. string.gsub(coordinates,'^%[','[') .. part2b          else                coordinates  = string.gsub(coordinates,'%]%,},')                ,'},') coordinates = part1a .. string.gsub(coordinates,'^%[','[[') .. part1b          end	   	   end

return coordinates

end

-- MULTISIDE - create multi-sided regular polygon - if number of sides > 20 can use to replace circle with its 360 points

function p.multiside(frame) local shape = "multiside" local sides = frame.args['sides'] or "3" if sides == nil or sides == "" then sides = "3" end sides = tonumber(sides) if sides 360 then sides = 3 end -- as number of sides grow - can use to make a rough circle above 20 local increment = 360/sides local inbetween = increment/2 local id = frame.args['id'] or "" id = string.gsub(id,"%,+","@") id = string.gsub(id,"%s+",'') id = string.gsub(id,"%@+",'@') local lat = frame.args['lat'] or "" local long = frame.args['long'] or "" local matrix = {} local coordinates = "" local count = 1 local type = frame.args['type'] or "line" if type ~= "poly" then type = "line" end if id == nil or id == "" then if lat == "" or lat == nil then error("Missing argument lat!") end if long == "" or long == nil then error("Missing argument long!") end if tonumber( lat ) > 90 or tonumber( lat ) < -90 then error("Latitudes must be between 90 and -90!") end if tonumber(long) > 180 or tonumber(long) < -180 then error("Longitudes must be between 180 and -180!") end else id = checkid(id) lat = latitude(id) long = longitude(id) end local r = frame.args['radius'] or ".5" r = tonumber(r) if r > 10 then error("10 for radius is MAX") end if r <= 0 then error("r has to be greater than 0") end local group = frame.args['group'] or 'multiside' local title = frame.args['title'] or 'A Multi-sided shape' local description = frame.args['desc'] or "" local descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) if description == nil then description = "" end local fill = frame.args['fill'] or "#ffff00" local stroke = frame.args['stroke'] or "#000000" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nil or mapframe == "" then mapframe = "no" end local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) --       local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke) local angle,ptx,pty = 0,0,0 local latitude = lat lat = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180) local count = 0 for i = increment,360, increment do            angle = (i + inbetween) * math.pi / 180 ptx = lat + r * math.cos( angle ) pty = long + r * math.sin( angle ) ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) count = count + 1 matrix[count] = "[" .. pty .. "," .. ptx .. "]@@@@@"       end

for i = 1,table.getn(matrix), 1 do         coordinates = coordinates .. matrix[i] end

coordinates = coordinates .. matrix[1] coordinates = string.gsub(coordinates,"@@@@@",",") coordinates = string.gsub(coordinates,",$",'')

coordinates = putittogether(mapframe,type,part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b,coordinates)

return coordinates

end

-- ELLIPSE

function p.ellipse(frame) local shape = "ellipse" local id = frame.args['id']	or "" local x,y = 0,0 local lat=frame.args['lat'] or "" local long=frame.args['long'] or "" if lat == "" or lat == nil or long == "" or long == nil then id = checkid(id) lat = latitude(id) long = longitude(id) end

x = string.format("%.6f",lat) y = string.format("%.6f",long) local group = frame.args['group'] or 'ellipse' local title = frame.args['title'] or 'An ellipse' local description = frame.args['desc'] or '' local descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) local r = frame.args['radius'] or ".5" r = tonumber(r) if r > 10 then error("10 for radius is MAX") end if r <= 0 then error("radius has to be greater than 0") end local fill = frame.args['fill'] or "#ccef64" local stroke = frame.args['stroke'] or "#0000ff" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end -- FUTURE USE local direction = frame.args['direction'] or "h" if direction == nil or direction == "" then direction = "h" end if direction ~= "v" then direction = "h" end -- if not v (ie. other garbage then force direction to be h)       local data = {} local coordinates = "" local ptx,pty,angle = 0,0,0 local type = frame.args['type'] or "line" -- default line for LineString if type ~= "line" then type = "poly" end local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) --       local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke)

if tonumber(x) >= 10.5 then x = math.log(math.tan((90 + x) * math.pi/360)) / (math.pi/180) elseif tonumber(x) <= -10.5 then x = math.log(math.tan((90 + x) * math.pi/360)) / (math.pi/180) end

for i = 1, 360 do          angle = i * math.pi / 180 ptx = x + r * math.cos( angle ) if direction == "v" then pty = y - 0.5 * r * math.sin( angle ) -- for ellipse vertical elseif direction == "h" then pty = y + 2.0 * r * math.sin(angle) -- for ellipse horizontal end

if tonumber(x) >= 10.5 then ptx = newlat(ptx) -- makes correction to make ellipse show up on map end

if tonumber(x) <= -10.5 then ptx = newlat(ptx) -- makes correction to make ellipse show up on map end

data[i] = '[' .. string.format("%.6f",pty) .. "," .. string.format("%.6f",ptx) .. ']'       end

for i = 5,359, 5 do               data[i] = data[i] .. "@@@@@"       end

for i = 1,360, 1 do       coordinates = coordinates .. data[i] end

coordinates = coordinates.gsub(coordinates,'%]%[','],[') coordinates = coordinates.gsub(coordinates,'%]@@@@@%[','],\n[') coordinates = "[" .. coordinates .. ',' .. data[1] .. "],"

if mapframe == "y" or mapframe == "yes" then if type == "poly" then coordinates = string.gsub(coordinates,'%]%,$',']]},') coordinates = part4a .. string.gsub(coordinates,'^%[','') .. part4b          else                coordinates = string.gsub(coordinates,'%]%,},')                ,']},')                coordinates = part3a .. coordinates .. part3b           end		else           if type == "poly" then                coordinates  = string.gsub(coordinates,'%]%,},')                ,'},') coordinates = part2a .. string.gsub(coordinates,'^%[','[[') .. part2b          else                coordinates = string.gsub(coordinates,'%]%,$',']},')                coordinates = part1a .. coordinates .. part1b           end				end        return coordinates

end

-- BOX FRAME

function p.boxframe(frame) local shape = "box" local id = frame.args['id']	or "" local lat=frame.args['lat'] or "" local long=frame.args['long'] or "" if lat == "" or lat == nil or long == "" or long == nil then id = checkid(id) lat = latitude(id) long = longitude(id) end

local group = frame.args['group'] or 'boxframe' local title = frame.args['title'] or 'A boxframe' local description = frame.args['desc'] or '' local descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) local r = frame.args['radius'] or ".5" r = tonumber(r) if r > 10 then error("10 for radius is MAX") end if r <= 0 then error("r has to be greater than 0") end local r2 = r * .85 local fill = frame.args['fill'] or "#ccef64" local stroke = frame.args['stroke'] or "#0000ff" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end local coordinates = "" local type = frame.args['type'] or "line" -- default line for LineString if type ~= "line" then type = "poly" end -- line to become MultiLineString local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) --       local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke) lat = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180)

local angle1,angle2,angle3,angle4 = 0,0,0,0 local ptx,ptx2,ptx3,ptx4 = 0,0,0,0 local pty,pty2,pty3,pty4 = 0,0,0,0 local ptxa,ptxb,ptxc,ptxd = 0,0,0,0 local ptya,ptyb,ptyc,ptyd = 0,0,0,0 local a = 45 local b = 135 local c = 225 local d = 315 angle1 = a * math.pi / 180 ptx,ptxa = lat + r * math.cos( angle1 ),lat + r2 * math.cos( angle1 ) pty,ptya = long + r * math.sin( angle1 ),long + r2 * math.sin( angle1 )

angle2 = b * math.pi /180 ptx2,ptxb = lat + r * math.cos( angle2 ),lat + r2 * math.cos( angle2 ) pty2,ptyb = long + r * math.sin( angle2 ),long + r2 * math.sin( angle2 )

angle3 = c * math.pi /180 ptx3,ptxc = lat + r * math.cos( angle3 ),lat + r2 * math.cos( angle3 ) pty3,ptyc = long + r * math.sin( angle3 ),long + r2 * math.sin( angle3 ) angle4 = d * math.pi /180 ptx4,ptxd = lat + r * math.cos( angle4 ),lat + r2 * math.cos( angle4 ) pty4,ptyd = long + r * math.sin( angle4 ),long + r2 * math.sin( angle4 ) ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) ptx2,pty2 = string.format("%.6f",newlat(ptx2)),string.format("%.6f",pty2) ptx3,pty3 = string.format("%.6f",newlat(ptx3)),string.format("%.6f",pty3) ptx4,pty4 = string.format("%.6f",newlat(ptx4)),string.format("%.6f",pty4) ptxa,ptya = string.format("%.6f",newlat(ptxa)),string.format("%.6f",ptya) ptxb,ptyb = string.format("%.6f",newlat(ptxb)),string.format("%.6f",ptyb) ptxc,ptyc = string.format("%.6f",newlat(ptxc)),string.format("%.6f",ptyc) ptxd,ptyd = string.format("%.6f",newlat(ptxd)),string.format("%.6f",ptyd) lat,long = string.format("%.6f",newlat(lat)),string.format("%.6f",long)

coordinates = "[" .. pty .. "," .. ptx .. "],[" .. pty2 .. "," .. ptx2 .. "],[" .. pty3 .. "," .. ptx3 .. "],[".. pty4 .. "," .. ptx4 .. "],[" .. pty .. "," .. ptx .. "]"       coordinates = coordinates .. "],[" .. "[" .. ptya .. "," .. ptxa .. "],[" .. ptyb .. "," .. ptxb .. "],[" .. ptyc .. "," .. ptxc .. "],[".. ptyd .. "," .. ptxd .. "],[" .. ptya .. "," .. ptxa .. "]"       if mapframe == "y" or mapframe == "yes" then if type == "poly" then coordinates = '' .. coordinates .. '},' coordinates = part4a .. coordinates .. part4b else coordinates = '' .. coordinates .. '},' coordinates = part3a .. coordinates .. part3b coordinates = string.gsub(coordinates,'"type":"LineString"','"type":"MultiLineString"') end else if type == "poly" then coordinates = '' .. coordinates .. '},' coordinates = part2a .. coordinates .. part2b else coordinates = '' .. coordinates .. '},' coordinates = part1a .. coordinates .. part1b coordinates = string.gsub(coordinates,'"type":"LineString"','"type":"MultiLineString"') end end

return coordinates

end

-- CRESCENT

function p.crescent(frame) local shape = "crescent" local id = frame.args['id']	or "" --       local lat,long = "","" local x,y,x2,y2 = 0,0,0,0 local newcenterx,newcentery = 0,0 local lat=frame.args['lat'] or "" local long=frame.args['long'] or "" if lat == "" or lat == nil or long == "" or long == nil then id = checkid(id) lat = latitude(id) long = longitude(id) end

x = string.format("%.6f",lat) y = string.format("%.6f",long) local group = frame.args['group'] or 'crescent' local title = frame.args['title'] or 'A crescent' local description = frame.args['desc'] or '' local descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) local r = frame.args['radius'] or ".5" r = tonumber(r) if r > 10 then error("10 for radius is MAX") end if r <= 0 then error("radius has to be greater than 0") end local fill = frame.args['fill'] or "#ccef64" local stroke = frame.args['stroke'] or "#0000ff" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end -- FUTURE USE local data = {} local data2 = {} local coordinates = "" local coordinates2 = "" local ptx,pty,angle,ptx2,pty2 = 0,0,0,0,0 local type = frame.args['type'] or "line" -- default line for LineString if type ~= "line" then type = "poly" end

local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) --       local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke)

x = math.log(math.tan((90 + x) * math.pi/360)) / (math.pi/180) x2 = x       y2 = y        for i = 1, 360 do           angle = i * math.pi / 180 ptx = x + r * math.cos( angle ) pty = y + 1.5 * r * math.sin(angle) -- for ellipse horizontal

ptx2 = x2 + r * math.cos (angle) pty2 = y2 + r * math.sin (angle)

if i == 90 then newcenterx = x + r * math.cos( angle ) newcentery = y + 1.25 * r * math.sin (angle) newcenterx = newlat(newcenterx) newcenterx = string.format("%.6f",newcenterx) newcentery = string.format("%.6f",newcentery) end

ptx = newlat(ptx) -- makes correction to make ellipse show up on map ptx2 = newlat(ptx2)

data[i] = '[' .. string.format("%.6f",pty) .. "," .. string.format("%.6f",ptx) .. ']'          data2[i] = '[' .. string.format("%.6f",pty2) .. "," .. string.format("%.6f",ptx2) .. ']'      end

for i = 5,360, 5 do           data[i] = data[i] .. "@@@@@"           data2[i] = data2[i] .. "@@@@@"       end

for i = 1,180, 1 do       coordinates = coordinates .. data[i] end

for i = 180,1, -1 do       coordinates2 = coordinates2 .. data2[i] end

coordinates = coordinates .. coordinates2 coordinates = coordinates.gsub(coordinates,'%]%[','],[') coordinates = coordinates.gsub(coordinates,'@@@@@$','') coordinates = coordinates.gsub(coordinates,'%]@@@@@%[','],\n[') coordinates = "[" .. coordinates .. ',' .. data[1] .. "],"

if mapframe == "y" or mapframe == "yes" then if type == "poly" then coordinates = string.gsub(coordinates,'%]%,$',']]},') coordinates = part4a .. string.gsub(coordinates,'^%[','') .. part4b          else                coordinates = string.gsub(coordinates,'%]%,},')                ,']},')                coordinates = part3a .. coordinates .. part3b           end		else           if type == "poly" then                coordinates  = string.gsub(coordinates,'%]%,},')                ,'},') coordinates = part2a .. string.gsub(coordinates,'^%[','[[') .. part2b          else                coordinates = string.gsub(coordinates,'%]%,$',']},')                coordinates = part1a .. coordinates .. part1b           end				end    return coordinates

end

-- CROSS

function p.cross(frame) local shape = "cross" local id = frame.args['id']	or "" --	  local lat,long = "","" local lat=frame.args['lat'] or "" local long=frame.args['long'] or "" if lat == "" or lat == nil or long == "" or long == nil then id = checkid(id) lat = latitude(id) long = longitude(id) end

-- to work with template Mapdraw2 which supplies an id of Q97 to make it work which reactes a lat long -- but is ignoring an input lat and long which is to take precedence over input of an id in the template

--if latxxx ~= nil and latxxx ~= "" then --	lat = latxxx --	end --if longxxx ~= nil and longxxx ~= "" then --	long = longxxx --	end local group = frame.args['group'] or 'cross' local title = frame.args['title'] or 'A Cross' local description = frame.args['desc'] or '' local descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) local r = frame.args['radius'] or ".5" r = tonumber(r) if r > 10 then error("10 for length is MAX") end if r <= 0 then error("r has to be greater than 0") end local r2 = r * .25 local fill = frame.args['fill'] or "#ff0000" local stroke = frame.args['stroke'] or "#ffffff" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end local coordinates = "" local type = frame.args['type'] or "line" -- default line for LineString if type ~= "line" then type = "poly" end

local angle = 0

local compass = positions(shape) local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) --       local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke)

lat = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180) for i = 1,table.getn(compass), 1 do         angle = compass[i] * math.pi / 180 if compass[i] == 45 or compass[i] == 135 or compass[i] == 225 or compass[i] == 315 then ptx = lat + r2 * math.cos( angle ) pty = long + r2 * math.sin( angle ) else ptx = lat + r * math.cos( angle ) pty = long + r * math.sin( angle ) end

ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty)

coordinates = coordinates .. "[" .. pty .. "," .. ptx .. "]@@@@@"

end coordinates = coordinates .. string.gsub(coordinates,'@@@@@.*','') coordinates = string.gsub(coordinates,'@@@@@',',')

coordinates = putittogether(mapframe,type,part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b,coordinates)

return coordinates end

function p.rhombus(frame) local shape = "rhombus" local direction = frame.args['direction'] or "v" if direction == nil or direction == "" then direction = "v" end if direction ~= "h" then direction = "v" end local id = frame.args['id']	or "" local lat=frame.args['lat'] or "" local long=frame.args['long'] or "" if lat == "" or lat == nil or long == "" or long == nil then id = checkid(id) lat = latitude(id) long = longitude(id) end

-- latlongcheck(lat,long) -- Future?

--	  local lat,long = "","" -- if id == nil or id == "" then --                if frame.args['lat'] == nil then error("Missing argument lat!") end --                if frame.args['long'] == nil then error("Missing argument long!") end --                lat = frame.args['lat'] --                long = frame.args['long'] --                if tonumber(frame.args['lat']) > 90 or tonumber(frame.args['lat']) < -90 then --          	    error("Latitude must be between 90 and -90!") end --                if tonumber(frame.args['long']) > 180 or tonumber(frame.args['long']) < -180 then --          	    error("Longitude must be between 180 and -180!") end --  	       else --                id = checkid(id) --                lat = latitude(id) --                long = longitude(id) --	  end local group = frame.args['group'] or 'rhombus' local title = frame.args['title'] or 'A rhombus' local description = frame.args['desc'] or '' local descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) local r = frame.args['radius'] or ".5" r = tonumber(r) if r > 10 then error("10 for radius is MAX") end if r <= 0 then error("r has to be greater than 0") end local r2 = r * 2 local fill = frame.args['fill'] or "#ccef64" local stroke = frame.args['stroke'] or "#0000ff" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke)

local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end local coordinates = "" local type = frame.args['type'] or "line" -- default line for LineString if type ~= "line" then type = "poly" end local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) --       local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke) lat = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180)

local angle1,angle2,angle3,angle4 = 0,0,0,0 local ptx,ptx2,ptx3,ptx4 = 0,0,0,0 local pty,pty2,pty3,pty4 = 0,0,0,0 local a,b,c,d = 0,0,0,0 if direction == "h" then a,b,c,d = 360,90,180,270 else a,b,c,d = 90,180,270,360 end

angle1 = a * math.pi / 180 ptx = lat + r * math.cos( angle1 ) pty = long + r * math.sin( angle1 )

angle2 = b * math.pi /180 ptx2 = lat + r2 * math.cos( angle2 ) pty2 = long + r2 * math.sin( angle2 )

angle3 = c * math.pi /180 ptx3 = lat + r * math.cos( angle3 ) pty3 = long + r * math.sin( angle3 ) angle4 = d * math.pi /180 ptx4 = lat + r2 * math.cos( angle4 ) pty4 = long + r2 * math.sin( angle4 ) ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) ptx2,pty2 = string.format("%.6f",newlat(ptx2)),string.format("%.6f",pty2) ptx3,pty3 = string.format("%.6f",newlat(ptx3)),string.format("%.6f",pty3) ptx4,pty4 = string.format("%.6f",newlat(ptx4)),string.format("%.6f",pty4) lat,long = string.format("%.6f",newlat(lat)),string.format("%.6f",long)

coordinates = "[" .. pty .. "," .. ptx .. "],[" .. pty2 .. "," .. ptx2 .. "],[" .. pty3 .. "," .. ptx3 .. "],[".. pty4 .. "," .. ptx4 .. "],[" .. pty .. "," .. ptx .. "]"

coordinates = putittogether(mapframe,type,part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b,coordinates)

return coordinates

end

-- DIAMOND

function p.diamond(frame) local shape = "diamond" local id = frame.args['id']	or "" local lat=frame.args['lat'] or "" local long=frame.args['long'] or "" if lat == "" or lat == nil or long == "" or long == nil then id = checkid(id) lat = latitude(id) long = longitude(id) end

local group = frame.args['group'] or 'diamond' local title = frame.args['title'] or 'A diamond' local description = frame.args['desc'] or '' local descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) local r = frame.args['radius'] or ".5" r = tonumber(r) if r > 10 then error("10 for radius is MAX") end if r <= 0 then error("r has to be greater than 0") end local fill = frame.args['fill'] or "#ccef64" local stroke = frame.args['stroke'] or "#0000ff" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end local coordinates = "" local type = frame.args['type'] or "line" -- default line for LineString if type ~= "line" then type = "poly" end local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) --       local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke) lat = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180)

local a = 360 local b = 90 local c = 180 local d = 270 angle1 = a * math.pi / 180 ptx = lat + r * math.cos( angle1 ) pty = long + r * math.sin( angle1 )

angle2 = b * math.pi /180 ptx2 = lat + r * math.cos( angle2 ) pty2 = long + r * math.sin( angle2 )

angle3 = c * math.pi /180 ptx3 = lat + r * math.cos( angle3 ) pty3 = long + r * math.sin( angle3 ) angle4 = d * math.pi /180 ptx4 = lat + r * math.cos( angle4 ) pty4 = long + r * math.sin( angle4 ) ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) ptx2,pty2 = string.format("%.6f",newlat(ptx2)),string.format("%.6f",pty2) ptx3,pty3 = string.format("%.6f",newlat(ptx3)),string.format("%.6f",pty3) ptx4,pty4 = string.format("%.6f",newlat(ptx4)),string.format("%.6f",pty4) lat,long = string.format("%.6f",newlat(lat)),string.format("%.6f",long)

coordinates = "[" .. pty .. "," .. ptx .. "],[" .. pty2 .. "," .. ptx2 .. "],[" .. pty3 .. "," .. ptx3 .. "],[".. pty4 .. "," .. ptx4 .. "],[" .. pty .. "," .. ptx .. "]"

coordinates = putittogether(mapframe,type,part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b,coordinates)

return coordinates

end -- SUN - draw circle with spikes as rays from sun

function p.sun(frame) local shape = "sun" local sunburst = frame.args['sunburst'] or "10" if sunburst == nil or sunburst == "" then sunburst = "10" end sunburst = tonumber(sunburst) if sunburst 30 then sunburst = 10 end local increment = 360/sunburst local inbetween = increment/2 local id = frame.args['id'] or "" id = string.gsub(id,"%,+","@") id = string.gsub(id,"%s+",'') id = string.gsub(id,"%@+",'@') local lat = frame.args['lat'] or "" local long = frame.args['long'] or "" local matrix = {} local coordinates = "" local count = 1 local type = frame.args['type'] or "line" if type ~= "poly" then type = "line" end if id == nil or id == "" then if lat == "" or lat == nil then error("Missing argument lat!") end if long == "" or long == nil then error("Missing argument long!") end if tonumber( lat ) > 90 or tonumber( lat ) < -90 then error("Latitudes must be between 90 and -90!") end if tonumber(long) > 180 or tonumber(long) < -180 then error("Longitudes must be between 180 and -180!") end else id = checkid(id) lat = latitude(id) long = longitude(id) end local r = frame.args['radius'] or ".5" r = tonumber(r) if r > 10 then error("10 for radius is MAX") end if r <= 0 then error("r has to be greater than 0") end local r2 = r * .45 local group = frame.args['group'] or 'sun' local title = frame.args['title'] or 'A sun' local description = frame.args['desc'] or "" local descattr = frame.args['descattr'] or 'l' -- TESTING if description == nil then description = "" end description = aligndesc(description,descattr) local fill = frame.args['fill'] or "#ffff00" local stroke = frame.args['stroke'] or "#000000" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nil or mapframe == "" then mapframe = "no" end local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) --       local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke) local angle,ptx,pty = 0,0,0 local latitude = lat lat = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180) local count = 0 for i = increment,360, increment do            angle = i * math.pi / 180 ptx = lat - r2 * math.cos( angle ) pty = long - r2 * math.sin( angle ) ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) count = count + 1 matrix[count] = "[" .. pty .. "," .. ptx .. "]@@@@@"

angle = (i + inbetween) * math.pi / 180 ptx = lat - r * math.cos( angle ) pty = long - r * math.sin( angle ) ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) count = count + 1 matrix[count] = "[" .. pty .. "," .. ptx .. "]@@@@@"       end

for i = 1,table.getn(matrix), 1 do         coordinates = coordinates .. matrix[i] end

coordinates = coordinates .. matrix[1] coordinates = string.gsub(coordinates,"@@@@@",",") coordinates = string.gsub(coordinates,",$",'') coordinates = putittogether(mapframe,type,part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b,coordinates)

return coordinates

end

-- STADIUM or pill capsule shape -- reduced number of coordinates for circular shape

function p.stadium(frame) local shape = "stadium" local id = frame.args['id'] or "" local x,y,x2,y2 = 0,0,0,0 local lat=frame.args['lat'] or "" local long=frame.args['long'] or "" if lat == "" or lat == nil or long == "" or long == nil then id = checkid(id) lat = latitude(id) long = longitude(id) end lat = string.format("%.6f",lat) long = string.format("%.6f",long) local group = frame.args['group'] or 'stadium' local title = frame.args['title'] or 'A Stadium' local description = frame.args['desc'] or '' local descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) local r = frame.args['radius'] or ".5" r = tonumber(r) if r > 10 then error("10 for radius is MAX") end if r <= 0 then error("radius has to be greater than 0") end local fill = frame.args['fill'] or "#ccef64" local stroke = frame.args['stroke'] or "#0000ff" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end local data = {} local data2 = {} local coordinates = "" local coordinates2 = "" local ptx,pty,angle,ptx2,pty2 = 0,0,0,0,0 local type = frame.args['type'] or "line" -- default line for LineString if type ~= "line" then type = "poly" end local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) --       local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke)

x = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180) angle = 90 * math.pi / 180 x = x + (r*1.5) * math.cos( angle ) y = long + (r*1.5) * math.sin (angle) x = newlat(x)

x2 = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180) angle = 270 * math.pi / 180 x = x + (r*1.5) * math.cos( angle ) y2 = long + (r*1.5) * math.sin (angle ) x2 = newlat(x2)

x = math.log(math.tan((90 + x) * math.pi/360)) / (math.pi/180) x2 =math.log(math.tan((90 + x2) * math.pi/360)) / (math.pi/180) local count = 1

for i = -2, 180, 2 do          angle = i * math.pi / 180 ptx = x + r * math.cos( angle ) pty = y + r * math.sin(angle) ptx = newlat(ptx) data[count] = '[' .. string.format("%.6f",pty) .. "," .. string.format("%.6f",ptx) .. ']'          count = count + 1 end

count = 1 for i = 178,360, 2 do          angle = i * math.pi / 180 ptx = x2 + r * math.cos( angle ) pty = y2 + r * math.sin(angle)

ptx = newlat(ptx) data2[count] = '[' .. string.format("%.6f",pty) .. "," .. string.format("%.6f",ptx) .. ']'          count = count + 1 end

for i = 1,table.getn(data), 1 do           coordinates = coordinates .. data[i] end

for i = 1,table.getn(data2), 1 do           coordinates2 = coordinates2 .. data2[i] end

coordinates = coordinates .. coordinates2 coordinates = coordinates.gsub(coordinates,'%]%[','],[') coordinates = coordinates.gsub(coordinates,'@@@@@$','') coordinates = coordinates.gsub(coordinates,'%]@@@@@%[','],\n[') coordinates = "[" .. coordinates .. ',' .. data[1] .. "],"       if mapframe == "y" or mapframe == "yes" then if type == "poly" then coordinates = string.gsub(coordinates,'%]%,$',']]},') coordinates = part4a .. string.gsub(coordinates,'^%[','') .. part4b          else                coordinates  = string.gsub(coordinates,'%]%,},')                ,']},')                coordinates = part3a .. coordinates .. part3b           end		else           if type == "poly" then                coordinates  = string.gsub(coordinates,'%]%,},')                ,'},') coordinates = part2a .. string.gsub(coordinates,'^%[','[[') .. part2b          else                coordinates  = string.gsub(coordinates,'%]%,$',']},')                coordinates = part1a .. coordinates .. part1b           end				end    return coordinates

end -- STAR6 -- 6 pointed star - six sided star

function p.star6(frame) local shape = "star6" local id = frame.args['id']	or "" local lat=frame.args['lat'] or "" local long=frame.args['long'] or "" if lat == "" or lat == nil or long == "" or long == nil then id = checkid(id) lat = latitude(id) long = longitude(id) end

local x = tonumber(lat) local y = tonumber(long) local latitude = string.format("%.6f",lat) local longitude = string.format("%.6f",long) local group = frame.args['group'] or 'star6' local title = frame.args['title'] or '6 pointed star' local description = frame.args['desc'] or '' local descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) local radius = frame.args['radius'] or ".5" radius = tonumber(radius) if radius > 10 then error("10 for radius is MAX") end if radius <= 0 then error("radius has to be greater than 0") end local radius2 = radius * 3; local fill = frame.args['fill'] or "#ccef64" local stroke = frame.args['stroke'] or "#0000ff" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end local ra,angle,ptx,pty = 0,0,0,0 local compass = {} local points = {} local coordinates = "" local type = frame.args['type'] or "line" -- default line for LineString if type ~= "line" then type = "poly" end local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) --       local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke)

x = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180) compass = positions(shape)

for i = 1,table.getn(compass), 1 do       mod = math.mod(i,2) if mod == 1 then r = radius else r = radius2 end angle = compass[i] * math.pi / 180 ptx = x + r * math.cos( angle ) pty = y + r * math.sin( angle ) ptx = newlat(ptx) -- TEST BELOW FIX       points[i] = '[' .. string.format("%.6f",pty) .. pty .. "," .. string.format("%.6f",ptx) .. "],"       points[i] = '[' .. string.format("%.6f",pty) .. "," .. string.format("%.6f",ptx) .. "],"

end

for i = 1,table.getn(points), 1 do        coordinates = coordinates .. points[i] .. "\n" end

coordinates = coordinates .. points[1]

if mapframe == "y" or mapframe == "yes" then if type == "poly" then coordinates = string.gsub(coordinates,'%]%,$',']]]},') coordinates = part4a .. string.gsub(coordinates,'^%[','[') .. part4b          else                coordinates  = string.gsub(coordinates,'%]%,},')                ,'},') coordinates = part3a .. string.gsub(coordinates,'^%[','') .. part3b          end	   else           if type == "poly" then                coordinates  = string.gsub(coordinates,'%]%,]},')                ,']},') coordinates = part2a .. string.gsub(coordinates,'^%[','[') .. part2b          else                coordinates  = string.gsub(coordinates,'%]%,},')                ,'},') coordinates = part1a .. string.gsub(coordinates,'^%[','[[') .. part1b          end	   	   end

return coordinates

end

-- BAR -- only creates a LineString with thickness of 4

function p.bar(frame) local shape = "bar" local id = frame.args['id']	or "" local lat=frame.args['lat'] or "" local long=frame.args['long'] or "" if lat == "" or lat == nil or long == "" or long == nil then id = checkid(id) lat = latitude(id) long = longitude(id) end

local direction = frame.args['direction'] or "h" if direction == nil or direction == "" then direction = "h" end if direction ~= "h" then direction = "v" end local group = frame.args['group'] or 'bar' local title = frame.args['title'] or 'A bar' local description = frame.args['desc'] or '' local descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) local r = frame.args['radius'] or ".5" r = tonumber(r) if r > 40 then error("40 for length is MAX") end -- 40 for bar shape only if r <= 0 then error("r has to be greater than 0") end --       local fill = frame.args['fill'] or "#000000"             -- fill not used - keep anyhow for time being local fill = "#000000" local stroke = frame.args['stroke'] or "#000000"          -- change color with stroke local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end local coordinates = "" local type = frame.args['type'] or "line" -- default line for LineString if type ~= "line" then type = "line" end

local angle = 0

local compass = positions(shape) local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) --       local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke)

lat = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180) for i = 1,table.getn(compass), 1 do         if direction == "v" then compass[i] = compass[i] + 90 end angle = compass[i] * math.pi / 180 ptx = lat + r * math.cos( angle ) pty = long + r * math.sin( angle )

ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty)

coordinates = coordinates .. "[" .. pty .. "," .. ptx .. "]@@@@@"

end

coordinates = string.gsub(coordinates,'@@@@@',',') coordinates = putittogether(mapframe,type,part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b,coordinates) coordinates = string.gsub(coordinates,'stroke%-width%":1','stroke-width":3')

return coordinates end

-- KITE - Shield

function p.kite(frame) local shape = "kite" local id = frame.args['id']	or "" local lat=frame.args['lat'] or "" local long=frame.args['long'] or "" if lat == "" or lat == nil or long == "" or long == nil then id = checkid(id) lat = latitude(id) long = longitude(id) end

local group = frame.args['group'] or 'kite' local title = frame.args['title'] or 'A kite' local description = frame.args['desc'] or '' local descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) local r = frame.args['radius'] or ".5" r = tonumber(r) if r > 10 then error("10 for radius is MAX") end if r <= 0 then error("r has to be greater than 0") end local fill = frame.args['fill'] or "#ccef64" local stroke = frame.args['stroke'] or "#0000ff" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end local coordinates = "" local type = frame.args['type'] or "line" -- default line for LineString if type ~= "line" then type = "poly" end

local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) --       local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke) lat = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180)

local a = 360 local b = 60 local c = 180 local d = 300 angle1 = a * math.pi / 180 ptx = lat + r * math.cos( angle1 ) pty = long + r * math.sin( angle1 )

angle2 = b * math.pi /180 ptx2 = lat + r * math.cos( angle2 ) pty2 = long + r * math.sin( angle2 )

angle3 = c * math.pi /180 ptx3 = lat + r * math.cos( angle3 ) pty3 = long + r * math.sin( angle3 ) angle4 = d * math.pi /180 ptx4 = lat + r * math.cos( angle4 ) pty4 = long + r * math.sin( angle4 ) ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) ptx2,pty2 = string.format("%.6f",newlat(ptx2)),string.format("%.6f",pty2) ptx3,pty3 = string.format("%.6f",newlat(ptx3)),string.format("%.6f",pty3) ptx4,pty4 = string.format("%.6f",newlat(ptx4)),string.format("%.6f",pty4) lat,long = string.format("%.6f",newlat(lat)),string.format("%.6f",long)

coordinates = "[" .. pty .. "," .. ptx .. "],[" .. pty2 .. "," .. ptx2 .. "],[" .. pty3 .. "," .. ptx3 .. "],[".. pty4 .. "," .. ptx4 .. "],[" .. pty .. "," .. ptx .. "]"

coordinates = putittogether(mapframe,type,part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b,coordinates)

return coordinates

end

-- ANNULUS - 2 circles forming a donut shape

function p.annulus(frame) local shape = "annulus" local id = frame.args['id']	or "" local lat=frame.args['lat'] or "" local long=frame.args['long'] or "" if lat == "" or lat == nil or long == "" or long == nil then id = checkid(id) lat = latitude(id) long = longitude(id) end

x = string.format("%.6f",lat) y = string.format("%.6f",long) local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end -- FUTURE USE if tonumber(lat) > 85.35 or tonumber(lat) < -85.35 then error("Latitude must be between 85.35 and -85.35!") end if tonumber(long) > 180 or tonumber(long) < -180 then error("Longitude must be between 180 and -180!") end -- END if

local group = frame.args['group'] or 'annulus' local title = frame.args['title'] or 'An annulus' local description = frame.args['desc'] or '' local descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) local r = frame.args['radius'] or ".5" r = tonumber(r) if r > 10 then error("10 for radius is MAX") end if r <= 0 then error("radius has to be greater than 0") end local r2 = r * .65 local fill = frame.args['fill'] or "#ccef64" local stroke = frame.args['stroke'] or "#0000ff" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local data = {} local data2 = {} local coordinates = "" local coordinates2 = "" local ptx,pty,angle,ptx2,pty2 = 0,0,0,0,0 local type = frame.args['type'] or "line" -- default line for LineString if type ~= "line" then type = "poly" end local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) --       local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke)

if tonumber(x) >= 10.5 then x = math.log(math.tan((90 + x) * math.pi/360)) / (math.pi/180) elseif tonumber(x) <= -10.5 then x = math.log(math.tan((90 + x) * math.pi/360)) / (math.pi/180) end

for i = 1, 360 do          angle = i * math.pi / 180 ptx = x + r * math.cos( angle ) pty = y + r * math.sin( angle ) ptx2 = x + r2 * math.cos( angle ) pty2 = y + r2 * math.sin( angle )

if tonumber(x) >= 10.5 then ptx = newlat(ptx) ptx2 = newlat(ptx2) end

if tonumber(x) <= -10.5 then ptx = newlat(ptx) ptx2 = newlat(ptx2) end

data[i] = '[' .. string.format("%.6f",pty) .. "," .. string.format("%.6f",ptx) .. ']'         data2[i] = '[' .. string.format("%.6f",pty2) .. "," .. string.format("%.6f",ptx2) .. ']'                 end

for i = 5,359, 5 do               data[i] = data[i] .. "@@@@@"               data2[i] = data2[i] .. "@@@@@"       end

-- cycle through array and build single string of all coordinates to be output

for i = 1,360, 1 do              coordinates = coordinates .. data[i] coordinates2 = coordinates2 .. data2[i] end

coordinates = coordinates.gsub(coordinates,'%]%[','],[') coordinates2 = coordinates2.gsub(coordinates2,'%]%[','],[') coordinates = coordinates.gsub(coordinates,'%]@@@@@%[','],\n[') coordinates2 = coordinates2.gsub(coordinates2,'%]@@@@@%[','],\n[') coordinates = "[" .. coordinates .. ',' .. data[1] .. "],"         coordinates2 = "[" .. coordinates2 .. ',' .. data2[1] .. "]],["         coordinates = coordinates2 .. coordinates coordinates = string.gsub(coordinates,'%]%]%],%[%[%[',']],[[') if mapframe == "y" or mapframe == "yes" then if type == "poly" then coordinates = string.gsub(coordinates,'%]%,$',']]},') coordinates = part4a .. string.gsub(coordinates,'^%[','') .. part4b			else               coordinates  = string.gsub(coordinates,'%]%,},'),'},') coordinates = string.gsub(coordinates,'^%[','')                               coordinates = part3a .. coordinates .. part3b                coordinates = string.gsub(coordinates,'LineString','MultiLineString')			end 		else			if type == "poly" then                coordinates  = string.gsub(coordinates,'%]%,},')                ,'},') coordinates = part2a .. string.gsub(coordinates,'^%[','') .. part2b			else               coordinates  = string.gsub(coordinates,'%]%,},'),'},') coordinates = string.gsub(coordinates,'^%[','[[')               coordinates = part1a .. coordinates .. part1b                coordinates = string.gsub(coordinates,'LineString','MultiLineString')                			end 			end

return coordinates

end

-- WEDGE

function p.wedge(frame) local shape = "wedge" local id = frame.args['id']	or "" local lat=frame.args['lat'] or "" local long=frame.args['long'] or "" if lat == "" or lat == nil or long == "" or long == nil then id = checkid(id) lat = latitude(id) long = longitude(id) end

local latitude = lat local longitude = long

local group = frame.args['group'] or 'wedge' local title = frame.args['title'] or 'A wedge' local description = frame.args['desc'] or '' local descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) local r = frame.args['radius'] or ".5" r = tonumber(r) if r > 10 then error("10 for length is MAX") end if r <= 0 then error("r has to be greater than 0") end local r2 = r * 2 local fill = frame.args['fill'] or "#ccef64" local stroke = frame.args['stroke'] or "#0000ff" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end local coordinates = "" local type = frame.args['type'] or "line" -- default line for LineString if type ~= "line" then type = "poly" end local direction = frame.args['direction'] or "1" if direction == nil or direction == "" then direction = "1" end direction = string.gsub(direction,'%..*','') if string.gsub(direction,"^[1-8]$","") ~= "" then direction="1" end direction = tonumber(direction) if direction <= 0 or direction >= 9 then error("Direction should be a number from 1 to 8!") end

local angle1,angle2,angle3 = 0,0,0 local ptx,ptx2,ptx3 = 0,0,0 local pty,pty2,pty3 = 0,0,0

local factor = {'340,360,20','25,45,65','70,90,110','115,135,155','160,180,200','205,225,245','250,270,290','295,315,335'} local a = string.gsub(factor[direction],'(%d+)(%d+)(%d+)','%1') local b = string.gsub(factor[direction],'(%d+)(%d+)(%d+)','%3') local c = string.gsub(factor[direction],'(%d+)(%d+)(%d+)','%5') local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) --      local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke)

lat = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180) angle = b * math.pi / 180 ptx = lat + (r*.02) * math.cos( angle ) pty = long + (r*.02) * math.sin( angle ) lat,long = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty)

lat = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180)

angle1 = a * math.pi / 180 ptx = lat + r2 * math.cos( angle1 ) pty = long + r2 * math.sin( angle1 )

angle2 = b * math.pi /180               -- used to compute center of wedge ptx2 = lat + r * math.cos( angle2 ) pty2 = long + r * math.sin( angle2 )

angle3 = c * math.pi /180 ptx3 = lat + r2 * math.cos( angle3 ) pty3 = long + r2 * math.sin( angle3 )

ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) ptx2,pty2 = string.format("%.6f",newlat(ptx2)),string.format("%.6f",pty2) ptx3,pty3 = string.format("%.6f",newlat(ptx3)),string.format("%.6f",pty3) lat,long = string.format("%.6f",newlat(lat)),string.format("%.6f",long)

coordinates = "[" .. pty .. "," .. ptx .. "],[" .. pty3 .. "," .. ptx3 .. "],[" .. long .. "," .. lat .. "],[" .. pty .. "," .. ptx .. "]"

coordinates = putittogether(mapframe,type,part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b,coordinates)

return coordinates end

-- KEYSTONE

function p.keystone(frame) local shape = "keystone" local id = frame.args['id']	or "" local lat=frame.args['lat'] or "" local long=frame.args['long'] or "" if lat == "" or lat == nil or long == "" or long == nil then id = checkid(id) lat = latitude(id) long = longitude(id) end

local group = frame.args['group'] or 'keystone' local title = frame.args['title'] or 'A keystone' local description = frame.args['desc'] or '' local descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) local r = frame.args['radius'] or ".5" r = tonumber(r) if r > 10 then error("10 for length is MAX") end if r <= 0 then error("r has to be greater than 0") end local r2 = r * .65 local fill = frame.args['fill'] or "#ccef64" local stroke = frame.args['stroke'] or "#0000ff" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end local coordinates = "" local type = frame.args['type'] or "line" -- default line for LineString if type ~= "line" then type = "poly" end

local angle = 0

local compass = positions(shape) local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) --       local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke)

lat = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180) for i = 1,table.getn(compass), 1 do         angle = compass[i] * math.pi / 180 if compass[i] == 26 or compass[i] == 334 then ptx = lat + r2 * math.cos( angle ) pty = long + r2 * math.sin( angle ) else ptx = lat + r * math.cos( angle ) pty = long + r * math.sin( angle ) end

ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty)

coordinates = coordinates .. "[" .. pty .. "," .. ptx .. "]@@@@@"

end

coordinates = coordinates .. string.gsub(coordinates,'@@@@@.*','') coordinates = string.gsub(coordinates,'@@@@@',',')

coordinates = putittogether(mapframe,type,part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b,coordinates)

return coordinates end

-- COG -- gear shape

function p.cog(frame) local shape = "cog" local id = frame.args['id']	or "" local lat=frame.args['lat'] or "" local long=frame.args['long'] or "" if lat == "" or lat == nil or long == "" or long == nil then id = checkid(id) lat = latitude(id) long = longitude(id) end

local group = frame.args['group'] or 'cog' local title = frame.args['title'] or 'A cog' local description = frame.args['desc'] or '' local descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) local r = frame.args['radius'] or ".5" r = tonumber(r) if r > 10 then error("10 for length is MAX") end if r <= 0 then error("r has to be greater than 0") end local r2 = r * .85 local r3 = r * .30 local fill = frame.args['fill'] or "#ccef64" local stroke = frame.args['stroke'] or "#0000ff" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end local coordinates = "" local coordinates2 = "" local type = frame.args['type'] or "line" -- default line for LineString if type ~= "line" then type = "poly" end

local angle = 0

local compass = positions(shape) local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) --      local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke)

lat = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180) for i = 1,table.getn(compass), 1 do

angle = (compass[i] - 33.5) * math.pi / 180 ptx = lat + r2 * math.cos( angle ) pty = long + r2 * math.sin( angle ) ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) coordinates = coordinates .. "[" .. pty .. "," .. ptx .. "]@@@@@"

angle = (compass[i] - 11) * math.pi / 180 ptx = lat + r2 * math.cos( angle ) pty = long + r2 * math.sin( angle ) ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) coordinates = coordinates .. "[" .. pty .. "," .. ptx .. "]@@@@@"

angle = (compass[i] -11.25) * math.pi / 180 ptx = lat + r * math.cos( angle ) pty = long + r * math.sin( angle ) ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) coordinates = coordinates .. "[" .. pty .. "," .. ptx .. "]@@@@@"

angle = (compass[i] + 11.25) * math.pi / 180 ptx = lat + r * math.cos( angle ) pty = long + r * math.sin( angle ) ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) coordinates = coordinates .. "[" .. pty .. "," .. ptx .. "]@@@@@"

end

coordinates = coordinates .. string.gsub(coordinates,'@@@@@.*','') coordinates = string.gsub(coordinates,'@@@@@',',')

compass = positions('quad')

for i = 1,table.getn(compass), 1 do         angle = compass[i] * math.pi / 180 ptx = lat + r3 * math.cos( angle ) pty = long + r3 * math.sin( angle )

ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty)

coordinates2 = coordinates2 .. "[" .. pty .. "," .. ptx .. "]@@@@@"

end coordinates2 = coordinates2 .. string.gsub(coordinates2,'@@@@@.*','') coordinates2 = string.gsub(coordinates2,'@@@@@',',') coordinates = coordinates .. "],[" .. coordinates2 if mapframe == "y" or mapframe == "yes" then if type == "poly" then coordinates = '' .. coordinates .. '},' coordinates = part4a .. coordinates .. part4b else coordinates = '' .. coordinates .. '},' coordinates = part3a .. coordinates .. part3b coordinates = string.gsub(coordinates,'LineString','MultiLineString') end else if type == "poly" then coordinates = '' .. coordinates .. '},' coordinates = part2a .. coordinates .. part2b else coordinates = '' .. coordinates .. '},' coordinates = part1a .. coordinates .. part1b coordinates = string.gsub(coordinates,'LineString','MultiLineString') end end

return coordinates end -- PENTAGRAM - Line String only -- Poly fills in the tips - lines still there

function p.pentagram(frame) local shape = "pentagram" local id = frame.args['id']	or "" local lat=frame.args['lat'] or "" local long=frame.args['long'] or "" if lat == "" or lat == nil or long == "" or long == nil then id = checkid(id) lat = latitude(id) long = longitude(id) end

local x = tonumber(lat) local y = tonumber(long) local latitude = string.format("%.6f",lat) local longitude = string.format("%.6f",long) local group = frame.args['group'] or 'pentagram' local title = frame.args['title'] or 'A pentagram' local description = frame.args['desc'] or '' local descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) local r = frame.args['radius'] or ".5" if r == nil or r == "" then r = "0.5" end r = tonumber(r) if r > 10 then error("10 for radius is MAX") end if r <= 0 then error("radius has to be greater than 0") end local fill = frame.args['fill'] or "#000000" local stroke = frame.args['stroke'] or "#0000ff" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end -- FUTURE USE local angle,ptx,pty = 0,0,0 local compass = {} local points = {} local coordinates = "" local type = frame.args['type'] or "line" -- default line for LineString if type ~= "poly" then type = "line" end local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) --       local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke)

x = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180) compass = positions(shape)

for i = 1,table.getn(compass), 1 do       angle = compass[i] * math.pi / 180 ptx = x + r * math.cos( angle ) pty = y + r * math.sin( angle ) ptx = newlat(ptx) points[i] = '[' .. string.format("%.6f",pty) .. "," .. string.format("%.6f",ptx) .. "],"

end

for i = 1,table.getn(points), 1 do        coordinates = coordinates .. points[i] .. "\n" end

coordinates = coordinates .. points[1]

if mapframe == "y" or mapframe == "yes" then if type == "poly" then coordinates = string.gsub(coordinates,'%]%,$',']]]},') coordinates = part4a .. string.gsub(coordinates,'^%[','[') .. part4b          else                coordinates  = string.gsub(coordinates,'%]%,},')                ,'},') coordinates = part3a .. string.gsub(coordinates,'^%[','') .. part3b          end	   else           if type == "poly" then                coordinates  = string.gsub(coordinates,'%]%,]},')                ,']},') coordinates = part2a .. string.gsub(coordinates,'^%[','[') .. part2b          else                coordinates  = string.gsub(coordinates,'%]%,},')                ,'},') coordinates = part1a .. string.gsub(coordinates,'^%[','[[') .. part1b          end	   	   end

return coordinates

end

-- X_SHAPE

function p.x(frame) local shape = "xshape" local id = frame.args['id']	or "" local lat=frame.args['lat'] or "" local long=frame.args['long'] or "" if lat == "" or lat == nil or long == "" or long == nil then id = checkid(id) lat = latitude(id) long = longitude(id) end

local group = frame.args['group'] or 'xshape' local title = frame.args['title'] or 'An X'       local description = frame.args['desc'] or '' local descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) local r = frame.args['radius'] or ".5" r = tonumber(r) if r > 10 then error("10 for length is MAX") end if r <= 0 then error("r has to be greater than 0") end local r2 = r * .375 local fill = frame.args['fill'] or "#ccef64" local stroke = frame.args['stroke'] or "#0000ff" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end local coordinates = "" local type = frame.args['type'] or "line" -- default line for LineString if type ~= "line" then type = "poly" end

local angle = 0

local compass = positions(shape) local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) --       local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke)

lat = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180) for i = 1,table.getn(compass), 1 do         angle = compass[i] * math.pi / 180 if compass[i] == 90 or compass[i] == 180 or compass[i] == 270 or compass[i] == 360 then ptx = lat + r2 * math.cos( angle ) pty = long + r2 * math.sin( angle ) else ptx = lat + r * math.cos( angle ) pty = long + r * math.sin( angle ) end

ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty)

coordinates = coordinates .. "[" .. pty .. "," .. ptx .. "]@@@@@"

end coordinates = coordinates .. string.gsub(coordinates,'@@@@@.*','') coordinates = string.gsub(coordinates,'@@@@@',',')

coordinates = putittogether(mapframe,type,part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b,coordinates)

return coordinates end

-- RECTANGLE - simple styled rectangle which makes it limited

function p.rectangle(frame) local shape = frame.args['rectangle'] or "rectangle" local id = frame.args['id']	or "" local lat=frame.args['lat'] or "" local long=frame.args['long'] or "" if lat == "" or lat == nil or long == "" or long == nil then id = checkid(id) lat = latitude(id) long = longitude(id) end

local group = frame.args['group'] or 'rectangle' local title = frame.args['title'] or 'A set rectangle' local description = frame.args['desc'] or '' local descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) local name = frame.args['name'] or "A Center Rectangle" local r = frame.args['radius'] or ".5" r = tonumber(r) r = r + r               if r > 10 then error("10 for radius is MAX") end if r <= 0 then error("r has to be greater than 0") end local fill = frame.args['fill'] or "#ccef64" local stroke = frame.args['stroke'] or "#0000ff" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end local coordinates = "" local type = frame.args['type'] or "line" -- default line for LineString if type ~= "line" then type = "poly" end

local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) --       local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke) lat = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180)

local angle1,angle2,angle3,angle4 = 0,0,0,0 local ptx,ptx2,ptx3,ptx4 = 0,0,0,0 local pty,pty2,pty3,pty4 = 0,0,0,0 --       local a = 45 --       local b = 135 --       local c = 225 --       local d = 315 local a = 60 local b = 120 local c = 240 local d = 300 angle1 = a * math.pi / 180 ptx = lat + r * math.cos( angle1 ) pty = long + r * math.sin( angle1 )

angle2 = b * math.pi /180 ptx2 = lat + r * math.cos( angle2 ) pty2 = long + r * math.sin( angle2 )

angle3 = c * math.pi /180 ptx3 = lat + r * math.cos( angle3 ) pty3 = long + r * math.sin( angle3 ) angle4 = d * math.pi /180 ptx4 = lat + r * math.cos( angle4 ) pty4 = long + r * math.sin( angle4 ) ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) ptx2,pty2 = string.format("%.6f",newlat(ptx2)),string.format("%.6f",pty2) ptx3,pty3 = string.format("%.6f",newlat(ptx3)),string.format("%.6f",pty3) ptx4,pty4 = string.format("%.6f",newlat(ptx4)),string.format("%.6f",pty4) lat,long = string.format("%.6f",newlat(lat)),string.format("%.6f",long)

coordinates = "[" .. pty .. "," .. ptx .. "],[" .. pty2 .. "," .. ptx2 .. "],[" .. pty3 .. "," .. ptx3 .. "],[".. pty4 .. "," .. ptx4 .. "],[" .. pty .. "," .. ptx .. "]"

coordinates = putittogether(mapframe,type,part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b,coordinates)

return coordinates

end

-- POINT

function p.point(frame) --	local partof = "" local t = {} local entity = '' local claims = '' local coordinates = "" local image = frame.args['image'] or "" if image ~= nil and image ~= "" then image = '' end local code = "" local count = 0 local lat = frame.args['lat'] or "" local long = frame.args['long'] or "" local id = frame.args['id'] or "" if lat == "" or lat == nil or long == "" or long == nil then id = checkid(id) lat = latitude(id) long = longitude(id) end

local description = frame.args['desc'] or '' local descattr = frame.args['descattr'] or 'l' -- TESTING local color = frame.args['color'] or "#ff0000" if string.len(color) ~= 7 then error("Incorrect length for argument color") end if string.gsub(color,"#[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]","") ~= "" then error("Incorrect hexidecimal format for argument color") end local title = frame.args['title'] or "" local symbol = frame.args['symbol'] or "city" local size = frame.args['size'] or "medium" if id ~= nil and id ~= '' and id ~= "" then entity = mw.wikibase.getEntityObject(id) claims = entity.claims if image == nil or image == "" then if pcall(function t = claims.P18 end) then if pcall(function t = entity.claims.P18[1].mainsnak.datavalue.value end ) then image = entity.claims.P18[1].mainsnak.datavalue.value if image ~= nil and image ~= "" then image = '' end end end end t = {} if pcall(function t = claims.P296 end) then if pcall(function t = entity.claims.P296[1].mainsnak.datavalue.value end ) then code = entity.claims.P296[1].mainsnak.datavalue.value end end end

if count == 0 then      -- #description has no beginning image then use image from wikidata if any if image ~= nil and image ~= "" then description = image .. description end end description = aligndesc(description,descattr)

-- Special Case - adding code (abbrev) to title while testing train stations - symbol rail trigger if symbol == "rail" then if title ~= nil and title ~= "" then if code ~= nil and code ~= "" then title = title .. ' (' .. code .. ')' end end end coordinates = "{\n" .. '\t"type": "Feature",\n' .. '\t\t"geometry": { "type": "Point", "coordinates": [' .. long .. "," .. lat .. ']},\n' coordinates = coordinates .. '\t\t"properties": {\n' .. '\t\t\t"description": "' .. description .. '",\n' .. '\t\t\t"title": "' .. title .. '",\n' coordinates = coordinates .. '\t\t\t"marker-color": "' .. color .. '",\n' .. '\t\t\t"marker-symbol": "' .. symbol .. '",\n' .. '\t\t\t"marker-size": "' .. size .. '",\n' coordinates = coordinates .. '\t\t}' .. '}\n'

return coordinates

end -- POINTER

function p.pointer(frame) local shape = "pointer" local id = frame.args['id']	or "" local lat=frame.args['lat'] or "" local long=frame.args['long'] or "" if lat == "" or lat == nil or long == "" or long == nil then id = checkid(id) lat = latitude(id) long = longitude(id) end

local latitude = lat local longitude = long

local group = frame.args['group'] or 'pointer' local title = frame.args['title'] or 'A pointer' local description = frame.args['desc'] or '' local descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) local r = frame.args['radius'] or ".5" r = tonumber(r) if r > 10 then error("10 for length is MAX") end if r <= 0 then error("r has to be greater than 0") end r = r * 2 local r2 = r/2 local r3 = r/3 local fill = frame.args['fill'] or "#ccef64" local stroke = frame.args['stroke'] or "#0000ff" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end local coordinates = "" local type = frame.args['type'] or "line" -- default line for LineString if type ~= "line" then type = "poly" end local direction = frame.args['direction'] or "1" if direction == nil or direction == "" then direction = "1" end direction = string.gsub(direction,'%..*','') if string.gsub(direction,"^[1-8]$","") ~= "" then direction="1" end direction = tonumber(direction) if direction <= 0 or direction >= 9 then error("Direction should be a number from 1 to 8!") end

local angle1,angle2,angle3,angle4 = 0,0,0,0 local ptx,ptx2,ptx3,ptx4 = 0,0,0,0 local pty,pty2,pty3,pty4 = 0,0,0,0

local factor = {'20,360,340','25,45,65','70,90,110','115,135,155','160,180,200','205,225,245','250,270,290','295,315,335'} local a = string.gsub(factor[direction],'%,.*$','') -- eat everything after a comma - hungry local b = string.gsub(factor[direction],'^.*%,','') -- eat everything up to a comma - hungry local c = string.gsub(factor[direction],'(%d+)(%d+)(%d+)','%3') -- MISSING FIX local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) --       local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke)

lat = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180)

angle1 = a * math.pi / 180 ptx = lat + r * math.cos( angle1 ) pty = long + r * math.sin( angle1 )

angle2 = b * math.pi /180 ptx2 = lat + r * math.cos( angle2 ) pty2 = long + r * math.sin( angle2 )

angle3 = c * math.pi /180 ptx3 = lat + r2 * math.cos( angle3 ) pty3 = long + r2 * math.sin( angle3 )

angle4 = c * math.pi /180 ptx4 = lat + r3 * math.cos( angle3 ) pty4 = long + r3 * math.sin( angle3 )

ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) ptx2,pty2 = string.format("%.6f",newlat(ptx2)),string.format("%.6f",pty2) ptx3,pty3 = string.format("%.6f",newlat(ptx3)),string.format("%.6f",pty3) ptx4,pty4 = string.format("%.6f",newlat(ptx4)),string.format("%.6f",pty4) lat,long = string.format("%.6f",newlat(lat)),string.format("%.6f",long)

coordinates = "[" .. pty .. "," .. ptx .. "],[" .. pty3 .. "," .. ptx3 .. "],[" .. pty2 .. "," .. ptx2 .. "],[" .. long .. "," .. lat .. "],[" .. pty .. "," .. ptx .. "]"

coordinates = putittogether(mapframe,type,part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b,coordinates)

return coordinates end

-- External from OpenStreetMap

function p.external(frame) local id = frame.args['id'] or 'Q20' local title = frame.args['title'] or "" local fill = frame.args['fill'] or "#87deaa" local stroke = frame.args['stroke'] or "#000000" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" local description = frame.args['desc'] or "" local descattr = frame.args['descattr'] or "l" local file = frame.args['file'] or "" local geotype = frame.args['geotype'] or "geoshape"

description = aligndesc(description,descattr)

if geotype == "page" then coordinates = '{' coordinates = coordinates .. '"type": "ExternalData",' coordinates = coordinates .. '\t\t "service": "' .. geotype .. '",' coordinates = coordinates .. '\t\t"title": "' .. file .. '"' coordinates = coordinates .. '}'   else coordinates = '{' coordinates = coordinates .. '"type": "ExternalData",\n' coordinates = coordinates .. '\t "properties": {\n' coordinates = coordinates .. '\t\t"title": "' .. title .. '",\n' coordinates = coordinates .. '\t\t"description": "' .. description .. '",\n' coordinates = coordinates .. '\t\t"fill": "' .. fill .. '",\n' coordinates = coordinates .. '\t\t"fill-opacity":' .. fillopacity .. ',\n' coordinates = coordinates .. '\t\t"stroke": "' .. stroke .. '",\n' coordinates = coordinates .. '\t\t"stroke-opacity":' .. strokeopacity .. ',\n' coordinates = coordinates .. '\t\t"stroke-width":' .. strokewidth .. ',\n' coordinates = coordinates .. '\t\t},\n' coordinates = coordinates .. '\t\t "service": "' .. geotype .. '",\n' coordinates = coordinates .. '\t\t"ids": "' .. id .. '"\n' coordinates = coordinates .. '}'   	end

return coordinates end

-- External from OpenStreetMap

function p.background(frame) local title = frame.args['title'] or "" local fill = frame.args['fill'] or "#baf326" local stroke = "#000000" local strokewidth = "4" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.025" local description = "" local coordinates = ""

coordinates = '{"type": "Feature","geometry": { "type":"Polygon", 	"coordinates":' coordinates = coordinates .. '[-3600,90], [3600, 90], [3600,-90], [-3600,-90], [-3600,90]},\n' coordinates = coordinates .. '\t\t"properties":{\n' coordinates = coordinates .. '\t\t"title": "' .. title .. '",\n' coordinates = coordinates .. '\t\t"description": "' .. description .. '",\n' coordinates = coordinates .. '\t\t"fill": "' .. fill .. '",\n' coordinates = coordinates .. '\t\t"stroke":"' .. stroke .. '",\n' coordinates = coordinates .. '\t\t"fill-opacity":' .. fillopacity .. ',\n' coordinates = coordinates .. '\t\t"stroke-width":' .. strokewidth .. '\n' coordinates = coordinates .. '}}'

return coordinates end

function p.empty(frame) return ""

end

-- LINE -- MAKE LINE2 which will take 2 sets of coordinates to build a line instead of IDs function p.line(frame) local shape = "line" local id = frame.args['id'] or "" local id2 = frame.args['id2'] or "" if id == nil or id == "" then error("Missing id!") end if id2 == nil or id2 == "" then error("Missing id!") end checkid(id) checkid(id2) local lat1,long1,lat2,long2 = "","","","" lat1 = latitude(id) lat2 = latitude(id2) long1 = longitude(id) long2 = longitude(id2) local type = "line" local title = frame.args['title'] or 'A line' local group = frame.args['group'] or "line" local description = frame.args['desc'] or '' local descattr = frame.args['descattr'] or 'l' -- TESTING local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end local coordinates = "" local fill = frame.args['fill'] or "#000000" local fillopacity = frame.args['fillopacity'] or "0.5" local stroke = frame.args['stroke'] or "#0000ff" local strokeopacity = frame.args['strokeopacity'] or "0.5" local strokewidth = frame.args['strokewidth'] or "1" local data = {} data[1] = "[" .. long1 .. "," .. lat1 .. "]"       data[2] = "[" .. long2 .. "," .. lat2 .. "]"       coordinates = "[" .. data[1] .. "," .. data[2] .. "]}," local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat1,long1,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) if mapframe == "y" or mapframe == "yes" then if type == "poly" then coordinates = string.gsub(coordinates,'%]%,$',']]},') coordinates = part4a .. string.gsub(coordinates,'^%[','') .. part4b          else                coordinates = string.gsub(coordinates,'%]%,},')                ,']},')                coordinates = part3a .. coordinates .. part3b           end		else           if type == "poly" then                coordinates  = string.gsub(coordinates,'%]%,},')                ,'},') coordinates = part2a .. string.gsub(coordinates,'^%[','[[') .. part2b          else                coordinates = string.gsub(coordinates,'%]%,$',']},')                coordinates = part1a .. coordinates .. part1b           end				end

return coordinates end

-- END MODULE

return p