Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion

Planet map

edited October 2014 in General Posts: 154

Simple Google Maps in Codea. You can drag the map around, zoom in and out.


--# Main -- Planet displayMode(OVERLAY) function getBounds(c) local l = math.floor(c.x)-3 local r = l + 5 local t = math.floor(c.y)-2 local b = t + 4 return l,r,t,b end function setup() print("Hello Planet!") uri = "https://khms1.google.com" .. "/kh/v=159&x=%s&y=%s&z=%s" z = 2 w,h = 2^z,2^z c = {x=w/2, y=h/2} l,r,t,b = getBounds(c) tiles = {} pt = nil touches = {} tscale = 1.0 parameter.watch("z") parameter.watch("c.x") parameter.watch("c.y") end function clear(t) local c = 0 for k,v in pairs(t) do c = c + 1 if c > 2 then t[k] = nil end end end function make_placeholder() local tile = image(256, 256) setContext(tile) smooth() fill(65, 59, 94, 255) stroke(30, 32, 59, 255) strokeWidth(1.0) rectMode(CORNER) rect(0,0,256,256) setContext() return tile end function draw_tile(z, x, y) local key = z .. "/" .. x .. "/" .. y local tile = tiles[key] if not tile then if x>=0 and x<w and y>=0 and y<h then print("downloading tile: ",z,x,y) http.request(string.format(uri, x, y, z), function(data, status, headers) if tonumber(status) == 200 then tiles[key] = data end end, function(err) print("oops: "..err) end) end tiles[key], tile = pt, pt end local sx = (x-l)*256 local sy = HEIGHT/tscale-(y-t+1)*256 sprite(tile, sx, sy) end function draw() background(40, 40, 50) if not pt then pt = make_placeholder() end scale(tscale) translate( math.floor(WIDTH/2/tscale-(c.x-l)*256), -math.floor(HEIGHT/2/tscale-(c.y-t)*256)) noSmooth() spriteMode(CORNER) local sx,sy for y=t,b do for x=l,r do draw_tile(z,x,y) end end end function discard(z,l,r,t,b) -- discard specific tile images -- to keep memory usage under control for x=l,r do for y=t,b do local key = z.."/"..x.."/"..y tiles[key] = nil end end collectgarbage() end function touched(touch) -- keep track of multiple touches if touch.state ~= ENDED then touches[touch.id] = touch else touches[touch.id] = nil clear(touches) end -- check for pinch/expand gestures local zt = {} for k,v in pairs(touches) do table.insert(zt, v) end if #zt == 2 then local a,b = zt[1],zt[2] if touch.state == BEGAN then local v1 = vec2(a.x, a.y) local v2 = vec2(b.x, b.y) sd = v1:dist(v2) elseif touch.state == MOVING then local v1 = vec2(a.x, a.y) local v2 = vec2(b.x, b.y) tscale = v1:dist(v2)/sd tscale = math.max(0.5,math.min(2,tscale)) end end if tscale >= 2.0 and touch.state == ENDED and z < 19 then tscale = 1.0 discard(z,l,r,t,b) -- zoom in z = z + 1 w,h = 2^z,2^z c.x = c.x * 2 c.y = c.y * 2 l,r,t,b = getBounds(c) return elseif tscale <= 0.5 and touch.state == ENDED and z > 0 then tscale = 1.0 discard(z,l,r,t,b) -- zoom out z = z - 1 w,h = 2^z,2^z c.x = c.x / 2 c.y = c.y / 2 l,r,t,b = getBounds(c) return end -- drag if touch.state == MOVING then c.x = c.x - touch.deltaX/256 c.y = c.y + touch.deltaY/256 nl,nr,nt,nb = getBounds(c) if nl>l then discard(z,l,l,t,b) elseif nl<l then discard(z,r,r,t,b) end l,r = nl,nr if nt>t then discard(z,l,r,t,t) elseif nt<t then discard(z,l,r,b,b) end t,b = nt,nb end if touch.state == ENDED then tscale = 1.0 end end
Tagged:

Comments

  • Posts: 154

    i edited the code above: broke up the "uri" value into two concatenated strings - to avoid the weird ampersand encoding that was happening with the link. Not super-elegant, but at least the code is correct now.

Sign In or Register to comment.