Tient j'ai testé de passer l'affichage en utilisant le VectorDrawing ça permet de faire quelques choses de plus propre pour tracer un chemin
si ça t'amuse voilà mon dernier code. Je n'ai pas retouché a la partie affichage je te laisse cette partie.
Code : Tout sélectionner
;**************************************************************
; Program: OSM (OpenStreetMap Module)
; Author: Thyphoon And Djes
; Date: Mai 17, 2016
; License: Free, unrestricted, credit appreciated
; but not required.
; Note: Please share improvement !
; Thanks: Progi1984 for the first OSM implementation
; Fred, Freak and all people who made purebasic what is it !
;**************************************************************
InitNetwork()
CompilerIf #PB_Compiler_Thread=0
MessageRequester("Warning !!","You must to Enable 'create ThreadSafe' in compiler option",#PB_MessageRequester_Ok )
End
CompilerEndIf
DeclareModule OSM
Declare InitOSM()
Declare OSMGadget(Gadget.i, X.i, Y.i, Width.i, Height.i)
Declare Event(Event.l)
Declare SetLocation(latitude.d, longitude.d, zoom = 15)
Declare SetZoom(Zoom.i, mode.i = #PB_Relative)
Declare LoadGpxFile(file.s);
Declare ZoomToArea()
Declare ConstructMap()
Declare DrawMap()
EndDeclareModule
Module OSM
#USEPROXY = #False
UsePNGImageDecoder()
UsePNGImageEncoder()
Enumeration #PB_Event_FirstCustomValue
#EvenementStartRefresh
#EvenementStopRefresh
EndEnumeration
CompilerIf #USEPROXY = #True
IncludeFile("C:\Users\lebrun_y_413\Documents\Developpement\Purebasic\includes Share\http.pbi")
CompilerEndIf
Structure Location
Longitude.d
Latitude.d
EndStructure
Structure Tile
X.d
Y.d
EndStructure
Structure Pixel
X.i
Y.i
EndStructure
Structure ImgMemCach
nImage.i
Zoom.i
XTile.i
YTile.i
EndStructure
Structure TileMemCach
List Image.ImgMemCach()
Mutex.i
Semaphore.i
EndStructure
Structure OSM
Windows.i ;
Gadget.i ; Canvas Gadget Id
TargetLocation.Location ; Latitude and Longitude from focus point
TargetTile.Tile ; Focus Tile coord
Position.Pixel ; Focus Point coord in Pixel
ServerURL.s ; Web Url ex: http://tile.openstreetmap.org/
ZoomMin.i ; Min Zoom supported by Server
ZoomMax.i ; Max Zoom supported by Server
Zoom.i ; Current Zoom
TileSize.i ; Tile Size downloaded on the server ex : 256
HDDCachePath.S ; path where to load an save tile downloaded from server
MemCache.TileMemCach ; to know image always in memory
; List MapImageIndex.ImgMemCach() ; List of Index from MemCache\Image() to construct map
Array MapImage.ImgMemCach(16,16)
MapImageMutex.i ; Mutex to lock
MapImageSemaphore.i ; Semaphore to control Thread
StartCursor.Pixel ; coord from start drag the map
DeltaCursor.Pixel ; delta from curent position and the start position
List track.Location() ;to display a track GPX on card
EndStructure
Global OSM.OSM
Procedure OSMGadget(Gadget.i, X.i, Y.i, Width.i, Height.i)
If Gadget = #PB_Any
OSM\Gadget = CanvasGadget(OSM\Gadget, X, Y, Width, Height)
Else
OSM\Gadget = Gadget
CanvasGadget(OSM\Gadget, X, Y, Width, Height)
EndIf
EndProcedure
Procedure LatLon2XY(*Location.Location, *Tile.Tile)
Protected n.d = Pow(2.0, OSM\Zoom)
Protected LatRad.d = Radian(*Location\Latitude)
*Tile\X = n * ( (*Location\Longitude + 180.0) / 360.0)
*Tile\Y = n * ( 1.0 - Log(Tan(LatRad) + 1.0/Cos(LatRad)) / #PI ) / 2.0
;Debug "Latitude : " + StrD(*Location\Latitude) + " ; Longitude : " + StrD(*Location\Longitude)
;Debug "Tile X : " + Str(*Tile\X) + " ; Tile Y : " + Str(*Tile\Y)
EndProcedure
Procedure XY2LatLon(*Tile.Tile, *Location.Location)
Protected n.d = Pow(2.0, OSM\Zoom)
Protected LatitudeRad.d
*Location\Longitude = *Tile\X / n * 360.0 - 180.0
LatitudeRad = ATan(SinH(#PI * (1.0 - 2.0 * *Tile\Y / n)))
*Location\Latitude = Degree(LatitudeRad)
EndProcedure
Procedure getPixelCoorfromLocation(*Location.Location,*Pixel.Pixel) ; TODO to Optimize
Protected mapWidth.l = Pow(2,OSM\Zoom+8)
Protected mapHeight.l = Pow(2,OSM\Zoom+8)
Protected x1.l,y1.l
; get x value
x1 = (*Location\Longitude+180)*(mapWidth/360)
; convert from degrees To radians
Protected latRad.d = *Location\Latitude*#PI/180;
Protected mercN.d = Log(Tan((#PI/4)+(latRad/2)));
y1 = (mapHeight/2)-(mapWidth*mercN/(2*#PI)) ;
Protected x2.l,y2.l
; get x value
x2 = (OSM\TargetLocation\Longitude+180)*(mapWidth/360)
; convert from degrees To radians
latRad = OSM\TargetLocation\Latitude*#PI/180;
; get y value
mercN = Log(Tan((#PI/4)+(latRad/2))) ;
y2 = (mapHeight/2)-(mapWidth*mercN/(2*#PI));
*Pixel\X=GadgetWidth(OSM\Gadget)/2-(x2-x1)+ OSM\DeltaCursor\X
*Pixel\Y=GadgetHeight(OSM\Gadget)/2-(y2-y1)+ OSM\DeltaCursor\Y
EndProcedure
Procedure distance(*posA.Location,*posB.Location)
Protected R.l = 6371; // km
Protected dLat.d = Radian(*posB\Latitude-*posA\Latitude);
Protected dLon.d = Radian(*posB\Longitude-*posA\Longitude)
Protected lat1.d = Radian(*posA\Latitude);
Protected lat2.d = Radian(*posB\Latitude);
Protected a.d = Sin(dLat/2) * Sin(dLat/2) + Sin(dLon/2) * Sin(dLon/2) * Cos(lat1) * Cos(lat2);
Protected c.d = 2 * ATan2(Sqr(a), Sqr(1-a));
Protected distance.d = R * c ;
ProcedureReturn distance
EndProcedure
; HaversineAlgorithm
Procedure.d HaversineInKM(*posA.Location,*posB.Location)
Static eQuatorialEarthRadius.d = 6378.1370;
Protected dlong.d = Radian(*posB\Longitude - *posA\Longitude);
Protected dlat.d = Radian(*posB\Latitude - *posA\Latitude);
Protected a.d = Pow(Sin(dlat / 2), 2) + Cos(Radian(*posA\Latitude)) * Cos(Radian(*posB\Latitude))* Pow(Sin(dlong / 2), 2);
Protected c.d = 2 * ATan2(Sqr(a), Sqr(1 - a));
Protected didstance.d = eQuatorialEarthRadius * c;
ProcedureReturn d;
EndProcedure
Procedure.d HaversineInM(*posA.Location,*posB.Location)
ProcedureReturn (1000 * HaversineInKM(@*posA,@*posB));
EndProcedure
Procedure LoadGpxFile(file.s)
If LoadXML(0, file.s)
Protected Message.s
If XMLStatus(0) <> #PB_XML_Success
Message = "Error in the XML file:" + Chr(13)
Message + "Message: " + XMLError(0) + Chr(13)
Message + "Line: " + Str(XMLErrorLine(0)) + " Character: " + Str(XMLErrorPosition(0))
MessageRequester("Error", Message)
EndIf
Protected *MainNode,*subNode,*child,child.l
*MainNode=MainXMLNode(0)
*MainNode=XMLNodeFromPath(*MainNode,"/gpx/trk/trkseg")
ClearList(OSM\track())
For child = 1 To XMLChildCount(*MainNode)
*child = ChildXMLNode(*MainNode, child)
AddElement(OSM\track())
If ExamineXMLAttributes(*child)
While NextXMLAttribute(*child)
Select XMLAttributeName(*child)
Case "lat"
OSM\track()\Latitude=ValD(XMLAttributeValue(*child))
Case "lon"
OSM\track()\Longitude=ValD(XMLAttributeValue(*child))
EndSelect
Wend
EndIf
Next
EndIf
EndProcedure
Procedure AddTileToMemCache(Zoom.i, XTile.i, YTile.i,nImage.i)
Protected Index.i
If IsImage(nImage)
LockMutex(OSM\MemCache\Mutex)
;We add To the List And load it
FirstElement(OSM\MemCache\Image())
AddElement(OSM\MemCache\Image())
Index=ListIndex(OSM\MemCache\Image())
OSM\MemCache\Image()\XTile=XTile
OSM\MemCache\Image()\YTile=YTile
OSM\MemCache\Image()\Zoom=Zoom
OSM\MemCache\Image()\nImage=nImage
UnlockMutex(OSM\MemCache\Mutex)
ProcedureReturn Index
Else
Debug "NO ADD TILE TO MEM CACHE BECAUSE BAD IMAGE"
EndIf
EndProcedure
Procedure.i GetTileFromMem(Zoom.i, XTile.i, YTile.i)
Protected nImage.i
LockMutex(OSM\MemCache\Mutex)
;Check if we have this Image in Memory
ForEach OSM\MemCache\Image()
If Zoom=OSM\MemCache\Image()\Zoom And OSM\MemCache\Image()\XTile=XTile And OSM\MemCache\Image()\YTile=YTile
nImage=OSM\MemCache\Image()\nImage
Debug "Load From MEM Tile X : " + Str(XTile) + " ; Tile Y : " + Str(YTile)+" IsImage:"+Str(IsImage(nImage))
Break;
;TODO Find a better way to clean Image in memory
; Clean Image in memory
ElseIf Zoom<>OSM\MemCache\Image()\Zoom
FreeImage(OSM\MemCache\Image()\nImage)
DeleteElement(OSM\MemCache\Image())
ElseIf ( OSM\MemCache\Image()\XTile<OSM\TargetTile\X-5 And OSM\MemCache\Image()\XTile>OSM\TargetTile\X+5 And OSM\MemCache\Image()\YTile<OSM\TargetTile\Y-5 And OSM\MemCache\Image()\YTile>OSM\TargetTile\Y+5 )
FreeImage(OSM\MemCache\Image()\nImage)
DeleteElement(OSM\MemCache\Image())
EndIf
Next
UnlockMutex(OSM\MemCache\Mutex)
ProcedureReturn nImage
EndProcedure
Procedure.i GetTileFromHDD(Zoom.i, XTile.i, YTile.i)
Protected nImage.i
Protected CacheFile.s = "OSM_" + Str(Zoom) + "_" + Str(XTile) + "_" + Str(YTile) + ".png"
If FileSize(OSM\HDDCachePath + cacheFile) > 0
nImage=LoadImage(#PB_Any, OSM\HDDCachePath + CacheFile)
If IsImage(nImage)
Debug "Load From HDD Tile X : " + Str(XTile) + " ; Tile Y : " + Str(YTile)+ "IsImage:"+Str(IsImage(nImage))
AddTileToMemCache(Zoom, XTile, YTile,nImage)
ProcedureReturn nImage
EndIf
EndIf
ProcedureReturn #False
EndProcedure
Procedure.i GetTileFromWeb(Zoom.i, XTile.i, YTile.i)
Protected *Buffer
Protected nImage.i
Protected CacheFile.s = "OSM_" + Str(Zoom) + "_" + Str(XTile) + "_" + Str(YTile) + ".png"
Protected TileURL.s = OSM\ServerURL + Str(Zoom) + "/" + Str(XTile) + "/" + Str(YTile) + ".png"
;Debug "DOWNLOAD : " + psURL
CompilerIf #USEPROXY = #True
Protected http.HTTP_Query
HTTP_proxy(@http, "spxy.bpi.fr", 3128)
HTTP_DownloadToMem(@http, TileURL)
nImage=CatchImage(#PB_Any, http\data, MemorySize(http\data))
If IsImage(nImage)
AddTileToMemCache(Zoom, XTile, YTile,nImage)
SaveImage(nImage, OSM\HDDCachePath + CacheFile, #PB_ImagePlugin_PNG)
Debug "Load From WEB Tile X : " + Str(XTile) + " ; Tile Y : " + Str(YTile)
EndIf
CompilerElse
*Buffer = ReceiveHTTPMemory(TileURL)
If *Buffer
nImage=CatchImage(#PB_Any, *Buffer, MemorySize(*Buffer))
If IsImage(nImage)
AddTileToMemCache(Zoom, XTile, YTile,nImage)
SaveImage(nImage, OSM\HDDCachePath + CacheFile, #PB_ImagePlugin_PNG)
Debug "Load From WEB Tile X : " + Str(XTile) + " ; Tile Y : " + Str(YTile)
FreeMemory(*Buffer)
Else
Debug "Can't catch image :" + TileURL
EndIf
Else
Debug "Problem loading :" + TileURL
EndIf
CompilerEndIf
ProcedureReturn nImage
EndProcedure
Procedure GetTile(*Index.ImgMemCach)
Protected Zoom.i, XTile.i, YTile.i
Zoom=*Index\Zoom
XTile=*Index\XTile
YTile=*Index\YTile
Protected nImage.i
nImage=GetTileFromMem(Zoom, XTile, YTile)
If nImage=0
nImage=GetTileFromHDD(Zoom, XTile, YTile)
If nImage=0
nImage=GetTileFromWeb(Zoom, XTile, YTile)
If nImage=0
Debug "Error GetTile Procedure : can't Load this Tile" ; TODO Check Why !!!
ProcedureReturn #False
EndIf
EndIf
EndIf
*Index\nImage=nImage
SignalSemaphore(OSM\MapImageSemaphore)
EndProcedure
Procedure ThreadConstructMap(z.i)
PostEvent(#EvenementStartRefresh)
Protected x.i, y.i
Protected nx.i = (GadgetWidth(OSM\Gadget)/OSM\TileSize)*2 ;How many tiles
Protected ny.i = (GadgetHeight(OSM\Gadget)/OSM\TileSize)*2
Protected tx.i = Int(OSM\TargetTile\X)
Protected ty.i = Int(OSM\TargetTile\Y)
Protected mx.i=Int(nx/2)
Protected my.i=Int(ny/2)
LockMutex(OSM\MapImageMutex)
For y = 0 To nx
For x = 0 To ny
WaitSemaphore(OSM\MapImageSemaphore)
OSM\MapImage(x,y)\XTile=tx+x-mx
OSM\MapImage(x,y)\YTile=ty+y-my
OSM\MapImage(x,y)\Zoom=OSM\Zoom
Protected th.i
th.i=CreateThread(@GetTile(),@OSM\MapImage(x,y))
Next
Next
UnlockMutex(OSM\MapImageMutex)
WaitThread(th)
PostEvent(#EvenementStopRefresh)
EndProcedure
Procedure ConstructMap()
CreateThread(@ThreadConstructMap(),0)
EndProcedure
Procedure DrawMap()
Static myTimer.i
If myTimer=0 Or ElapsedMilliseconds()-myTimer>250 ;To limit refreash
Protected x.i, y.i, nx.i, ny.i, mx.i, my.i, n.i = 0
Protected deltaX.i, deltaY.i
Protected nImage.i
Protected x2.i, y2.i
LockMutex(OSM\MapImageMutex)
deltaX = OSM\TileSize*(OSM\TargetTile\X - Int(OSM\TargetTile\X))
deltaY = OSM\TileSize*(OSM\TargetTile\Y - Int(OSM\TargetTile\Y))
mx = GadgetWidth(OSM\Gadget)/2
my = GadgetHeight(OSM\Gadget)/2
nx = (GadgetWidth(OSM\Gadget)/OSM\TileSize)*2 ;How many tiles
ny = (GadgetWidth(OSM\Gadget)/OSM\TileSize)*2
StartVectorDrawing(CanvasVectorOutput(OSM\Gadget))
AddPathBox(0, 0, GadgetWidth(OSM\Gadget), GadgetHeight(OSM\Gadget))
VectorSourceColor(RGBA(255, 255, 255, 255))
StrokePath(10)
For y = 0 To nx
For x = 0 To ny
x2 = x*256 + OSM\DeltaCursor\X + mx -deltaX-(nx/2)*OSM\TileSize
y2 = y*256 + OSM\DeltaCursor\Y + my - deltaY-(ny/2)*OSM\TileSize
nImage=OSM\MapImage(x,y)\nImage
If nimage=0
MovePathCursor(x2, y2+20)
DrawVectorText( "Loading")
ElseIf IsImage(nImage) And (x2 + 256) > 0 And (y2 + 256) > 0 And x2 < GadgetWidth(OSM\Gadget) And y2 < GadgetHeight(OSM\Gadget)
MovePathCursor(x2,y2)
DrawVectorImage(ImageID(nImage))
Else
MovePathCursor(x2, y2+20)
DrawVectorText("Error Loading")
EndIf
Next
Next
UnlockMutex(OSM\MapImageMutex)
;Circle(GadgetWidth(OSM\Gadget)/2, GadgetHeight(OSM\Gadget)/2, 5, RGB(Random(255),Random(255),Random(255)))
;DrawText(0, 0, "DeltaCursorX : " + Str(OSM\DeltaCursor\X) + " deltaX : " + Str(deltaX) + " Tile X : " + StrD(OSM\TargetTile\X))
;DrawText(0, 16, "Image loaded:"+Str(ListSize(OSM\MemCache\Image())))
; Draw Track
Protected Pixel.Pixel
Protected Location.Location
ForEach OSM\track()
If ListIndex(OSM\track())=0
Location\Latitude=OSM\track()\Latitude
Location\Longitude=OSM\track()\Longitude
EndIf
If ListIndex(OSM\track())=50
; Debug HaversineInKM(@Location,@OSM\track())
Location\Latitude=OSM\track()\Latitude
Location\Longitude=OSM\track()\Longitude
EndIf
If @OSM\TargetLocation\Latitude<>0 And @OSM\TargetLocation\Longitude<>0
getPixelCoorfromLocation(@OSM\track(),@Pixel)
x=Pixel\X
y=Pixel\Y
;If x>0 And y>0 And x<GadgetWidth(OSM\Gadget) And y<GadgetHeight(OSM\Gadget)
If ListIndex(OSM\track())=0
MovePathCursor(x,y)
Else
AddPathLine(x,y)
EndIf
;EndIf
EndIf
Next
VectorSourceColor(RGBA(0, 255, 0, 150))
StrokePath(10, #PB_Path_RoundEnd|#PB_Path_RoundCorner)
StopVectorDrawing()
myTimer=ElapsedMilliseconds()
EndIf
EndProcedure
Procedure SetLocation(latitude.d, longitude.d, zoom = 15)
If zoom > OSM\ZoomMax : zoom = OSM\ZoomMax : EndIf
If zoom < OSM\ZoomMin : zoom = OSM\ZoomMin : EndIf
OSM\Zoom = zoom
OSM\TargetLocation\Latitude = latitude
OSM\TargetLocation\Longitude = longitude
LatLon2XY(@OSM\TargetLocation, @OSM\TargetTile)
OSM\Position\X = OSM\TargetTile\X * OSM\TileSize ;Convert X, Y in tile.decimal into real pixels
OSM\Position\Y = OSM\TargetTile\Y * OSM\TileSize
EndProcedure
Macro Min(a,b)
(Bool((a) <= (b)) * (a) + Bool((b) < (a)) * (b))
EndMacro
Macro Max(a,b)
(Bool((a) >= (b)) * (a) + Bool((b) > (a)) * (b))
EndMacro
Procedure ZoomToArea()
;Source => http://gis.stackexchange.com/questions/19632/how-to-calculate-the-optimal-zoom-level-to-display-two-or-more-points-on-a-map
;bounding box in long/lat coords (x=long, y=lat)
Protected MinY.d,MaxY.d,MinX.d,MaxX.d
ForEach OSM\track()
If ListIndex(OSM\track())=0 Or OSM\track()\Longitude<MinX
MinX=OSM\track()\Longitude
EndIf
If ListIndex(OSM\track())=0 Or OSM\track()\Longitude>MaxX
MaxX=OSM\track()\Longitude
EndIf
If ListIndex(OSM\track())=0 Or OSM\track()\Latitude<MinY
MinY=OSM\track()\Latitude
EndIf
If ListIndex(OSM\track())=0 Or OSM\track()\Latitude>MaxY
MaxY=OSM\track()\Latitude
EndIf
Next
Protected DeltaX.d=MaxX-MinX ;assumption ! In original code DeltaX have no source
Protected centerX.d=MinX+DeltaX/2 ; assumption ! In original code CenterX have no source
Protected paddingFactor.f= 1.2 ;paddingFactor: this can be used to get the "120%" effect ThomM refers to. Value of 1.2 would get you the 120%.
ry1.d = Log((Sin(Radian(MinY)) + 1) / Cos(Radian(MinY)));
ry2.d = Log((Sin(Radian(MaxY)) + 1) / Cos(Radian(MaxY)));
ryc.d = (ry1 + ry2) / 2;
centerY.d = Degree(ATan(SinH(ryc)));
resolutionHorizontal.d = DeltaX / GadgetWidth(OSM\Gadget);
vy0.d = Log(Tan(#PI*(0.25 + centerY/360)));
vy1.d = Log(Tan(#PI*(0.25 + MaxY/360)));
viewHeightHalf.d = GadgetHeight(OSM\Gadget)/2;
zoomFactorPowered.d = viewHeightHalf / (40.7436654315252*(vy1 - vy0));
resolutionVertical.d = 360.0 / (zoomFactorPowered * OSM\TileSize);
resolution.d = Max(resolutionHorizontal, resolutionVertical)* paddingFactor;
zoom.d = Log(360 / (resolution * OSM\TileSize))/Log(2)
lon.d = centerX;
lat.d = centerY;
Debug "lat:"+StrD(lat)
Debug "lon:"+StrD(lon)
Debug "zoom:"+StrD(zoom)
SetLocation(lat,lon, Round(zoom,#PB_Round_Down))
EndProcedure
Procedure TileTranslate(*Tile.Tile, tx.d, ty.d)
Debug " - move - "
Protected pfValue.d
If tx <> 0
pfValue = *Tile\X - tx
If pfValue > Pow(2, OSM\Zoom) - 1
*Tile\X = Pow(2, OSM\Zoom) - 2
ElseIf pfValue < 0
*Tile\X = Pow(2, OSM\Zoom) - 2
Else
*Tile\X = pfValue
EndIf
EndIf
If ty <> 0
pfValue = *Tile\Y - ty
If pfValue > Pow(2, OSM\Zoom) - 1
*Tile\Y = Pow(2, OSM\Zoom) - 2
ElseIf pfValue < 0
*Tile\Y = Pow(2, OSM\Zoom) - 2
Else
*Tile\Y = pfValue
EndIf
EndIf
EndProcedure
Procedure SetZoom(Zoom.i, mode.i = #PB_Relative)
Select mode
Case #PB_Relative
OSM\Zoom = OSM\Zoom + zoom
Case #PB_Absolute
OSM\Zoom = zoom
EndSelect
If OSM\Zoom > OSM\ZoomMax : OSM\Zoom = OSM\ZoomMax : EndIf
If OSM\Zoom < OSM\ZoomMin : OSM\Zoom = OSM\ZoomMin : EndIf
LatLon2XY(@OSM\TargetLocation, @OSM\TargetTile)
OSM\Position\X = OSM\TargetTile\X * OSM\TileSize ;Convert X, Y in tile.decimal into real pixels
OSM\Position\Y = OSM\TargetTile\Y * OSM\TileSize
ConstructMap()
DrawMap()
EndProcedure
Procedure InitOSM()
Debug GetTemporaryDirectory()
OSM\HDDCachePath = GetTemporaryDirectory()
OSM\ServerURL = "http://tile.openstreetmap.org/" ;"https://tile.thunderforest.com/cycle/";
OSM\ZoomMin = 0
OSM\ZoomMax = 18
OSM\StartCursor\X = - 1
OSM\TileSize = 256
OSM\MemCache\Mutex=CreateMutex()
;OSM\MemCache\Semaphore=CreateSemaphore(1)
OSM\MapImageMutex=CreateMutex()
OSM\MapImageSemaphore=CreateSemaphore(8)
OSM\Windows=0
AddWindowTimer(OSM\Windows,1, 500)
EndProcedure
Procedure Event(Event.l)
Protected Gadget.i
Protected tx.d, ty.d
Protected OldX.i, OldY.i
If IsGadget(OSM\Gadget) And GadgetType(OSM\Gadget) = #PB_GadgetType_Canvas
Select Event
Case #EvenementStartRefresh
;Debug "Start"
AddWindowTimer(OSM\Windows,1, 500)
Case #EvenementStopRefresh
;Debug "Stop"
DrawMap()
;RemoveWindowTimer(OSM\Windows, 1)
Case #PB_Event_Timer
If EventTimer()=1;=#Timer_Draw
DrawMap()
EndIf
Case #PB_Event_Gadget ;{
Gadget = EventGadget()
Select Gadget
Case OSM\Gadget
Select EventType()
Case #PB_EventType_LeftButtonDown
;Mem cursor Coord
OSM\StartCursor\X = GetGadgetAttribute(OSM\Gadget, #PB_Canvas_MouseX)
OSM\StartCursor\Y = GetGadgetAttribute(OSM\Gadget, #PB_Canvas_MouseY)
Case #PB_EventType_MouseMove
If OSM\StartCursor\X<>-1
OSM\DeltaCursor\X=GetGadgetAttribute(OSM\Gadget, #PB_Canvas_MouseX)-OSM\StartCursor\X
OSM\DeltaCursor\Y=GetGadgetAttribute(OSM\Gadget, #PB_Canvas_MouseY)-OSM\StartCursor\Y
EndIf
DrawMap()
Case #PB_EventType_LeftButtonUp
DrawMap()
tx=(OSM\DeltaCursor\X/256)
ty=(OSM\DeltaCursor\Y/256)
OSM\DeltaCursor\X=0
OSM\DeltaCursor\Y=0
OSM\StartCursor\X=-1
TileTranslate(@OSM\TargetTile,tx,ty)
XY2LatLon(@OSM\TargetTile,@OSM\TargetLocation)
ConstructMap()
EndSelect
EndSelect
EndSelect
Else
MessageRequester("Module OSM", "You must use OSMGadget before", #PB_MessageRequester_Ok )
End
EndIf
EndProcedure
EndModule
;Demonstration
CompilerIf #PB_Compiler_IsMainFile
Enumeration
#Window_0
#Map
#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
;- Main
If OpenWindow(#Window_0, 260, 225, 700, 571, "OpenStreetMap", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_TitleBar | #PB_Window_ScreenCentered )
OSM::InitOSM()
LoadFont(0, "Wingdings", 12)
LoadFont(1, "Arial", 12, #PB_Font_Bold)
OSM::OSMGadget(#Map, 10, 10, 512, 512)
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, 90, 20, "")
TextGadget(#Text_4, 530, 250, 60, 15, "Longitude : ")
StringGadget(#String_1, 600, 250, 90, 20, "")
Define Event.i, Gadget.i, Quit.b = #False
Define pfValue.d
;OSM::SetLocation(49.04599, 2.03347, 17)
OSM::SetLocation(49.0346374511718750,2.0787782669067383,17)
OSM::LoadGpxFile("Rallye.gpx")
OSM::ZoomToArea()
OSM::ConstructMap()
OSM::DrawMap()
Repeat
Event = WaitWindowEvent()
OSM::Event(Event)
Select Event
Case #PB_Event_CloseWindow : Quit = 1
Case #PB_Event_Gadget ;{
Gadget = EventGadget()
Select Gadget
Case #Button_4
OSM::SetZoom(1)
Case #Button_5
OSM::SetZoom( - 1)
EndSelect
EndSelect
Until Quit = #True
EndIf
CompilerEndIf