OpenStreetMap embedded in your application
Posted: Mon Aug 24, 2009 10:10 am
Hello, I give you a new code for embedding OSM in your application.
(If you use it, thank you for talking me... I like seeing what become my code)
Download the package : http://partage.rootslabs.net/SourceCode_OSM.zip
OR
Get the wrapper of LibCurl (files dll, lib, et the two *Inc&Res.pb)
http://code.google.com/p/rwrappers/sour ... nk/LibCurl
(If you use it, thank you for talking me... I like seeing what become my code)
Download the package : http://partage.rootslabs.net/SourceCode_OSM.zip
OR
Get the wrapper of LibCurl (files dll, lib, et the two *Inc&Res.pb)
http://code.google.com/p/rwrappers/sour ... nk/LibCurl
Code: Select all
IncludePath ""
XIncludeFile "RW_LibCurl_Inc.pb"
UsePNGImageDecoder()
UseSQLiteDatabase()
EnableExplicit
Enumeration
#Window_0
#Image_0
#Image_1
#Image_2
#Image_3
#Button_0
#Button_1
#Button_2
#Button_3
#Button_4
#Button_5
#Combo_0
#Text_0
#Text_1
#Text_2
#Text_3
#Text_4
#String_0
#String_1
EndEnumeration
#_DQ_ = Chr(34)
Global gfLatitude.f = 46.97
Global gfLongitude.f = 2.75
Global gfxTile.f
Global gfyTile.f
Global glZoom.l = 6
Global glLayerCur.l = 0
Global glSQLiteDB.l
Global gsSQLiteDBPath.s
Global glGadget.l
Global glEvent.l
Global glQuit.l
Global gRWCurl_Proxy.l = #false
; #True if you use a proxy else #false
Global gRWCurl_ProxyIP.s = ""
Global gRWCurl_ProxyPort.s = ""
Global gRWCurl_ProxyAuthLogin.s = ""
Global gRWCurl_ProxyAuthPwd.s = ""
Structure S_OSM_Layers
sName.s
sURL.s
lZoomMin.l
lZoomMax.l
EndStructure
#OSM_Layers_Num = 5
Global Dim OSM_Layers_Dim.S_OSM_Layers(#OSM_Layers_Num)
OSM_Layers_Dim(0)\sName = "OSM Mapnik"
OSM_Layers_Dim(0)\sURL = "http://tile.openstreetmap.org/"
OSM_Layers_Dim(0)\lZoomMin = 0
OSM_Layers_Dim(0)\lZoomMax = 18
OSM_Layers_Dim(1)\sName = "OSM Osmarender/Tiles@Home"
OSM_Layers_Dim(1)\sURL = "http://tah.openstreetmap.org/Tiles/tile/"
OSM_Layers_Dim(1)\lZoomMin = 0
OSM_Layers_Dim(1)\lZoomMax = 17
OSM_Layers_Dim(2)\sName = "OSM Cycle Map"
OSM_Layers_Dim(2)\sURL = "http://andy.sandbox.cloudmade.com/tiles/cycle/"
OSM_Layers_Dim(2)\lZoomMin = 0
OSM_Layers_Dim(2)\lZoomMax = 18
OSM_Layers_Dim(3)\sName = "OSM Maplint"
OSM_Layers_Dim(3)\sURL = "http://tah.openstreetmap.org/Tiles/maplint/"
OSM_Layers_Dim(3)\lZoomMin = 12
OSM_Layers_Dim(3)\lZoomMax = 16
OSM_Layers_Dim(4)\sName = "NPE out-of-copyright map "
OSM_Layers_Dim(4)\sURL = "http://richard.dev.openstreetmap.org/npe/"
OSM_Layers_Dim(4)\lZoomMin = 13
OSM_Layers_Dim(4)\lZoomMax = 15
Define.f pfValue
;@author : Guimauve
;@url : http://www.purebasic.fr/french/viewtopic.php?t=2322
Procedure.f SinH(Angle.f)
#e = 2.7182818
ProcedureReturn (Pow(#e, angle) - Pow(#e, -angle)) / 2
EndProcedure
;@desc Open the main window
;@author Progi1984
Procedure WindowMain_Open()
If OpenWindow(#Window_0, 260, 225, 700, 571, "OpenStreetMap", #PB_Window_SystemMenu | #PB_Window_TitleBar | #PB_Window_ScreenCentered )
LoadFont(0,"Wingdings",12)
LoadFont(1,"Arial",12,#PB_Font_Bold)
ImageGadget(#Image_0, 10, 10, 256, 256, 0)
ImageGadget(#Image_1, 266, 10, 256, 256, 0)
ImageGadget(#Image_2, 10, 266, 256, 256, 0)
ImageGadget(#Image_3, 266, 266, 256, 256, 0)
TextGadget(#Text_0, 530, 10, 60, 15, "Layers :")
ComboBoxGadget(#Combo_0, 550, 30, 130, 20)
AddGadgetItem(#Combo_0, 0, OSM_Layers_Dim(0)\sName)
AddGadgetItem(#Combo_0, 1, OSM_Layers_Dim(1)\sName)
AddGadgetItem(#Combo_0, 2, OSM_Layers_Dim(2)\sName)
AddGadgetItem(#Combo_0, 3, OSM_Layers_Dim(3)\sName)
AddGadgetItem(#Combo_0, 4, OSM_Layers_Dim(4)\sName)
SetGadgetState(#Combo_0, 0)
TextGadget(#Text_1, 530, 50, 60, 15, "Movements :")
ButtonGadget(#Button_0, 550, 100, 30, 30, Chr($E7)) : SetGadgetFont(#Button_0, FontID(0))
ButtonGadget(#Button_1, 610, 100, 30, 30, Chr($E8)) : SetGadgetFont(#Button_1, FontID(0))
ButtonGadget(#Button_2, 580, 070, 30, 30, Chr($E9)) : SetGadgetFont(#Button_2, FontID(0))
ButtonGadget(#Button_3, 580, 130, 30, 30, Chr($EA)) : SetGadgetFont(#Button_3, FontID(0))
TextGadget(#Text_2, 530, 160, 60, 15, "Zoom :")
ButtonGadget(#Button_4, 550, 180, 50, 30, "+") : SetGadgetFont(#Button_4, FontID(1))
ButtonGadget(#Button_5, 600, 180, 50, 30, "-") : SetGadgetFont(#Button_5, FontID(1))
TextGadget(#Text_3, 530, 230, 60, 15, "Latitude :")
StringGadget(#String_0, 600, 230, 50, 20, "46.97",#PB_String_ReadOnly|#PB_String_BorderLess)
TextGadget(#Text_4, 530, 250, 60, 15, "Longitude :")
StringGadget(#String_1, 600, 250, 50, 20, "2.75",#PB_String_ReadOnly|#PB_String_BorderLess)
EndIf
EndProcedure
;@desc Permits to translate XY Coordinates to Lon/Lat Coordinates
;@author Progi1984
Procedure OSM_LatLon2XY()
Protected n.l = Pow(2, glZoom)
gfxTile = Int(((gfLongitude + 180) / 360) * n)
gfyTile = Int((1-(Log(Tan(gfLatitude * #PI / 180)+(1/Cos(gfLatitude*#PI/180)))/#PI))/2*n)
EndProcedure
;@desc Permits to translate Lon/Lat Coordinates to XY Coordinates
;@author Progi1984
Procedure OSM_XY2LatLon()
Protected n.l = Pow(2, glZoom)
Protected pfLatitudeRad.f
gfLongitude = gfxTile / n * 360.0 - 180.0
pfLatitudeRad = ATan(SinH(#PI * (1 - 2 * gfyTile / n)))
gfLatitude = pfLatitudeRad * 180.0 / #PI
EndProcedure
;@desc Draws 4 subtiles for the XY Coordinates
;@author Progi1984
Macro OSM_GetSquareTile()
Debug "======"
OSM_GetImage(0, glZoom+1,2*gfxTile ,2*gfyTile)
OSM_GetImage(1, glZoom+1,2*gfxTile+1,2*gfyTile)
OSM_GetImage(2, glZoom+1,2*gfxTile ,2*gfyTile+1)
OSM_GetImage(3, glZoom+1,2*gfxTile+1,2*gfyTile+1)
Debug "======"
EndMacro
Macro OSM_TestXYCoordinates(_CoordTile_, _Inc_, _Test_)
pfValue = _CoordTile_ _Inc_ 0.5
If pfValue _Test_
_CoordTile_ = Pow(2, glZoom) - 2
Else
_CoordTile_ = pfValue
EndIf
EndMacro
Procedure OSM_GetImage(Image.l, Zoom.l, XTile.l, YTile.l)
Protected psProxyURL.s = gRWCurl_ProxyIP+":"+gRWCurl_ProxyPort
Protected psProxyAuth.s = gRWCurl_ProxyAuthLogin+":"+gRWCurl_ProxyAuthPwd
Protected plMemory.l
Protected psURL.s = OSM_Layers_Dim(glLayerCur)\sURL+Str(Zoom)+"/"+Str(XTile)+"/"+Str(YTile)+".png"
Protected gPWRCurl = curl_easy_init()
Protected plImageSize.l
Protected plImageMem.l
Protected psSQLRequest.s
Protected pbImageOK.b
Protected plRes.l
; Test if in cache else download it
DatabaseQuery(glSQLiteDB, "SELECT * FROM cache WHERE cache_layer="+#_DQ_+Str(glLayerCur)+#_DQ_+" AND cache_zoom="+#_DQ_+Str(Zoom)+#_DQ_+" AND cache_x="+#_DQ_+Str(XTile)+#_DQ_+" AND cache_y="+#_DQ_+Str(YTile)+#_DQ_+"")
If FirstDatabaseRow(glSQLiteDB)
Debug "CACHE : "+Str(glLayerCur)+"\"+Str(Zoom)+"\"+Str(XTile)+"\"+Str(Ytile)
plImageSize = GetDatabaseLong(glSQLiteDB,6)
If plImageSize
plImageMem = AllocateMemory(plImageSize)
GetDatabaseBlob(glSQLiteDB, 5, plImageMem, plImageSize)
FinishDatabaseQuery(glSQLiteDB)
If CatchImage(0, plImageMem)
SetGadgetState(#Image_0+Image, ImageID(0))
FreeImage(0)
FreeMemory(plImageMem)
EndIf
pbImageOK = #True
EndIf
Else
Debug DatabaseError()
EndIf
If pbImageOK = #False
Debug "DOWNLOAD : "+Str(glLayerCur)+"\"+Str(Zoom)+"\"+Str(XTile)+"\"+Str(Ytile)
RW_LibCurl_InitData()
If gRWCurl_Proxy = #True
curl_easy_setopt(gPWRCurl, #CURLOPT_HTTPPROXYTUNNEL, #True)
curl_easy_setopt(gPWRCurl, #CURLOPT_PROXY, @psProxyURL)
If psProxyAuth <> ""
curl_easy_setopt(gPWRCurl, #CURLOPT_PROXYUSERPWD, @psProxyAuth)
EndIf
EndIf
curl_easy_setopt(gPWRCurl, #CURLOPT_URL, @psURL)
curl_easy_setopt(gPWRCurl, #CURLOPT_WRITEFUNCTION, @RW_LibCurl_WriteDataFunction())
curl_easy_perform(gPWRCurl)
curl_easy_cleanup(gPWRCurl)
plMemory = RW_LibCurl_GetData()
If plMemory
psSQLRequest = "INSERT INTO cache(cache_layer, cache_zoom, cache_x, cache_y, cache_image, cache_imagesize) VALUES ("
psSQLRequest + Str(glLayerCur)+","
psSQLRequest + Str(Zoom)+","
psSQLRequest + Str(XTile)+","
psSQLRequest + Str(YTile)+","
psSQLRequest + "?,"
psSQLRequest + Str(MemorySize(plMemory))+")"
SetDatabaseBlob(glSQLiteDB, 0, plMemory, MemorySize(plMemory))
plRes = DatabaseUpdate(glSQLiteDB, psSQLRequest)
If plRes = 0
Debug psSQLRequest
Debug DatabaseError()
EndIf
If CatchImage(0, plMemory, MemorySize(plMemory))
SetGadgetState(#Image_0+Image, ImageID(0))
FreeImage(0)
FreeMemory(plMemory)
EndIf
EndIf
EndIf
EndProcedure
Procedure OSM_CacheInit()
Protected psSQLRequest.s
If gsSQLiteDBPath = ""
gsSQLiteDBPath = GetCurrentDirectory()+"OSMCache.sqlite"
EndIf
If FileSize(gsSQLiteDBPath) <= 0
If CreateFile(0, gsSQLiteDBPath)
CloseFile(0)
EndIf
glSQLiteDB = OpenDatabase(#PB_Any, gsSQLiteDBPath, "", "")
If glSQLiteDB
psSQLRequest = "CREATE TABLE "+#_DQ_+"main"+#_DQ_+"."+#_DQ_+"cache"+#_DQ_+" ("
psSQLRequest + #_DQ_+"id_cache"+#_DQ_+" INTEGER PRIMARY KEY AUTOINCREMENT Not NULL , "
psSQLRequest + #_DQ_+"cache_layer"+#_DQ_+" INTEGER Not NULL Default 0, "
psSQLRequest + #_DQ_+"cache_zoom"+#_DQ_+" INTEGER Not NULL , "
psSQLRequest + #_DQ_+"cache_x"+#_DQ_+" INTEGER Not NULL , "
psSQLRequest + #_DQ_+"cache_y"+#_DQ_+" INTEGER Not NULL , "
psSQLRequest + #_DQ_+"cache_image"+#_DQ_+" BLOB, "
psSQLRequest + #_DQ_+"cache_imagesize"+#_DQ_+" INTEGER Not NULL"
psSQLRequest + ")"
DatabaseUpdate(glSQLiteDB, psSQLRequest)
EndIf
Else
glSQLiteDB = OpenDatabase(#PB_Any, gsSQLiteDBPath, "", "")
EndIf
EndProcedure
WindowMain_Open()
; Init DB
OSM_CacheInit()
; Init Map
OSM_LatLon2XY()
OSM_GetSquareTile()
Repeat
glEvent = WaitWindowEvent()
Select glEvent
Case #PB_Event_CloseWindow : glQuit = 1
Case #PB_Event_Gadget ;{
glGadget = EventGadget()
Select glGadget
Case #Button_0 ;{ To left
OSM_TestXYCoordinates(gfxTile, -, < 0)
OSM_GetSquareTile()
OSM_XY2LatLon()
SetGadgetText(#String_1, StrF(gfLongitude))
;}
Case #Button_1 ;{ To Right
OSM_TestXYCoordinates(gfxTile, +,> Pow(2, glZoom) - 1)
OSM_GetSquareTile()
OSM_XY2LatLon()
SetGadgetText(#String_1, StrF(gfLongitude))
;}
Case #Button_2 ;{ To Top
OSM_TestXYCoordinates(gfyTile, -, < 0)
OSM_GetSquareTile()
OSM_XY2LatLon()
SetGadgetText(#String_0, StrF(gfLatitude))
;}
Case #Button_3 ;{ To Bottom
OSM_TestXYCoordinates(gfyTile, +, > Pow(2, glZoom) - 1)
OSM_GetSquareTile()
OSM_XY2LatLon()
SetGadgetText(#String_0, StrF(gfLatitude))
;}
Case #Button_4 ;{ Zoom +
If glZoom < OSM_Layers_Dim(glLayerCur)\lZoomMax
glZoom + 1
OSM_LatLon2XY()
OSM_GetSquareTile()
EndIf
;}
Case #Button_5 ;{ Zoom -
If glZoom > OSM_Layers_Dim(glLayerCur)\lZoomMin
glZoom - 1
OSM_LatLon2XY()
OSM_GetSquareTile()
EndIf
;}
Case #Combo_0 ;{ Layers
pfValue = GetGadgetState(#Combo_0)
If pfValue >= 0 And pfValue < #OSM_Layers_Num And pfValue <> glLayerCur
; Current Layer
glLayerCur = pfValue
; Zoom
If glZoom < OSM_Layers_Dim(glLayerCur)\lZoomMin
glZoom = OSM_Layers_Dim(glLayerCur)\lZoomMin +1
EndIf
If glZoom > OSM_Layers_Dim(glLayerCur)\lZoomMax
glZoom = OSM_Layers_Dim(glLayerCur)\lZoomMax
EndIf
OSM_LatLon2XY()
OSM_GetSquareTile()
EndIf
;}
EndSelect
;}
EndSelect
Until glQuit = 1