Openstreet Maps

Some bare code to draw an openstreet map ( http://www.openstreetmap.org )in Codea.

And one question: how can I know when an http.request is completed ? This code starts draw before tiles are actually downloaded.
How can I overcome that?

-- openmaps first final version, bare functions, no interface 
displayMode(FULLSCREEN)
function setup()

pi=math.pi 
flow_doit=1
flow_drawit=1

end

-- This function gets called once every frame
function draw()
    background(40, 40, 50)
    
    -- PUT HERE YOUR COORDS
    
    xcenter=23.8 ---lon
    
    ycenter=38.01 ---lat
    
    z=15-- THE ZOOM LEVEL
    
    xdraw,ydraw=CalcTiles(xcenter,ycenter,z)
    DrawTiles()

end

function CalcTiles(lon,lat,zoom)
    local x=lon; local y=lat ;local n=2^zoom ; local zoom=zoom
-- calculate the tiles pair   
    x=(x/180)*pi 
    x=math.ceil(0.5*(1+(x/pi))*n)
    local yr=(y/180)*pi
    y=math.tan(yr)+(1/math.cos(yr))
    yr=math.log(y)/pi
    y=math.ceil((1-yr)/2 *n)
-- the tiles pair is x,y
SaveTiles(x,y,zoom) ---ok download and save the tiles on disk

--  here some calcuations regarding the scale etc    
--  you dont need them to draw the map
    lonx,lony=scaleofmap(x,y,n)
    lonx1,lony1=scaleofmap(x+1,y-1,n)
    
    difx=lonx1-lonx
    dify=lony1-lony
    
    drx=((lonx-xcenter)/difx)*256
    dry=((lony-ycenter)/dify)*256

return x,y
end --CalcTiles

function SaveTiles(x,y,zoom)
    
-- these are some URLS with tiles, choose as you like

--local url1="http://otile1.mqcdn.com/tiles/1.0.0/map/"
-- local url1="http://oatile1.mqcdn.com/naip/"
--local url1="http://a.tile.openstreetmap.org/"
local url1="http://a.tile.opencyclemap.org/cycle/"


local x=x; local y=y local zoom=zoom
   
-- flow_doit=0 --if you are playing with drawing make it 0 to dont download the tiles agn and agn
if flow_doit==1 then
flow_doit=0 ; flow_drawit=1 --dont read again the tiles in this session

local x2=x-2
for ix=1,4 do
    local y2=y-2
    
    for iy=1,3 do
    local url=url1..zoom.."/"..x2.."/"..y2..".png"
   -- local imgnam= 'Documents:'..x2.."_"..y2
    local imgnam= 'Dropbox:'..x2.."_"..y2 --choose disk
    
            http.request(url, function(img,status,head)
            saveImage(imgnam,img)
            end ) -- download and save the tiles, sometimes it takes long
                  -- if you see a blank screen just restart the app
    
    y2=y2+1
    end --iy
    
x2=x2+1
end --ix 
end --if doit
return
end --SaveTiles
    
function scaleofmap(x,y,n)
local   lonx=(x/n *360)-180
local   lony=pi*(1-2*y/n)
        lony=math.sinh(lony)
        lony=math.atan(lony)
        lony=math.deg(lony)
 return lonx,lony  
end --scaleofmap

-- DrawTiles
-- last edit 2Dec
-- read the tiles from the local storage and draw the map on screen
function DrawTiles()
    pushStyle()
    
    if flow_drawit==1 then --dont regenerate the image if you didnt load another map
        flow_drawit=0
        
    mapImage=image(1024,768)
    setContext(mapImage)  
    local posx=0; local x2=xdraw-2
    for ix=1,4 do --4 tiles 256px horizontal
    
    local posy=512; local y2=ydraw-2   
    for iy=1,3 do --3 tiles 256px vertical
   -- local imgnam= 'Documents:'..x2.."_"..y2
    local imgnam= 'Dropbox:'..x2.."_"..y2
    
    spriteMode(CORNER); sprite(imgnam, posx,posy)

    
    --enable these if you want to see tile's corners
    --fill(252, 149, 8, 255)
    --strokeWidth(0)
    --ellipseMode(CENTER)
    --ellipse(posx,posy,15)
    
    posy=posy-256
    y2=y2+1
    
    end --iy

    x2=x2+1
    posx=posx+256
    end --ix 

---end making the mapImage

-- here is the point you choose as original coordinates
strokeWidth(0)
fill(227, 43, 29, 255)
ellipseMode(CENTER)
ellipse(WIDTH/2-drx,HEIGHT/2 -256/2-dry ,15)

--- ---

setContext()  --stop drawing on mapImage
  end --if drawit  

clip(0,30,1024,738) --draw the image on screen
    spriteMode(CENTER)
    sprite(mapImage,WIDTH/2, HEIGHT/2)
clip()

popStyle()
end

Maybe you can have a loading icon shown before the image tiles are loaded. Ive used something similar when loading tiles from google maps, and storing the downloaded tiles in Documents locally.


tiles = {}
function loadTile(x, y)
    local url = "Documents:gmap" .. x .. "-" .. y
    local im = readImage(url)
    if im then
        tiles[x .. "-" .. y] = im
        return
    end
    
    local lat,long = 58.592, 16.189
    local ts = 300
    long = long + x*3.86/ts
    lat = lat + y*2/ts
    http.get( 
        "http://maps.googleapis.com/maps/api/staticmap?"..
 --       "center=norrkoping" ..
        "center="..lat..","..long..
        "&maptype=hybrid&zoom=15&size="..
        ts.."x".. ts.."&maptype=satellite&sensor=true", 
        function (tile)
            saveImage(url, tile)
            tiles[x .. "-" .. y] = tile
        end
    )
end

Thanks @tnlogy , seems ok now.