-- keeping original shape for a circle -- Matroc -- other shapes etc. moved to a Sandbox  local p = {}  local function newlat(a) -- newlat = math.log(math.tan((90 + a) * math.pi / 360)) / (math.pi / 180) -- worked this code elsewhere in function can remove    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       -- straight line at top of map   if newlatitude < -89.5 then point = -89.5 end -- END if     -- straight line at bottom of map   return newlatitude 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 -- 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 part1a = '<maplink class="no-icon" text="" latitude="' .. lat .. '" longitude="' .. long .. '" '         local part1a = part1a .. 'zoom="5" group="' .. group .. '">\n{"type": "Feature","geometry":\t{"coordinates":\n'          local part2a = '\n\t\t"type":"LineString"},\n\t"properties":{\n\t\t"title": "' .. title .. '",\n'         local part2a = part2a .. '\t\t"description": "' .. description .. '",\n'         local part2a = part2a .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":1\n}}\n</maplink>\n'          local part1b = '<maplink class="no-icon" text="" latitude="' .. lat .. '" longitude="' .. long .. '" '         local part1b = part1b .. 'zoom="5" group="' .. group .. '">\n{"type": "Feature","geometry":\t{"coordinates":\n'          local part2b = '\n\t\t"type":"Polygon"},\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 part1c = '<mapframe text="" latitude="' .. lat .. '" longitude="' .. long .. '" '         local part1c = part1c .. '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": {"coordinates":\n'          local part2ca = '\n\t\t"type":"LineString"},\n\t"properties":{\n\t\t"title": "' .. title .. '",\n'         local part2ca = part2ca .. '\t\t"description": "' .. description .. '",\n\t\t"fill": "' .. fill .. '",\n'         local part2ca = part2ca .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":1\n}\n}]}\n</mapframe>\n'                  local part2cb = '\n\t\t"type":"Polygon"},\n\t"properties":{\n\t\t"title": "' .. title .. '",\n'         local part2cb = part2cb .. '\t\t"description": "' .. description .. '",\n\t\t"fill": "' .. fill .. '",\n'         local part2cb = part2cb .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":1\n}\n}]}\n</mapframe>\n'           return part1a,part2a,part1b,part2b,part1c,part2ca,part2cb 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 -- END if -- I set this as a default - function will not handle the polar circles yet will still handle areas within the majority of a map         if tonumber(long) > 180 or tonumber(long) < -180 then         	error("Longitude must be between 180 and -180!") end -- END if -- this will draw a full circle at 0 lat and 180 long         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"   -- default         -- radius of 10 is approx. 500 km - futz with sizes - below 3 would probably be adequate         -- .1 is about 20km - .0001 is about 30 m                 r = tonumber(r)                 if r > 10 then error("10 for radius is MAX") end   -- END if - my default                 if r <= 0 then error("radius has to be greater than 0") end -- END if         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 -- END if          local part1a,part2a,part1b,part2b,part1c,part2ca,part2cb = 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 -- END if ELSEIF          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 -- END if          if tonumber(x) <= -10.5 then           ptx = newlat(ptx) -- makes correction to make circle show up on map - lower latitudes         end -- END if            data[i] = '[' .. string.format("%.6f",pty) .. "," .. string.format("%.6f",ptx) .. ']'         end -- END for          for i = 5,359, 5 do                 data[i] = data[i] .. "@@@@@"         end -- END for  -- cycle through array and build single string of all coordinates to be output          for i = 1,360, 1 do                coordinates = coordinates .. data[i]         end -- END for          coordinates = coordinates.gsub(coordinates,'%]%[','],[')         coordinates = coordinates.gsub(coordinates,'%]@@@@@%[','],\n[')         coordinates = "[" .. coordinates .. ',' .. data[1] .. "],"          -- close the circle extra precautionary measure          if mapframe == "y" or mapframe == "yes" then 			if type == "poly" then                 coordinates  = string.gsub(coordinates,'%]%,$',']],')                 coordinates = part1c .. string.gsub(coordinates,'^%[','[[') .. part2cb 			else                 coordinates = part1c .. coordinates .. part2ca 			end -- END if 		else 			if type == "poly" then                 coordinates  = string.gsub(coordinates,'%]%,$',']],')                 coordinates = part1b .. string.gsub(coordinates,'^%[','[[') .. part2b 			else                 coordinates = part1a .. coordinates .. part2a 			end -- END if		 		 		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    -- END MODULE   return p