Module:Sandbox/Matroc/Mapdraw

From Wikivoyage
Jump to navigation Jump to search
[view] [edit] [history] [purge] Documentation

Documentation removed.

-- 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 = '<maplink class="no-icon" text="" latitude="' .. lat .. '" longitude="' .. long .. '" '
        local part1a = part1a .. 'zoom="5" group="' .. group .. '">\n{"type": "Feature","geometry": {"type":"LineString", "coordinates":\n'

--        local part1b = '\n\t"properties":{' .. xprogcomment .. '\t\t"title": "' .. title .. '",\n'
--        local part1b = part1b .. '\t\t"description": "' .. description .. '",\n'
--        local part1b = part1b .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":1\n}}\n</maplink>\n'
       local part1b = '\n\t"properties":{\n\t\t"title": "' .. title .. '",\n'
       local part1b = part1b .. '\t\t"description": "' .. description .. '",\n'
       local part1b = part1b .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":1\n}}\n</maplink>\n'

        local part2a = '<maplink class="no-icon" text="" latitude="' .. lat .. '" longitude="' .. long .. '" '
        local part2a = part2a .. 'zoom="5" group="' .. group .. '">\n{"type": "Feature","geometry": { "type":"Polygon", \t"coordinates":\n'

--        local part2b = '\n\t"properties":{' .. xprogcomment .. '\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</maplink>\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</maplink>\n'

        local part3a = '<mapframe text="" latitude="' .. lat .. '" longitude="' .. long .. '" '
        local part3a = part3a .. 'zoom="5" group="' .. group .. '" width="600" height="400" >\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</mapframe>\n' 
        local part3b = '\n\t"properties":{\n\t\t"title": "' .. title .. '",\n'
        local part3b = part3b .. '\t\t"description": "' .. description .. '",\n'
        local part3b = part3b .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":1\n}\n}]}\n</mapframe>\n' 

        local part4a = '<mapframe text="" latitude="' .. lat .. '" longitude="' .. long .. '" '
        local part4a = part4a .. 'zoom="5" group="' .. group .. '" width="600" height="400" >\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</mapframe>\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</mapframe>\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* {{marker|type=vicinity|name=Center Circle|lat=' .. lat .. "|long=" .. long .. '}}\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 < 3 or 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* {{marker|type=vicinity|name=Center Multi-sided shape|lat=' .. latitude .. "|long=" .. long .. '}}\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* {{marker|type=vicinity|name=Center Rectangle|lat=' .. lat .. "|long=" .. long .. '}}\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* {{marker|type=vicinity|name=Center Box|lat=' .. lat .. "|long=" .. long .. '}}\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* {{marker|type=vicinity|name=Center Boxframe|lat=' .. lat .. "|long=" .. long .. '}}\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* {{marker|type=vicinity|name=Center Triangle|lat=' .. lat .. "|long=" .. long .. '}}\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* {{marker|type=vicinity|name=Center Equitri|lat=' .. lat .. "|long=" .. long .. '}}\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* {{marker|type=vicinity|name=Center Ellipse|lat=' .. lat .. "|long=" .. long .. '}}\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* {{marker|type=vicinity|name=Center Star|lat=' .. lat .. "|long=" .. long .. '}}\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* {{marker|type=vicinity|name=Center Pointer|lat=' .. ptx4 .. "|long=" .. pty4 .. '}}\n'
          coordinates = coordinates .. '\n* {{marker|type=vicinity|name=Points to Position|lat=' .. latitude .. "|long=" .. longitude .. '}}\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* {{marker|type=vicinity|name=Center Pentagon|lat=' .. lat .. "|long=" .. long .. '}}\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* {{marker|type=vicinity|name=Center Hexagon|lat=' .. lat .. "|long=" .. long .. '}}\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* {{marker|type=vicinity|name=Begin line|lat=' .. string.format("%.6f",lat1) .. "|long=" .. string.format("%.6f",long1) .. '}}\n'
                coordinates = coordinates .. '\n* {{marker|type=vicinity|name=End line|lat=' .. string.format("%.6f",lat2) .. "|long=" .. string.format("%.6f",long2) .. '}}\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* {{marker|type=vicinity|name=Center Diamond|lat=' .. lat .. "|long=" .. long .. '}}\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* {{marker|type=vicinity|name=Center Kite|lat=' .. lat .. "|long=" .. long .. '}}\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* {{marker|type=vicinity|name=Center Crescent|lat=' .. newcenterx .. "|long=" .. newcentery .. '}}\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* {{marker|type=vicinity|name=Center Star(2)|lat=' .. lat .. "|long=" .. long .. '}}\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* {{marker|type=vicinity|name=Center Hexagram|lat=' .. lat .. "|long=" .. long .. '}}\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* {{marker|type=vicinity|name=Center Octagon|lat=' .. lat .. "|long=" .. long .. '}}\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<mapframe text="" latitude="'
output = output .. latitude .. '" longitude="' .. longitude .. '" zoom="8" width="900" height="400" group="mask" class="no-icon"'
output = output .. 'align="center">\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</mapframe>'
     end

    if mapframe == "y" and mapshape == "y" then
output = output .. '\n<mapframe text="" latitude="'
output = output .. latitude .. '" longitude="' .. longitude .. '" zoom="8" width="900" height="400" group="mapshape" class="no-icon"'
output = output .. ' align="center">\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</mapframe>'
    end

    if maplink == "y" and mask == "y" then
output = output .. '\n<maplink text="" latitude="' .. latitude .. '" longitude="' .. longitude ..'" zoom="8" group="mask"'
output = output .. ' class="no-icon" align="center">\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[[-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 mask",\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</maplink>'
    end

    if maplink == "y" and mapshape == "y" then
output = output .. '\n<maplink text="" latitude="' .. latitude .. '" longitude="' .. longitude .. '" zoom="8" group="mapshape"'
output = output .. ' class="no-icon" align="center">\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":2\n}\n}]}'
output = output .. '\n</maplink>'

    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* {{marker|type=vicinity|name=Center BBox|lat=' .. lat .. "|long=" .. long .. '}}\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* {{marker|type=vicinity|name=HalfCircle|lat=' .. lat .. "|long=" .. long .. '}}\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* {{marker|type=vicinity|name=Center Decagon|lat=' .. lat .. "|long=" .. long .. '}}\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* {{marker|type=vicinity|name=Center Annulus|lat=' .. lat .. "|long=" .. long .. '}}\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* {{marker|type=vicinity|name=Center Rhombus|lat=' .. lat .. "|long=" .. long .. '}}\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* {{marker|type=vicinity|name=Wedge|lat=' .. ptx2 .. "|long=" .. pty2 .. '}}\n'
          coordinates = coordinates .. '\n* {{marker|type=vicinity|name=Wedge|lat=' .. latitude .. "|long=" .. longitude .. '}}\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* {{marker|type=vicinity|name=Center Cross|lat=' .. lat .. "|long=" .. long .. '}}\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* {{marker|type=vicinity|name=Center X|lat=' .. lat .. "|long=" .. long .. '}}\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* {{marker|type=vicinity|name=Center Bar | lat=' .. lat .. "|long=" .. long .. '}}\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 < 10 or 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* {{marker|type=vicinity|name=Center Dot | lat=' .. lat .. "|long=" .. long .. '}}\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* {{marker|type=vicinity|name=Center Keystone | lat=' .. lat .. "|long=" .. long .. '}}\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* {{marker|type=vicinity|name=Center Cog | lat=' .. lat .. "|long=" .. long .. '}}\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 = '<maplink text="" zoom="5" latitude="' .. lat .. '" longitude="' .. long .. '" group="cities" class=no-icon>\n'
        part1a = part1a .. '\t{\n\t"type": "Feature",\n\t\t"geometry": { "type":"MultiPoint", "coordinates":\n\t\t\t'

        local part1b = '\n\t"properties": {\n\t\t"title": "' .. title .. '",\n\t\t'
        part1b = part1b .. '"description": "' .. description .. '",\n\t\t"marker-color": "' .. color .. '",\n\t\t'
        part1b = part1b .. '"marker-size": "medium",\n\t\t"marker-symbol": "' .. symbol .. '",\n\t\t\t'
        part1b = part1b .. '}\n}</maplink>\n'

        local part2a = '<mapframe text="" latitude="' .. lat .. '" longitude="' .. long .. '" '
        part2a = part2a .. 'zoom="5" group="' .. group .. '" width="600" height="400" >\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</mapframe>\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* {{marker|type=vicinity|name=Center Arrow | lat=' .. lat .. "|long=" .. long .. '}}\n' .. '\n* {{marker|type=vicinity|name=Points To | lat=' .. latitude .. "|long=" .. longitude .. '}}\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* {{marker|type=vicinity|name=Center Pentagram|lat=' .. lat .. "|long=" .. long .. '}}\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 = '<maplink class="no-icon" text="" latitude="' .. lat .. '" longitude="' .. long .. '" '
        local part1a = part1a .. 'zoom="5" group="' .. group .. '">\n{"type": "Feature","geometry":'
        local part1a = part1a .. '{ \n\t"type":"MultiLineString",\n\t"coordinates":\n'

        local part1b = '\n\t"properties":{\n\t\t"title": "' .. title .. '",\n'
        local part1b = part1b .. '\t\t"description": "' .. description .. '",\n'
        local part1b = part1b .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":1\n}}\n</maplink>\n'

        local part2a = '<mapframe text="" latitude="' .. lat .. '" longitude="' .. long .. '" '
        part2a = part2a .. 'zoom="5" group="' .. group .. '" width="600" height="400" >\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</mapframe>\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 < 10 or 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* {{marker|type=vicinity|name=Center Sun|lat=' .. latitude .. "|long=" .. long .. '}}\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* {{marker|type=vicinity|name=Center Stadium|lat=' .. lat .. "|long=" .. long .. '}}\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<maplink text=""  group="' .. group .. '" class=no-icon>'
           route = route .. '\n{'
           route = route .. '\n\t"type": "Feature",'
           route = route .. '\n\t"geometry":'
           route = route .. '\n\t{"coordinates":'
           route = route .. '\n\t[[' .. coordinates .. ']],'
--           route = route .. '\n\t' .. coordinates
--           route = route ..'\n]],'
           route= route .. '\n\t"type":"LineString"},'
           route = route .. '\n\t"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}}</maplink>\n'
else
           route = route .. '\n<mapframe text="' .. text .. '" latitude=' .. lat .. ' longitude=' .. long
           route = route .. ' zoom=' .. zoom .. ' width=' .. width .. ' height=' .. height .. ' group=' .. group .. ' show=' .. show .. ">"
           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}}}</mapframe>\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 .. '<maplink text="" latitude="' .. lat .. '" longitude="' .. long .. '" zoom="5" width="600" height="500" group="mask" class="no-icon">\n'
output = output .. '\t{\n'
output = output .. '\t"type": "ExternalData",\n'
output = output .. '\t"properties": {\n'
output = output .. '\t"title": "' .. title .. '",\n'
output = output .. '"description": "' .. description .. '",\n'
output = output .. '\t"fill": "' .. fill .. '",\n'
output = output .. '\t"fill-opacity": 0.2,\n'
output = output .. '\t"stroke": "#4d4d4d",\n'
output = output .. '\t"stroke-width": 1\n'
output = output .. '\t},\n'
output = output .. '\t"service": "' .. type .. '",\n'
output = output .. '\t"ids": "' .. id .. '"\n'
output = output .. '}\n'
output = output .. '</maplink>'	

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 < 1 or 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* {{marker|type=vicinity|name=Triangle X|lat=' .. lat .. "|long=" .. long .. '}}\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,'</maplink>',']}</maplink>')
        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* {{marker|type=vicinity|name=Center House|lat=' .. lat .. "|long=" .. long .. '}}\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 = '<maplink class="no-icon" text="" latitude="' .. lat .. '" longitude="' .. long .. '" '
        local part1a = part1a .. 'zoom="5" group="' .. group .. '">\n{"type": "Feature","geometry":'
        local part1a = part1a .. '{ \n\t"type":"MultiLineString",\n\t"coordinates":\n'

        local part1b = '\n\t"properties":{\n\t\t"title": "' .. title .. '",\n'
        local part1b = part1b .. '\t\t"description": "' .. description .. '",\n'
        local part1b = part1b .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":' .. strokewidth .. '\n}}\n</maplink>\n'

        local part2a = '<mapframe text="" latitude="' .. lat .. '" longitude="' .. long .. '" '
        part2a = part2a .. 'zoom="5" group="' .. group .. '" width="600" height="400" >\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</mapframe>\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