Module:Sandbox/Matroc/Mapdraw

-- November 2016 An experimental Module -- Matroc -- The following though code is for drawing certain shapes (circle, ellipse, box (square), kite, rectangle, triangle, equitri -- line, star, star2, hexagram, wedge, pointer, pentagon, hexagon, octagon, diamond, crescent etc. -- as a Polygon or LineString -gt Most functions can output a maplink or a mapframe plus optional marker.

-- The function newlat below is used by function p.circle as well as functions p.ellipse, p.star, p.pointer, -- p.pentagon and p.hexagon etc.

local p = {}

-- BETA Rough calculator of distance between 2 coordinates (lat,long) in miles and kilometres

function p.distance(frame) -- in Progress local x1 = tonumber(frame.args['lat1']) or 1 local x2 = tonumber(frame.args['lat2']) or 1 local y1 = tonumber(frame.args['long1']) or 1 local y2 = tonumber(frame.args['long2']) or 1 local lat1 = math.rad(x1) local lat2 = math.rad(x2) local long1 = math.rad(y1) local long2 = math.rad(y2) local longd = long2 - long1 local latd = lat2 - lat1 local x = (math.sin(latd/2))^2 + math.cos(lat1) * math.cos(lat2) * (math.sin(longd/2))^2 local y = 2 * math.atan2( math.sqrt(x), math.sqrt(1-x) ) local distance1 = 3959 * y -- miles (2 sources a: 3861 b: 3959) local distance2 = 6371 * y -- kilometers (2 sources a: 6373 b: 6371) return "Approximate distance in miles: " .. string.format("%.6f",distance1) .. " Approximate distance in kilometers: " .. string.format("%.6f",distance2) end

-- 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

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

local part1a = ' \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 \n'

local part2a = ' \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 \n'

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":{' .. xprogcomment .. '\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 \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 \n'

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": {' .. xprogcomment .. '\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 \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 \n'

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

local function positions(shape) local positions = {} positions['octagon'] = {45,90,135,180,225,270,315,360} positions['hexagram'] = {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['decagon'] = {18,54,90,126,162,198,234,270,306,342} 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

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

-- CIRCLE

function p.circle(frame) local shape = "circle" local id = frame.args['id']	or "" local lat,long = "","" local x,y = 0,0 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 x = string.format("%.6f",lat) y = string.format("%.6f",long) local marker = frame.args['marker'] or "no" if marker == nil or marker == "" then marker = "no" end 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 local group = frame.args['group'] or 'circle' local title = frame.args['title'] or 'A circle' local description = frame.args['desc'] or '' 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" checkhex(fill,stroke) 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 = 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 ) --        ptx, pty = x + r * math.cos( angle ), y + r * math.sin( angle ) -- original code split for readability above

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

if tonumber(x) <= -10.5 then ptx = newlat(ptx) -- makes correction to make circle show up on map - lower latitudes 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        if marker == "yes" or marker == "y" then              coordinates = coordinates .. '\n* \n'        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 class = frame.args['class'] or "n" if not class then class = "n" end local sides = frame.args['sides'] or "3" if sides == nil or sides == "" then sides = "3" end sides = tonumber(sides) if sides 40 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'] 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 "" if description == nil then description = "" end local fill = frame.args['fill'] or "#ffff00" local stroke = frame.args['stroke'] or "#000000" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nil or mapframe == "" then mapframe = "no" end local marker = frame.args['marker'] or "no"

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,",$",'')

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 .. '},' if class == "y" then part2a = string.gsub(part2a,'no%-icon','icon') part2b = string.gsub(part2b,'\n$','') end coordinates = part2a .. coordinates .. part2b

else coordinates = '[' .. coordinates .. ']},'                       coordinates = part1a .. coordinates .. part1b end end if marker == "yes" or marker == "y" then coordinates = coordinates .. '\n* \n' end

return coordinates

end

-- RECTANGLE

function p.rectangle(frame) local shape = "rectangle" if frame.args['upper'] == nil or frame.args['upper'] == "" then error("Missing argument upper!") end if frame.args['lower'] == nil or frame.args['lower'] == "" then error("Missing argument lower!") end local separator = "@@@@@" local x = string.gsub(frame.args['upper'],'%,','@@@@@') local y = string.gsub(frame.args['lower'],'%,','@@@@@') x = string.gsub(x,'%s+','') y = string.gsub(y,'%s+','') local tt = {} local data = {} local latitudes = {} local longitudes = {} local count = 1 local marker = frame.args['marker'] or "no" if marker == nil or marker == "" then marker = "no" end local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end -- FUTURE USE for str in string.gmatch(x,"([^"..separator.."]+)") do		if str ~= nil and str ~= "" then tt[count] = str count = count + 1 end end

for str in string.gmatch(y,"([^"..separator.."]+)") do		if str ~= nil and str ~= "" then tt[count] = str count = count + 1 end end

if count >=6 then error("Check the upper and lower arguments for format!") end for i=1,4 do          if tt[i] == nil or tt[i] == "" then error("Check for missing latitude or longitude separated by a comma!") end end

longitudes[1] = tonumber(tt[2]) if longitudes[1] > 180 or longitudes[1] <- 180 then error("longitude should be between 180 and -180") end data[1] = "[" .. tt[2]

latitudes[1] = tonumber(tt[1]) if latitudes[1] > 90 or latitudes[1] <- 90 then error("latitude should be between 90 and -90") end data[2] = "," .. tt[1] .. "]"

longitudes[2] = tonumber(tt[2]) if longitudes[2] > 180 or longitudes[2] <- 180 then error("longitude should be between 180 and -180") end data[3] = "[" .. tt[2]

latitudes[2] = tonumber(tt[3]) if latitudes[2] > 90 or latitudes[2] <- 90 then error("latitude should be between 90 and -90") end data[4] = "," .. tt[3] .. "]"

longitudes[3] = tonumber(tt[4]) if longitudes[3] > 180 or longitudes[3] <- 180 then error("longitude should be between 180 and -180") end data[5] = "[" .. tt[4]

latitudes[3] = tonumber(tt[3]) if latitudes[3] > 90 or latitudes[3] <- 90 then error("latitude should be between 90 and -90") end data[6] = "," .. tt[3] .. "]"

longitudes[4] = tonumber(tt[4]) if longitudes[4] > 180 or longitudes[4] <- 180 then error("longitude should be between 180 and -180") end data[7] = "[" .. tonumber(tt[4])

latitudes[4] = tonumber(tt[1]) if latitudes[4] > 90 or latitudes[4] <- 90 then error("latitude should be between 90 and -90") end data[8] = "," .. tt[1] .. "]"

table.sort(latitudes) table.sort(longitudes) local lat = latitudes[1] + ((latitudes[4] - latitudes[1]) / 2 ) local long = longitudes[1] + ((longitudes[4] - longitudes[1]) / 2) local group = frame.args['group'] or 'rectangle' local title = frame.args['title'] or 'A rectangle' local description = frame.args['desc'] or '' local fill = frame.args['fill'] or "#ccef64" local stroke = frame.args['stroke'] or "#0000ff" checkhex(fill,stroke) 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 = parts(lat,long,group,title,description,fill,stroke)

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

coordinates = coordinates.gsub(coordinates,'%]%[','],[') coordinates = coordinates.gsub(coordinates,'%]@@@@@%[','],\n[') coordinates = "[" .. 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 = 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		        if marker == "yes" or marker == "y" then               coordinates = coordinates .. '\n* \n'        end        return coordinates

end

-- BOX - Square

function p.box(frame) local shape = "box" local id = frame.args['id']	or "" 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 'box' local title = frame.args['title'] or 'A box' local description = frame.args['desc'] or '' 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" checkhex(fill,stroke) local marker = frame.args['marker'] or "no" if marker == nil or marker == "" then marker = "no" end 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 = 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 .. "]"

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

if marker == "yes" or marker == "y" then coordinates = coordinates .. '\n* \n' end

return coordinates

end

-- BOX FRAME

function p.boxframe(frame) local shape = "box" local id = frame.args['id']	or "" 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 'boxframe' local title = frame.args['title'] or 'A boxframe' local description = frame.args['desc'] or '' 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" checkhex(fill,stroke) local marker = frame.args['marker'] or "no" if marker == nil or marker == "" then marker = "no" end 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 = 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

if marker == "yes" or marker == "y" then coordinates = coordinates .. '\n* \n' end

return coordinates

end

-- TRIANGLE

function p.triangle(frame) local shape = "triangle" if frame.args['coord1'] == nil or frame.args['coord1'] == "" then error("Missing argument coord1!") end if frame.args['coord2'] == nil or frame.args['coord2'] == "" then error("Missing argument coord2!") end if frame.args['coord3'] == nil or frame.args['coord3'] == "" then error("Missing argument coord3!") end local separator = "@@@@@" local x = string.gsub(frame.args['coord1'],'%,','@@@@@') local y = string.gsub(frame.args['coord2'],'%,','@@@@@') local z = string.gsub(frame.args['coord3'],'%,','@@@@@') x = string.gsub(x,'%s+','') y = string.gsub(y,'%s+','') z = string.gsub(z,'%s+','') local tt = {} local data = {} local latitudes = {} local longitudes = {} local count = 1 local marker = frame.args['marker'] or "no" if marker == nil or marker == "" then marker = "no" end local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end -- FUTURE USE for str in string.gmatch(x,"([^"..separator.."]+)") do		if str ~= nil and str ~= "" then tt[count] = str count = count + 1 end end

for str in string.gmatch(y,"([^"..separator.."]+)") do		if str ~= nil and str ~= "" then tt[count] = str count = count + 1 end end

for str in string.gmatch(z,"([^"..separator.."]+)") do		if str ~= nil and str ~= "" then tt[count] = str count = count + 1 end end

if count >=8 then error("Check the upper and lower arguments for format!") end for i=1,6 do          if tt[i] == nil or tt[i] == "" then error("Check for missing latitude or longitude separated by a comma!") end end

longitudes[1] = tonumber(tt[2]) if longitudes[1] > 180 or longitudes[1] <- 180 then error("longitude should be between 180 and -180") end data[1] = "[" .. tt[2]

latitudes[1] = tonumber(tt[1]) if latitudes[1] > 90 or latitudes[1] <- 90 then error("latitude should be between 90 and -90") end data[2] = "," .. tt[1] .. "]"

longitudes[2] = tonumber(tt[4]) if longitudes[2] > 180 or longitudes[2] <- 180 then error("longitude should be between 180 and -180") end data[3] = "[" .. tt[4]

latitudes[2] = tonumber(tt[3]) if latitudes[2] > 90 or latitudes[2] <- 90 then error("latitude should be between 90 and -90") end data[4] = "," .. tt[3] .. "]"

longitudes[3] = tonumber(tt[6]) if longitudes[3] > 180 or longitudes[3] <- 180 then error("longitude should be between 180 and -180") end data[5] = "[" .. tt[6]

latitudes[3] = tonumber(tt[5]) if latitudes[3] > 90 or latitudes[3] <- 90 then error("latitude should be between 90 and -90") end data[6] = "," .. tt[5] .. "]"

local lat = (latitudes[1] + latitudes[2] + latitudes[3]) / 3 local long = (longitudes[1] + longitudes[2] + longitudes[3]) / 3 lat = string.format("%.6f",lat) long = string.format("%.6f",long) local group = frame.args['group'] or 'triangle' local title = frame.args['title'] or 'A triangle' local description = frame.args['desc'] or '' local fill = frame.args['fill'] or "#ccef64" local stroke = frame.args['stroke'] or "#0000ff" checkhex(fill,stroke) 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 = parts(lat,long,group,title,description,fill,stroke)

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

coordinates = coordinates.gsub(coordinates,'%]%[','],[') coordinates = coordinates.gsub(coordinates,'%]@@@@@%[','],\n[') coordinates = "[" .. 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 = 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

if marker == "yes" or marker == "y" then coordinates = coordinates .. '\n* \n' end

return coordinates

end

-- EQUITRI

function p.equitri(frame) local shape = "equitri" local id = frame.args['id']	or "" 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 'equitri' local title = frame.args['title'] or 'An equilateral triangle' local description = frame.args['desc'] or '' 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" checkhex(fill,stroke) local marker = frame.args['marker'] or "no" if marker == nil or marker == "" then marker = "no" end 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" 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 = 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 .. "]"

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

lat = (ptx + ptx2 + ptx3) / 3 long = (pty + pty2 + pty3 ) / 3

if marker == "yes" or marker == "y" then coordinates = coordinates .. '\n* \n' end

return coordinates

end

-- ELLIPSE

function p.ellipse(frame) local shape = "ellipse" local id = frame.args['id']	or "" local lat,long = "","" local x,y = 0,0 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 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 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" checkhex(fill,stroke) local marker = frame.args['marker'] or "no" if marker == nil or marker == "" then marker = "no" end local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end -- FUTURE USE local style = frame.args['style'] or "h" if style == nil or style == "" then style = "h" end if style ~= "v" then style = "h" end -- if not v (ie. other garbage then force style 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 = 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 style == "v" then pty = y - 0.5 * r * math.sin( angle ) -- for ellipse vertical elseif style == "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        if marker == "yes" or marker == "y" then                coordinates = coordinates .. '\n* \n'        end        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,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 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 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" checkhex(fill,stroke) local marker = frame.args['marker'] or "no" if marker == nil or marker == "" then marker = "no" end 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 = 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

if marker == "yes" or marker == "y" then coordinates = coordinates .. '\n* \n' end

return coordinates

end

-- POINTER

function p.pointer(frame) local shape = "pointer" local id = frame.args['id']	or "" 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 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 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" checkhex(fill,stroke) local marker = frame.args['marker'] or "no" if marker == nil or marker == "" then marker = "no" end 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" direction = string.gsub(direction,'%..*','') 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')

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 .. "]"

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

if marker == "yes" or marker == "y" then coordinates = coordinates .. '\n* \n' coordinates = coordinates .. '\n* \n' end

return coordinates end

-- PENTAGON

function p.pentagon(frame) local shape = "pentagon" local id = frame.args['id']	or "" local lat,long = "","" if id == "" or id == nil 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 'pentagon' local title = frame.args['title'] or 'A pentagon' local description = frame.args['desc'] or '' 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 r2 = r/2 local r3 = r/3 local fill = frame.args['fill'] or "#ccef64" local stroke = frame.args['stroke'] or "#0000ff" checkhex(fill,stroke) local marker = frame.args['marker'] or "no" if marker == nil or marker == "" then marker = "no" end 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 a,b,c,d,e = 360,72,144,216,288 local angle1,angle2,angle3,angle4,angle5 = 0,0,0,0,0 local ptx,ptx2,ptx3,ptx4,ptx5 = 0,0,0,0,0 local pty,pty2,pty3,pty4,pty5 = 0,0,0,0,0

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 )

angle4 = d * math.pi /180 ptx4 = lat + r * math.cos( angle4 ) pty4 = long + r * math.sin( angle4 )

angle5 = e * math.pi /180 ptx5 = lat + r * math.cos( angle5 ) pty5 = long + r * math.sin( angle5 )

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) ptx5,pty5 = string.format("%.6f",newlat(ptx5)),string.format("%.6f",pty5) lat,long = string.format("%.6f",newlat(lat)),string.format("%.6f",long)

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

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 if marker == "yes" or marker == "y" then coordinates = coordinates .. '\n* \n' end

return coordinates end

-- HEXAGON

function p.hexagon(frame) local shape = "hexagon" local id = frame.args['id']	or "" 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 'hexagon' local title = frame.args['title'] or 'A hexigon' local description = frame.args['desc'] or '' 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 r2 = r/2 local r3 = r/3 local fill = frame.args['fill'] or "#ccef64" local stroke = frame.args['stroke'] or "#0000ff" checkhex(fill,stroke) local marker = frame.args['marker'] or "no" if marker == nil or marker == "" then marker = "no" end 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 a,b,c,d,e,f = 30,90,150,210,270,330 local angle1,angle2,angle3,angle4,angle5,angle6 = 0,0,0,0,0,0 local ptx,ptx2,ptx3,ptx4,ptx5,ptx6 = 0,0,0,0,0,0 local pty,pty2,pty3,pty4,pty5,pty6 = 0,0,0,0,0,0

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 )

angle4 = d * math.pi /180 ptx4 = lat + r * math.cos( angle4 ) pty4 = long + r * math.sin( angle4 )

angle5 = e * math.pi /180 ptx5 = lat + r * math.cos( angle5 ) pty5 = long + r * math.sin( angle5 )

angle6 = f * math.pi /180 ptx6 = lat + r * math.cos( angle6 ) pty6 = long + r * math.sin( angle6 )

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) ptx5,pty5 = string.format("%.6f",newlat(ptx5)),string.format("%.6f",pty5) ptx6,pty6 = string.format("%.6f",newlat(ptx6)),string.format("%.6f",pty6) lat,long = string.format("%.6f",newlat(lat)),string.format("%.6f",long)

coordinates = "[" .. pty .. "," .. ptx .. "],[" .. pty2 .. "," .. ptx2 .. "],[" .. pty3 .. "," .. ptx3 .. "],[" .. pty4 .. "," .. ptx4 .. "],[" .. pty5 .. "," .. ptx5 .. "],[" .. pty6 .. "," .. ptx6 .. "],[" .. pty .. "," .. ptx .. "]"

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 if marker == "yes" or marker == "y" then coordinates = coordinates .. '\n* \n' end

return coordinates end

-- LINE

function p.line(frame) local shape = "line" local coord1 = frame.args['coord1'] or "" local coord2 = frame.args['coord2'] or "" local lat1,long1,lat2,long2 = "","","","" local ids = frame.args['ids'] or "" local type = "line" local marker = frame.args['marker'] or "no" if marker == nil or marker == "" then marker = "no" end local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end -- FUTURE USE local fill = "#ccef64" -- not needed as this is a line but keeping text etc. consistent throughout local group = frame.args['group'] or 'line' local title = frame.args['title'] or 'A line' local description = frame.args['desc'] or '' local stroke = frame.args['stroke'] or "#0000ff" checkhex(fill,stroke) local data = {} local coordinates = ""

-- if no ids then coord1 and coord2 is required for building coordinates

if ids == nil or ids == "" then if coord1 == nil or coord1 == "" then error("Missing argument coord1!") end if coord2 == nil or coord2 == "" then error("Missing argument coord2!") end

lat1 = string.gsub(coord1,"%,.*","") long1 = string.gsub(coord1,".*%,",'') lat2 = string.gsub(coord2,"%,.*","") long2 = string.gsub(coord2,".*%,",'') else ids = string.gsub(ids,"q","Q") -- do a lazy check for format of ids - "^[Q]%d+%,[Q]%d+$")           local checker = string.gsub(ids,"^[Q]%d+%,[Q]%d+$","")            if checker ~= "" then error("Bad format for parameter ids!") end            lat1 = string.gsub(ids,"%,.*","")            long1 = string.gsub(ids,"%,.*","")            lat2 = string.gsub(ids,".*%,",)            long2 = string.gsub(ids,".*%,",)

lat1 = latitude(lat1) long1 = longitude(long1) lat2 = latitude(lat2) long2 = longitude(long2) if lat1 == "" or lat2 == "" then error("latitude not found in wikidata!") end if long1 == "" or long2 == "" then error("longitude not found in wikidata!") end end

-- Need to CORRECT CENTER - OFF A BIT - FOR LATER WORK local latitude = string.format("%.6f",(lat1 + lat2) / 2) local longitude = string.format("%.6f",(long1 + long2) / 2)

data[1] = "[" .. long1 .. "," .. lat1 .. "]"       data[2] = "[" .. long2 .. "," .. lat2 .. "]"       coordinates = "[" .. data[1] .. "," .. data[2] .. "]},"

-- Text for building a maplink - added together with line coordinates in final output

local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat1,long1,group,title,description,fill,stroke)

if mapframe == "y" or mapframe == "yes" then coordinates = part3a .. coordinates .. part3b else coordinates = part1a .. coordinates .. part1b end

if marker == "yes" or marker == "y" then coordinates = coordinates .. '\n* \n' coordinates = coordinates .. '\n* \n' end

return coordinates end

-- DIAMOND

function p.diamond(frame) local shape = "diamond" local id = frame.args['id']	or "" 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 'diamond' local title = frame.args['title'] or 'A diamond' local description = frame.args['desc'] or '' 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" checkhex(fill,stroke) local marker = frame.args['marker'] or "no" if marker == nil or marker == "" then marker = "no" end 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 = 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 .. "]"

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

if marker == "yes" or marker == "y" then coordinates = coordinates .. '\n* \n' end

return coordinates

end

-- KITE - Shield

function p.kite(frame) local shape = "kite" local id = frame.args['id']	or "" 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 'kite' local title = frame.args['title'] or 'A kite' local description = frame.args['desc'] or '' 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" checkhex(fill,stroke) local marker = frame.args['marker'] or "no" if marker == nil or marker == "" then marker = "no" end 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 = 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 .. "]"

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

if marker == "yes" or marker == "y" then coordinates = coordinates .. '\n* \n' 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 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 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 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" checkhex(fill,stroke) local marker = frame.args['marker'] or "no" if marker == nil or marker == "" then marker = "no" end 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 = 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        if marker == "yes" or marker == "y" then               coordinates = coordinates .. '\n* \n'        end

return coordinates

end

-- STAR2 -- reworked star pointing North

function p.star2(frame) local shape = "star2" local id = frame.args['id']	or "" 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 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 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" checkhex(fill,stroke) local marker = frame.args['marker'] or "no" if marker == nil or marker == "" then marker = "no" end 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 = 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 CODE 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

if marker == "yes" or marker == "y" then coordinates = coordinates .. '\n* \n' end

return coordinates

end

-- HEXAGRAM -- 6 pointed star - six sided star

function p.hexagram(frame) local shape = "hexagram" local id = frame.args['id']	or "" 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 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 'hexagram' local title = frame.args['title'] or 'A hexagram' local description = frame.args['desc'] or '' 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" checkhex(fill,stroke) local marker = frame.args['marker'] or "no" if marker == nil or marker == "" then marker = "no" end 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 = 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 CODE 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

if marker == "yes" or marker == "y" then coordinates = coordinates .. '\n* \n' end

return coordinates

end

-- Octagon -- 8 sided shape

function p.octagon(frame) local shape = "octagon" local id = frame.args['id']	or "" 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 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 'octagon' local title = frame.args['title'] or 'An octagon' local description = frame.args['desc'] or ''

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 fill = frame.args['fill'] or "#ccef64" local stroke = frame.args['stroke'] or "#0000ff" checkhex(fill,stroke) local marker = frame.args['marker'] or "no" if marker == nil or marker == "" then marker = "no" end 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 = 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 + radius * math.cos( angle ) pty = y + radius * math.sin( angle ) ptx = newlat(ptx) -- TEST CODE 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

if marker == "yes" or marker == "y" then coordinates = coordinates .. '\n* \n' end

return coordinates

end

-- Only for a single polygon or shape - not multiple polygons or shapes yet -- Enter mapmask template coordinates as argument ie. |123,78.9|123,89.9|123,78.9 -- Create a mapmask in a mapframe or maplink -- Create a geoshape in a mapframe or maplink

function p.mapmark(frame) local data={} local markers = {} local counter = 0 local coordinates = "" local markerstext = "" local output = "" local latitude = "" local longitude = "" local mask = frame.args['mask'] or "y" if mask == nil then mask = "y" end local mapshape = frame.args['mapshape'] or "n" if mapshape == nil then mapshape = "n" end local maplink = frame.args['maplink'] or "n" if maplink == nil then maplink = "n" end local mapframe = frame.args['mapframe'] or "y" if maplink == nil then mapframe = "y" end local marker = frame.args['marker'] or "n" if marker == nil then marker = "n" end if mapframe == "n" then maplink = "y" end if maplink == "y" then mapframe = "n" end                     -- if maplink that overrides mapframe if mask == "n" then mapshape = "y" end if mapshape == "y" then mask = "n" end                        -- if mapshape that overrides mask

local markerstype = "" local markercount = 0 for x in ipairs( frame.args ) do        data[x] = frame.args[x] if data[x] ~= nil and data[x] ~= "" then if marker == "y" then markercount = markercount + 1 if markercount <= 90 then markerstype = "vicinity" end if markercount > 90 and markercount <= 180 then markerstype = "around" end if markercount > 180 and markercount <= 270 then markerstype = "view" end if markercount > 270 and markercount <= 360 then markerstype = "do" end if markercount > 360 and markercount <= 450 then markerstype = "lime" end if markercount > 450 and markercount <= 540 then markerstype = "listing" end if markercount > 540 and markercount <= 630 then markerstype = "gold" end if markercount > 630 and markercount <= 720 then markerstype = "see" end if markercount > 720 and markercount <= 810 then markerstype = "red" end if markercount > 810 and markercount <= 900 then markerstype = "silver" end if markercount > 900 and markercount <= 990 then markerstype = "go" end if markercount > 990 and markercount <= 1080 then markerstype = "other" end if markercount >1080 and markercount <= 1170 then markerstype = "sleep" end if markercount > 1170 and markercount <= 1260 then markerstype = "buy" end if markercount > 1260 and markercount <= 1350 then markerstype = "drink" end

-- markers[x] = "\n* {{marker|type=vicinity|name=Location: " .. data[x] .. "|lat=" .. string.gsub(data[x],',.*','') markers[x] = "\n* {{marker|type=" .. markerstype .. "|name=Location: " .. data[x] .. "|lat=" .. string.gsub(data[x],',.*','') markers[x] = markers[x] .. "|long=" .. string.gsub(data[x],'^.*,','') .. "}}"            end data[x] = "[" .. string.gsub(data[x],'^(.*)(%,)(.*)$','%3%2%1') .. "]"        end end

for i = 1,table.getn(data) do        if string.find(data[i],'%a+') == nil and string.find(data[i],'%u+') == nil then if data[i] ~= nil and data[i] ~= "" then if latitude == "" then latitude = string.gsub(data[i],'(%[.*%,)(.*)(%])','%2') end

if longitude == "" then longitude = string.gsub(data[i],'(%[)(.*)(%,.*)','%2') end

-- for error checking -- if latitude ~= nil then return "lat: " .. latitude .. " long: " .. longitude end

coordinates = coordinates .. "," .. data[i] end end end

coordinates = string.gsub(coordinates,'^%,','') coordinates = '[' .. coordinates .. "]"

if marker == "y" then for i =1,table.getn(markers) do           if markers[i] ~= nil and markers[i] ~= "" then if string.find(markers[i],'lat=%a+') == nil and string.find(markers[i],'lat=%u+') == nil then markerstext = markerstext .. markers[i] end end end end

if mapframe == "y" and mask == "y" then output = output .. '\n\n\t{"type": "FeatureCollection",\n\t\t"features": [\n\t\t\t{"type": "Feature",\n\t\t\t\t"geometry":' output = output .. '{"coordinates":\n\t[\n\t\t\t-3600,90], [3600, 90], [3600,-90], [-3600,-90], [-3600,90,\n\t\t\t' output = output .. coordinates output = output .. '\n\t],\n\t\t\t"type":"Polygon"},\n\t\t\t"properties":{\n\t\t\t"title": "A mapmask",\n\t\t\t"description": "",' output = output .. '\n\t\t\t"fill": "#808080",\n\t\t\t"fill-opacity": 0.4,\n\t\t\t"stroke":"#000000",\n\t\t\t"stroke-width":1\n}\n}]}' output = output .. '\n ' end

if mapframe == "y" and mapshape == "y" then output = output .. '\n\n\t{"type": "FeatureCollection",\n\t\t"features": [\n\t\t\t{"type": "Feature",' output = output .. '\n\t\t\t\t"geometry": {"coordinates":\n\t[\n\t\t\t' output = output .. coordinates output = output .. '\n\t],\n\t\t\t"type":"Polygon"},\n\t\t\t"properties":{\n\t\t\t"title": "A mapshape",\n\t\t\t"description":' output = output .. ' "",\n\t\t\t"fill": "#ffffb2",\n\t\t\t"stroke":"#888888",\n\t\t\t"stroke-width":3\n}\n}]}' output = output .. '\n ' end

if maplink == "y" and mask == "y" then output = output .. '\n ' end

if maplink == "y" and mapshape == "y" then output = output .. '\n '

end

if marker == "y" then output = output .. markerstext end

return output

end

-- BBOX - bounding box

function p.bbox(frame) local shape = "bbox" local coord1 = frame.args['coord1'] or "" local coord2 = frame.args['coord2'] or "" local coord3 = frame.args['coord3'] or "" local coord4 = frame.args['coord4'] or "" local lat1,long1,lat2,long2,lat3,long3,lat4,long4 = "","","","","","","","" local ids = frame.args['ids'] or "" local type = frame.args['fill'] or "line" if type ~= "poly" then type = "line" end local marker = frame.args['marker'] or "no" if marker == nil or marker == "" then marker = "no" end local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end -- FUTURE USE local group = frame.args['group'] or 'bbox' local title = frame.args['title'] or 'A bbox' local description = frame.args['desc'] or '' local fill = frame.args['fill'] or "#ccef64" local stroke = frame.args['stroke'] or "#0000ff" checkhex(fill,stroke) local data = {} local coordinates = ""

if ids == nil or ids == "" then if coord1 == nil or coord1 == "" then error("Missing argument coord1!") end if coord2 == nil or coord2 == "" then error("Missing argument coord2!") end if coord3 == nil or coord3 == "" then error("Missing argument coord3!") end if coord4 == nil or coord4 == "" then coord4 = coord1 end lat1 = string.gsub(coord1,"%,.*","") long1 = string.gsub(coord1,".*%,",'') lat2 = string.gsub(coord2,"%,.*","") long2 = string.gsub(coord2,".*%,",'') lat3 = string.gsub(coord3,"%,.*","") long3 = string.gsub(coord3,".*%,",'') lat4 = string.gsub(coord4,"%,.*","") long4 = string.gsub(coord4,".*%,",'') else ids = string.gsub(ids,"q","Q") ids = string.gsub(ids,"%s+","") -- do a lazy check for format of ids - "^[Q]%d+%,[Q]%d+$")           local checker = ""            checker = string.gsub(ids,"^[Q]%d+%$","")                if checker == "" then error("ids requires at least 3 wikidata IDs") end 			            checker = string.gsub(ids,"^[Q]%d+%,[Q]%d+$","")                if checker == "" then error("ids requires at least 3 wikidata IDs") end 		   ids = ids .. "," .. ids                         - insure 4th to work with even though they overlap            ids = string.gsub(ids,"%,","@@@@@")	        local separator = "@@@@@"            local counter = 1            local idsarray = {}            for str in string.gmatch(ids,"([^"..separator.."]+)") do                  idsarray[counter] = str                  counter = counter + 1	            end            lat1,long1 = latitude(idsarray[1]),longitude(idsarray[1])            lat2,long2 = latitude(idsarray[2]),longitude(idsarray[2]) lat3,long3 = latitude(idsarray[3]),longitude(idsarray[3]) lat4,long4 = latitude(idsarray[4]),longitude(idsarray[4]) -- could be a duplicate of 1 if we added it in program if lat1 == "" or lat2 == "" or lat3 == "" or lat4 == "" then error("latitude not found in wikidata!") end if long1 == "" or long2 == "" or long3 == "" or long4 == "" then error("longitude not found in wikidata!") end end

local bboxlat = {} local bboxlong = {} local bboxcoords = "" bboxlat[1] = lat1 bboxlong[1] = long1 bboxlat[2] = lat2 bboxlong[2] = long2 bboxlat[3] = lat3 bboxlong[3] = long3 bboxlat[4] = lat4 bboxlong[4] = long4 table.sort(bboxlat) table.sort(bboxlong) bboxcoords = '"bbox": [' .. bboxlong[1] .. "," .. bboxlat[1] .. "," .. bboxlong[4] .. "," ..bboxlat[4] .. "],\n\t\t"

local lat = (bboxlat[1] + bboxlat[4])/2 local long = (bboxlong[1] + bboxlong[4])/2 local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke) part1a = string.gsub(part1a,'"Feature",','"Feature",' .. bboxcoords) part2a = string.gsub(part2a,'"Feature",','"Feature",' .. bboxcoords) part3a = string.gsub(part3a,'"Feature",','"Feature",' .. bboxcoords) part4a = string.gsub(part4a,'"Feature",','"Feature",' .. bboxcoords) coordinates = coordinates .. "[" .. bboxlong[1] .. "," .. bboxlat[1] .. "],["		coordinates = coordinates .. bboxlong[4] .. "," .. bboxlat[1] .. "],["		coordinates = coordinates .. bboxlong[4] .. "," .. bboxlat[4] .. "],["		coordinates = coordinates .. bboxlong[1] .. "," .. bboxlat[4] .. "],[" .. bboxlong[1] .. "," .. bboxlat[1] .. "]" -- close

coordinates = string.gsub(coordinates,'stroke-width":1','stroke-width":2') 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

if marker == "yes" or marker == "y" then coordinates = coordinates .. '\n* \n' end

return coordinates

end

-- HALFCIRCLE

function p.halfcircle(frame) local shape = "halfcircle" local shade = frame.args['shade'] or "left" if shade ~= "right" then shade = "left" end local id = frame.args['id']	or "" local lat,long = "","" local x,y = 0,0 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 x = tonumber(lat) y = tonumber(long) local marker = frame.args['marker'] or "no" if marker == nil or marker == "" then marker = "no" end 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

local group = frame.args['group'] or 'halfcircle' local title = frame.args['title'] or 'A halfcircle' local description = frame.args['desc'] or '' 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" checkhex(fill,stroke) local data = {} for i=1, 360 do          data[i] = "" end --       local data2 = {} 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 = parts(lat,long,group,title,description,fill,stroke)

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

for i = 1,360, 1 do          angle = i * math.pi / 180 ptx = x + r * math.cos( angle ) pty = y + r * math.sin( angle ) if tonumber(x) >= 10.5 then ptx = newlat(ptx) -- makes correction to make circle show up on map - upper latitudes end

if tonumber(x) <= -10.5 then ptx = newlat(ptx) -- makes correction to make circle show up on map - lower latitudes end data[i] = '[' .. string.format("%.6f",pty) .. "," .. string.format("%.6f",ptx) .. ']'       end

if shade == "right" then for i = 1,180, 1 do               coordinates = coordinates .. data[i] end coordinates = coordinates .. data[360] else for i = 180,360, 1 do              coordinates = coordinates .. data[i] end coordinates = coordinates .. data[180] end

coordinates = coordinates.gsub(coordinates,'%]%[','],[') coordinates = coordinates.gsub(coordinates,'%]@@@@@%[','],\n[') coordinates = coordinates.gsub(coordinates,'@@@@@%,',',') coordinates = "[" .. 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 = 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        if marker == "yes" or marker == "y" then              coordinates = coordinates .. '\n* \n'        end        return coordinates

end

-- Decagon -- 10 sided shape

function p.decagon(frame) local shape = "decagon" local id = frame.args['id']	or "" 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 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 'decagon' local title = frame.args['title'] or 'A decagon' local description = frame.args['desc'] or ''

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 fill = frame.args['fill'] or "#ccef64" local stroke = frame.args['stroke'] or "#0000ff" checkhex(fill,stroke) local marker = frame.args['marker'] or "no" if marker == nil or marker == "" then marker = "no" end 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 = 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 + radius * math.cos( angle ) pty = y + radius * math.sin( angle ) ptx = newlat(ptx) -- TEST CODE 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

if marker == "yes" or marker == "y" then coordinates = coordinates .. '\n* \n' end

return coordinates

end

-- Annulus

-- ANNULUS - 2 circles forming a donut shape

function p.annulus(frame) local shape = "annulus" local id = frame.args['id']	or "" local lat,long = "","" local x,y = 0,0 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 x = string.format("%.6f",lat) y = string.format("%.6f",long) local marker = frame.args['marker'] or "no" if marker == nil or marker == "" then marker = "no" end 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 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" 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 = 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        if marker == "yes" or marker == "y" then              coordinates = coordinates .. '\n* \n'        end        return coordinates

end

function p.rhombus(frame) local shape = "rhombus" local direction = frame.args['direction'] or "vertical" if direction ~= "horizontal" then direction = "vertical" end local id = frame.args['id']	or "" 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 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" checkhex(fill,stroke) local marker = frame.args['marker'] or "no" if marker == nil or marker == "" then marker = "no" end 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 = 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 == "horizontal" 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 .. "]"

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

if marker == "yes" or marker == "y" then coordinates = coordinates .. '\n* \n' end

return coordinates

end

-- WEDGE

function p.wedge(frame) local shape = "wedge" local id = frame.args['id']	or "" 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 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 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" checkhex(fill,stroke) local marker = frame.args['marker'] or "no" if marker == nil or marker == "" then marker = "no" end 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" direction = string.gsub(direction,'%..*','') 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 = 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 .. "]"

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

if marker == "yes" or marker == "y" then coordinates = coordinates .. '\n* \n' coordinates = coordinates .. '\n* \n' end

return coordinates end

-- CROSS

function p.cross(frame) local shape = "cross" local id = frame.args['id']	or "" 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 'cross' local title = frame.args['title'] or 'A Cross' local description = frame.args['desc'] or '' 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" checkhex(fill,stroke) local marker = frame.args['marker'] or "no" if marker == nil or marker == "" then marker = "no" end 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 = 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,'@@@@@',',')

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

if marker == "yes" or marker == "y" then lat = string.format("%.6f",newlat(lat)) coordinates = coordinates .. '\n* \n' end

return coordinates end

-- X_SHAPE

function p.x_shape(frame) local shape = "xshape" local id = frame.args['id']	or "" 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 'xshape' local title = frame.args['title'] or 'An X'       local description = frame.args['desc'] or '' 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" checkhex(fill,stroke) local marker = frame.args['marker'] or "no" if marker == nil or marker == "" then marker = "no" end 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 = 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,'@@@@@',',')

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

if marker == "yes" or marker == "y" then lat = string.format("%.6f",newlat(lat)) coordinates = coordinates .. '\n* \n' 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,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 direction = frame.args['direction'] or "horizontal" if direction ~= "horizontal" then direction = "vertical" end local group = frame.args['group'] or 'bar' local title = frame.args['title'] or 'A bar' local description = frame.args['desc'] or '' 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 checkhex(fill,stroke) local marker = frame.args['marker'] or "no" if marker == nil or marker == "" then marker = "no" end 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 = 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 == "vertical" 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,'@@@@@',',')

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

coordinates = string.gsub(coordinates,'stroke%-width%":1','stroke-width":3')

if marker == "yes" or marker == "y" then lat = string.format("%.6f",newlat(lat)) coordinates = coordinates .. '\n* \n' end

return coordinates end

-- DOT -- creates a grayish dot

function p.dot(frame) local shape = "dot" local id = frame.args['id']	or "" 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 'dot' local title = frame.args['title'] or 'A dot' local description = frame.args['desc'] or '' local size = "30"                                 -- fixed size no longer a parameter

-- frame.args['size'] or "10"  -- default of 1 -- if size == nil or size == "" then size = "10" end         -- just a check -- size = string.gsub(size,'%..*','') -- if size == "" then error("size should currently be a whole number!") end -- size = tonumber(size) -- if size 30 then error("The Dot size is currently limited from 10 to 30 for use!") end local fill = frame.args['fill'] or "#000000"         -- no longer a parameter but keeping rest of code consistent local stroke = frame.args['stroke'] or "#000000"     -- can change the color using stroke checkhex(fill,stroke) local marker = frame.args['marker'] or "no" if marker == nil or marker == "" then marker = "no" end 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" -- force default line for LineString if type ~= "line" then type = "line" end

lat = string.format("%.6f",lat) long = string.format("%.6f",long) local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke)

coordinates = coordinates .. "[" .. long .. "," .. lat .. "],[" .. long .. "," .. lat .. "]"

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

-- Make thickness of size and add opacity fixed at 30 and 0.4 respectively

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

if marker == "yes" or marker == "y" then coordinates = coordinates .. '\n* \n' end

return coordinates

end

-- KEYSTONE

function p.keystone(frame) local shape = "keystone" local id = frame.args['id']	or "" 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 'keystone' local title = frame.args['title'] or 'A keystone' local description = frame.args['desc'] or '' 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" checkhex(fill,stroke) local marker = frame.args['marker'] or "no" if marker == nil or marker == "" then marker = "no" end 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 = 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,'@@@@@',',')

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

if marker == "yes" or marker == "y" then lat = string.format("%.6f",newlat(lat)) coordinates = coordinates .. '\n* \n' end

return coordinates end

-- COG -- gear shape

function p.cog(frame) local shape = "cog" local id = frame.args['id']	or "" 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 'cog' local title = frame.args['title'] or 'A cog' local description = frame.args['desc'] or '' 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" checkhex(fill,stroke) local marker = frame.args['marker'] or "no" if marker == nil or marker == "" then marker = "no" end 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 = 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

if marker == "yes" or marker == "y" then lat = string.format("%.6f",newlat(lat)) coordinates = coordinates .. '\n* \n' end

return coordinates end

-- MULTIPOINT

function p.multipoint(frame) local shape = "multipoint" local ids = frame.args['ids'] or "" ids = string.gsub(ids,"%,+","@") ids = string.gsub(ids,"%s+",'') ids = string.gsub(ids,"%@+",'@') local coords = frame.args['coords'] or "" coords = string.gsub(coords,"%@+","@") -- multiple @'s to a @ local separator = "@" local coordsx = {} local coordinates = "" local count = 1 local lat = "" local long = "" if ids == nil or ids == "" then if coords == "" or coords == nil then error("Missing argument coords!") end count = 1 for str in string.gmatch(coords,"([^"..separator.."]+)") do		if str ~= nil and str ~= "" then lat = string.gsub(str,",.*",'') long = string.gsub(str,"^.*,",'') 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 coordsx[count] = string.format("%.6f",long) .. "," .. string.format("%.6f",lat) count = count + 1 end end else count = 1 for str in string.gmatch(ids,"([^"..separator.."]+)") do		 if str ~= nil and str ~= "" then str = checkid(str) lat = latitude(str) long = longitude(str) coordsx[count] = string.format("%.6f",long) .. "," .. string.format("%.6f",lat) count = count + 1 end end end local group = frame.args['group'] or 'multipoint' local title = frame.args['title'] or 'A multipoint' local description = frame.args['desc'] or "" local color = frame.args['color'] or "#ffccaa" 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 symbol = frame.args['symbol'] or "star" local mapframe = frame.args['mapframe'] or "no" if mapframe == nil or mapframe == "" then mapframe = "no" end local maplink = frame.args['maplink'] or "yes"

local part1a = ' \n'

local part2a = '\n{"type": "FeatureCollection",\n\t"features":' part2a = part2a .. '[\n\t\t{\n\t\t"type": "Feature",\n\t\t"geometry": {"coordinates":\n\t\t'

local part2b = '\n\t\t"type":"MultiPoint"},\n\t"properties":{\n\t\t"title": "' .. title .. '",\n' part2b = part2b .. '\t\t"description": "' .. description .. '",\n\t\t"marker-color": "' .. color .. '",\n\t\t' part2b = part2b .. '"marker-size": "medium",\n\t\t"marker-symbol": "' .. symbol .. '",\n\t\t\t' part2b = part2b .. '\n}\n}]}\n \n'

for i = 1,table.getn(coordsx), 1 do       coordinates = coordinates .. "[" .. coordsx[i] .. "]@@@@@"     end coordinates = string.gsub(coordinates,"@@@@@",",") coordinates = string.gsub(coordinates, '%,$','') if mapframe == "y" or mapframe == "yes" then coordinates = '[' .. coordinates .. '],'                 coordinates = part2a .. coordinates .. part2b else coordinates = '[' .. coordinates .. ']},'               coordinates = part1a .. coordinates .. part1b end

return coordinates

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,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 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 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 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 checkhex(fill,stroke) local marker = frame.args['marker'] or "no" if marker == nil or marker == "" then marker = "no" end 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 = 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))

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

-- Make thickness of 3

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

if marker == "yes" or marker == "y" then lat = string.format("%.6f",lat) coordinates = coordinates .. '\n* \n' .. '\n* \n' 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,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 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 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" checkhex(fill,stroke) local marker = frame.args['marker'] or "no" if marker == nil or marker == "" then marker = "no" end 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 = 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

if marker == "yes" or marker == "y" then coordinates = coordinates .. '\n* \n' end

return coordinates

end

-- MULTILINE - draw lines from pairs of coordinates

function p.multiline(frame)

local shape = "multiline" local ids = frame.args['ids'] or "" ids = string.gsub(ids,"%,+","@") ids = string.gsub(ids,"%s+",'') ids = string.gsub(ids,"%@+",'@') local coords = frame.args['coords'] or "" coords = string.gsub(coords,"%s+",'') coords = string.gsub(coords,"%@+","@") -- multiple @'s to a @ local separator = "@" local coordsx = {} local coordinates = "" local count = 1 local lat = "" local long = "" local type = "line" if ids == nil or ids == "" then if coords == "" or coords == nil then error("Missing argument coordinates!") end count = 1 for str in string.gmatch(coords,"([^"..separator.."]+)") do		         if str ~= nil and str ~= "" then lat = string.gsub(str,",.*",'') long = string.gsub(str,"^.*,",'') 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 coordsx[count] = string.format("%.6f",long) .. "," .. string.format("%.6f",lat) count = count + 1 end end else count = 1 for str in string.gmatch(ids,"([^"..separator.."]+)") do		           if str ~= nil and str ~= "" then str = checkid(str) lat = latitude(str) long = longitude(str) coordsx[count] = string.format("%.6f",long) .. "," .. string.format("%.6f",lat) count = count + 1 end end end local group = frame.args['group'] or 'multiline' local title = frame.args['title'] or 'A multiline' local description = frame.args['desc'] or "" if description == nil then description = "" end local fill = "#000000" local stroke = frame.args['stroke'] or "#ffccaa" if string.len(stroke) ~= 7 then error("Incorrect length for argument color!") 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 color!") end local mapframe = frame.args['mapframe'] or "no" if mapframe == nil or mapframe == "" then mapframe = "no" end local mod = math.mod(table.getn(coordsx),2) if mod == 1 then error("Need even number of matching coordinates!") end local i = 0 for i = 1,table.getn(coordsx), 1 do         coordinates = coordinates .. "[" .. coordsx[i] .. "]@@@@@"         i = i + 1 coordinates = coordinates .. "[" .. coordsx[i] .. "]]@@@@@["         if i == table.getn(coordsx) then break end end

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

local part1a = ' \n'

local part2a = '\n{"type": "FeatureCollection",\n\t"features":' part2a = part2a .. '[\n\t\t{\n\t\t"type": "Feature",\n\t\t"geometry": { \n\t"type":"MultiLineString",\n\t"coordinates":\n\t\t'

local part2b = '\n\t"properties":{\n\t\t"title": "' .. title .. '",\n' part2b = part2b .. '\t\t"description": "' .. description .. '",\n\t\t' part2b = part2b .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":1,\n\t\t\t' part2b = part2b .. '}\n}]}\n \n'

-- No Polygons just MultiLineString

if mapframe == "y" or mapframe == "yes" then coordinates = '' .. coordinates .. '},' coordinates = part2a .. coordinates .. part2b else coordinates = '' .. coordinates .. '},' coordinates = part1a .. coordinates .. part1b end

-- No Markers unless wanted can code - could end up with a few or large amount of markers

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'] 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 "" if description == nil then description = "" end local fill = frame.args['fill'] or "#ffff00" local stroke = frame.args['stroke'] or "#000000" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nil or mapframe == "" then mapframe = "no" end local marker = frame.args['marker'] or "no" 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,",$",'')

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

if marker == "yes" or marker == "y" then coordinates = coordinates .. '\n* \n' end

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 lat,long = "","" local x,y,x2,y2 = 0,0,0,0

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

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 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" checkhex(fill,stroke) local marker = frame.args['marker'] or "no" if marker == nil or marker == "" then marker = "no" end 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 = 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        if marker == "yes" or marker == "y" then               coordinates = coordinates .. '\n* \n'        end

return coordinates

end

-- Draw a route -- BETA - TEST -- Currently draws a maplink with 1 route - can edit to input/output multiple routes in 1 maplink but this will suffice -- for now -- A mapframw can also be created for 1 route - multiple routes can be added later

function p.drawroute(frame) local route = "" local newcoordinates = "" local group = frame.args['group'] or 'route' local show = frame.args['show'] or group local title = frame.args['title'] or '' local description = frame.args['description'] or '' local coordinates = frame.args['coordinates'] or '' local flip = frame.args['flip'] or 'no'                  -- flip the lat,long input in coordinates parameter local separator = "@" local type = frame.args['type'] or 'maplink' local lat=frame.args['lat'] or "34" local long=frame.args['long'] or "-40" local zoom = "5" local width="400" local height="350" local text = frame.args['text'] or "" if type ~= "maplink" then type = "mapframe" end

if coordinates == "" or coordinates == nil then return "" end coordinates = string.gsub(coordinates,'\n',' ') coordinates = string.gsub(coordinates,'%s+','') coordinates = string.gsub(coordinates,'@+','@') if flip == 'no' or flip == "n" then coordinates = string.gsub(coordinates,'@','],[') else for str in string.gmatch(coordinates,"([^"..separator.."]+)") do           	         str = string.gsub(str,'(.*),(.*)','%2,%1') newcoordinates = newcoordinates .. str .. "],["                end coordinates = string.gsub(newcoordinates,'%],%[$','') end if type == 'maplink' then route = route .. '\n \n' else route = route .. '\n"          route = route .. '\n{"type":"Feature", "properties":{' route = route .. '\n\t\t"title": "' .. title .. '",' route = route .. '\n\t\t"description": "' .. description .. '",' route = route .. '\n\t\t"stroke":"#0000ff",' route = route .. '\n\t\t"stroke-width":2},' route = route .. '\n\t"geometry":' route= route .. '\n\t{"type":"LineString",' route = route .. '\n\t"coordinates":' route = route .. '\n\t' .. coordinates .. '' route = route .. '\n}}} \n' end

return route

end

-- Function to draw a maplink for producing a mapshape -- Only need the Wikidata ID and color for fill as parameters (id=Q8888 - fill=#ffcc00 -- Optional parameter(s): description -- rest filled in which you can edit -- added type -- this fetches info based on wikidata and contents of OpenStreetMap

function p.drawmapshape(frame) local id = frame.args['id'] or "" local fill = frame.args['fill'] or "#ffcc00" checkhex(fill,"#4d4d4d") local output = "" local type = frame.args['type'] or "mapshape" if type == "geoshape" or type == "geoline" or type == "geomask" then type = type else type = "geoshape" end

if id == nil or id == "" then return end id = checkid(id) local description = frame.args['description'] or "" local lat = latitude(id) local long = longitude(id) lat = string.format("%.6f",lat) long = string.format("%.6f",long) local language = frame.args['lang'] or mw.language.getContentLanguage(id).code

local title = "" local wiki = language .. "wikivoyage" local titlex = mw.wikibase.label(id) local entity = mw.wikibase.getEntityObject(id) if entity == nil then return end title = entity:getSitelink(wiki) if title == nil or title == "" then title = titlex end

output = output .. ' '

return output

end

-- RIGHT triangle - using a box as reference instead of a circle - slightly different than an equilateral triangle -- does not point to anything just a triangular shape - have to adjust manually for the moment

function p.righttriangle(frame) local shape = "letters" local id = frame.args['id']	or "" 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 side = frame.args['side'] or 1 side = tonumber(side) if side 4 then side = 1 end local group = frame.args['group'] or 'letters' local title = frame.args['title'] or 'Text line' local description = frame.args['desc'] or '' local r = frame.args['radius'] or ".5" if r == nil or r == "" then r = .5 end 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" checkhex(fill,stroke) local marker = frame.args['marker'] or "no" if marker == nil or marker == "" then marker = "no" end 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 = 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 if side == 1 then d = 225 end if side == 2 then c = 135 end if side == 3 then b = 45 end if side == 4 then a = 315 end

local rx = r * 2 -- For something else 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 .. "]"

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

if marker == "yes" or marker == "y" then coordinates = coordinates .. '\n* \n' end

return coordinates

end

-- THIS FUNCTION IS BEING DEVELOPED THROUGH ITERATION -- DESIGNING AS YOU GO SO TO SPEAK AND PUTTING IDEAS IN AS TO PROCESS -- BEAR WITH IT -- Need to draw one more set of points

function p.textline(frame) local shape = "letters" local line = frame.args['line'] or "" if line == nil or line == "" then return "" end -- LOWERCASE IS CHANGED TO UPPERCASE LATER if string.gsub(line,"^[% A-Z0-9a-z%[%]%(%)%-%-_%<%>%/:]+$","") ~= "" then error("only A-Z a-z [ ] < > - _  / are alowed!") end if string.len(line) > 1 then              -- funky add extraspace at beginning and end line = "@" .. line .. "@"		  end 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 'letters' local title = frame.args['title'] or 'Text line' local description = frame.args['desc'] or '' local radius = frame.args['radius'] or .5 if radius == nil or radius == "" then radius = .5 end radius = tonumber(radius) if radius > 10 then error("10 for radius is MAX") end if radius <= 0 then error("r has to be greater than 0") end radius1 = radius * .75 radius2 = radius local fill = frame.args['fill'] or "#ccef64" if fill == nil or fill == "" then fill = "#ccef64" end local stroke = frame.args['stroke'] or "#0000ff" if stroke == nil or stroke == "" then stroke = "#0000ff" end checkhex(fill,stroke) local coordinates = "" local boxcoordinates = "" local combinedcoords = "" local type = "line" local letter = "" local factor = 2

local stringlength = 0 stringlength = string.len(line) local lower = 0 _,lower = string.gsub(line,'%l','') stringlength = stringlength - lower stringlength = stringlength + (lower * .75)

local calc = 0 local adjust = frame.args['adjust'] or "none" -- TO MAKE ROUGH ADJUSTMENT OF STARTING POSITION if adjust == nil or adjust == "" then adjust = "none" end

if adjust ~= "right" and adjust ~= "center" and adjust ~= "left" then adjust = "none" end

local boxit = frame.args['boxit'] or "n" if boxit == "" or boxit == nil then boxit = "n" end if boxit ~= "n" then boxit = "y" end

local frameit = {} -- CHANGE TO LineString with stroke-width of

local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke) local angle = 0

local recx1,recx2,recx3,recx4 = 0,0,0,0 local recy1,recy2,recy3,recy4 = 0,0,0,0

local ptxnew,latx,latxx,latxxx,latcc,ptx1,ptx2,ptx3,ptx4,ptx5,ptx6,ptx7,ptx8,ptx9 = 0,0,0,0,0,0,0,0,0,0,0,0,0,0 local ptx10,ptx11,ptx12,ptx13,ptx14,ptx15,ptx16,ptx17,ptx18,ptx19,ptx20 = 0,0,0,0,0,0,0,0,0,0,0 local ptynew,longx,longxx,longxxx,longcc,pty1,pty2,pty3,pty4,pty5,pty6,pty7,pty8,pty9 = 0,0,0,0,0,0,0,0,0,0,0,0,0,0 local pty10,pty11,pty12,pty13,pty14,pty15,pty16,pty17,pty18,pty19,pty20 = 0,0,0,0,0,0,0,0,0,0,0 -- Build a rectangular shape to get the 4 corners -- Below is a square so have to extend it upward using a different center point -- top corners

local a = 45             -- right upper corner - pty1 local b = 135            -- right lower corner - pty2 local c = 225            -- left lower corner -- pty3 local d = 315            -- left upper corner -- pty4 local e = 180            -- bottom center rectangle -- longxx,pty5 local f = 360            -- upper center rectangle -- longx,longxxx,longcc,pty6 local g = 270            -- upper center left side rectangle -- pty7,pty11,pty13,pty15,pty17,pty19,pty21 local h = 90             -- upper center right side rectangle -- pty8,pty12,pty14,pty16,pty18,pty20,pty22 local i = 140            -- add to letter Q -- pty9 local j = 160            -- add for letter Q -- pty10

-- move line over to right or left to approximate center of line if stringlength > 1 then if adjust == "center" then lat = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180) angle = 270 * math.pi /180 lat = lat + (radius * (stringlength * 1)) * math.cos( angle ) long = long + (radius * (stringlength * 1)) * math.sin( angle ) lat,long = string.format("%.6f",newlat(lat)),string.format("%.6f",long) angle = 0 end if adjust == "left" then lat = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180) angle = 270 * math.pi /180 lat = lat + (radius * (stringlength * 2)) * math.cos( angle ) long = long + (radius * (stringlength * 2)) * math.sin( angle ) lat,long = string.format("%.6f",newlat(lat)),string.format("%.6f",long) angle = 0 end if adjust == "right" then lat = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180) angle = 90 * math.pi /180 if boxit == "y" then lat = lat + (radius * 4) * math.cos(angle) long = long + (radius * 4) * math.sin( angle) else lat = lat + (radius * 2) * math.cos(angle) long = long + (radius * 2) * math.sin( angle) end lat,long = string.format("%.6f",newlat(lat)),string.format("%.6f",long) angle = 0 end

end

-- Maybe WORK MOVING LETTERS AROUND ie lc letter followed by uppercase letter local letterbefore = "" local letterafter = "" local letternow = ""

for zz = 1,string.len(line) do

letter = string.sub(line,zz,zz)

letterafter = string.sub(line,zz + 1, zz + 1) letternow = letter letterbefore = string.sub(line,zz - 1, zz - 1)

if string.find(letter,'%l') == 1 then radius = radius1 letter = string.upper(letter) else radius = radius2 end

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

angle = f * math.pi / 180 latx = lat + (radius*.5) * math.cos(angle) longx = long + (radius*.5) * math.sin(angle)

angle = f * math.pi / 180 latcc = lat + (radius*.25) * math.cos(angle) longcc = long + (radius*.25) * math.sin(angle) angle = e * math.pi / 180 latxx = lat + (radius * .4) * math.cos(angle) longxx = long + (radius * .4) * math.sin(angle)

angle = f * math.pi / 180 latxxx = lat + (radius) * math.cos(angle) longxxx = long + (radius) * math.sin(angle)

angle = a * math.pi / 180 ptx1 = latx + radius * math.cos( angle ) pty1 = longx + radius * math.sin( angle )

recx1 = latx + (radius * 1.5) * math.cos( angle ) recy1 = longx + (radius * 1.5) * math.sin( angle )

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

recx2 = lat + (radius * 1.5) * math.cos( angle ) recy2 = long + (radius * 1.5) * math.sin( angle )

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

recx3 = lat + (radius * 1.5) * math.cos( angle ) recy3 = long + (radius * 1.5) * math.sin( angle )

angle = d * math.pi /180 ptx4 = latx + radius * math.cos( angle ) pty4 = longx + radius * math.sin( angle )

recx4 = latx + (radius * 1.5) * math.cos( angle ) recy4 = longx + (radius * 1.5) * math.sin( angle )

angle = e * math.pi /180 ptx5 = lat + (radius * .7) * math.cos( angle ) pty5 = long + (radius * .7) * math.sin( angle )

angle = f * math.pi /180 ptx6 = lat + (radius + (radius * .2)) * math.cos( angle ) pty6 = long + (radius + (radius * .2)) * math.sin( angle ) angle = g * math.pi /180 ptx7 = latx + (radius * .7) * math.cos( angle ) pty7 = longx + (radius * .7) * math.sin( angle )

angle = h * math.pi /180 ptx8 = latx + (radius * .7) * math.cos( angle ) pty8 = longx + (radius * .7) * math.sin( angle )

angle = i * math.pi /180 ptx9 = lat + (radius * 1.2) * math.cos( angle ) pty9 = long + (radius * 1.2) * math.sin( angle )

angle = j * math.pi /180 ptx10 = latx + (radius * .8) * math.cos( angle ) pty10 = longx + (radius * .8) * math.sin( angle )

angle = g * math.pi /180 ptx11 = lat + (radius * .5) * math.cos( angle ) pty11 = long + (radius * .5) * math.sin( angle )

angle = h * math.pi /180 ptx12 = lat + (radius * .5) * math.cos( angle ) pty12 = long + (radius * .5) * math.sin( angle )

angle = g * math.pi /180 ptx13 = lat + (radius * .7) * math.cos( angle ) pty13 = long + (radius * .7) * math.sin( angle )

angle = h * math.pi /180 ptx14 = lat + (radius * .7) * math.cos( angle) pty14 = long + (radius * .7) * math.sin( angle )

angle = g * math.pi /180                                 -- left right ptx15 = latxx + (radius * .7) * math.cos( angle ) pty15 = longxx + (radius * .7) * math.sin( angle )

angle = h * math.pi /180 ptx16 = latxx + (radius * .7) * math.cos( angle ) pty16 = longxx + (radius * .7) * math.sin( angle )

angle = g * math.pi /180                                 -- left right of center bottom top ptx17 = ptx5 + (radius * .5) * math.cos( angle ) pty17 = pty5 + (radius * .5) * math.sin( angle )

angle = h * math.pi /180 ptx18 = ptx5 + (radius * .5) * math.cos( angle ) pty18 = pty5 + (radius * .5) * math.sin( angle )

angle = g * math.pi /180                                 -- left right of center bottom top ptx19 = ptx6 + (radius * .5) * math.cos( angle ) pty19 = pty6 + (radius * .5) * math.sin( angle )

angle = h * math.pi /180 ptx20 = ptx6 + (radius * .5) * math.cos( angle ) pty20 = pty6 + (radius * .5) * math.sin( angle )

angle = g * math.pi /180                                 -- left right ptx21 = latxxx + (radius * .7) * math.cos( angle ) pty21 = longxxx + (radius * .7) * math.sin( angle )

angle = h * math.pi /180 ptx22 = latxxx + (radius * .7) * math.cos( angle ) pty22 = longxxx + (radius * .7) * math.sin( angle ) recx1,recy1 = string.format("%.6f",newlat(recx1)),string.format("%.6f",recy1) recx2,recy2 = string.format("%.6f",newlat(recx2)),string.format("%.6f",recy2) recx3,recy3 = string.format("%.6f",newlat(recx3)),string.format("%.6f",recy3) recx4,recy4 = string.format("%.6f",newlat(recx4)),string.format("%.6f",recy4) ptx1,pty1 = string.format("%.6f",newlat(ptx1)),string.format("%.6f",pty1) 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) ptx5,pty5 = string.format("%.6f",newlat(ptx5)),string.format("%.6f",pty5) ptx6,pty6 = string.format("%.6f",newlat(ptx6)),string.format("%.6f",pty6) ptx7,pty7 = string.format("%.6f",newlat(ptx7)),string.format("%.6f",pty7) ptx8,pty8 = string.format("%.6f",newlat(ptx8)),string.format("%.6f",pty8) ptx9,pty9 = string.format("%.6f",newlat(ptx9)),string.format("%.6f",pty9) ptx10,pty10 = string.format("%.6f",newlat(ptx10)),string.format("%.6f",pty10) ptx11,pty11 = string.format("%.6f",newlat(ptx11)),string.format("%.6f",pty11) ptx12,pty12 = string.format("%.6f",newlat(ptx12)),string.format("%.6f",pty12) ptx13,pty13 = string.format("%.6f",newlat(ptx13)),string.format("%.6f",pty13) ptx14,pty14 = string.format("%.6f",newlat(ptx14)),string.format("%.6f",pty14) ptx15,pty15 = string.format("%.6f",newlat(ptx15)),string.format("%.6f",pty15) ptx16,pty16 = string.format("%.6f",newlat(ptx16)),string.format("%.6f",pty16) ptx17,pty17 = string.format("%.6f",newlat(ptx17)),string.format("%.6f",pty17) ptx18,pty18 = string.format("%.6f",newlat(ptx18)),string.format("%.6f",pty18) ptx19,pty19 = string.format("%.6f",newlat(ptx19)),string.format("%.6f",pty19) ptx20,pty20 = string.format("%.6f",newlat(ptx20)),string.format("%.6f",pty20) ptx21,pty21 = string.format("%.6f",newlat(ptx21)),string.format("%.6f",pty21) ptx22,pty22 = string.format("%.6f",newlat(ptx22)),string.format("%.6f",pty22)

lat,long = string.format("%.6f",newlat(lat)),string.format("%.6f",long) latx,longx = string.format("%.6f",newlat(latx)),string.format("%.6f",longx) latxx,longxx = string.format("%.6f",newlat(latxx)),string.format("%.6f",longxx) latxxx,longxxx = string.format("%.6f",newlat(latxxx)),string.format("%.6f",longxxx) latcc,longcc = string.format("%.6f",newlat(latcc)),string.format("%.6f",longcc)

-- 1st basic test of initial points are set for some letters -- trying letter N TEST ok -- routine to break up letters into pieces then put them together building tables of some kind -- for each character -- letter 1 (no matter what letter it is) -- build coordinates for that letter no matter what it is ie. letter N do instructons xyz then put coordinates in array of letters -- long road to haul -- SMALLER LETTERS WOULD BE A DIFFERENT RADIUS - perhaps r*.75 - COME TO THAT AFTER WE BUILD THE CAPS - FIGURE OUT HOW TO KEEP A -- SINGLE CENTER POINT but adjusting for size looks like it might be difficult -- SINCE THERE IS NOT EXEC in SCRIBUNTO another issue arises as well - be nice to put command in array - CHECK

coordinates = ""

if boxit == "y" then if frameit[1] == nil then frameit[1] = "" ..recy4 .. "," .. recx4 .. "],[" .. recy3 .. "," .. recx3 .. "]"         frameit[2] = ",[" .. recy4 .. "," .. recx4 .. "" frameit[3] = ",[" .. recy2 .. "," .. recx2 .. "],[" .. recy1 .. "," .. recx1 .. "]" --for single letter else frameit[3] = ",[" .. recy2 .. "," .. recx2 .. "],[" .. recy1 .. "," .. recx1 .. "]"      end end

if letter == "A" then coordinates = "" .. pty3 .. "," .. ptx3 .. "],[" .. pty6 .. "," .. ptx6 .. "],[" .. pty2 .. "," .. ptx2 .. "," .. pty11 .. "," .. ptx11 .. "],[" .. pty12 .. "," .. ptx12 .. ""

elseif letter == "B" then -- KEEP OLD FOR NOW coordinates = "[" .. pty3 .. "," .. ptx3 .. "],[" .. pty4 .. "," .. ptx4 .. "],[" .. pty6 .. "," .. ptx6 .. "],[" .. pty8 .. "," .. ptx8 .. "],[" ..long .. "," .. lat .. "],[" .. pty2 .. "," .. ptx2 .. "],[" .. pty3 .. "," .. ptx3 .. "]"

coordinates = "[" .. pty3 .. "," .. ptx3 .. "],[" .. pty4 .. "," .. ptx4 .. "],[" .. pty20 .. "," .. ptx20 .. "],[" .. pty22 .. "," .. ptx22 .. "],[" .. pty8 .. "," .. ptx8 .. "],[" ..longcc .. "," .. latcc .. "],[" .. pty14 .. "," .. ptx14 .. "],[" .. pty16 .. "," .. ptx16 .. "],[" .. pty18 .. "," .. ptx18 .. "],[" .. pty3 .. "," .. ptx3 .. "]"

elseif letter == "C" then -- KEEP FOR TIME BEING coordinates = "[" .. pty2 .. "," .. ptx2 .. "],[" .. pty3 .. "," .. ptx3 .. "],[" .. pty4 .. "," .. ptx4 .. "],[" .. pty1 .. "," .. ptx1 .. "]"

coordinates = "[" .. pty16 .. "," .. ptx16 .. "],[" .. pty18 .. "," .. ptx18 .. "],[" .. pty17 .. "," .. ptx17 .. "],[" .. pty15 .. "," .. ptx15 .. "],[" .. pty21 .. "," .. ptx21 .. "],[" .. pty19 .. "," .. ptx19 .. "],[" .. pty20 .. "," .. ptx20 .. "],[" .. pty22 .. "," .. ptx22 .. "]"

elseif letter == "D" then -- KEEP FOR TIME BEING     coordinates = "[" .. pty3 .. "," .. ptx3 .. "],[" .. pty4 .. "," .. ptx4 .. "],[" .. pty6 .. "," .. ptx6 .. "],[" .. pty8 .. "," .. ptx8 .. "],[" .. pty5 .. "," .. ptx5 .. "],[" .. pty3 .. "," .. ptx3 .. "]"

coordinates = "[" .. pty3 .. "," .. ptx3 .. "],[" .. pty4 .. "," .. ptx4 .. "],[" .. pty20 .. "," .. ptx20 .. "],[" .. pty22 .. "," .. ptx22 .. "],[" .. pty16 .. "," .. ptx16 .. "],[" .. pty18 .. "," .. ptx18 .. "],[" .. pty3 .. "," .. ptx3 .. "]"

elseif letter == "E" then coordinates = "[" .. pty1 .. "," .. ptx1 .. "],[" .. pty4 .. "," .. ptx4 .. "],[" .. pty7 .. "," .. ptx7 .. "],[" .. longx .. "," .. latx .. "],[" .. pty7 .. "," .. ptx7 .. "],[" .. pty3 .. "," .. ptx3 .. "],[" .. pty2 .. "," .. ptx2 .. "]" elseif letter == "F" then coordinates = "[" .. pty1 .. "," .. ptx1 .. "],[" .. pty4 .. "," .. ptx4 .. "],[" .. pty7 .. "," .. ptx7 .. "],[" .. longx .. "," .. latx .. "],[" .. pty7 .. "," .. ptx7 .. "],[" .. pty3 .. "," .. ptx3 .. "]" elseif letter == "G" then -- KEEP FOR TIME BEING     coordinates = "[" .. pty1 .. "," .. ptx1 .. "],[" .. pty4 .. "," .. ptx4 .. "],[" .. pty3 .. "," .. ptx3 .. "],[" .. pty2 .. "," .. ptx2 .. "],[" .. pty8 .. "," .. ptx8 .. "],[" .. long .. "," .. lat .. "]"

coordinates = "[" .. pty22 .. "," .. ptx22 .. "],[" .. pty20 .. "," .. ptx20 .. "],[" .. pty19 .. "," .. ptx19 .. "],[" .. pty21 .. "," .. ptx21 .. "],[" .. pty15 .. "," .. ptx15 .. "],[" .. pty17 .. "," .. ptx17 .. "],[" .. pty2 .. "," .. ptx2 .. "],[" .. pty8 .. "," .. ptx8 .. "],[" .. long .. "," .. lat .. "]"

elseif letter == "H" then coordinates = "[" .. pty4 .. "," .. ptx4 .. "],[" .. pty3 .. "," .. ptx3 .. "],[" .. pty7 .. "," .. ptx7 .. "],[" .. pty8 .. "," .. ptx8 .. "],[" .. pty1 .. "," .. ptx1 .. "],[" .. pty2 .. "," .. ptx2 .. "]" elseif letter == "I" then -- KEEP OLD FOR TIME BEING coordinates = "[" .. pty3 .. "," .. ptx3 .. "],[" .. pty2 .. "," .. ptx2 .. "],[" .. pty5 .. "," .. ptx5 .. "],[" .. pty6 .. "," .. ptx6 .. "],[" .. pty1 .. "," .. ptx1 .. "],[" .. pty4 .. "," .. ptx4 .. "]"

coordinates = "[" .. pty19 .. "," .. ptx19 .. "],[" .. pty20 .. "," .. ptx20 .. "],[" .. pty6 .. "," .. ptx6 .. "],[" .. pty5 .. "," .. ptx5 .. "],[" .. pty17 .. "," .. ptx17 .. "],[" .. pty18 .. "," .. ptx18 .. "]"

elseif letter == "J" then -- KEEP OLD FOR TIME BEING     coordinates = "[" .. pty1 .. "," .. ptx1 .. "],[" .. pty4 .. "," .. ptx4 .. "],[" .. pty6 .. "," .. ptx6 .. "],[" .. pty5 .. "," .. ptx5 .. "],[" .. pty3 .. "," .. ptx3 .. "]"

coordinates = "[" .. pty20 .. "," .. ptx20 .. "],[" .. pty19 .. "," .. ptx19 .. "],[" .. pty6 .. "," .. ptx6 .. "],[" .. pty5 .. "," .. ptx5 .. "],[" .. pty17 .. "," .. ptx17 .. "],[" .. pty15 .. "," .. ptx15 .. "]"

elseif letter == "K" then coordinates = "[" .. pty4 .. "," .. ptx4 .. "],[" .. pty3 .. "," .. ptx3 .. "],[" .. pty7 .. "," .. ptx7 .. "],[" .. longx .. "," .. latx .. "],[" .. pty1 .. "," .. ptx1 .. "],[" .. longx .. "," .. latx .. "],[" .. pty2 .. "," .. ptx2 .. "]" elseif letter == "L" then coordinates = "[" .. pty2 .. "," .. ptx2 .. "],[" .. pty3 .. "," .. ptx3 .. "],[" .. pty4 .. "," .. ptx4 .. "]" elseif letter == "M" then coordinates = "[" .. pty3 .. "," .. ptx3 .. "],[" .. pty4 .. "," .. ptx4 .. "],[" .. longx .. "," .. latx .. "],[" .. pty1 .. "," .. ptx1 .. "],[".. pty2 .. "," .. ptx2 .. "]" elseif letter == "N" then coordinates = "[" .. pty3 .. "," .. ptx3 .. "],[" .. pty4 .. "," .. ptx4 .. "],[" .. pty2 .. "," .. ptx2 .. "],[".. pty1 .. "," .. ptx1 .. "],[" .. pty1 .. "," .. ptx1 .. "]" elseif letter == "O" then -- KEEP OLD FOR TIME BEING     coordinates = "[" .. pty1 .. "," .. ptx1 .. "],[" .. pty2 .. "," .. ptx2 .. "],[" .. pty3 .. "," .. ptx3 .. "],[" .. pty4 .. "," .. ptx4 .. "],[" .. pty1 .. "," .. ptx1 .. "]"

coordinates = "[" .. pty22 .. "," .. ptx22 .. "],[" .. pty20 .. "," .. ptx20 .. "],[" .. pty19 .. "," .. ptx19 .. "],[" .. pty21 .. "," .. ptx21 .. "],[" .. pty15 .. "," .. ptx15 .. "],[" .. pty17 .. "," .. ptx17 .. "],[" .. pty18 .. "," .. ptx18 .. "],[" .. pty16 .. "," .. ptx16 .. "],[" .. pty22 .. "," .. ptx22 .. "]"

elseif letter == "P" then -- KEEP OLD FOR TIME BEING     coordinates = "[" .. pty3 .. "," .. ptx3 .. "],[" .. pty4 .. "," .. ptx4 .. "],[" .. pty1 .. "," .. ptx1 .. "],[" .. pty8 .. "," .. ptx8 .. "],[" .. pty7 .. "," .. ptx7 .. "]"

coordinates = "[" .. pty3 .. "," .. ptx3 .. "],[" .. pty4 .. "," .. ptx4 .. "],[" .. pty20 .. "," .. ptx20 .. "],[" .. pty22 .. "," .. ptx22 .. "],[" .. pty8 .. "," .. ptx8 .. "],[" .. pty7 .. "," .. ptx7 .. "]"

elseif letter == "Q" then

-- KEEP OLD FOR TIME BEING     coordinates = "" .. pty1 .. "," .. ptx1 .. "],[" .. pty2 .. "," .. ptx2 .. "],[" .. pty3 .. "," .. ptx3 .. "],[" .. pty4 .. "," .. ptx4 .. "],[" .. pty1 .. "," .. ptx1 .. "," .. pty9 .. "," .. ptx9 .. "],[" .. pty10 .. "," .. ptx10 .. "" coordinates = "" .. pty22 .. "," .. ptx22 .. "],[" .. pty20 .. "," .. ptx20 .. "],[" .. pty19 .. "," .. ptx19 .. "],[" .. pty21 .. "," .. ptx21 .. "],[" .. pty15 .. "," .. ptx15 .. "],[" .. pty17 .. "," .. ptx17 .. "],[" .. pty18 .. "," .. ptx18 .. "],[" .. pty16 .. "," .. ptx16 .. "],[" .. pty22 .. "," .. ptx22 .. "," .. pty9 .. "," .. ptx9 .. "],[" .. pty10 .. "," .. ptx10 .. ""

elseif letter == "R" then -- KEEP OLD FOR TIME BEING     coordinates = "[" .. pty3 .. "," .. ptx3 .. "],[" .. pty4 .. "," .. ptx4 .. "],[" .. pty1 .. "," .. ptx1 .. "],[" .. pty8 .. "," .. ptx8 .. "],[" .. pty7 .. "," .. ptx7 .. "],[" .. longx .. "," .. latx .. "],[" .. pty2 .. "," .. ptx2 .. "]"

coordinates = "[" .. pty3 .. "," .. ptx3 .. "],[" .. pty4 .. "," .. ptx4 .. "],[" .. pty20 .. "," .. ptx20 .. "],[" .. pty22 .. "," .. ptx22 .. "],[" .. pty8 .. "," .. ptx8 .. "],[" .. pty7 .. "," .. ptx7 .. "],[" .. longx .. "," .. latx .. "],[" .. pty2 .. "," .. ptx2 .. "]"

elseif letter == "S" then

-- KEEP FOR TIME BEING    coordinates = "[" .. pty1 .. "," .. ptx1 .. "],[" .. pty4 .. "," .. ptx4 .. "],[" .. pty7 .. "," .. ptx7 .. "],[" .. long .. "," .. lat .. "],[" .. pty2 .. "," .. ptx2 .. "],[" .. pty3 .. "," .. ptx3 .. "]"

coordinates = "[" .. pty22 .. "," .. ptx22 .. "],[" .. pty1 .. "," .. ptx1 .. "],[" .. pty19 .. "," .. ptx19 .. "],[" .. pty21 .. "," .. ptx21 .. "],[" .. pty7 .. "," .. ptx7 .. "],[" .. pty14 .. "," .. ptx14 .. "],[" .. pty2 .. "," .. ptx2 .. "],[" .. pty17 .. "," .. ptx17 .. "],[" .. pty15 .. "," .. ptx15 .. "]"

elseif letter == "T" then coordinates = "[" .. pty1 .. "," .. ptx1 .. "],[" .. pty4 .. "," .. ptx4 .. "],[" .. pty6 .. "," .. ptx6 .. "],[" .. pty5 .. "," .. ptx5 .. "]"

elseif letter == "U" then coordinates = "[" .. pty1 .. "," .. ptx1 .. "],[" .. pty2 .. "," .. ptx2 .. "],[" .. pty3 .. "," .. ptx3 .. "],[" .. pty4.. "," .. ptx4 .. "]" elseif letter == "V" then coordinates = "[" .. pty1 .. "," .. ptx1 .. "],[" .. pty5 .. "," .. ptx5 .. "],[" .. pty4 .. "," .. ptx4 .. "],[" .. pty4 .. "," .. ptx4 .. "]" elseif letter == "W" then coordinates = "[" .. pty1 .. "," .. ptx1 .. "],[" .. pty2 .. "," .. ptx2 .. "],[" .. longx .. "," .. latx .. "],[" .. pty3 .. "," .. ptx3 .. "],[" .. pty4 .. "," .. ptx4 .. "]" elseif letter == "X" then coordinates = "" .. pty1 .. "," .. ptx1 .. "],[" .. pty3 .. "," .. ptx3 .. "," .. pty4 .. "," .. ptx4 .. "],[" .. pty2 .. "," .. ptx2 .. "" elseif letter == "Y" then coordinates = "[" .. pty1 .. "," .. ptx1 .. "],[" .. longx .. "," .. latx .. "],[" .. pty5 .. "," .. ptx5 .. "],[" .. longx .. "," .. latx .. "],[" .. pty4 .. "," .. ptx4 .. "]" elseif letter == "Z" then coordinates = "[" .. pty4 .. "," .. ptx4 .. "],[" .. pty1 .. "," .. ptx1 .. "],[" .. pty3 .. "," .. ptx3 .. "],[" .. pty2 .. "," .. ptx2 .. "]"

elseif letter == "_" then coordinates = "[" .. pty2 .. "," .. ptx2 .. "],[" .. pty3 .. "," .. ptx3 .. "]"

elseif letter == "-" then coordinates = "[" .. pty12 .. "," .. ptx12 .. "],[" .. pty11 .. "," .. ptx11 .. "]"

elseif letter == "0" then -- KEEP FOR TIME BEING     coordinates = "[".. pty1 .. "," .. ptx1 .. "],[" .. pty2 .. "," .. ptx2 .. "],[" .. pty3 .. "," .. ptx3 .. "],[" .. pty4 .. "," .. ptx4 .. "],[" .. pty1 .. "," .. ptx1 .. "],[" .. pty3 .. "," .. ptx3 .. "]"

coordinates = "" .. pty22 .. "," .. ptx22 .. "],[" .. pty20 .. "," .. ptx20 .. "],[" .. pty19 .. "," .. ptx19 .. "],[" .. pty21 .. "," .. ptx21 .. "],[" .. pty15 .. "," .. ptx15 .. "],[" .. pty17 .. "," .. ptx17 .. "],[" .. pty18 .. "," .. ptx18 .. "],[" .. pty16 .. "," .. ptx16 .. "],[" .. pty22 .. "," .. ptx22 .. "," .. pty1 .. "," .. ptx1 .. "],[" .. pty3 .. "," .. ptx3 .. ""

elseif letter == "1" then coordinates = "[" .. pty7 .. "," .. ptx7 .. "],[" .. pty6 .. "," .. ptx6 .. "],[" .. pty5 .. "," .. ptx5 .. "],[" .. pty3 .. "," .. ptx3 .. "],[" .. pty2 .. "," .. ptx2 .. "]"

elseif letter == "2" then -- KEEP OLD FOR TIME BEING     coordinates = "[" .. pty4 .. "," .. ptx4 .. "],[" .. pty6 .. "," .. ptx6 .. "],[" .. pty8 .. "," .. ptx8 .. "],[" .. pty3 .. "," .. ptx3 .. "],[" .. pty2 .. "," .. ptx2 .."]"

coordinates = "[" .. pty4 .. "," .. ptx4 .. "],[" .. pty20 .. "," .. ptx20 .. "],[" .. pty22 .. "," .. ptx22 .. "],[" .. pty8 .. "," .. ptx8 .. "],[" .. pty13 .. "," .. ptx13 .. "],[" .. pty15 .. "," .. ptx15 .. "],[" .. pty3 .. "," .. ptx3 .. "],[" .. pty2 .. "," .. ptx2 .."]"

elseif letter == "3" then -- KEEP OLD FOR NOW coordinates = "[" .. pty4 .. "," .. ptx4 .. "],[" .. pty1 .. "," .. ptx1 .. "],[" .. longx .. "," .. latx .. "],[" .. pty8 .. "," .. ptx8 .. "],[" .. pty2 .. "," .. ptx2 .. "],[" .. pty3 .. "," .. ptx3 .. "]"

coordinates = "[" .. pty4 .. "," .. ptx4 .. "],[" .. pty1 .. "," .. ptx1 .. "],[" .. longx .. "," .. latx .. "],[" .. pty14 .. "," .. ptx14 .. "],[" .. pty2 .. "," .. ptx2 .. "],[" .. pty3 .. "," .. ptx3 .. "]"

elseif letter == "4" then coordinates = "[" .. pty2 .. "," .. ptx2 .. "],[" .. pty1 .. "," .. ptx1 .. "],[" .. pty13 .. "," .. ptx13 .. "],[" .. pty14 .. "," .. ptx14 .. "]"

elseif letter == "5" then coordinates = "[" .. pty1 .. "," .. ptx1 .. "],[" .. pty4 .. "," .. ptx4 .. "],[" .. pty7 .. "," .. ptx7 .. "],[" .. pty8 .. "," .. ptx8 .. "],[" .. pty2 .. "," .. ptx2 .. "],[" .. pty3 .. "," .. ptx3 .. "]"

elseif letter == "6" then -- KEEP FOR TIME BEING     coordinates = "[" .. pty7 .. "," .. ptx7 .. "],[" .. pty8 .. "," .. ptx8 .. "],[" .. pty2 .. "," .. ptx2 .. "],[" .. pty3 .. "," .. ptx3 .. "],[" .. pty4 .. "," .. ptx4 .. "]"

coordinates = "[" .. pty13 .. "," .. ptx13 .. "],[" .. pty14 .. "," .. ptx14 .. "],[" .. pty2 .. "," .. ptx2 .. "],[" .. pty3 .. "," .. ptx3 .. "],[" .. pty21 .. "," .. ptx21 .. "],[" .. pty19 .. "," .. ptx19 .. "],[" .. pty6 .. "," .. ptx6 .. "]"

elseif letter == "7" then -- KEEP OLD FOR TIME BEING     coordinates = "[" .. pty4 .. "," .. ptx4 .. "],[" .. pty1 .. "," .. ptx1 .. "],[" .. long .. "," .. lat .. "],[" .. pty5 .. "," .. ptx5 .. "]"

coordinates = "" .. pty4 .. "," .. ptx4 .. "],[" .. pty1 .. "," .. ptx1 .. "],[" .. long .. "," .. lat .. "],[" .. pty5 .. "," .. ptx5 .. "," .. pty11 .. "," .. ptx11 .. "],[" .. pty12 .. "," .. ptx12 .. ""

elseif letter == "8" then -- KEEP OLD FOR TIME BEING   coordinates = "[" .. pty4 .. "," .. ptx4 .. "],[" .. pty1 .. "," .. ptx1 .. "],[" .. longx .. "," .. latx .. "],[" .. pty2 .. "," .. ptx2 .. "],[" .. pty3 .. "," .. ptx3 .. "],[" .. longx .. "," .. latx .. "],[" .. pty4 .. "," .. ptx4 .. "]"

coordinates = "[" .. pty19 .. "," .. ptx19 .. "],[" .. pty20 .. "," .. ptx20 .. "],[" .. pty22 .. "," .. ptx22 .. "],[" .. pty8 .. "," .. ptx8 .. "],[" .. longcc .. "," .. latcc .. "],[" .. pty14 .. "," .. ptx14 .. "],[" .. pty16 .. "," .. ptx16 .. "],[" .. pty18 .. "," .. ptx18 .. "],[" .. pty17 .. "," .. ptx17 .. "],[" .. pty15 .. "," .. ptx15 .. "],[" .. pty13 .. "," .. ptx13 .. "],[" .. longcc .. "," .. latcc .. "],[" .. pty7 .. "," .. ptx7 .. "],[" .. pty21 .. "," .. ptx21 .. "],[" .. pty19 .. "," .. ptx19 .. "]"

elseif letter == "9" then coordinates = "[" .. pty8 .. "," .. ptx8 .. "],[" .. pty7 .. "," .. ptx7 .. "],[" .. pty4 .. "," .. ptx4 .. "],[" .. pty1 .. "," .. ptx1 .. "],[" .. pty8 .. "," .. ptx8 .. "],[" .. pty5 .. "," .. ptx5 .. "]"

elseif letter == "(" then -- KEEP OLD FOR TIME BEING     coordinates = "[" .. pty1 .. "," .. ptx1 .. "],[" .. longx .. "," .. latx .. "],[" .. long .. "," .. lat .. "],[" .. pty2 .. "," .. ptx2 .. "]"

coordinates = "[" .. pty1 .. "," .. ptx1 .. "],[" .. longx .. "," .. latx .. "],[" .. long .. "," .. lat .. "],[" .. pty2 .. "," .. ptx2 .. "]"

elseif letter == ")" then -- KEEP OLD FOR TIME BEING coordinates = "[" .. pty4 .. "," .. ptx4 .. "],[" .. longx .. "," .. latx .. "],[" .. long .. "," .. lat .. "],[" .. pty3 .. "," .. ptx3 .. "]"

coordinates = "[" .. pty4 .. "," .. ptx4 .. "],[" .. longx .. "," .. latx .. "],[" .. long .. "," .. lat .. "],[" .. pty3 .. "," .. ptx3 .. "]"

factor = 1

elseif letter == "[" then coordinates = "[" .. pty1 .. "," .. ptx1 .. "],[" .. pty6 .. "," .. ptx6 .. "],[" .. pty5 .. "," .. ptx5 .. "],[" .. pty2 .. "," .. ptx2 .. "]"

elseif letter == "]" then coordinates = "[" .. pty4 .. "," .. ptx4 .. "],[" .. pty6 .. "," .. ptx6 .. "],[" .. pty5 .. "," .. ptx5 .. "],[" .. pty3 .. "," .. ptx3 .. "]"     factor = 1

elseif letter == "<" then -- KEEP FOR TIME BEING     coordinates = "[" .. pty1 .. "," .. ptx1 .. "],[" .. long .. "," .. lat .. "],[" .. pty2 .. "," .. ptx2 .. "]"    coordinates = "[" .. pty22 .. "," .. ptx22 .. "],[" .. pty13 .. "," .. ptx13 .. "],[" .. pty18 .. "," .. ptx18 .. "]"

elseif letter == ">" then -- KEEP FOR TIME BEING coordinates = "[" .. pty4 .. "," .. ptx4 .. "],[" .. long .. "," .. lat .. "],[" .. pty3 .. "," .. ptx3 .. "]"     coordinates = "[" .. pty21 .. "," .. ptx21 .. "],[" .. pty14 .. "," .. ptx14 .. "],[" .. pty17 .. "," .. ptx17 .. "]"

factor = 1

elseif letter == "/" then coordinates = "[" .. pty1 .. "," .. ptx1 .. "],[" .. pty3 .. "," .. ptx3 .. "]"

elseif letter == "." then -- BUILD LATER coordinates = "[" .. pty17 .. ",".. ptx17 .. "],[" .. pty17 .. "," .. ptx17 .. "]"

elseif letter == "@" then coordinates = coordinates

elseif letter == " " then coordinates = coordinates factor = 1.75

elseif letter == ":" then coordinates = "" .. longx .. "," .. latx .. "],[" .. longx .. "," .. latx .. "," .. long .. "," .. lat .. "],[" .. long .. "," .. lat .. "" end

if combinedcoords == "" then combinedcoords = coordinates elseif coordinates ~= "" then combinedcoords = combinedcoords .. "],[" .. coordinates end

if string.find(letternow,'%l') == 1 and (string.find(letterafter,'%u') == 1 or string.find(letterafter,'%d') == 1) then radius = radius2 factor = 2 end lat = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180) angle = 90 * math.pi /180 ptxnew = lat + (radius * factor) * math.cos( angle ) ptynew = long + (radius * factor) * math.sin( angle )

lat,long = string.format("%.6f",newlat(ptxnew)),string.format("%.6f",ptynew) factor = 2 end

coordinates = combinedcoords

if boxit == "y" then boxcoordinates = '{ "type": "FeatureCollection", "features": [ {"type": "Feature","geometry": {"type":"LineString", "coordinates":' .. frameit[1] .. frameit[3] .. frameit[2] .. '},"properties":{ "title": "", "description": "", "stroke":"#000000", "stroke-width":1 }},' end

if string.match(coordinates,'%]%]%,%[%[') then part1a = string.gsub(part1a,'LineString','MultiLineString') coordinates = "[" .. coordinates .. "]"       end part1b = string.gsub(part1b,'%"stroke%-width%"%:1','"stroke-width":3') coordinates = '[' .. coordinates .. ']},'	coordinates = string.gsub(coordinates,'%[%[%[%[','[')	coordinates = string.gsub(coordinates,'%]%]%]%]',']') coordinates = string.gsub(coordinates,',%[%[%[',',') -- TROUBLE SHOOT LATER	coordinates = string.gsub(coordinates,'%]%]%],',',')

if boxit == "y" then part1a = string.gsub(part1a,'{"type": "Feature"',boxcoordinates .. '{"type": "Feature"') part1b = string.gsub(part1b,' ',']} ') end

coordinates = part1a .. coordinates .. part1b

return coordinates

end -- House

function p.house(frame) local shape = "house" local id = frame.args['id']	or "" 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 'house' local title = frame.args['title'] or 'A house' local description = frame.args['desc'] or '' 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" checkhex(fill,stroke) local marker = frame.args['marker'] or "no" if marker == nil or marker == "" then marker = "no" end 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 = 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 angle5,angle6,angle7,angle8 = 0,0,0,0 local ptx,ptx2,ptx3,ptx4 = 0,0,0,0 local ptx5,ptx6,ptx7,ptx8 = 0,0,0,0 local pty,pty2,pty3,pty4 = 0,0,0,0 local pty5,pty6,pty7,pty8 = 0,0,0,0 local a = 360 local b = 270 local c = 270 local d = 240 local e = 120 local f = 90 local g = 90 local h = 360 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+r/3) * math.cos( angle2 ) pty2 = long + (r+r/3) * 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*1.20) * math.cos( angle4 ) pty4 = long + (r*1.20) * math.sin( angle4 )

angle5 = e * math.pi /180 ptx5 = lat + (r*1.20) * math.cos( angle5 ) pty5 = long + (r*1.20) * math.sin( angle5 ) angle6 = f * math.pi /180 ptx6 = lat + r * math.cos( angle6 ) pty6 = long + r * math.sin( angle6 ) angle7 = g * math.pi /180 ptx7 = lat + (r+r/3) * math.cos( angle7 ) pty7 = long + (r+r/3) * math.sin( angle7 ) angle8 = h * math.pi /180 ptx8 = lat + r * math.cos( angle8 ) pty8 = long + r * math.sin( angle8 ) 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) ptx5,pty5 = string.format("%.6f",newlat(ptx5)),string.format("%.6f",pty5) ptx6,pty6 = string.format("%.6f",newlat(ptx6)),string.format("%.6f",pty6) ptx7,pty7 = string.format("%.6f",newlat(ptx7)),string.format("%.6f",pty7) ptx8,pty8 = string.format("%.6f",newlat(ptx8)),string.format("%.6f",pty8) lat,long = string.format("%.6f",newlat(lat)),string.format("%.6f",long)

coordinates = "[" .. pty .. "," .. ptx .. "],[" .. pty2 .. "," .. ptx2 .. "],["       coordinates = coordinates .. pty3 .. "," .. ptx3 .. "],[".. pty4 .. "," .. ptx4 .. "],["      coordinates = coordinates .. pty5 .. "," .. ptx5 .. "],[".. pty6 .. "," .. ptx6 .. "],["       coordinates = coordinates .. pty7 .. "," .. ptx7 .. "],[".. pty8 .. "," .. ptx8 .. "],["               coordinates = coordinates .. pty .. "," .. ptx .. "]"

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

if marker == "yes" or marker == "y" then coordinates = coordinates .. '\n* \n' end

return coordinates

end -- x - draw 2 lines to make an X

function p.x(frame)

local shape = "x" local id = frame.args['id'] or "" local lat = frame.args['lat'] or "" local long = frame.args['long'] or "" local r = frame.args['radius'] or 2 if id == "" or id == nil 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 'other' local title = frame.args['title'] or 'X'       local description = frame.args['desc'] or "" if description == nil then description = "" end local fill = "#000000" local stroke = frame.args['stroke'] or "#ffccaa" if string.len(stroke) ~= 7 then error("Incorrect length for argument color!") 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 color!") end local strokewidth = frame.args['strokewidth'] or "3" local mapframe = frame.args['mapframe'] or "no" if mapframe == nil or mapframe == "" then mapframe = "no" end local a,b,c,d = 315,135,45,225 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

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 )

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) local coords = "" coords = ptx .. "," .. pty .. "@" .. ptx2 .. "," .. pty2 .. "@" .. ptx3 .. "," .. pty3 .. "@" .. ptx4 .. "," .. pty4 -- if coords ~= "" then return coords end local separator = "@" local coordsx = {} local coordinates = "" local count = 1

local type = "line" for str in string.gmatch(coords,"([^"..separator.."]+)") do		         if str ~= nil and str ~= "" then lat = string.gsub(str,",.*",'') long = string.gsub(str,"^.*,",'') 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 coordsx[count] = string.format("%.6f",long) .. "," .. string.format("%.6f",lat) count = count + 1 end end

local mod = math.mod(table.getn(coordsx),2) if mod == 1 then error("Need even number of matching coordinates!") end --       local i = 1 --       for i = 1,table.getn(coordsx),1 do --          coordinates = coordinates .. "[" .. coordsx[i] .. "]@@@@@" --         i = i + 1 --         coordinates = coordinates .. "[" .. coordsx[i] .. "]]@@@@@[" --        --          if i == table.getn(coordsx) then break end --       end for k,v in ipairs(coordsx) do if math.mod(k,2) == 1 then coordinates = coordinates .. "[" .. v .. "]@@@@@" else coordinates = coordinates .. "[" .. v .. "]]@@@@@[" end end

coordinates = string.gsub(coordinates,"@@@@@",",") coordinates = string.gsub(coordinates,"%],%[$",'') coordinates = string.gsub(coordinates, '%,$','') -- if coordinates ~= "" then return coordinates end local part1a = ' \n'

local part2a = '\n{"type": "FeatureCollection",\n\t"features":' part2a = part2a .. '[\n\t\t{\n\t\t"type": "Feature",\n\t\t"geometry": { \n\t"type":"MultiLineString",\n\t"coordinates":\n\t\t'

local part2b = '\n\t"properties":{\n\t\t"title": "' .. title .. '",\n' part2b = part2b .. '\t\t"description": "' .. description .. '",\n\t\t' part2b = part2b .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":' .. strokewidth .. ',\n\t\t\t' part2b = part2b .. '}\n}]}\n \n'

-- No Polygons just MultiLineString

if mapframe == "y" or mapframe == "yes" then coordinates = '' .. coordinates .. '},' coordinates = part2a .. coordinates .. part2b else coordinates = '' .. coordinates .. '},' coordinates = part1a .. coordinates .. part1b end

-- No Markers unless wanted can code - could end up with a few or large amount of markers

return coordinates

end

-- END MODULE

return p