Sandbox/Matroc/Mapdraw2
From Halal Explorer
< Module:Sandbox/MatrocDocumentation for this module may be created at Module:Sandbox/Matroc/Mapdraw2/doc
Script error: Lua error: Cannot create process: proc_open(/dev/null): Failed to open stream: Operation not permitted
-- This is an experimental module by Matroc - 1/11/2018 -- Used in conjunction with template that is making use of {{#tag:mapframe}} and {{#tag:maplink}} -- Will change name as more shapes further developed.... -- Conversion of some of the Mapshapes for general use and further development probably desired by more skilled -- Scribunto - Lua programmers -- Shapes built using different coding approaches thus need to combine and simplify as much as possible -- Probably change coordinates to data or something like that. -- NEED TO WORK OUT USING lat and long if lat and long not found in wikidata in Module and template as well -- Latitude and Longitude are recalculated to position correctly for mercator type maps - thus can draw shapes -- without curvature distortion. -- 26 Aug -- many wikidata entries do not have lat long - if lat and long are provided as parameters then -- going to get around getting the coordinates by putting those parameters 1st then wikidata lat long -- JSON errors will still happen - at least this is a work around getting so that they can be corrected local p = {} -- CONVERT NEWLATITTUDE local function newlat(a) newlatitude = 180/math.pi * (2 * math.atan(math.exp( a * math.pi/180)) - math.pi/2 ) if newlatitude > 89.5 then point = 89.5 end -- END if if newlatitude < -89.5 then point = -89.5 end -- END if return newlatitude end -- GET LATITUDE local function latitude(wikidata) local latitude = "" local entity = mw.wikibase.getEntityObject(wikidata) if entity == nil then error("Wikidata ID " .. wikidata .. " not found!") end local claims = entity.claims if claims == nil then error("Wikidata ID found No Data!") end if claims.P625 ~= nil then latitude = entity.claims.P625[1].mainsnak.datavalue.value.latitude return latitude end if latitude == "" then error("Latitude not found in Wikidata!") end return latitude end -- GET LONGITUDE -- P625 local function longitude(wikidata) local longitude = "" local entity = mw.wikibase.getEntityObject(wikidata) if entity == nil then error("Wikidata ID " .. wikidata .. " not found!") end local claims = entity.claims if claims == nil then error("Wikidata ID found No Data!") end if claims.P625 ~= nil then longitude = entity.claims.P625[1].mainsnak.datavalue.value.longitude return longitude end if longitude == "" then error("Longitude not found in Wikidata!") end return longitude end -- TEST ADD LEFT _ RIGHT _ CENTER for Description local function aligndesc(description,descattr) if description ~= nil and description ~= "" then if descattr == "l" then description = "<div style='font-size:14px; text-align:left;'>" .. description .. "</div>" elseif descattr == "r" then description = "<div style='font-size:14px; text-align:right;'>" .. description .. "</div>" elseif descattr == "c" then description = "<div style='font-size:14px; text-align:center;'>" .. description .. "</div>" else description = description end end description = string.gsub(description,'"','\\"') -- change " to \" for Kartographer return description end -- TESTING ADDING fillopacity,strokeopacity and strokewidth FUTURE local function partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) -- Maplink content LineString local part1a = '\n{"type": "Feature","geometry": {"type":"LineString", "coordinates":\n' local part1b = '\n\t"properties":{\n\t\t"title": "' .. title .. '",\n' local part1b = part1b .. '\t\t"description": "' .. description .. '",\n' local part1b = part1b .. '\t\t"stroke-opacity":' .. strokeopacity .. ',\n' local part1b = part1b .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":' .. strokewidth .. '\n}}\n' -- Maplink content Polygon local part2a = '\n{"type": "Feature","geometry": { "type":"Polygon", \t"coordinates":\n' local part2b = '\n\t"properties":{\n\t\t"title": "' .. title .. '",\n' local part2b = part2b .. '\t\t"description": "' .. description .. '",\n\t\t"fill": "' .. fill .. '",\n' local part2b = part2b .. '\t\t"fill-opacity":' .. fillopacity .. ',\n' local part2b = part2b .. '\t\t"stroke-opacity":' .. strokeopacity .. ',\n' local part2b = part2b .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":' .. strokewidth .. '\n}}\n' -- Mapframe content LineString local part3a = '\n{"type": "FeatureCollection",\n\t"features": [\n\t\t{\n\t\t"type": "Feature",\n\t\t"geometry": {\n\t\t"type":"LineString", "coordinates":\n' local part3b = '\n\t"properties":{\n\t\t"title": "' .. title .. '",\n' local part3b = part3b .. '\t\t"description": "' .. description .. '",\n' local part3b = part3b .. '\t\t"stroke-opacity":' .. strokeopacity .. ',\n' local part3b = part3b .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":' .. strokewidth .. '\n}\n}]}\n' -- Mapframe content Polygon local part4a = '\n{"type": "FeatureCollection",\n\t"features": [\n\t\t{\n\t\t"type": "Feature",\n\t\t"geometry": {\n\t\t"type":"Polygon", "coordinates":\n' local part4b = '\n\t"properties": {\n\t\t"title": "' .. title .. '",\n' local part4b = part4b .. '\t\t"description": "' .. description .. '",\n\t\t"fill": "' .. fill .. '",\n' local part4b = part4b .. '\t\t"fill-opacity":' .. fillopacity .. ',\n' local part4b = part4b .. '\t\t"stroke-opacity":' .. strokeopacity .. ',\n' local part4b = part4b .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":' .. strokewidth .. '\n}\n}]}\n' return part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b end local function parts(lat,long,group,title,description,fill,stroke) -- local xprogcomment = '\n\t\t"__xprogcomment__" : "Mapdraw",\n\t\t"__xprogcomment__date__" : "' .. os.date("%m/%d/%Y -- %I:%M:%S") .. '",\n' -- ERROR SPOT PART1A MAYBE AS THIS WAS MISSING PIECE PROBABLY DELETED SOMEWHERE DURING DEVELOPMENT -- WILL HAVE TO TEST VARIOUS PIECES TO INSURE THIS HAS BEEN CORRECTED -- Put together content for template -- Maplink content LineString local part1a = '\n{"type": "Feature","geometry": {"type":"LineString", "coordinates":\n' local part1b = '\n\t"properties":{\n\t\t"title": "' .. title .. '",\n' local part1b = part1b .. '\t\t"description": "' .. description .. '",\n' local part1b = part1b .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":1\n}}\n' -- Maplink content Polygon local part2a = '\n{"type": "Feature","geometry": { "type":"Polygon", \t"coordinates":\n' local part2b = '\n\t"properties":{\n\t\t"title": "' .. title .. '",\n' local part2b = part2b .. '\t\t"description": "' .. description .. '",\n\t\t"fill": "' .. fill .. '",\n' local part2b = part2b .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":1\n}}\n' -- Mapframe content LineString local part3a = '\n{"type": "FeatureCollection",\n\t"features": [\n\t\t{\n\t\t"type": "Feature",\n\t\t"geometry": {\n\t\t"type":"LineString", "coordinates":\n' local part3b = '\n\t"properties":{\n\t\t"title": "' .. title .. '",\n' local part3b = part3b .. '\t\t"description": "' .. description .. '",\n' local part3b = part3b .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":1\n}\n}]}\n' -- Mapframe content Polygon local part4a = '\n{"type": "FeatureCollection",\n\t"features": [\n\t\t{\n\t\t"type": "Feature",\n\t\t"geometry": {\n\t\t"type":"Polygon", "coordinates":\n' local part4b = '\n\t"properties": {\n\t\t"title": "' .. title .. '",\n' local part4b = part4b .. '\t\t"description": "' .. description .. '",\n\t\t"fill": "' .. fill .. '",\n' local part4b = part4b .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":1\n}\n}]}\n' return part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b end -- For other functions if to be added from original Module Mapdraw local function positions(shape) local positions = {} 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['cross'] = {15,45,75,105,135,165,195,225,255,285,315,345} positions['xshape'] = {30,60,90,120,150,180,210,240,270,300,330,360} positions['bar'] = {90,270} positions['keystone'] = {35,26,55,160,200,305,334,325} positions['cog'] = {45,90,135,180,225,270,315,360} positions['quad'] = {360,90,180,270} positions['arrow'] = {360,45,90,135,180,225,270,315} positions['pentagram'] = {360,144,288,72,216} return positions[shape] end -- FUTURE CHANGE TO CHECK AND IF NEED BE CREATE DEFAULT fill AND stroke local function checkhex(fill,stroke) if string.len(fill) ~= 7 then error("Incorrect length for argument fill!") end if string.gsub(fill,"#[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]","") ~= "" then error("Incorrect hexidecimal format for argument fill!") end if string.len(stroke) ~= 7 then error("Incorrect length for argument stroke!") end if string.gsub(stroke,"#[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]","") ~= "" then error("Incorrect hexidecimal format for argument stroke!") end end local function checkid(id) id = string.gsub(id,"q","Q") id = string.gsub(id,"%s+","") if string.gsub(id,"^[Q]%d+$","") ~= "" then error("Bad format for parameter id!") end -- return id end -- Several variants of code being concatted depending upon the shape - only used for p.arrow right now local function putittogether(mapframe,type,part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b,coordinates) if mapframe == "y" or mapframe == "yes" then if type == "poly" then coordinates = '[[' .. coordinates .. ']]},' coordinates = part4a .. coordinates .. part4b else coordinates = '[' .. coordinates .. ']},' coordinates = part3a .. coordinates .. part3b end else if type == "poly" then coordinates = '[[' .. coordinates .. ']]},' coordinates = part2a .. coordinates .. part2b else coordinates = '[' .. coordinates .. ']},' coordinates = part1a .. coordinates .. part1b end end return coordinates end function p.id(frame) -- if frame.args[1]~=nil and frame.args[1]~='' then -- return frame.args[1] -- end local arg1 = frame.args[1] local entity = mw.wikibase.getEntityObject(arg1) -- local entity = mw.wikibase.getEntityObject() if entity == nil then return end return entity.id end -- GET LATITUDE -- P625 as standalone function function p.latitude(frame) -- if frame.args[1]~=nil and frame.args[1]~='' then -- return frame.args[1] -- end local latitude = "" local arg1 = frame.args[1] local entity = mw.wikibase.getEntityObject(arg1) -- local entity = mw.wikibase.getEntityObject() if entity == nil then return latitude end local claims = entity.claims if claims == nil then return latitude end if claims.P625 ~= nil then latitude = entity.claims.P625[1].mainsnak.datavalue.value.latitude return latitude end return latitude end -- GET LONGITUDE -- P625 as standalone function function p.longitude(frame) -- if frame.args[1]~=nil and frame.args[1]~='' then -- return frame.args[1] -- end local longitude = "" local arg1 = frame.args[1] local entity = mw.wikibase.getEntityObject(arg1) -- local entity = mw.wikibase.getEntityObject() if entity == nil then return longitude end local claims = entity.claims if claims == nil then return longitude end if claims.P625 ~= nil then longitude = entity.claims.P625[1].mainsnak.datavalue.value.longitude return longitude end return longitude end -- ARROW -- only creates a Polygon with a stroke thickness of 3 and fill-opacity of 1.0 function p.arrow(frame) local shape = "arrow" local id = frame.args['id'] or "" local lat,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 string.gsub(direction,"^[1-8]$","") ~= "" then direction="1" end if tonumber(direction) < 1 or tonumber(direction) > 8 then direction = "1" end direction = tonumber(direction) local group = frame.args['group'] or 'arrow' local title = frame.args['title'] or 'An arrow' local description = frame.args['desc'] or '' local descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) local r = frame.args['radius'] or ".5" r = tonumber(r) if r > 10 then error("10 for length is MAX") end -- exception for bar only if r <= 0 then error("r has to be greater than 0") end local r2 = r * .50 local r3 = r * .475 local fill = frame.args['fill'] or "#000000" -- fill arg - default is black if fill == nil or fill == "" then fill = "#000000" end local stroke = frame.args['stroke'] or "#000000" -- stroke arg - default is black if stroke == nil or stroke == "" then stroke = fill end local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end local coordinates = "" local type = frame.args['type'] or "poly" -- default is polygon if type ~= "poly" then type = "line" end local angle,ptx,pty = 0,0,0 local compass = positions(shape) local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) -- local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke) lat = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180) angle = (compass[direction]) * math.pi / 180 ptx = lat - (r*1.05) * math.cos( angle ) pty = long - (r*1.05) * math.sin( angle ) lat,long = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) lat = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180) local matrix = {} -- 1 angle = (compass[direction] - 18) * math.pi / 180 ptx = lat + r2 * math.cos( angle ) pty = long + r2 * math.sin( angle ) ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) matrix[1] = "[" .. pty .. "," .. ptx .. "]@@@@@" -- 2 angle = compass[direction] * math.pi / 180 ptx = lat + r * math.cos( angle ) pty = long + r * math.sin( angle ) ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) matrix[2] = "[" .. pty .. "," .. ptx .. "]@@@@@" --3 angle = (compass[direction] + 18) * math.pi / 180 ptx = lat + r2 * math.cos( angle ) pty = long + r2 * math.sin( angle ) ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) matrix[3] = "[" .. pty .. "," .. ptx .. "]@@@@@" -- 4 angle = (compass[direction] - 2) * math.pi / 180 ptx = lat + r3 * math.cos( angle ) pty = long + r3 * math.sin( angle ) ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) matrix[4] = "[" .. pty .. "," .. ptx .. "]@@@@@" -- 5 angle = (compass[direction] + 181) * math.pi / 180 ptx = lat + r * math.cos( angle ) pty = long + r * math.sin( angle ) ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) matrix[5] = "[" .. pty .. "," .. ptx .. "]@@@@@" -- 6 angle = (compass[direction] + 179) * math.pi / 180 ptx = lat + r * math.cos( angle ) pty = long + r * math.sin( angle ) ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) matrix[6] = "[" .. pty .. "," .. ptx .. "]@@@@@" -- 7 angle = (compass[direction] + 2) * math.pi / 180 ptx = lat + r3 * math.cos( angle ) pty = long + r3 * math.sin( angle ) ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) matrix[7] = "[" .. pty .. "," .. ptx .. "]@@@@@" for i=1,table.getn(matrix),1 do coordinates = coordinates .. matrix[i] end coordinates = coordinates .. matrix[1] coordinates = string.gsub(coordinates,'@@@@@$','') coordinates = string.gsub(coordinates,'@@@@@',',') lat = string.format("%.6f",newlat(lat)) coordinates = putittogether(mapframe,type,part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b,coordinates) -- Make thickness of 3 coordinates = string.gsub(coordinates,'stroke%-width%":1','fill-opacity": 1.0,\n\t\t"stroke-width":4') return coordinates end -- BOX - Square function p.box(frame) local shape = frame.args['box'] or "box" local id = frame.args['id'] or "" local lat,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 descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) local name = frame.args['name'] or "A Center Box" local r = frame.args['radius'] or ".5" r = tonumber(r) if r > 10 then error("10 for radius is MAX") end if r <= 0 then error("r has to be greater than 0") end local fill = frame.args['fill'] or "#ccef64" local stroke = frame.args['stroke'] or "#0000ff" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end local coordinates = "" local type = frame.args['type'] or "line" -- default line for LineString if type ~= "line" then type = "poly" end local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) -- local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke) lat = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180) local angle1,angle2,angle3,angle4 = 0,0,0,0 local ptx,ptx2,ptx3,ptx4 = 0,0,0,0 local pty,pty2,pty3,pty4 = 0,0,0,0 local a = 45 local b = 135 local c = 225 local d = 315 angle1 = a * math.pi / 180 ptx = lat + r * math.cos( angle1 ) pty = long + r * math.sin( angle1 ) angle2 = b * math.pi /180 ptx2 = lat + r * math.cos( angle2 ) pty2 = long + r * math.sin( angle2 ) angle3 = c * math.pi /180 ptx3 = lat + r * math.cos( angle3 ) pty3 = long + r * math.sin( angle3 ) angle4 = d * math.pi /180 ptx4 = lat + r * math.cos( angle4 ) pty4 = long + r * math.sin( angle4 ) ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) ptx2,pty2 = string.format("%.6f",newlat(ptx2)),string.format("%.6f",pty2) ptx3,pty3 = string.format("%.6f",newlat(ptx3)),string.format("%.6f",pty3) ptx4,pty4 = string.format("%.6f",newlat(ptx4)),string.format("%.6f",pty4) lat,long = string.format("%.6f",newlat(lat)),string.format("%.6f",long) coordinates = "[" .. pty .. "," .. ptx .. "],[" .. pty2 .. "," .. ptx2 .. "],[" .. pty3 .. "," .. ptx3 .. "],[".. pty4 .. "," .. ptx4 .. "],[" .. pty .. "," .. ptx .. "]" coordinates = putittogether(mapframe,type,part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b,coordinates) return coordinates end -- EQUITRI function p.equitri(frame) local shape = "equitri" local id = frame.args['id'] or "" local lat,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 descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) local r = frame.args['radius'] or ".5" r = tonumber(r) if r > 10 then error("10 for radius is MAX") end if r <= 0 then error("r has to be greater than 0") end r = r * 2 local fill = frame.args['fill'] or "#ccef64" local stroke = frame.args['stroke'] or "#0000ff" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end local coordinates = "" local type = frame.args['type'] or "line" -- default line for LineString if type ~= "line" then type = "poly" end local direction = frame.args['direction'] or "1" if direction == nil or direction == "" then direction="1" end if string.gsub(direction,"^[1-4]$","") ~= "" then direction="1" end -- direction = string.gsub(direction,"%..*","") direction = tonumber(direction) if direction <= 0 or direction >=5 then error("direction should be a number from 1 to 4!") end local factors = {} factors[1] = "360,120,240" factors[2] = "90,210,330" factors[3] = "180,300,60" factors[4] = "270,150,30" local points = factors[direction] a = string.gsub(points,'%,.*$','') b = string.gsub(points,'(%d+%,)(%d+)(%,%d+)',"%2") c = string.gsub(points,'^.*,','') local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) -- local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke) lat = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180) angle1 = a * math.pi / 180 ptx = lat + r * math.cos( angle1 ) pty = long + r * math.sin( angle1 ) angle2 = b * math.pi /180 ptx2 = lat + r * math.cos( angle2 ) pty2 = long + r * math.sin( angle2 ) angle3 = c * math.pi /180 ptx3 = lat + r * math.cos( angle3 ) pty3 = long + r * math.sin( angle3 ) ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) ptx2,pty2 = string.format("%.6f",newlat(ptx2)),string.format("%.6f",pty2) ptx3,pty3 = string.format("%.6f",newlat(ptx3)),string.format("%.6f",pty3) lat,long = string.format("%.6f",newlat(lat)),string.format("%.6f",long) coordinates = "[" .. pty .. "," .. ptx .. "],[" .. pty2 .. "," .. ptx2 .. "],[" .. pty3 .. "," .. ptx3 .. "],[" .. pty .. "," .. ptx .. "]" coordinates = putittogether(mapframe,type,part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b,coordinates) return coordinates end -- STAR -- to be reworked for vertical placement of top of star function p.star(frame) local shape = "star" local id = frame.args['id'] or "" local lat,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 descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) local radius = frame.args['radius'] or ".5" radius = tonumber(radius) if radius > 10 then error("10 for radius is MAX") end if radius <= 0 then error("radius has to be greater than 0") end local radius2 = radius * 3; local fill = frame.args['fill'] or "#ccef64" local stroke = frame.args['stroke'] or "#0000ff" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end -- FUTURE USE latitude = math.log(math.tan((90 + latitude) * math.pi/360)) / (math.pi/180) local ra,angle = 0,0 local points = {} local coordinates = "" local type = frame.args['type'] or "line" -- default line for LineString if type ~= "line" then type = "poly" end local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) -- local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke) for i = 1,10, 1 do mod = math.mod(i,2) if mod == 1 then ra = radius else ra = radius2 end angle = ((2 * math.pi / 10)) * i points[i] = '[' .. string.format("%.6f",longitude + (ra * math.cos(angle))) .. "," points[i] = points[i] .. string.format("%.6f",newlat(latitude + (ra * math.sin(angle)))) .. "]," end for i = 1,10, 1 do coordinates = coordinates .. points[i] .. "\n" end coordinates = coordinates .. points[1] if mapframe == "y" or mapframe == "yes" then if type == "poly" then coordinates = string.gsub(coordinates,'%]%,$',']]]},') coordinates = part4a .. string.gsub(coordinates,'^%[','[[[') .. part4b else coordinates = string.gsub(coordinates,'%]%,$',']]},') coordinates = part3a .. string.gsub(coordinates,'^%[','[[') .. part3b end else if type == "poly" then coordinates = string.gsub(coordinates,'%]%,$',']]]},') coordinates = part2a .. string.gsub(coordinates,'^%[','[[[') .. part2b else coordinates = string.gsub(coordinates,'%]%,$',']]},') coordinates = part1a .. string.gsub(coordinates,'^%[','[[') .. part1b end end return coordinates end -- STAR2 -- reworked star pointing North function p.star2(frame) local shape = "star2" local id = frame.args['id'] or "" local lat,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 descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) local radius = frame.args['radius'] or ".5" radius = tonumber(radius) if radius > 10 then error("10 for radius is MAX") end if radius <= 0 then error("radius has to be greater than 0") end local radius2 = radius * 3; local fill = frame.args['fill'] or "#ccef64" local stroke = frame.args['stroke'] or "#0000ff" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end -- FUTURE USE local ra,angle,ptx,pty = 0,0,0,0 local compass = {} local points = {} local coordinates = "" local type = frame.args['type'] or "line" -- default line for LineString if type ~= "line" then type = "poly" end local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) -- local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke) x = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180) compass = positions(shape) for i = 1,table.getn(compass), 1 do mod = math.mod(i,2) if mod == 1 then r = radius else r = radius2 end angle = compass[i] * math.pi / 180 ptx = x + r * math.cos( angle ) pty = y + r * math.sin( angle ) ptx = newlat(ptx) points[i] = '[' .. string.format("%.6f",pty) .. pty .. "," .. string.format("%.6f",ptx) .. "]," end for i = 1,table.getn(points), 1 do coordinates = coordinates .. points[i] .. "\n" end coordinates = coordinates .. points[1] if mapframe == "y" or mapframe == "yes" then if type == "poly" then coordinates = string.gsub(coordinates,'%]%,$',']]]},') coordinates = part4a .. string.gsub(coordinates,'^%[','[[[') .. part4b else coordinates = string.gsub(coordinates,'%]%,$',']]},') coordinates = part3a .. string.gsub(coordinates,'^%[','[[') .. part3b end else if type == "poly" then coordinates = string.gsub(coordinates,'%]%,$',']]]},') coordinates = part2a .. string.gsub(coordinates,'^%[','[[[') .. part2b else coordinates = string.gsub(coordinates,'%]%,$',']]},') coordinates = part1a .. string.gsub(coordinates,'^%[','[[') .. part1b end end return coordinates end -- MULTISIDE - create multi-sided regular polygon - if number of sides > 20 can use to replace circle with its 360 points function p.multiside(frame) local shape = "multiside" local sides = frame.args['sides'] or "3" if sides == nil or sides == "" then sides = "3" end sides = tonumber(sides) if sides < 3 or sides > 360 then sides = 3 end -- as number of sides grow - can use to make a rough circle above 20 local increment = 360/sides local inbetween = increment/2 local id = frame.args['id'] or "" id = string.gsub(id,"%,+","@") id = string.gsub(id,"%s+",'') id = string.gsub(id,"%@+",'@') local lat = frame.args['lat'] or "" local long = frame.args['long'] or "" local matrix = {} local coordinates = "" local count = 1 local type = frame.args['type'] or "line" if type ~= "poly" then type = "line" end if id == nil or id == "" then if lat == "" or lat == nil then error("Missing argument lat!") end if long == "" or long == nil then error("Missing argument long!") end if tonumber( lat ) > 90 or tonumber( lat ) < -90 then error("Latitudes must be between 90 and -90!") end if tonumber(long) > 180 or tonumber(long) < -180 then error("Longitudes must be between 180 and -180!") end else id = checkid(id) lat = latitude(id) long = longitude(id) end local r = frame.args['radius'] or ".5" r = tonumber(r) if r > 10 then error("10 for radius is MAX") end if r <= 0 then error("r has to be greater than 0") end local group = frame.args['group'] or 'multiside' local title = frame.args['title'] or 'A Multi-sided shape' local description = frame.args['desc'] or "" local descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) if description == nil then description = "" end local fill = frame.args['fill'] or "#ffff00" local stroke = frame.args['stroke'] or "#000000" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nil or mapframe == "" then mapframe = "no" end local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) -- local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke) local angle,ptx,pty = 0,0,0 local latitude = lat lat = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180) local count = 0 for i = increment,360, increment do angle = (i + inbetween) * math.pi / 180 ptx = lat + r * math.cos( angle ) pty = long + r * math.sin( angle ) ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) count = count + 1 matrix[count] = "[" .. pty .. "," .. ptx .. "]@@@@@" end for i = 1,table.getn(matrix), 1 do coordinates = coordinates .. matrix[i] end coordinates = coordinates .. matrix[1] coordinates = string.gsub(coordinates,"@@@@@",",") coordinates = string.gsub(coordinates,",$",'') coordinates = putittogether(mapframe,type,part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b,coordinates) return coordinates end -- ELLIPSE function p.ellipse(frame) local shape = "ellipse" local id = frame.args['id'] or "" local 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 descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) local r = frame.args['radius'] or ".5" r = tonumber(r) if r > 10 then error("10 for radius is MAX") end if r <= 0 then error("radius has to be greater than 0") end local fill = frame.args['fill'] or "#ccef64" local stroke = frame.args['stroke'] or "#0000ff" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end -- FUTURE USE local direction = frame.args['direction'] or "h" if direction == nil or direction == "" then direction = "h" end if direction ~= "v" then direction = "h" end -- if not v (ie. other garbage then force direction to be h) local data = {} local coordinates = "" local ptx,pty,angle = 0,0,0 local type = frame.args['type'] or "line" -- default line for LineString if type ~= "line" then type = "poly" end local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) -- local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke) if tonumber(x) >= 10.5 then x = math.log(math.tan((90 + x) * math.pi/360)) / (math.pi/180) elseif tonumber(x) <= -10.5 then x = math.log(math.tan((90 + x) * math.pi/360)) / (math.pi/180) end for i = 1, 360 do angle = i * math.pi / 180 ptx = x + r * math.cos( angle ) if direction == "v" then pty = y - 0.5 * r * math.sin( angle ) -- for ellipse vertical elseif direction == "h" then pty = y + 2.0 * r * math.sin(angle) -- for ellipse horizontal end if tonumber(x) >= 10.5 then ptx = newlat(ptx) -- makes correction to make ellipse show up on map end if tonumber(x) <= -10.5 then ptx = newlat(ptx) -- makes correction to make ellipse show up on map end data[i] = '[' .. string.format("%.6f",pty) .. "," .. string.format("%.6f",ptx) .. ']' end for i = 5,359, 5 do data[i] = data[i] .. "@@@@@" end for i = 1,360, 1 do coordinates = coordinates .. data[i] end coordinates = coordinates.gsub(coordinates,'%]%[','],[') coordinates = coordinates.gsub(coordinates,'%]@@@@@%[','],\n[') coordinates = "[" .. coordinates .. ',' .. data[1] .. "]," if mapframe == "y" or mapframe == "yes" then if type == "poly" then coordinates = string.gsub(coordinates,'%]%,$',']]},') coordinates = part4a .. string.gsub(coordinates,'^%[','[[') .. part4b else coordinates = string.gsub(coordinates,'%]%,$',']},') coordinates = part3a .. coordinates .. part3b end else if type == "poly" then coordinates = string.gsub(coordinates,'%]%,$',']]},') coordinates = part2a .. string.gsub(coordinates,'^%[','[[') .. part2b else coordinates = string.gsub(coordinates,'%]%,$',']},') coordinates = part1a .. coordinates .. part1b end end return coordinates end -- BOX FRAME function p.boxframe(frame) local shape = "box" local id = frame.args['id'] or "" local lat,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 descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) local r = frame.args['radius'] or ".5" r = tonumber(r) if r > 10 then error("10 for radius is MAX") end if r <= 0 then error("r has to be greater than 0") end local r2 = r * .85 local fill = frame.args['fill'] or "#ccef64" local stroke = frame.args['stroke'] or "#0000ff" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end local coordinates = "" local type = frame.args['type'] or "line" -- default line for LineString if type ~= "line" then type = "poly" end -- line to become MultiLineString local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) -- local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke) lat = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180) local angle1,angle2,angle3,angle4 = 0,0,0,0 local ptx,ptx2,ptx3,ptx4 = 0,0,0,0 local pty,pty2,pty3,pty4 = 0,0,0,0 local ptxa,ptxb,ptxc,ptxd = 0,0,0,0 local ptya,ptyb,ptyc,ptyd = 0,0,0,0 local a = 45 local b = 135 local c = 225 local d = 315 angle1 = a * math.pi / 180 ptx,ptxa = lat + r * math.cos( angle1 ),lat + r2 * math.cos( angle1 ) pty,ptya = long + r * math.sin( angle1 ),long + r2 * math.sin( angle1 ) angle2 = b * math.pi /180 ptx2,ptxb = lat + r * math.cos( angle2 ),lat + r2 * math.cos( angle2 ) pty2,ptyb = long + r * math.sin( angle2 ),long + r2 * math.sin( angle2 ) angle3 = c * math.pi /180 ptx3,ptxc = lat + r * math.cos( angle3 ),lat + r2 * math.cos( angle3 ) pty3,ptyc = long + r * math.sin( angle3 ),long + r2 * math.sin( angle3 ) angle4 = d * math.pi /180 ptx4,ptxd = lat + r * math.cos( angle4 ),lat + r2 * math.cos( angle4 ) pty4,ptyd = long + r * math.sin( angle4 ),long + r2 * math.sin( angle4 ) ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) ptx2,pty2 = string.format("%.6f",newlat(ptx2)),string.format("%.6f",pty2) ptx3,pty3 = string.format("%.6f",newlat(ptx3)),string.format("%.6f",pty3) ptx4,pty4 = string.format("%.6f",newlat(ptx4)),string.format("%.6f",pty4) ptxa,ptya = string.format("%.6f",newlat(ptxa)),string.format("%.6f",ptya) ptxb,ptyb = string.format("%.6f",newlat(ptxb)),string.format("%.6f",ptyb) ptxc,ptyc = string.format("%.6f",newlat(ptxc)),string.format("%.6f",ptyc) ptxd,ptyd = string.format("%.6f",newlat(ptxd)),string.format("%.6f",ptyd) lat,long = string.format("%.6f",newlat(lat)),string.format("%.6f",long) coordinates = "[" .. pty .. "," .. ptx .. "],[" .. pty2 .. "," .. ptx2 .. "],[" .. pty3 .. "," .. ptx3 .. "],[".. pty4 .. "," .. ptx4 .. "],[" .. pty .. "," .. ptx .. "]" coordinates = coordinates .. "],[" .. "[" .. ptya .. "," .. ptxa .. "],[" .. ptyb .. "," .. ptxb .. "],[" .. ptyc .. "," .. ptxc .. "],[".. ptyd .. "," .. ptxd .. "],[" .. ptya .. "," .. ptxa .. "]" if mapframe == "y" or mapframe == "yes" then if type == "poly" then coordinates = '[[' .. coordinates .. ']]},' coordinates = part4a .. coordinates .. part4b else coordinates = '[[' .. coordinates .. ']]},' coordinates = part3a .. coordinates .. part3b coordinates = string.gsub(coordinates,'"type":"LineString"','"type":"MultiLineString"') end else if type == "poly" then coordinates = '[[' .. coordinates .. ']]},' coordinates = part2a .. coordinates .. part2b else coordinates = '[[' .. coordinates .. ']]},' coordinates = part1a .. coordinates .. part1b coordinates = string.gsub(coordinates,'"type":"LineString"','"type":"MultiLineString"') end end return coordinates end -- CRESCENT function p.crescent(frame) local shape = "crescent" local id = frame.args['id'] or "" local lat,long = "","" local x,y,x2,y2 = 0,0,0,0 local newcenterx,newcentery = 0,0 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 descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) local r = frame.args['radius'] or ".5" r = tonumber(r) if r > 10 then error("10 for radius is MAX") end if r <= 0 then error("radius has to be greater than 0") end local fill = frame.args['fill'] or "#ccef64" local stroke = frame.args['stroke'] or "#0000ff" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end -- FUTURE USE local data = {} local data2 = {} local coordinates = "" local coordinates2 = "" local ptx,pty,angle,ptx2,pty2 = 0,0,0,0,0 local type = frame.args['type'] or "line" -- default line for LineString if type ~= "line" then type = "poly" end local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) -- local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke) x = math.log(math.tan((90 + x) * math.pi/360)) / (math.pi/180) x2 = x y2 = y for i = 1, 360 do angle = i * math.pi / 180 ptx = x + r * math.cos( angle ) pty = y + 1.5 * r * math.sin(angle) -- for ellipse horizontal ptx2 = x2 + r * math.cos (angle) pty2 = y2 + r * math.sin (angle) if i == 90 then newcenterx = x + r * math.cos( angle ) newcentery = y + 1.25 * r * math.sin (angle) newcenterx = newlat(newcenterx) newcenterx = string.format("%.6f",newcenterx) newcentery = string.format("%.6f",newcentery) end ptx = newlat(ptx) -- makes correction to make ellipse show up on map ptx2 = newlat(ptx2) data[i] = '[' .. string.format("%.6f",pty) .. "," .. string.format("%.6f",ptx) .. ']' data2[i] = '[' .. string.format("%.6f",pty2) .. "," .. string.format("%.6f",ptx2) .. ']' end for i = 5,360, 5 do data[i] = data[i] .. "@@@@@" data2[i] = data2[i] .. "@@@@@" end for i = 1,180, 1 do coordinates = coordinates .. data[i] end for i = 180,1, -1 do coordinates2 = coordinates2 .. data2[i] end coordinates = coordinates .. coordinates2 coordinates = coordinates.gsub(coordinates,'%]%[','],[') coordinates = coordinates.gsub(coordinates,'@@@@@$','') coordinates = coordinates.gsub(coordinates,'%]@@@@@%[','],\n[') coordinates = "[" .. coordinates .. ',' .. data[1] .. "]," if mapframe == "y" or mapframe == "yes" then if type == "poly" then coordinates = string.gsub(coordinates,'%]%,$',']]},') coordinates = part4a .. string.gsub(coordinates,'^%[','[[') .. part4b else coordinates = string.gsub(coordinates,'%]%,$',']},') coordinates = part3a .. coordinates .. part3b end else if type == "poly" then coordinates = string.gsub(coordinates,'%]%,$',']]},') coordinates = part2a .. string.gsub(coordinates,'^%[','[[') .. part2b else coordinates = string.gsub(coordinates,'%]%,$',']},') coordinates = part1a .. coordinates .. part1b end end return coordinates end -- CROSS function p.cross(frame) local shape = "cross" local id = frame.args['id'] or "" local lat,long = "","" 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 descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) local r = frame.args['radius'] or ".5" r = tonumber(r) if r > 10 then error("10 for length is MAX") end if r <= 0 then error("r has to be greater than 0") end local r2 = r * .25 local fill = frame.args['fill'] or "#ff0000" local stroke = frame.args['stroke'] or "#ffffff" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end local coordinates = "" local type = frame.args['type'] or "line" -- default line for LineString if type ~= "line" then type = "poly" end local angle = 0 local compass = positions(shape) local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) -- local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke) lat = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180) for i = 1,table.getn(compass), 1 do angle = compass[i] * math.pi / 180 if compass[i] == 45 or compass[i] == 135 or compass[i] == 225 or compass[i] == 315 then ptx = lat + r2 * math.cos( angle ) pty = long + r2 * math.sin( angle ) else ptx = lat + r * math.cos( angle ) pty = long + r * math.sin( angle ) end ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) coordinates = coordinates .. "[" .. pty .. "," .. ptx .. "]@@@@@" end coordinates = coordinates .. string.gsub(coordinates,'@@@@@.*','') coordinates = string.gsub(coordinates,'@@@@@',',') coordinates = putittogether(mapframe,type,part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b,coordinates) return coordinates end function p.rhombus(frame) local shape = "rhombus" local direction = frame.args['direction'] or "v" if direction == nil or direction == "" then direction = "v" end if direction ~= "h" then direction = "v" end local id = frame.args['id'] or "" local lat,long = "","" if id == nil or id == "" then if frame.args['lat'] == nil then error("Missing argument lat!") end if frame.args['long'] == nil then error("Missing argument long!") end lat = frame.args['lat'] long = frame.args['long'] if tonumber(frame.args['lat']) > 90 or tonumber(frame.args['lat']) < -90 then error("Latitude must be between 90 and -90!") end if tonumber(frame.args['long']) > 180 or tonumber(frame.args['long']) < -180 then error("Longitude must be between 180 and -180!") end else id = checkid(id) lat = latitude(id) long = longitude(id) end local group = frame.args['group'] or 'rhombus' local title = frame.args['title'] or 'A rhombus' local description = frame.args['desc'] or '' local descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) local r = frame.args['radius'] or ".5" r = tonumber(r) if r > 10 then error("10 for radius is MAX") end if r <= 0 then error("r has to be greater than 0") end local r2 = r * 2 local fill = frame.args['fill'] or "#ccef64" local stroke = frame.args['stroke'] or "#0000ff" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end local coordinates = "" local type = frame.args['type'] or "line" -- default line for LineString if type ~= "line" then type = "poly" end local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) -- local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke) lat = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180) local angle1,angle2,angle3,angle4 = 0,0,0,0 local ptx,ptx2,ptx3,ptx4 = 0,0,0,0 local pty,pty2,pty3,pty4 = 0,0,0,0 local a,b,c,d = 0,0,0,0 if direction == "h" then a,b,c,d = 360,90,180,270 else a,b,c,d = 90,180,270,360 end angle1 = a * math.pi / 180 ptx = lat + r * math.cos( angle1 ) pty = long + r * math.sin( angle1 ) angle2 = b * math.pi /180 ptx2 = lat + r2 * math.cos( angle2 ) pty2 = long + r2 * math.sin( angle2 ) angle3 = c * math.pi /180 ptx3 = lat + r * math.cos( angle3 ) pty3 = long + r * math.sin( angle3 ) angle4 = d * math.pi /180 ptx4 = lat + r2 * math.cos( angle4 ) pty4 = long + r2 * math.sin( angle4 ) ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) ptx2,pty2 = string.format("%.6f",newlat(ptx2)),string.format("%.6f",pty2) ptx3,pty3 = string.format("%.6f",newlat(ptx3)),string.format("%.6f",pty3) ptx4,pty4 = string.format("%.6f",newlat(ptx4)),string.format("%.6f",pty4) lat,long = string.format("%.6f",newlat(lat)),string.format("%.6f",long) coordinates = "[" .. pty .. "," .. ptx .. "],[" .. pty2 .. "," .. ptx2 .. "],[" .. pty3 .. "," .. ptx3 .. "],[".. pty4 .. "," .. ptx4 .. "],[" .. pty .. "," .. ptx .. "]" coordinates = putittogether(mapframe,type,part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b,coordinates) return coordinates end -- DIAMOND function p.diamond(frame) local shape = "diamond" local id = frame.args['id'] or "" local lat,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 descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) local r = frame.args['radius'] or ".5" r = tonumber(r) if r > 10 then error("10 for radius is MAX") end if r <= 0 then error("r has to be greater than 0") end local fill = frame.args['fill'] or "#ccef64" local stroke = frame.args['stroke'] or "#0000ff" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end local coordinates = "" local type = frame.args['type'] or "line" -- default line for LineString if type ~= "line" then type = "poly" end local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) -- local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke) lat = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180) local a = 360 local b = 90 local c = 180 local d = 270 angle1 = a * math.pi / 180 ptx = lat + r * math.cos( angle1 ) pty = long + r * math.sin( angle1 ) angle2 = b * math.pi /180 ptx2 = lat + r * math.cos( angle2 ) pty2 = long + r * math.sin( angle2 ) angle3 = c * math.pi /180 ptx3 = lat + r * math.cos( angle3 ) pty3 = long + r * math.sin( angle3 ) angle4 = d * math.pi /180 ptx4 = lat + r * math.cos( angle4 ) pty4 = long + r * math.sin( angle4 ) ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) ptx2,pty2 = string.format("%.6f",newlat(ptx2)),string.format("%.6f",pty2) ptx3,pty3 = string.format("%.6f",newlat(ptx3)),string.format("%.6f",pty3) ptx4,pty4 = string.format("%.6f",newlat(ptx4)),string.format("%.6f",pty4) lat,long = string.format("%.6f",newlat(lat)),string.format("%.6f",long) coordinates = "[" .. pty .. "," .. ptx .. "],[" .. pty2 .. "," .. ptx2 .. "],[" .. pty3 .. "," .. ptx3 .. "],[".. pty4 .. "," .. ptx4 .. "],[" .. pty .. "," .. ptx .. "]" coordinates = putittogether(mapframe,type,part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b,coordinates) return coordinates end -- SUN - draw circle with spikes as rays from sun function p.sun(frame) local shape = "sun" local sunburst = frame.args['sunburst'] or "10" if sunburst == nil or sunburst == "" then sunburst = "10" end sunburst = tonumber(sunburst) if sunburst < 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'] or "" local matrix = {} local coordinates = "" local count = 1 local type = frame.args['type'] or "line" if type ~= "poly" then type = "line" end if id == nil or id == "" then if lat == "" or lat == nil then error("Missing argument lat!") end if long == "" or long == nil then error("Missing argument long!") end if tonumber( lat ) > 90 or tonumber( lat ) < -90 then error("Latitudes must be between 90 and -90!") end if tonumber(long) > 180 or tonumber(long) < -180 then error("Longitudes must be between 180 and -180!") end else id = checkid(id) lat = latitude(id) long = longitude(id) end local r = frame.args['radius'] or ".5" r = tonumber(r) if r > 10 then error("10 for radius is MAX") end if r <= 0 then error("r has to be greater than 0") end local r2 = r * .45 local group = frame.args['group'] or 'sun' local title = frame.args['title'] or 'A sun' local description = frame.args['desc'] or "" local descattr = frame.args['descattr'] or 'l' -- TESTING if description == nil then description = "" end description = aligndesc(description,descattr) local fill = frame.args['fill'] or "#ffff00" local stroke = frame.args['stroke'] or "#000000" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nil or mapframe == "" then mapframe = "no" end local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) -- local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke) local angle,ptx,pty = 0,0,0 local latitude = lat lat = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180) local count = 0 for i = increment,360, increment do angle = i * math.pi / 180 ptx = lat - r2 * math.cos( angle ) pty = long - r2 * math.sin( angle ) ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) count = count + 1 matrix[count] = "[" .. pty .. "," .. ptx .. "]@@@@@" angle = (i + inbetween) * math.pi / 180 ptx = lat - r * math.cos( angle ) pty = long - r * math.sin( angle ) ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) count = count + 1 matrix[count] = "[" .. pty .. "," .. ptx .. "]@@@@@" end for i = 1,table.getn(matrix), 1 do coordinates = coordinates .. matrix[i] end coordinates = coordinates .. matrix[1] coordinates = string.gsub(coordinates,"@@@@@",",") coordinates = string.gsub(coordinates,",$",'') coordinates = putittogether(mapframe,type,part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b,coordinates) return coordinates end -- STADIUM or pill capsule shape -- reduced number of coordinates for circular shape function p.stadium(frame) local shape = "stadium" local id = frame.args['id'] or "" local 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 descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) local r = frame.args['radius'] or ".5" r = tonumber(r) if r > 10 then error("10 for radius is MAX") end if r <= 0 then error("radius has to be greater than 0") end local fill = frame.args['fill'] or "#ccef64" local stroke = frame.args['stroke'] or "#0000ff" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end local data = {} local data2 = {} local coordinates = "" local coordinates2 = "" local ptx,pty,angle,ptx2,pty2 = 0,0,0,0,0 local type = frame.args['type'] or "line" -- default line for LineString if type ~= "line" then type = "poly" end local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) -- local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke) x = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180) angle = 90 * math.pi / 180 x = x + (r*1.5) * math.cos( angle ) y = long + (r*1.5) * math.sin (angle) x = newlat(x) x2 = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180) angle = 270 * math.pi / 180 x = x + (r*1.5) * math.cos( angle ) y2 = long + (r*1.5) * math.sin (angle ) x2 = newlat(x2) x = math.log(math.tan((90 + x) * math.pi/360)) / (math.pi/180) x2 =math.log(math.tan((90 + x2) * math.pi/360)) / (math.pi/180) local count = 1 for i = -2, 180, 2 do angle = i * math.pi / 180 ptx = x + r * math.cos( angle ) pty = y + r * math.sin(angle) ptx = newlat(ptx) data[count] = '[' .. string.format("%.6f",pty) .. "," .. string.format("%.6f",ptx) .. ']' count = count + 1 end count = 1 for i = 178,360, 2 do angle = i * math.pi / 180 ptx = x2 + r * math.cos( angle ) pty = y2 + r * math.sin(angle) ptx = newlat(ptx) data2[count] = '[' .. string.format("%.6f",pty) .. "," .. string.format("%.6f",ptx) .. ']' count = count + 1 end for i = 1,table.getn(data), 1 do coordinates = coordinates .. data[i] end for i = 1,table.getn(data2), 1 do coordinates2 = coordinates2 .. data2[i] end coordinates = coordinates .. coordinates2 coordinates = coordinates.gsub(coordinates,'%]%[','],[') coordinates = coordinates.gsub(coordinates,'@@@@@$','') coordinates = coordinates.gsub(coordinates,'%]@@@@@%[','],\n[') coordinates = "[" .. coordinates .. ',' .. data[1] .. "]," if mapframe == "y" or mapframe == "yes" then if type == "poly" then coordinates = string.gsub(coordinates,'%]%,$',']]},') coordinates = part4a .. string.gsub(coordinates,'^%[','[[') .. part4b else coordinates = string.gsub(coordinates,'%]%,$',']},') coordinates = part3a .. coordinates .. part3b end else if type == "poly" then coordinates = string.gsub(coordinates,'%]%,$',']]},') coordinates = part2a .. string.gsub(coordinates,'^%[','[[') .. part2b else coordinates = string.gsub(coordinates,'%]%,$',']},') coordinates = part1a .. coordinates .. part1b end end return coordinates end -- 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 descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) local radius = frame.args['radius'] or ".5" radius = tonumber(radius) if radius > 10 then error("10 for radius is MAX") end if radius <= 0 then error("radius has to be greater than 0") end local radius2 = radius * 3; local fill = frame.args['fill'] or "#ccef64" local stroke = frame.args['stroke'] or "#0000ff" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end local ra,angle,ptx,pty = 0,0,0,0 local compass = {} local points = {} local coordinates = "" local type = frame.args['type'] or "line" -- default line for LineString if type ~= "line" then type = "poly" end local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) -- local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke) x = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180) compass = positions(shape) for i = 1,table.getn(compass), 1 do mod = math.mod(i,2) if mod == 1 then r = radius else r = radius2 end angle = compass[i] * math.pi / 180 ptx = x + r * math.cos( angle ) pty = y + r * math.sin( angle ) ptx = newlat(ptx) points[i] = '[' .. string.format("%.6f",pty) .. pty .. "," .. string.format("%.6f",ptx) .. "]," end for i = 1,table.getn(points), 1 do coordinates = coordinates .. points[i] .. "\n" end coordinates = coordinates .. points[1] if mapframe == "y" or mapframe == "yes" then if type == "poly" then coordinates = string.gsub(coordinates,'%]%,$',']]]},') coordinates = part4a .. string.gsub(coordinates,'^%[','[[[') .. part4b else coordinates = string.gsub(coordinates,'%]%,$',']]},') coordinates = part3a .. string.gsub(coordinates,'^%[','[[') .. part3b end else if type == "poly" then coordinates = string.gsub(coordinates,'%]%,$',']]]},') coordinates = part2a .. string.gsub(coordinates,'^%[','[[[') .. part2b else coordinates = string.gsub(coordinates,'%]%,$',']]},') coordinates = part1a .. string.gsub(coordinates,'^%[','[[') .. part1b end end return coordinates end -- BAR -- only creates a LineString with thickness of 4 function p.bar(frame) local shape = "bar" local id = frame.args['id'] or "" local lat,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 "h" if direction == nil or direction == "" then direction = "h" end if direction ~= "h" then direction = "v" end local group = frame.args['group'] or 'bar' local title = frame.args['title'] or 'A bar' local description = frame.args['desc'] or '' local descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) local r = frame.args['radius'] or ".5" r = tonumber(r) if r > 40 then error("40 for length is MAX") end -- 40 for bar shape only if r <= 0 then error("r has to be greater than 0") end -- local fill = frame.args['fill'] or "#000000" -- fill not used - keep anyhow for time being local fill = "#000000" local stroke = frame.args['stroke'] or "#000000" -- change color with stroke local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end local coordinates = "" local type = frame.args['type'] or "line" -- default line for LineString if type ~= "line" then type = "line" end local angle = 0 local compass = positions(shape) local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) -- local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke) lat = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180) for i = 1,table.getn(compass), 1 do if direction == "v" then compass[i] = compass[i] + 90 end angle = compass[i] * math.pi / 180 ptx = lat + r * math.cos( angle ) pty = long + r * math.sin( angle ) ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) coordinates = coordinates .. "[" .. pty .. "," .. ptx .. "]@@@@@" end coordinates = string.gsub(coordinates,'@@@@@',',') coordinates = putittogether(mapframe,type,part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b,coordinates) coordinates = string.gsub(coordinates,'stroke%-width%":1','stroke-width":3') return coordinates end -- KITE - Shield function p.kite(frame) local shape = "kite" local id = frame.args['id'] or "" local lat,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 descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) local r = frame.args['radius'] or ".5" r = tonumber(r) if r > 10 then error("10 for radius is MAX") end if r <= 0 then error("r has to be greater than 0") end local fill = frame.args['fill'] or "#ccef64" local stroke = frame.args['stroke'] or "#0000ff" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end local coordinates = "" local type = frame.args['type'] or "line" -- default line for LineString if type ~= "line" then type = "poly" end local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) -- local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke) lat = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180) local a = 360 local b = 60 local c = 180 local d = 300 angle1 = a * math.pi / 180 ptx = lat + r * math.cos( angle1 ) pty = long + r * math.sin( angle1 ) angle2 = b * math.pi /180 ptx2 = lat + r * math.cos( angle2 ) pty2 = long + r * math.sin( angle2 ) angle3 = c * math.pi /180 ptx3 = lat + r * math.cos( angle3 ) pty3 = long + r * math.sin( angle3 ) angle4 = d * math.pi /180 ptx4 = lat + r * math.cos( angle4 ) pty4 = long + r * math.sin( angle4 ) ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) ptx2,pty2 = string.format("%.6f",newlat(ptx2)),string.format("%.6f",pty2) ptx3,pty3 = string.format("%.6f",newlat(ptx3)),string.format("%.6f",pty3) ptx4,pty4 = string.format("%.6f",newlat(ptx4)),string.format("%.6f",pty4) lat,long = string.format("%.6f",newlat(lat)),string.format("%.6f",long) coordinates = "[" .. pty .. "," .. ptx .. "],[" .. pty2 .. "," .. ptx2 .. "],[" .. pty3 .. "," .. ptx3 .. "],[".. pty4 .. "," .. ptx4 .. "],[" .. pty .. "," .. ptx .. "]" coordinates = putittogether(mapframe,type,part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b,coordinates) return coordinates end -- ANNULUS - 2 circles forming a donut shape function p.annulus(frame) local shape = "annulus" local id = frame.args['id'] or "" local lat,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 mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end -- FUTURE USE if tonumber(lat) > 85.35 or tonumber(lat) < -85.35 then error("Latitude must be between 85.35 and -85.35!") end if tonumber(long) > 180 or tonumber(long) < -180 then error("Longitude must be between 180 and -180!") end -- END if local group = frame.args['group'] or 'annulus' local title = frame.args['title'] or 'An annulus' local description = frame.args['desc'] or '' local descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) local r = frame.args['radius'] or ".5" r = tonumber(r) if r > 10 then error("10 for radius is MAX") end if r <= 0 then error("radius has to be greater than 0") end local r2 = r * .65 local fill = frame.args['fill'] or "#ccef64" local stroke = frame.args['stroke'] or "#0000ff" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local data = {} local data2 = {} local coordinates = "" local coordinates2 = "" local ptx,pty,angle,ptx2,pty2 = 0,0,0,0,0 local type = frame.args['type'] or "line" -- default line for LineString if type ~= "line" then type = "poly" end local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) -- local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke) if tonumber(x) >= 10.5 then x = math.log(math.tan((90 + x) * math.pi/360)) / (math.pi/180) elseif tonumber(x) <= -10.5 then x = math.log(math.tan((90 + x) * math.pi/360)) / (math.pi/180) end for i = 1, 360 do angle = i * math.pi / 180 ptx = x + r * math.cos( angle ) pty = y + r * math.sin( angle ) ptx2 = x + r2 * math.cos( angle ) pty2 = y + r2 * math.sin( angle ) if tonumber(x) >= 10.5 then ptx = newlat(ptx) ptx2 = newlat(ptx2) end if tonumber(x) <= -10.5 then ptx = newlat(ptx) ptx2 = newlat(ptx2) end data[i] = '[' .. string.format("%.6f",pty) .. "," .. string.format("%.6f",ptx) .. ']' data2[i] = '[' .. string.format("%.6f",pty2) .. "," .. string.format("%.6f",ptx2) .. ']' end for i = 5,359, 5 do data[i] = data[i] .. "@@@@@" data2[i] = data2[i] .. "@@@@@" end -- cycle through array and build single string of all coordinates to be output for i = 1,360, 1 do coordinates = coordinates .. data[i] coordinates2 = coordinates2 .. data2[i] end coordinates = coordinates.gsub(coordinates,'%]%[','],[') coordinates2 = coordinates2.gsub(coordinates2,'%]%[','],[') coordinates = coordinates.gsub(coordinates,'%]@@@@@%[','],\n[') coordinates2 = coordinates2.gsub(coordinates2,'%]@@@@@%[','],\n[') coordinates = "[" .. coordinates .. ',' .. data[1] .. "]," coordinates2 = "[" .. coordinates2 .. ',' .. data2[1] .. "]],[" coordinates = coordinates2 .. coordinates coordinates = string.gsub(coordinates,'%]%]%],%[%[%[',']],[[') if mapframe == "y" or mapframe == "yes" then if type == "poly" then coordinates = string.gsub(coordinates,'%]%,$',']]},') coordinates = part4a .. string.gsub(coordinates,'^%[','[[') .. part4b else coordinates = string.gsub(coordinates,'%]%,$',']]},') coordinates = string.gsub(coordinates,'^%[','[[') coordinates = part3a .. coordinates .. part3b coordinates = string.gsub(coordinates,'LineString','MultiLineString') end else if type == "poly" then coordinates = string.gsub(coordinates,'%]%,$',']]},') coordinates = part2a .. string.gsub(coordinates,'^%[','[[') .. part2b else coordinates = string.gsub(coordinates,'%]%,$',']]},') coordinates = string.gsub(coordinates,'^%[','[[') coordinates = part1a .. coordinates .. part1b coordinates = string.gsub(coordinates,'LineString','MultiLineString') end end return coordinates end -- WEDGE function p.wedge(frame) local shape = "wedge" local id = frame.args['id'] or "" local lat,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 descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) local r = frame.args['radius'] or ".5" r = tonumber(r) if r > 10 then error("10 for length is MAX") end if r <= 0 then error("r has to be greater than 0") end local r2 = r * 2 local fill = frame.args['fill'] or "#ccef64" local stroke = frame.args['stroke'] or "#0000ff" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end local coordinates = "" local type = frame.args['type'] or "line" -- default line for LineString if type ~= "line" then type = "poly" end local direction = frame.args['direction'] or "1" if direction == nil or direction == "" then direction = "1" end direction = string.gsub(direction,'%..*','') if string.gsub(direction,"^[1-8]$","") ~= "" then direction="1" end direction = tonumber(direction) if direction <= 0 or direction >= 9 then error("Direction should be a number from 1 to 8!") end local angle1,angle2,angle3 = 0,0,0 local ptx,ptx2,ptx3 = 0,0,0 local pty,pty2,pty3 = 0,0,0 local factor = {'340,360,20','25,45,65','70,90,110','115,135,155','160,180,200','205,225,245','250,270,290','295,315,335'} local a = string.gsub(factor[direction],'(%d+)(,)(%d+)(,)(%d+)','%1') local b = string.gsub(factor[direction],'(%d+)(,)(%d+)(,)(%d+)','%3') local c = string.gsub(factor[direction],'(%d+)(,)(%d+)(,)(%d+)','%5') local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) -- local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke) lat = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180) angle = b * math.pi / 180 ptx = lat + (r*.02) * math.cos( angle ) pty = long + (r*.02) * math.sin( angle ) lat,long = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) lat = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180) angle1 = a * math.pi / 180 ptx = lat + r2 * math.cos( angle1 ) pty = long + r2 * math.sin( angle1 ) angle2 = b * math.pi /180 -- used to compute center of wedge ptx2 = lat + r * math.cos( angle2 ) pty2 = long + r * math.sin( angle2 ) angle3 = c * math.pi /180 ptx3 = lat + r2 * math.cos( angle3 ) pty3 = long + r2 * math.sin( angle3 ) ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) ptx2,pty2 = string.format("%.6f",newlat(ptx2)),string.format("%.6f",pty2) ptx3,pty3 = string.format("%.6f",newlat(ptx3)),string.format("%.6f",pty3) lat,long = string.format("%.6f",newlat(lat)),string.format("%.6f",long) coordinates = "[" .. pty .. "," .. ptx .. "],[" .. pty3 .. "," .. ptx3 .. "],[" .. long .. "," .. lat .. "],[" .. pty .. "," .. ptx .. "]" coordinates = putittogether(mapframe,type,part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b,coordinates) return coordinates end -- KEYSTONE function p.keystone(frame) local shape = "keystone" local id = frame.args['id'] or "" local lat,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 descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) local r = frame.args['radius'] or ".5" r = tonumber(r) if r > 10 then error("10 for length is MAX") end if r <= 0 then error("r has to be greater than 0") end local r2 = r * .65 local fill = frame.args['fill'] or "#ccef64" local stroke = frame.args['stroke'] or "#0000ff" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end local coordinates = "" local type = frame.args['type'] or "line" -- default line for LineString if type ~= "line" then type = "poly" end local angle = 0 local compass = positions(shape) local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) -- local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke) lat = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180) for i = 1,table.getn(compass), 1 do angle = compass[i] * math.pi / 180 if compass[i] == 26 or compass[i] == 334 then ptx = lat + r2 * math.cos( angle ) pty = long + r2 * math.sin( angle ) else ptx = lat + r * math.cos( angle ) pty = long + r * math.sin( angle ) end ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) coordinates = coordinates .. "[" .. pty .. "," .. ptx .. "]@@@@@" end coordinates = coordinates .. string.gsub(coordinates,'@@@@@.*','') coordinates = string.gsub(coordinates,'@@@@@',',') coordinates = putittogether(mapframe,type,part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b,coordinates) return coordinates end -- COG -- gear shape function p.cog(frame) local shape = "cog" local id = frame.args['id'] or "" local lat,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 descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) local r = frame.args['radius'] or ".5" r = tonumber(r) if r > 10 then error("10 for length is MAX") end if r <= 0 then error("r has to be greater than 0") end local r2 = r * .85 local r3 = r * .30 local fill = frame.args['fill'] or "#ccef64" local stroke = frame.args['stroke'] or "#0000ff" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end local coordinates = "" local coordinates2 = "" local type = frame.args['type'] or "line" -- default line for LineString if type ~= "line" then type = "poly" end local angle = 0 local compass = positions(shape) local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) -- local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke) lat = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180) for i = 1,table.getn(compass), 1 do angle = (compass[i] - 33.5) * math.pi / 180 ptx = lat + r2 * math.cos( angle ) pty = long + r2 * math.sin( angle ) ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) coordinates = coordinates .. "[" .. pty .. "," .. ptx .. "]@@@@@" angle = (compass[i] - 11) * math.pi / 180 ptx = lat + r2 * math.cos( angle ) pty = long + r2 * math.sin( angle ) ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) coordinates = coordinates .. "[" .. pty .. "," .. ptx .. "]@@@@@" angle = (compass[i] -11.25) * math.pi / 180 ptx = lat + r * math.cos( angle ) pty = long + r * math.sin( angle ) ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) coordinates = coordinates .. "[" .. pty .. "," .. ptx .. "]@@@@@" angle = (compass[i] + 11.25) * math.pi / 180 ptx = lat + r * math.cos( angle ) pty = long + r * math.sin( angle ) ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) coordinates = coordinates .. "[" .. pty .. "," .. ptx .. "]@@@@@" end coordinates = coordinates .. string.gsub(coordinates,'@@@@@.*','') coordinates = string.gsub(coordinates,'@@@@@',',') compass = positions('quad') for i = 1,table.getn(compass), 1 do angle = compass[i] * math.pi / 180 ptx = lat + r3 * math.cos( angle ) pty = long + r3 * math.sin( angle ) ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) coordinates2 = coordinates2 .. "[" .. pty .. "," .. ptx .. "]@@@@@" end coordinates2 = coordinates2 .. string.gsub(coordinates2,'@@@@@.*','') coordinates2 = string.gsub(coordinates2,'@@@@@',',') coordinates = coordinates .. "],[" .. coordinates2 if mapframe == "y" or mapframe == "yes" then if type == "poly" then coordinates = '[[' .. coordinates .. ']]},' coordinates = part4a .. coordinates .. part4b else coordinates = '[[' .. coordinates .. ']]},' coordinates = part3a .. coordinates .. part3b coordinates = string.gsub(coordinates,'LineString','MultiLineString') end else if type == "poly" then coordinates = '[[' .. coordinates .. ']]},' coordinates = part2a .. coordinates .. part2b else coordinates = '[[' .. coordinates .. ']]},' coordinates = part1a .. coordinates .. part1b coordinates = string.gsub(coordinates,'LineString','MultiLineString') end end return coordinates end -- PENTAGRAM - Line String only -- Poly fills in the tips - lines still there function p.pentagram(frame) local shape = "pentagram" local id = frame.args['id'] or "" local lat,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 descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) local r = frame.args['radius'] or ".5" if r == nil or r == "" then r = "0.5" end r = tonumber(r) if r > 10 then error("10 for radius is MAX") end if r <= 0 then error("radius has to be greater than 0") end local fill = frame.args['fill'] or "#000000" local stroke = frame.args['stroke'] or "#0000ff" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end -- FUTURE USE local angle,ptx,pty = 0,0,0 local compass = {} local points = {} local coordinates = "" local type = frame.args['type'] or "line" -- default line for LineString if type ~= "poly" then type = "line" end local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) -- local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke) x = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180) compass = positions(shape) for i = 1,table.getn(compass), 1 do angle = compass[i] * math.pi / 180 ptx = x + r * math.cos( angle ) pty = y + r * math.sin( angle ) ptx = newlat(ptx) points[i] = '[' .. string.format("%.6f",pty) .. "," .. string.format("%.6f",ptx) .. "]," end for i = 1,table.getn(points), 1 do coordinates = coordinates .. points[i] .. "\n" end coordinates = coordinates .. points[1] if mapframe == "y" or mapframe == "yes" then if type == "poly" then coordinates = string.gsub(coordinates,'%]%,$',']]]},') coordinates = part4a .. string.gsub(coordinates,'^%[','[[[') .. part4b else coordinates = string.gsub(coordinates,'%]%,$',']]},') coordinates = part3a .. string.gsub(coordinates,'^%[','[[') .. part3b end else if type == "poly" then coordinates = string.gsub(coordinates,'%]%,$',']]]},') coordinates = part2a .. string.gsub(coordinates,'^%[','[[[') .. part2b else coordinates = string.gsub(coordinates,'%]%,$',']]},') coordinates = part1a .. string.gsub(coordinates,'^%[','[[') .. part1b end end return coordinates end -- X_SHAPE function p.x(frame) local shape = "xshape" local id = frame.args['id'] or "" local lat,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 descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) local r = frame.args['radius'] or ".5" r = tonumber(r) if r > 10 then error("10 for length is MAX") end if r <= 0 then error("r has to be greater than 0") end local r2 = r * .375 local fill = frame.args['fill'] or "#ccef64" local stroke = frame.args['stroke'] or "#0000ff" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end local coordinates = "" local type = frame.args['type'] or "line" -- default line for LineString if type ~= "line" then type = "poly" end local angle = 0 local compass = positions(shape) local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) -- local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke) lat = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180) for i = 1,table.getn(compass), 1 do angle = compass[i] * math.pi / 180 if compass[i] == 90 or compass[i] == 180 or compass[i] == 270 or compass[i] == 360 then ptx = lat + r2 * math.cos( angle ) pty = long + r2 * math.sin( angle ) else ptx = lat + r * math.cos( angle ) pty = long + r * math.sin( angle ) end ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) coordinates = coordinates .. "[" .. pty .. "," .. ptx .. "]@@@@@" end coordinates = coordinates .. string.gsub(coordinates,'@@@@@.*','') coordinates = string.gsub(coordinates,'@@@@@',',') coordinates = putittogether(mapframe,type,part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b,coordinates) return coordinates end -- RECTANGLE - simple styled rectangle which makes it limited function p.rectangle(frame) local shape = frame.args['rectangle'] or "rectangle" local id = frame.args['id'] or "" local lat,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 'rectangle' local title = frame.args['title'] or 'A set rectangle' local description = frame.args['desc'] or '' local descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) local name = frame.args['name'] or "A Center Rectangle" local r = frame.args['radius'] or ".5" r = tonumber(r) r = r + r if r > 10 then error("10 for radius is MAX") end if r <= 0 then error("r has to be greater than 0") end local fill = frame.args['fill'] or "#ccef64" local stroke = frame.args['stroke'] or "#0000ff" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end local coordinates = "" local type = frame.args['type'] or "line" -- default line for LineString if type ~= "line" then type = "poly" end local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) -- local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke) lat = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180) local angle1,angle2,angle3,angle4 = 0,0,0,0 local ptx,ptx2,ptx3,ptx4 = 0,0,0,0 local pty,pty2,pty3,pty4 = 0,0,0,0 -- local a = 45 -- local b = 135 -- local c = 225 -- local d = 315 local a = 60 local b = 120 local c = 240 local d = 300 angle1 = a * math.pi / 180 ptx = lat + r * math.cos( angle1 ) pty = long + r * math.sin( angle1 ) angle2 = b * math.pi /180 ptx2 = lat + r * math.cos( angle2 ) pty2 = long + r * math.sin( angle2 ) angle3 = c * math.pi /180 ptx3 = lat + r * math.cos( angle3 ) pty3 = long + r * math.sin( angle3 ) angle4 = d * math.pi /180 ptx4 = lat + r * math.cos( angle4 ) pty4 = long + r * math.sin( angle4 ) ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) ptx2,pty2 = string.format("%.6f",newlat(ptx2)),string.format("%.6f",pty2) ptx3,pty3 = string.format("%.6f",newlat(ptx3)),string.format("%.6f",pty3) ptx4,pty4 = string.format("%.6f",newlat(ptx4)),string.format("%.6f",pty4) lat,long = string.format("%.6f",newlat(lat)),string.format("%.6f",long) coordinates = "[" .. pty .. "," .. ptx .. "],[" .. pty2 .. "," .. ptx2 .. "],[" .. pty3 .. "," .. ptx3 .. "],[".. pty4 .. "," .. ptx4 .. "],[" .. pty .. "," .. ptx .. "]" coordinates = putittogether(mapframe,type,part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b,coordinates) return coordinates end -- POINT function p.point(frame) -- local partof = "" local t = {} local entity = '' local claims = '' local coordinates = "" local image = frame.args['image'] or "" if image ~= nil and image ~= "" then image = '[[File:' .. image .. '|center|border|280x280px|link=]]' end local code = "" local count = 0 local lat = frame.args['lat'] or "" local long = frame.args['long'] or "" local id = frame.args['id'] or "" if id == nil or id == "" then 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) if lat == "" then lat = latitude(id) end if long == "" then long = longitude(id) end end local description = frame.args['desc'] or '' local descattr = frame.args['descattr'] or 'l' -- TESTING local color = frame.args['color'] or "#ff0000" if string.len(color) ~= 7 then error("Incorrect length for argument color") end if string.gsub(color,"#[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]","") ~= "" then error("Incorrect hexidecimal format for argument color") end local title = frame.args['title'] or "" local symbol = frame.args['symbol'] or "city" local size = frame.args['size'] or "medium" if id ~= nil and id ~= '' and id ~= "Q97" then entity = mw.wikibase.getEntityObject(id) claims = entity.claims if image == nil or image == "" then if pcall(function () t = claims.P18 end) then if pcall(function () t = entity.claims.P18[1].mainsnak.datavalue.value end ) then image = entity.claims.P18[1].mainsnak.datavalue.value if image ~= nil and image ~= "" then image = '[[File:' .. image .. '|center|border|280x280px|link=]]' end end end end t = {} if pcall(function () t = claims.P296 end) then if pcall(function () t = entity.claims.P296[1].mainsnak.datavalue.value end ) then code = entity.claims.P296[1].mainsnak.datavalue.value end end end if count == 0 then -- #description has no beginning image then use image from wikidata if any if image ~= nil and image ~= "" then description = image .. description end end description = aligndesc(description,descattr) -- Special Case - adding code (abbrev) to title while testing train stations - symbol rail trigger if symbol == "rail" then if title ~= nil and title ~= "" then if code ~= nil and code ~= "" then title = title .. ' (' .. code .. ')' end end end coordinates = "{\n" .. '\t"type": "Feature",\n' .. '\t\t"geometry": { "type": "Point", "coordinates": [' .. long .. "," .. lat .. ']},\n' coordinates = coordinates .. '\t\t"properties": {\n' .. '\t\t\t"description": "' .. description .. '",\n' .. '\t\t\t"title": "' .. title .. '",\n' coordinates = coordinates .. '\t\t\t"marker-color": "' .. color .. '",\n' .. '\t\t\t"marker-symbol": "' .. symbol .. '",\n' .. '\t\t\t"marker-size": "' .. size .. '",\n' coordinates = coordinates .. '\t\t}' .. '}\n' return coordinates end -- POINTER function p.pointer(frame) local shape = "pointer" local id = frame.args['id'] or "" local lat,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 descattr = frame.args['descattr'] or 'l' -- TESTING description = aligndesc(description,descattr) local r = frame.args['radius'] or ".5" r = tonumber(r) if r > 10 then error("10 for length is MAX") end if r <= 0 then error("r has to be greater than 0") end r = r * 2 local r2 = r/2 local r3 = r/3 local fill = frame.args['fill'] or "#ccef64" local stroke = frame.args['stroke'] or "#0000ff" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" checkhex(fill,stroke) local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end local coordinates = "" local type = frame.args['type'] or "line" -- default line for LineString if type ~= "line" then type = "poly" end local direction = frame.args['direction'] or "1" if direction == nil or direction == "" then direction = "1" end direction = string.gsub(direction,'%..*','') if string.gsub(direction,"^[1-8]$","") ~= "" then direction="1" end direction = tonumber(direction) if direction <= 0 or direction >= 9 then error("Direction should be a number from 1 to 8!") end local angle1,angle2,angle3,angle4 = 0,0,0,0 local ptx,ptx2,ptx3,ptx4 = 0,0,0,0 local pty,pty2,pty3,pty4 = 0,0,0,0 local factor = {'20,360,340','25,45,65','70,90,110','115,135,155','160,180,200','205,225,245','250,270,290','295,315,335'} local a = string.gsub(factor[direction],'%,.*$','') -- eat everything after a comma - hungry local b = string.gsub(factor[direction],'^.*%,','') -- eat everything up to a comma - hungry local c = string.gsub(factor[direction],'(%d+)(,)(%d+)(,)(%d+)','%3') -- MISSING FIX local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat,long,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) -- local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = parts(lat,long,group,title,description,fill,stroke) lat = math.log(math.tan((90 + lat) * math.pi/360)) / (math.pi/180) angle1 = a * math.pi / 180 ptx = lat + r * math.cos( angle1 ) pty = long + r * math.sin( angle1 ) angle2 = b * math.pi /180 ptx2 = lat + r * math.cos( angle2 ) pty2 = long + r * math.sin( angle2 ) angle3 = c * math.pi /180 ptx3 = lat + r2 * math.cos( angle3 ) pty3 = long + r2 * math.sin( angle3 ) angle4 = c * math.pi /180 ptx4 = lat + r3 * math.cos( angle3 ) pty4 = long + r3 * math.sin( angle3 ) ptx,pty = string.format("%.6f",newlat(ptx)),string.format("%.6f",pty) ptx2,pty2 = string.format("%.6f",newlat(ptx2)),string.format("%.6f",pty2) ptx3,pty3 = string.format("%.6f",newlat(ptx3)),string.format("%.6f",pty3) ptx4,pty4 = string.format("%.6f",newlat(ptx4)),string.format("%.6f",pty4) lat,long = string.format("%.6f",newlat(lat)),string.format("%.6f",long) coordinates = "[" .. pty .. "," .. ptx .. "],[" .. pty3 .. "," .. ptx3 .. "],[" .. pty2 .. "," .. ptx2 .. "],[" .. long .. "," .. lat .. "],[" .. pty .. "," .. ptx .. "]" coordinates = putittogether(mapframe,type,part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b,coordinates) return coordinates end -- External from OpenStreetMap function p.external(frame) local id = frame.args['id'] or 'Q20' local title = frame.args['title'] or "" local fill = frame.args['fill'] or "#87deaa" local stroke = frame.args['stroke'] or "#000000" local strokewidth = frame.args['strokewidth'] or "1" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.5" local description = frame.args['desc'] or "" local descattr = frame.args['descattr'] or "l" local file = frame.args['file'] or "" local geotype = frame.args['geotype'] or "geoshape" description = aligndesc(description,descattr) if geotype == "page" then coordinates = '{' coordinates = coordinates .. '"type": "ExternalData",' coordinates = coordinates .. '\t\t "service": "' .. geotype .. '",' coordinates = coordinates .. '\t\t"title": "' .. file .. '"' coordinates = coordinates .. '}' else coordinates = '{' coordinates = coordinates .. '"type": "ExternalData",\n' coordinates = coordinates .. '\t "properties": {\n' coordinates = coordinates .. '\t\t"title": "' .. title .. '",\n' coordinates = coordinates .. '\t\t"description": "' .. description .. '",\n' coordinates = coordinates .. '\t\t"fill": "' .. fill .. '",\n' coordinates = coordinates .. '\t\t"fill-opacity":' .. fillopacity .. ',\n' coordinates = coordinates .. '\t\t"stroke": "' .. stroke .. '",\n' coordinates = coordinates .. '\t\t"stroke-opacity":' .. strokeopacity .. ',\n' coordinates = coordinates .. '\t\t"stroke-width":' .. strokewidth .. ',\n' coordinates = coordinates .. '\t\t},\n' coordinates = coordinates .. '\t\t "service": "' .. geotype .. '",\n' coordinates = coordinates .. '\t\t"ids": "' .. id .. '"\n' coordinates = coordinates .. '}' end return coordinates end -- External from OpenStreetMap function p.background(frame) local title = frame.args['title'] or "" local fill = frame.args['fill'] or "#baf326" local stroke = "#000000" local strokewidth = "4" local strokeopacity = frame.args['strokeopacity'] or "0.5" local fillopacity = frame.args['fillopacity'] or "0.025" local description = "" local coordinates = "" coordinates = '{"type": "Feature","geometry": { "type":"Polygon", "coordinates":' coordinates = coordinates .. '[[[-3600,90], [3600, 90], [3600,-90], [-3600,-90], [-3600,90]]]},\n' coordinates = coordinates .. '\t\t"properties":{\n' coordinates = coordinates .. '\t\t"title": "' .. title .. '",\n' coordinates = coordinates .. '\t\t"description": "' .. description .. '",\n' coordinates = coordinates .. '\t\t"fill": "' .. fill .. '",\n' coordinates = coordinates .. '\t\t"stroke":"' .. stroke .. '",\n' coordinates = coordinates .. '\t\t"fill-opacity":' .. fillopacity .. ',\n' coordinates = coordinates .. '\t\t"stroke-width":' .. strokewidth .. '\n' coordinates = coordinates .. '}}' return coordinates end function p.empty(frame) return "" end -- LINE function p.line(frame) local shape = "line" local id = frame.args['id'] or "" local id2 = frame.args['id2'] or "" if id == nil or id == "" then error("Missing id!") end if id2 == nil or id2 == "" then error("Missing id!") end checkid(id) checkid(id2) local lat1,long1,lat2,long2 = "","","","" lat1 = latitude(id) lat2 = latitude(id2) long1 = longitude(id) long2 = longitude(id2) local type = "line" local title = frame.args['title'] or 'A line' local group = frame.args['group'] or "line" local description = frame.args['desc'] or '' local descattr = frame.args['descattr'] or 'l' -- TESTING local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end local coordinates = "" local fill = frame.args['fill'] or "#000000" local fillopacity = frame.args['fillopacity'] or "0.5" local stroke = frame.args['stroke'] or "#0000ff" local strokeopacity = frame.args['strokeopacity'] or "0.5" local strokewidth = frame.args['strokewidth'] or "1" local data = {} data[1] = "[" .. long1 .. "," .. lat1 .. "]" data[2] = "[" .. long2 .. "," .. lat2 .. "]" coordinates = "[" .. data[1] .. "," .. data[2] .. "]}," local part1a,part1b,part2a,part2b,part3a,part3b,part4a,part4b = partsnew(lat1,long1,group,title,description,fill,fillopacity,stroke,strokewidth,strokeopacity) if mapframe == "y" or mapframe == "yes" then if type == "poly" then coordinates = string.gsub(coordinates,'%]%,$',']]},') coordinates = part4a .. string.gsub(coordinates,'^%[','[[') .. part4b else coordinates = string.gsub(coordinates,'%]%,$',']},') coordinates = part3a .. coordinates .. part3b end else if type == "poly" then coordinates = string.gsub(coordinates,'%]%,$',']]},') coordinates = part2a .. string.gsub(coordinates,'^%[','[[') .. part2b else coordinates = string.gsub(coordinates,'%]%,$',']},') coordinates = part1a .. coordinates .. part1b end end return coordinates end -- END MODULE return p