Module:Mapdraw

-- keeping original shape for a circle -- Matroc -- other shapes etc. moved to a Sandbox

local p = {}

local function newlat(a) -- newlat = math.log(math.tan((90 + a) * math.pi / 360)) / (math.pi / 180) -- worked this code elsewhere in function can remove newlatitude = 180/math.pi * (2 * math.atan(math.exp( a * math.pi/180)) - math.pi/2 ) if newlatitude > 89.5 then point = 89.5 end -- END if      -- straight line at top of map if newlatitude < -89.5 then point = -89.5 end -- END if    -- straight line at bottom of map return newlatitude end

local function checkhex(fill,stroke) if string.len(fill) ~= 7 then error("Incorrect length for argument fill!") end if string.gsub(fill,"#[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]","") ~= "" then error("Incorrect hexidecimal format for argument fill!") end if string.len(stroke) ~= 7 then error("Incorrect length for argument stroke!") end if string.gsub(stroke,"#[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]","") ~= "" then error("Incorrect hexidecimal format for argument stroke!") end end

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

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

-- GET LONGITUDE -- P625

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

local function parts(lat,long,group,title,description,fill,stroke) local part1a = ' \n'

local part1b = ' \n'

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

local part2ca = '\n\t\t"type":"LineString"},\n\t"properties":{\n\t\t"title": "' .. title .. '",\n' local part2ca = part2ca .. '\t\t"description": "' .. description .. '",\n\t\t"fill": "' .. fill .. '",\n' local part2ca = part2ca .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":1\n}\n}]}\n \n' local part2cb = '\n\t\t"type":"Polygon"},\n\t"properties":{\n\t\t"title": "' .. title .. '",\n' local part2cb = part2cb .. '\t\t"description": "' .. description .. '",\n\t\t"fill": "' .. fill .. '",\n' local part2cb = part2cb .. '\t\t"stroke":"' .. stroke .. '",\n\t\t"stroke-width":1\n}\n}]}\n \n'

return part1a,part2a,part1b,part2b,part1c,part2ca,part2cb end

-- CIRCLE

function p.circle(frame) local shape = "circle" local id = frame.args['id']	or "" local lat,long = "","" local x,y = 0,0 if id == nil or id == "" then if frame.args['lat'] == nil then error("Missing argument lat!") end if frame.args['long'] == nil then error("Missing argument long!") end lat = frame.args['lat'] long = frame.args['long'] if tonumber(frame.args['lat']) > 90 or tonumber(frame.args['lat']) < -90 then error("Latitude must be between 90 and -90!") end if tonumber(frame.args['long']) > 180 or tonumber(frame.args['long']) < -180 then error("Longitude must be between 180 and -180!") end else id = checkid(id) lat = latitude(id) long = longitude(id) end x = string.format("%.6f",lat) y = string.format("%.6f",long) local marker = frame.args['marker'] or "no" if marker == nil or marker == "" then marker = "no" end local mapframe = frame.args['mapframe'] or "no" if mapframe == nill or mapframe == "" then mapframe = "no" end -- FUTURE USE if tonumber(lat) > 85.35 or tonumber(lat) < -85.35 then error("Latitude must be between 85.35 and -85.35!") end -- END if -- I set this as a default - function will not handle the polar circles yet will still handle areas within the majority of a map if tonumber(long) > 180 or tonumber(long) < -180 then error("Longitude must be between 180 and -180!") end -- END if -- this will draw a full circle at 0 lat and 180 long local group = frame.args['group'] or 'circle' local title = frame.args['title'] or 'A circle' local description = frame.args['desc'] or '' local r = frame.args['radius'] or ".5"  -- default -- radius of 10 is approx. 500 km - futz with sizes - below 3 would probably be adequate -- .1 is about 20km - .0001 is about 30 m               r = tonumber(r) if r > 10 then error("10 for radius is MAX") end  -- END if - my default if r <= 0 then error("radius has to be greater than 0") end -- END if       local fill = frame.args['fill'] or "#ccef64" local stroke = frame.args['stroke'] or "#0000ff" checkhex(fill,stroke) local data = {} local coordinates = "" local ptx,pty,angle = 0,0,0 local type = frame.args['type'] or "line" -- default line for LineString if type ~= "line" then type = "poly" end -- END if

local part1a,part2a,part1b,part2b,part1c,part2ca,part2cb = parts(lat,long,group,title,description,fill,stroke)

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

for i = 1, 360 do          angle = i * math.pi / 180 ptx = x + r * math.cos( angle ) pty = y + r * math.sin( angle ) --        ptx, pty = x + r * math.cos( angle ), y + r * math.sin( angle ) -- original code split for readability above

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

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

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

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

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

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

coordinates = coordinates.gsub(coordinates,'%]%[','],[') coordinates = coordinates.gsub(coordinates,'%]@@@@@%[','],\n[') coordinates = "[" .. coordinates .. ',' .. data[1] .. "],"         -- close the circle extra precautionary measure

if mapframe == "y" or mapframe == "yes" then if type == "poly" then coordinates = string.gsub(coordinates,'%]%,$',']],') coordinates = part1c .. string.gsub(coordinates,'^%[','') .. part2cb			else               coordinates = part1c .. coordinates .. part2ca			end -- END if		else			if type == "poly" then                coordinates  = string.gsub(coordinates,'%]%,,')                ,',') coordinates = part1b .. string.gsub(coordinates,'^%[','[[') .. part2b			else               coordinates = part1a .. coordinates .. part2a			end -- END if				end        if marker == "yes" or marker == "y" then              coordinates = coordinates .. '\n* \n'        end        return coordinates

end

-- END MODULE

return p