
PBMap - Cartes OSM, Here, Geoserver dans un Canvas
Re: OpenStreetMap dans un Canvas
Il va falloir revoir le mode de chargement pour qu'il se fasse dès un déplacement. C'est plus compliqué que prévu 

Re: OpenStreetMap dans un Canvas
J'avais prévu de charger les Tiles avec un Thread je commence a bien maîtriser les Mutexs et les sémaphoresdjes a écrit :Il va falloir revoir le mode de chargement pour qu'il se fasse dès un déplacement. C'est plus compliqué que prévu

j'ai fais des testes ce matin encore mais j'arrive toujours sur la même problématique.
Re: OpenStreetMap dans un Canvas
Le problème vient du calcul de déplacement inverse, c'est à dire retrouver les coordonnées de la tuile "actuelle", et lui rajouter le décalage précédent (ce qui n'est pas fait), plus le déplacement en cours. Bref, il faudrait vraiment que ce soit dynamique pour être toujours centré sur la bonne tuile.
Re: OpenStreetMap dans un Canvas
pourtant dans mon code je lorsqu'on bouge la map effectivement tant que tu es appuyer ça ne fait qu'un déclage en pixel de l'image... mais des que tu relaches le bouton de la souris je recalcule les coordonées du Tiledjes a écrit :Le problème vient du calcul de déplacement inverse, c'est à dire retrouver les coordonnées de la tuile "actuelle", et lui rajouter le décalage précédent (ce qui n'est pas fait), plus le déplacement en cours. Bref, il faudrait vraiment que ce soit dynamique pour être toujours centré sur la bonne tuile.
Code : Tout sélectionner
tx=(OSM\DeltaCursor\X/512)
ty=(OSM\DeltaCursor\Y/512)
TileTranslate(@OSM\TargetTile,tx.d,ty.d)
puis je converti tout de suite en Latitude Longitude
Code : Tout sélectionner
XY2LatLon(@OSM\TargetTile,@OSM\TargetLocation)
Code : Tout sélectionner
Case OSM\Gadget
Select EventType()
Case #PB_EventType_LeftButtonDown ; Un clic gauche je mémorise la position
;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 ; la souris se déplace je calcule le décalage par rapport a la position d'origine.
If OSM\StartCursor\X<>0 Or OSM\StartCursor\Y<>0
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
Case #PB_EventType_LeftButtonUp ; je relache je calcul les nouvelles coordonées
Define tx.d,ty.d
tx=(OSM\DeltaCursor\X/512)
ty=(OSM\DeltaCursor\Y/512)
OSM\DeltaCursor\X=0
OSM\DeltaCursor\Y=0
OSM\StartCursor\X=0
OSM\StartCursor\Y=0
TileTranslate(@OSM\TargetTile,tx.d,ty.d)
XY2LatLon(@OSM\TargetTile,@OSM\TargetLocation)
GetSquareTile()
;move(tx,ty)
;SetGadgetText(#String_1, StrD(osm\gfLongitude))
;SetGadgetText(#String_0, StrD(osm\gfLatitude))
EndSelect
Re: OpenStreetMap dans un Canvas
Oui, je suis dessus. D'abord, quand le déplacement est très grand, il n'y a plus de nouvelles tuiles sur les bords. Ensuite, le calcul se base sur la tuile de départ, jusqu'au relâchement. Or, la nouvelle tuile peut être très loin de la première, du coup le calcul n'est pas bon. Enfin, on arrive à une position qui n'est pas "juste", donc il faut une nouvelle position de départ "décalée".
Re: OpenStreetMap dans un Canvas
heu ....djes a écrit :Oui, je suis dessus. D'abord, quand le déplacement est très grand, il n'y a plus de nouvelles tuiles sur les bords. Ensuite, le calcul se base sur la tuile de départ, jusqu'au relâchement. Or, la nouvelle tuile peut être très loin de la première, du coup le calcul n'est pas bon. Enfin, on arrive à une position qui n'est pas "juste", donc il faut une nouvelle position de départ "décalée".

Un tile déplacé a l'écran de 256 pixels correspond bien a 0.5 dans les coordonnées du Tile sur la Map .. donc si on deplace de 512 pixel ça devrait décalé de 1 tile complet. c'est bine ça.. ou bien il faut prendre en référence le quadrant ? j'avoue m'y perdre


je vais essayer de vérifier ça
Re: OpenStreetMap dans un Canvas
Moi aussi je m'y perdsThyphoon a écrit :heu ....djes a écrit :Oui, je suis dessus. D'abord, quand le déplacement est très grand, il n'y a plus de nouvelles tuiles sur les bords. Ensuite, le calcul se base sur la tuile de départ, jusqu'au relâchement. Or, la nouvelle tuile peut être très loin de la première, du coup le calcul n'est pas bon. Enfin, on arrive à une position qui n'est pas "juste", donc il faut une nouvelle position de départ "décalée".tu me dis si je me trompe
Un tile déplacé a l'écran de 256 pixels correspond bien a 0.5 dans les coordonnées du Tile sur la Map .. donc si on deplace de 512 pixel ça devrait décalé de 1 tile complet. c'est bine ça.. ou bien il faut prendre en référence le quadrant ? j'avoue m'y perdre... lollll en tout cas merci de te pencher dessus
![]()
je vais essayer de vérifier ça

Voilà où j'en suis

Code : Tout sélectionner
InitNetwork()
DeclareModule OSM
Declare InitOSM()
Declare OSMGadget(Gadget.i, X.l, Y.l, Width.l, Height.l)
Declare Event(Event.l)
Declare SetLocation(latitude.d, longitude.d, zoom = 15)
Declare DrawMap()
Declare SetZoom(Zoom.l, mode.l = #PB_Relative)
EndDeclareModule
Module OSM
#USEPROXY = #False
UsePNGImageDecoder()
UsePNGImageEncoder()
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.l
Y.l
EndStructure
Structure OSM
Gadget.i
TargetLocation.Location
TargetTile.tile
ServerURL.s
ZoomMin.l
ZoomMax.l
Zoom.l
CachePath.S
StartCursor.Pixel
DeltaCursor.Pixel
Shift.Pixel
EndStructure
Global OSM.OSM
Procedure InitOSM()
OSM\CachePath = GetTemporaryDirectory()
OSM\ServerURL = "http : //tile.openstreetmap.org/"
OSM\ZoomMin = 0
OSM\ZoomMax = 18
OSM\StartCursor\X = - 1
EndProcedure
Procedure OSMGadget(Gadget.i, X.l, Y.l, Width.l, Height.l)
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), 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
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 LoadMapTile(Image.l, Zoom.l, XTile.l, YTile.l)
Protected *Buffer
Protected TileURL.s = OSM\ServerURL + Str(Zoom) + "/" + Str(XTile) + "/" + Str(YTile) + ".png"
; Test if in cache else download it
Protected CacheFile.s = "OSM_" + Str(Zoom) + "_" + Str(XTile) + "_" + Str(YTile) + ".png"
If FileSize(osm\cachePath + cacheFile) > 0
;Debug "Use Cache : " + cacheFile
LoadImage(Image, OSM\CachePath + CacheFile)
Else
;Debug "DOWNLOAD : " + psURL
CompilerIf #USEPROXY = #True
Protected http.HTTP_Query
HTTP_proxy(@http, "spxy.bpi.fr", 3128)
HTTP_DownloadToMem(@http, TileURL)
If IsImage(Image)
FreeImage(Image)
EndIf
If CatchImage(Image, http\data, MemorySize(http\data))
SaveImage(Image, OSM\CachePath + CacheFile, #PB_ImagePlugin_PNG)
EndIf
CompilerElse
*Buffer = ReceiveHTTPMemory(TileURL) ;TODO to thread by using #PB_HTTP_Asynchronous
If IsImage(Image)
FreeImage(Image)
EndIf
If *Buffer
If CatchImage(Image, *Buffer, MemorySize(*Buffer))
SaveImage(image, OSM\CachePath + CacheFile, #PB_ImagePlugin_PNG)
FreeMemory(*Buffer)
EndIf
EndIf
CompilerEndIf
EndIf
EndProcedure
Procedure GetSquareTile()
Protected x.l, y.l, nx.l, ny.l, n.l = 0, tx.l, ty.l
nx = Int(GadgetWidth(OSM\Gadget)/256)
ny = Int(GadgetHeight(OSM\Gadget)/256)
tx = 2*OSM\TargetTile\X
ty = 2*OSM\TargetTile\Y
For y = ty - ny To ty + ny + ny - 1
For x = tx - nx To tx + nx + nx - 1
Debug Str(x) + " " + Str(y)
LoadMapTile(n, OSM\Zoom + 1, x, y)
n = n + 1
Next
Next
Debug Str(n) + " Images Chargées";
EndProcedure
Procedure DrawMap()
Protected x.l, y.l, nx.l, ny.l, mx.l, my.l, n.l = 0
Protected deltaX.l, deltaY.l
;Protected tx.l, ty.l
Protected x2.l, y2.l
;deltaX = 512*(OSM\TargetTile\X - Int(OSM\TargetTile\X)) - 256 ;TODO Why - 256 ?????
;deltaY = 512*(OSM\TargetTile\Y - Int(OSM\TargetTile\Y)) - 512 ;TODO Why - 512 ?????
;tx = 2 * OSM\TargetTile\X
;ty = 2 * OSM\TargetTile\Y
nx = Int(GadgetWidth(OSM\Gadget)/256)
ny = Int(GadgetHeight(OSM\Gadget)/256)
StartDrawing(CanvasOutput(OSM\Gadget))
Box(0, 0, GadgetWidth(OSM\Gadget), GadgetHeight(OSM\Gadget), RGB(255, 255, 255))
For y = - ny To ny + ny - 1
For x = - nx To nx + nx - 1
x2 = x*256 + OSM\DeltaCursor\X ;+ OSM\Shift\X
y2 = y*256 + OSM\DeltaCursor\Y ;+ OSM\Shift\Y
If IsImage(n) And (x2 + 256) > 0 And (y2 + 256) > 0 And x2 < GadgetWidth(OSM\Gadget) And y2 < GadgetHeight(OSM\Gadget)
DrawImage(ImageID(n), x2, y2, 254, 254)
DrawText( x2, y2, Str(x - Int(nx/2)) + ", " + Str(y - Int(ny/2)))
EndIf
n = n + 1
Next
Next
Circle(GadgetWidth(OSM\Gadget)/2, GadgetHeight(OSM\Gadget)/2, 5, #Red)
DrawText(0, 0, "DeltaCursorX : " + Str(OSM\DeltaCursor\X) + " deltaX : " + Str(deltaX) + " Tile X : " + StrD(OSM\TargetTile\X))
StopDrawing()
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)
GetSquareTile()
DrawMap()
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.l, mode.l = #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)
GetSquareTile()
DrawMap()
EndProcedure
Procedure Event(Event.l)
Protected Gadget.i
Protected tx.i, ty.i
If IsGadget(OSM\Gadget) And GadgetType(OSM\Gadget) = #PB_GadgetType_Canvas
Select Event
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
tx = GetGadgetAttribute(OSM\Gadget, #PB_Canvas_MouseX) - OSM\StartCursor\X + OSM\Shift\X
ty = GetGadgetAttribute(OSM\Gadget, #PB_Canvas_MouseY) - OSM\StartCursor\Y + OSM\Shift\Y
TileTranslate(@OSM\TargetTile, tx/256, ty/256)
OSM\DeltaCursor\X = tx%256
OSM\DeltaCursor\Y = ty%256
SetLocation(OSM\TargetLocation\Latitude, OSM\TargetLocation\Longitude, OSM\Zoom)
EndIf
Case #PB_EventType_LeftButtonUp
OSM\Shift\X = OSM\DeltaCursor\X
OSM\Shift\Y = OSM\DeltaCursor\Y
OSM\DeltaCursor\X = 0
OSM\DeltaCursor\Y = 0
OSM\StartCursor\X = - 1
;move(tx, ty)
;SetGadgetText(#String_1, StrD(osm\gfLongitude))
;SetGadgetText(#String_0, StrD(osm\gfLatitude))
EndSelect
EndSelect
EndSelect
Else
MessageRequester("Module OSM", "You must use OSMGadget before", #PB_MessageRequester_Ok )
End
EndIf
EndProcedure
EndModule
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.l, Gadget.l, Quit.b = #False
Define pfValue.d
OSM::SetLocation(49.04599, 2.03347)
;OSM::SetLocation(49.0361165, 2.0456982)
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
Re: OpenStreetMap dans un Canvas
Ha oui Bravo ça prend formedjes a écrit : Moi aussi je m'y perds
Voilà où j'en suis, pas loin je crois![]()


On a toujours un saut currieux des qu'on se déplace de plus d'un quadrant.
Re: OpenStreetMap dans un Canvas
Oui, il y a un problème au niveau du chargement. Là, pareil, va falloir transformer ça en dynamique pour éviter des rechargements inutiles alors qu'il y a un cache et qu'on pourrait en garder en mémoire.Thyphoon a écrit :Ha oui Bravo ça prend formedjes a écrit : Moi aussi je m'y perds
Voilà où j'en suis, pas loin je crois![]()
... faut que je regarde en détail ce que tu as fait.
![]()
On a toujours un saut currieux des qu'on se déplace de plus d'un quadrant.
Re: OpenStreetMap dans un Canvas
Franchement c'est quand même pas super simple leur système ... et pas super bien documenté. Ou alors c'est moi.djes a écrit : Oui, il y a un problème au niveau du chargement. Là, pareil, va falloir transformer ça en dynamique pour éviter des rechargements inutiles alors qu'il y a un cache.
c'est comme on est toujours pas centré sur les coordonnées demandées.
normalement pour se positioner dans le Tile ça devrait être ça
Code : Tout sélectionner
deltaX = 512*(OSM\TargetTile\X - Int(OSM\TargetTile\X))
deltaY = 512*(OSM\TargetTile\Y - Int(OSM\TargetTile\Y))

Re: OpenStreetMap dans un Canvas
Oui, c'est pas si simple. La difficulté, c'est de jongler avec les "ardoises" et les coordonnées des bords ; d'habitude je me fais un petit papier pour savoir où je vais mais là je perds beaucoup de temps à savoir comment fonctionne ce qui a été fait et dans quel but ! En plus je n'ai pas codé depuis TRES longtemps.
Re: OpenStreetMap dans un Canvas
lolll désolé ça fait pas mal de temps que je tourne en rond sur ce problème j'avais d'abord essayé de me débrouiller tout seul.. et comme j'y arrivais pas, en cherchant je suis tombé sur le code de Progi1984 qui m'a pas mal inspiré. Mais voilà je tourne en rond depuis pas mal de temps et je comprends pas bien le pourquoi du comment ...djes a écrit :Oui, c'est pas si simple. La difficulté, c'est de jongler avec les "ardoises" et les coordonnées des bords ; d'habitude je me fais un petit papier pour savoir où je vais mais là je perds beaucoup de temps à savoir comment fonctionne ce qui a été fait et dans quel but ! En plus je n'ai pas codé depuis TRES longtemps.
Pourtant j'en ai fait des dessins sur des bouts de papier

Je suis encore loin de pouvoir afficher de multiple point sur une carte et de pouvoir les déplacer en drag and drop pour leur changer leur position
En tout cas un grand merci du temps que tu passes.

Re: OpenStreetMap dans un Canvas
Bah, ça me change, entre deux autres trucs 

Re: OpenStreetMap dans un Canvas
Ca commence à fonctionner (faudra nettoyer ce sujet après
)

Code : Tout sélectionner
InitNetwork()
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 GetSquareTile()
Declare DrawMap()
Declare SetZoom(Zoom.i, mode.i = #PB_Relative)
EndDeclareModule
Module OSM
#USEPROXY = #False
UsePNGImageDecoder()
UsePNGImageEncoder()
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.i
Y.i
EndStructure
Structure Pixel
X.i
Y.i
EndStructure
Structure OSM
Gadget.i
TargetLocation.Location
TargetTile.tile
ServerURL.s
ZoomMin.i
ZoomMax.i
Zoom.i
CachePath.S
StartCursor.Pixel
DeltaCursor.Pixel
Shift.Pixel
EndStructure
Global OSM.OSM
Procedure InitOSM()
OSM\CachePath = GetTemporaryDirectory()
OSM\ServerURL = "http : //tile.openstreetmap.org/"
OSM\ZoomMin = 0
OSM\ZoomMax = 18
OSM\StartCursor\X = - 1
EndProcedure
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), 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
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 LoadMapTile(Image.i, Zoom.i, XTile.i, YTile.i)
Protected *Buffer
Protected TileURL.s = OSM\ServerURL + Str(Zoom) + "/" + Str(XTile) + "/" + Str(YTile) + ".png"
; Test if in cache else download it
Protected CacheFile.s = "OSM_" + Str(Zoom) + "_" + Str(XTile) + "_" + Str(YTile) + ".png"
If FileSize(osm\cachePath + cacheFile) > 0
;Debug "Use Cache : " + cacheFile
LoadImage(Image, OSM\CachePath + CacheFile)
Else
;Debug "DOWNLOAD : " + psURL
CompilerIf #USEPROXY = #True
Protected http.HTTP_Query
HTTP_proxy(@http, "spxy.bpi.fr", 3128)
HTTP_DownloadToMem(@http, TileURL)
If IsImage(Image)
FreeImage(Image)
EndIf
If CatchImage(Image, http\data, MemorySize(http\data))
SaveImage(Image, OSM\CachePath + CacheFile, #PB_ImagePlugin_PNG)
EndIf
CompilerElse
*Buffer = ReceiveHTTPMemory(TileURL) ;TODO to thread by using #PB_HTTP_Asynchronous
If IsImage(Image)
FreeImage(Image)
EndIf
If *Buffer
If CatchImage(Image, *Buffer, MemorySize(*Buffer))
SaveImage(image, OSM\CachePath + CacheFile, #PB_ImagePlugin_PNG)
FreeMemory(*Buffer)
EndIf
EndIf
CompilerEndIf
EndIf
EndProcedure
Procedure GetSquareTile()
Protected x.i, y.i, nx.i, ny.i, n.i = 0, tx.i, ty.i
nx = Int(GadgetWidth(OSM\Gadget)/256)
ny = Int(GadgetHeight(OSM\Gadget)/256)
tx = 2*OSM\TargetTile\X
ty = 2*OSM\TargetTile\Y
For y = ty - ny To ty + ny + ny - 1
For x = tx - nx To tx + nx + nx - 1
Debug Str(x) + " " + Str(y)
LoadMapTile(n, OSM\Zoom + 1, x, y)
n = n + 1
Next
Next
Debug Str(n) + " Images Chargées";
EndProcedure
Procedure DrawMap()
Protected x.i, y.i, nx.i, ny.i, mx.i, my.i, n.i = 0
Protected deltaX.i, deltaY.i
;Protected tx.i, ty.i
Protected x2.i, y2.i
;deltaX = 512*(OSM\TargetTile\X - Int(OSM\TargetTile\X)) - 256 ;TODO Why - 256 ?????
;deltaY = 512*(OSM\TargetTile\Y - Int(OSM\TargetTile\Y)) - 512 ;TODO Why - 512 ?????
;tx = 2 * OSM\TargetTile\X
;ty = 2 * OSM\TargetTile\Y
nx = Int(GadgetWidth(OSM\Gadget)/256)
ny = Int(GadgetHeight(OSM\Gadget)/256)
StartDrawing(CanvasOutput(OSM\Gadget))
Box(0, 0, GadgetWidth(OSM\Gadget), GadgetHeight(OSM\Gadget), RGB(255, 255, 255))
For y = - ny To ny + ny - 1
For x = - nx To nx + nx - 1
x2 = x*256 + OSM\DeltaCursor\X ;+ OSM\Shift\X
y2 = y*256 + OSM\DeltaCursor\Y ;+ OSM\Shift\Y
If IsImage(n) And (x2 + 256) > 0 And (y2 + 256) > 0 And x2 < GadgetWidth(OSM\Gadget) And y2 < GadgetHeight(OSM\Gadget)
DrawImage(ImageID(n), x2, y2, 254, 254)
DrawText( x2, y2, Str(x - Int(nx/2)) + ", " + Str(y - Int(ny/2)))
EndIf
n = n + 1
Next
Next
Circle(GadgetWidth(OSM\Gadget)/2, GadgetHeight(OSM\Gadget)/2, 5, #Red)
DrawText(0, 0, "DeltaCursorX : " + Str(OSM\DeltaCursor\X) + " deltaX : " + Str(deltaX) + " Tile X : " + StrD(OSM\TargetTile\X))
StopDrawing()
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)
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)
GetSquareTile()
DrawMap()
EndProcedure
Procedure Event(Event.l)
Protected Gadget.i
Protected tx.i, ty.i
If IsGadget(OSM\Gadget) And GadgetType(OSM\Gadget) = #PB_GadgetType_Canvas
Select Event
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
tx = GetGadgetAttribute(OSM\Gadget, #PB_Canvas_MouseX) - OSM\StartCursor\X + OSM\Shift\X
ty = GetGadgetAttribute(OSM\Gadget, #PB_Canvas_MouseY) - OSM\StartCursor\Y + OSM\Shift\Y
;TileTranslate(@OSM\TargetTile, tx/256, ty/256)
OSM\DeltaCursor\X = tx%512
OSM\DeltaCursor\Y = ty%512
If tx/512 <> 0 Or ty/512 <> 0
Debug tx/512
Debug ty/512
OSM\TargetTile\X - tx/512
OSM\TargetTile\Y - ty/512
OSM\Shift\X = OSM\DeltaCursor\X
OSM\Shift\Y = OSM\DeltaCursor\Y
OSM\StartCursor\X = GetGadgetAttribute(OSM\Gadget, #PB_Canvas_MouseX)
OSM\StartCursor\Y = GetGadgetAttribute(OSM\Gadget, #PB_Canvas_MouseY)
XY2LatLon(@OSM\TargetTile, @OSM\TargetLocation)
;SetLocation(OSM\TargetLocation\Latitude, OSM\TargetLocation\Longitude, OSM\Zoom)
Debug OSM\TargetLocation\Latitude
GetSquareTile()
EndIf
DrawMap()
EndIf
Case #PB_EventType_LeftButtonUp
OSM\Shift\X = OSM\DeltaCursor\X
OSM\Shift\Y = OSM\DeltaCursor\Y
OSM\DeltaCursor\X = 0
OSM\DeltaCursor\Y = 0
OSM\StartCursor\X = - 1
;move(tx, ty)
;SetGadgetText(#String_1, StrD(osm\gfLongitude))
;SetGadgetText(#String_0, StrD(osm\gfLatitude))
EndSelect
EndSelect
EndSelect
Else
MessageRequester("Module OSM", "You must use OSMGadget before", #PB_MessageRequester_Ok )
End
EndIf
EndProcedure
EndModule
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)
OSM::GetSquareTile()
OSM::DrawMap()
;OSM::SetLocation(49.0361165, 2.0456982)
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
Re: OpenStreetMap dans un Canvas
Bravo ^_^
Faut que je regarde de plus prêt comment tu as fait.
Je suis pas là durant 24h mais des Samedi que je regarde ça de plus prêt
Faut que je regarde de plus prêt comment tu as fait.
Je suis pas là durant 24h mais des Samedi que je regarde ça de plus prêt