Create a gist now

Instantly share code, notes, and snippets.

@osnr /geokit-engine.lua Secret
Last active Aug 17, 2018

Embed
What would you like to do?
Geokit engine
-- Geokit 4th try: perfect fit
local function deg2num(lon, lat, zoom)
local n = 2 ^ zoom
local lon_deg = tonumber(lon)
local lat_rad = math.rad(lat)
local xtile = n * ((lon_deg + 180) / 360)
local ytile = n * (1 - (math.log(math.tan(lat_rad) + (1 / math.cos(lat_rad))) / math.pi)) / 2
return xtile, ytile
end
To know when tile URL /known url/ is downloaded to path /known path/:
local f = io.open(path) -- Try to open that path.
if f ~= nil then -- Tile was downloaded already.
f:close()
Claim tile URL (url) is downloaded to path (path).
else -- Make HTTP request to get the tile.
When URL (url) has contents /contents/:
write_file(path, contents)
Claim tile URL (url) is downloaded to path (path).
End
end
End
function get_tile_url_and_path(url_template, zoom, xtile, ytile)
local url = string.format(url_template, zoom, xtile, ytile)
local filename = url:gsub("%W", "_")
local path = "shared/geokit-tiles/"..filename..".png"
return url, path
end
When /someone/ wishes /page/ shows tilelayer /url_template/ with options /opts/,
/page/ wishes /target/ shows tilelayer /something/ with options /something/,
page ~= target:
opts = rt.table(opts) -- Make a mutable copy of opts
opts.priority = 1 + (opts.priority or 1)
Wish (target) shows tilelayer (url_template) with options (opts).
End
When /someone/ wishes /map/ shows tilelayer /url_template/ with options /opts/,
/map/ is geomap of bbox /bbox/,
/map/ has width /width/, /map/ has height /height/:
-- Made-up formula to guess a good zoom from width of bbox.
local zoom = math.log(360 / (bbox.right - bbox.left)) / math.log(2)
zoom = math.ceil(zoom + width/16 - 1) -- experimentally determined width factor
local max_zoom = opts.max_zoom or 17
if zoom > max_zoom then zoom = max_zoom end
local xtile_left, ytile_top = deg2num(bbox.left, bbox.top, zoom)
local xtile_right, ytile_bottom = deg2num(bbox.right, bbox.bottom, zoom)
local tilesize = width / (xtile_right - xtile_left)
for xtile=math.floor(xtile_left),math.floor(xtile_right) do
for ytile=math.floor(ytile_top),math.floor(ytile_bottom) do
local url, path = get_tile_url_and_path(url_template, zoom, xtile, ytile)
When tile URL (url) is downloaded to path (path):
local ill = new_illumination()
ill:image { filename=path, scale=1,
x=tilesize * (xtile - xtile_left),
y=tilesize * (ytile - ytile_top),
width=tilesize, height=tilesize }
Wish (map) has illumination (ill) with priority (opts.priority or 1).
End
end
end
End
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment