PBMap - OSM, Here, Geoserver maps in a Canvas gadget

Applications, Games, Tools, User libs and useful stuff coded in PureBasic
User avatar
djes
Addict
Addict
Posts: 1806
Joined: Sat Feb 19, 2005 2:46 pm
Location: Pas-de-Calais, France

Re: PBMap - OpenStreetMap in a Canvas gadget

Post by djes »

Several new additions in the new beta, especially 3 callbacks :
  • SetCallBackMarker(*Marker.PBMap::Marker) (Typhoon's modification) : allows to receive full markers infos when moving a marker
  • SetCallBackDrawTile(x.i, y.i, image.i, alpha.d = 1) : allows to alter "on the fly" tile rendering
  • SetCallBackModifyTileFile(Filename.s, OriginalURL.s) : called after tile downloading and permits to change the file
To download and test here : https://github.com/djes/PBMap/tree/djes
vwidmer
Enthusiast
Enthusiast
Posts: 282
Joined: Mon Jan 20, 2014 6:32 pm

Re: PBMap - OSM, Here, Geoserver maps in a Canvas gadget

Post by vwidmer »

What do u think about adding support for shapefiles or kmz?
WARNING: I dont know what I am doing! I just put stuff here and there and sometimes like magic it works. So please improve on my code and post your changes so I can learn more. TIA
User avatar
djes
Addict
Addict
Posts: 1806
Joined: Sat Feb 19, 2005 2:46 pm
Location: Pas-de-Calais, France

Re: PBMap - OSM, Here, Geoserver maps in a Canvas gadget

Post by djes »

vwidmer wrote:What do u think about adding support for shapefiles or kmz?
Sure, it would be nice, and is already on the TODO list. I have looked for documentation about this. SHP support would need a library like this : http://shapelib.maptools.org/
For KML/KMZ, there's already everything in PB for a basic support.
vwidmer
Enthusiast
Enthusiast
Posts: 282
Joined: Mon Jan 20, 2014 6:32 pm

Re: PBMap - OSM, Here, Geoserver maps in a Canvas gadget

Post by vwidmer »

Did you see on the shaprelib page at the bottom couple of people have ported it to VB already. Maybe wont be too hard to port it to PB?
WARNING: I dont know what I am doing! I just put stuff here and there and sometimes like magic it works. So please improve on my code and post your changes so I can learn more. TIA
User avatar
djes
Addict
Addict
Posts: 1806
Joined: Sat Feb 19, 2005 2:46 pm
Location: Pas-de-Calais, France

Re: PBMap - OSM, Here, Geoserver maps in a Canvas gadget

Post by djes »

vwidmer wrote:Did you see on the shaprelib page at the bottom couple of people have ported it to VB already. Maybe wont be too hard to port it to PB?
No, it should be easy I think, but I haven't a C compiler here, maybe there's some compiled dll on the web...?
vwidmer
Enthusiast
Enthusiast
Posts: 282
Joined: Mon Jan 20, 2014 6:32 pm

Re: PBMap - OSM, Here, Geoserver maps in a Canvas gadget

Post by vwidmer »

WARNING: I dont know what I am doing! I just put stuff here and there and sometimes like magic it works. So please improve on my code and post your changes so I can learn more. TIA
User avatar
djes
Addict
Addict
Posts: 1806
Joined: Sat Feb 19, 2005 2:46 pm
Location: Pas-de-Calais, France

Re: PBMap - OSM, Here, Geoserver maps in a Canvas gadget

Post by djes »

vwidmer wrote:no I mean did you see this?

http://shapelib.maptools.org/dl/contrib/ShapeIO2.zip
Well, the full port of the VB source would take a lot of time. I've compiled the shapelib dll, but I have to convert the headers so it can be used with PB. Are you interested ?
vwidmer
Enthusiast
Enthusiast
Posts: 282
Joined: Mon Jan 20, 2014 6:32 pm

Re: PBMap - OSM, Here, Geoserver maps in a Canvas gadget

Post by vwidmer »

Yes am intersted.

Though I am on linux so maybe I would have to compile it as well to a .so.

I have see lots of weather shapefiles that I thought would be nice to overlay on the map.
Also notice a few tile sites have shapefiles with them.

See here: http://www.nhc.noaa.gov/gis/

But this site also has some KML/KMZ so if it will be dificult to support shaprefiles I think KML/MKZ files maybe a better choice for the greater group of people since it is maybe more standardized by google?
WARNING: I dont know what I am doing! I just put stuff here and there and sometimes like magic it works. So please improve on my code and post your changes so I can learn more. TIA
User avatar
djes
Addict
Addict
Posts: 1806
Joined: Sat Feb 19, 2005 2:46 pm
Location: Pas-de-Calais, France

Re: PBMap - OSM, Here, Geoserver maps in a Canvas gadget

Post by djes »

shp and kml are both exchange standard, not very good ones if you want my opinion, geomatic has a lot to do before having great file formats... Anyway theses files are zipped too, so you'll have to choose the files (or the folder or http links), unzip them, and project/draw them.
User avatar
Andre
PureBasic Team
PureBasic Team
Posts: 2056
Joined: Fri Apr 25, 2003 6:14 pm
Location: Germany (Saxony, Deutscheinsiedel)
Contact:

Re: PBMap - OSM, Here, Geoserver maps in a Canvas gadget

Post by Andre »

Hi djes,

as I reported earlier about random crashes when loading the map (which weren't fully solved since I'm using the automatic clean-up of the tempory drawer with the loaded map tiles, but I haven't tried anything else since I'm using PBMap "only" for an internal tool), we've probably a solution by german PB forum user 'DarkSoul' posted here: http://www.purebasic.fr/german/viewtopi ... 28&start=9
(line number = 1196 and following lines)

He means, if the PostEvent() gets moved outside the Mutex code block, then the crash shouldn't happen anymore.
I've not the possibility to check this in my project code for now, but maybe it give you already the right idea? 8)
Bye,
...André
(PureBasicTeam::Docs & Support - PureArea.net | Order:: PureBasic | PureVisionXP)
User avatar
djes
Addict
Addict
Posts: 1806
Joined: Sat Feb 19, 2005 2:46 pm
Location: Pas-de-Calais, France

Re: PBMap - OSM, Here, Geoserver maps in a Canvas gadget

Post by djes »

Hi Andre, I was thinking that the problem was resolved for long. Anyway, I don't see any potential problem with this workaround (except if user changes the windows or gadget), so if you don't have bugs anymore, I'll update the main code. Don't you want an access to the git?
User avatar
Franky666
User
User
Posts: 17
Joined: Wed Jan 09, 2008 10:43 pm
Location: Germany

Re: PBMap - OSM, Here, Geoserver maps in a Canvas gadget

Post by Franky666 »

btw. DarkSoul is known an Franky666 here. :mrgreen:

If you don't understand german language: The program doesn't crash. It does hang in following situation:

The thread that is responsible to load the map tiles, wants to pass its PostEvent (the part of the code where the workaround is for) to the main thread and waits for it (unfortunately, while it is keep locking the mutex).
Because the mutex is still locked by the thread, the main thread may get stuck a few lines below on LockMutex() (I don't remember the exact line number) and can't receive the event from the other thread because it is sleeping.
So both threads waits forever. Because one of them is the main thread, the whole application freezes.

If you pull the PostEvent() out of the mutex block (which is safe) using intermediate variables, that situation cannot happen anymore. I don't think it is a big trouble if the gadgets/windows get changed while the event is passed. You could check in the main thread if the gadgets/windows are still there.
User avatar
djes
Addict
Addict
Posts: 1806
Joined: Sat Feb 19, 2005 2:46 pm
Location: Pas-de-Calais, France

Re: PBMap - OSM, Here, Geoserver maps in a Canvas gadget

Post by djes »

Thank you to have taken time to translate your post, Darksoul, even if I have mostly understood with the Google "translation", it's far clearer for me now ! I'm on holidays, when I'll get time, I'll fix the git code. If some of you want a git access, just ask, this little project was not initiated by me and is not mine, but to the pb's community.

Edit: I have changed the GetImageThread() further than you could imagine. In fact, I think that the mutex has no real reason to be used there, as the memory management is made outside and that we're working with a reserved tile memory. Could you test this version ? Thank you.
User avatar
Andre
PureBasic Team
PureBasic Team
Posts: 2056
Joined: Fri Apr 25, 2003 6:14 pm
Location: Germany (Saxony, Deutscheinsiedel)
Contact:

Re: PBMap - OSM, Here, Geoserver maps in a Canvas gadget

Post by Andre »

@Franky666: thanks for jumping in here, as your tips could be more worthful than my simpler 'take a look...' here :D

@djes: thank your for your offer with the GitHub account - but I'm just thinking, that I'm not really able to help/improve the existing code, I'm not more as a user of your fantastic PBMap module :mrgreen:

I just tested your new beta mentioned above (I had missed the newer code of July 2017, was still using PBMap code of June 2017 until now :oops:), it runs fine at a first test. If it will run without hanging now, need to be tested in a longer run, as this occured after an hour or so of using my tool with the PBMap included... I will report here :-)

Another question I have right now: What is the right way of using two canvas gadgets (in separate panels) in the same program/window? For now I have done a full cleanup with PBMap::Quit() and re-initialization with PBMap::InitPBMap() after each switch between the different panels (editing modules) of my GeoWorldEditor.
This causes also an "non-valid MemoryID" error at the line 2598 with the code

Code: Select all

        FreeMemory(*Tile)                                       ; Frees the data needed for the thread (*tile=PBMap\MemCache\Images(key)\Tile)
There should be a smarter way, or?
(It's not needed to have the two PBMap instances / canvas gadgets at the same time, but if available this would be fine too :mrgreen:)

Thank you!
Bye,
...André
(PureBasicTeam::Docs & Support - PureArea.net | Order:: PureBasic | PureVisionXP)
User avatar
Andre
PureBasic Team
PureBasic Team
Posts: 2056
Joined: Fri Apr 25, 2003 6:14 pm
Location: Germany (Saxony, Deutscheinsiedel)
Contact:

Re: PBMap - OSM, Here, Geoserver maps in a Canvas gadget

Post by Andre »

To show what I mean, and where the "invalid MemoryID" error occurs, I hacked together the following 'quick & dirty' example using two CanvasGadgets with PBMap. Switching between the panels raises the error at line 2598 in the PBMap.pb include.

Maybe it's possible to adapt my code in a way, that two (or more) different CanvasGadget displaying PBMap content become possible.... or maybe something must be adapted in the PBMap include... 8)

Thank you for any help!

@djes: when we got the problem handled, and if you like it, feel free to add the following example to the PBMap package.

Code: Select all

; Based on the orginal PBMap example (delivered with the package in Feb. 2018), this is an example with
; less functionality, but with 2 different Canvas Map gadgets placed in 2 tabs of a PanelGadget...
; (for testing purposes related to my GeoWorldEditor)
;
; Author: André Beer
; Last change: 26. Feb. 2018
;
; ****************************************************************
; 
;- Example of application
; 
; ****************************************************************
XIncludeFile "PBMap.pb"

InitNetwork()

Enumeration
  #Window_0
  #Map
  #Gdt_Left
  #Gdt_Right
  #Gdt_Up
  #Gdt_Down
  #Button_4
  #Button_5
  #Combo_0
  #Text_0
  #Text_1
  #Text_2
  #Text_3
  #Text_4
  #StringLatitude
  #StringLongitude
  #Gdt_AddMarker
  #Gdt_Degrees
  #Gdt_ClearDiskCache
  #TextGeoLocationQuery
  #StringGeoLocationQuery
  ; Additions for a 2nd panel:
  #PanelGadget
  #Map2_Canvas
  #Map2_Move
  #Map2_Left
  #Map2_Right
  #Map2_Up
  #Map2_Down
  #Map2_Zoom
  #Map2_ZoomIn
  #Map2_ZoomOut
  #Map2_LatitudeText
  #Map2_StringLatitude
  #Map2_LongitudeText
  #Map2_StringLongitude  
EndEnumeration

; Menu events
Enumeration
  #MenuEventLonLatStringEnter
  #MenuEventGeoLocationStringEnter
EndEnumeration

Structure Location
  Longitude.d
  Latitude.d
EndStructure

Procedure UpdateLocation(*Location.Location)
  SetGadgetText(#StringLatitude, StrD(*Location\Latitude))
  SetGadgetText(#StringLongitude, StrD(*Location\Longitude))
  ProcedureReturn 0
EndProcedure

; This callback demonstration procedure will receive relative coords from canvas
Procedure MyMarker(x.i, y.i, Focus = #False, Selected = #False)
  Protected color = RGBA(0, 255, 0, 255) 
  MovePathCursor(x, y)
  AddPathLine(-16,-32,#PB_Path_Relative)
  AddPathCircle(16,0,16,180,0,#PB_Path_Relative)
  AddPathLine(-16,32,#PB_Path_Relative)
  VectorSourceColor(color)
  FillPath(#PB_Path_Preserve)
  If Focus
    VectorSourceColor(RGBA($FF, $FF, 0, $FF))
    StrokePath(2)
  ElseIf Selected
    VectorSourceColor(RGBA($FF, $FF, 0, $FF))
    StrokePath(3)
  Else
    VectorSourceColor(RGBA(0, 0, 0, 255))
    StrokePath(1)
  EndIf
EndProcedure

Procedure MarkerMoveCallBack(*Marker.PBMap::Marker)
  Debug "Identifier : " + *Marker\Identifier + "(" + StrD(*Marker\GeographicCoordinates\Latitude) + ", " + StrD(*Marker\GeographicCoordinates\Longitude) + ")"
EndProcedure

; Example of a custom procedure to alter tile rendering
Procedure DrawTileCallBack(x.i, y.i, image.i, alpha.d)
  MovePathCursor(x, y)
  DrawVectorImage(ImageID(image), 255 * alpha)
EndProcedure

; Example of a custom procedure to alter tile file just after loading
Procedure.s ModifyTileFileCallback(CacheFile.s, OrgURL.s)
  Protected ImgNB = LoadImage(#PB_Any, CacheFile)
  If ImgNB
    StartDrawing(ImageOutput(ImgNB))
    DrawText(0, 0,"PUREBASIC", RGB(255, 255, 0))
    StopDrawing()
    ;*** Could be used to create new files
    ; Cachefile = ReplaceString(Cachefile, ".png", "_PB.png") 
    ;***
    If SaveImage(ImgNB, CacheFile, #PB_ImagePlugin_PNG, 0, 32) ;Warning, the 32 is mandatory as some tiles aren't correctly rendered
      ; Send back the new name (not functional by now)
      ProcedureReturn CacheFile
    EndIf
  EndIf
EndProcedure
        
Procedure MainPointer(x.i, y.i)
  VectorSourceColor(RGBA(255, 255,255, 255)) : AddPathCircle(x, y,32) : StrokePath(1)
  VectorSourceColor(RGBA(0, 0, 0, 255)) : AddPathCircle(x, y, 29):StrokePath(2)
EndProcedure

Procedure ResizeAll()
  Protected PanelTabHeight = GetGadgetAttribute(#PanelGadget, #PB_Panel_TabHeight)
  ResizeGadget(#PanelGadget, #PB_Ignore, #PB_Ignore, WindowWidth(#Window_0), WindowHeight(#Window_0)-PanelTabHeight)
  Protected PanelItemWidth = GetGadgetAttribute(#PanelGadget, #PB_Panel_ItemWidth)
  Protected PanelItemHeight = GetGadgetAttribute(#PanelGadget, #PB_Panel_ItemHeight) 
  ; First tab:
  ResizeGadget(#Map, 10, 10, PanelItemWidth-198, PanelItemHeight-59)
  ResizeGadget(#Text_1, PanelItemWidth-170, #PB_Ignore, #PB_Ignore, #PB_Ignore)
  ResizeGadget(#Gdt_Left, PanelItemWidth-150, #PB_Ignore, #PB_Ignore, #PB_Ignore)
  ResizeGadget(#Gdt_Right, PanelItemWidth-90, #PB_Ignore, #PB_Ignore, #PB_Ignore)
  ResizeGadget(#Gdt_Up,   PanelItemWidth-120, #PB_Ignore, #PB_Ignore, #PB_Ignore)
  ResizeGadget(#Gdt_Down, PanelItemWidth-120, #PB_Ignore, #PB_Ignore, #PB_Ignore)
  ResizeGadget(#Text_2, PanelItemWidth-170, #PB_Ignore, #PB_Ignore, #PB_Ignore)
  ResizeGadget(#Button_4, PanelItemWidth-150, #PB_Ignore, #PB_Ignore, #PB_Ignore)
  ResizeGadget(#Button_5, PanelItemWidth-100, #PB_Ignore, #PB_Ignore, #PB_Ignore)
  ResizeGadget(#Text_3, PanelItemWidth-170, #PB_Ignore, #PB_Ignore, #PB_Ignore)
  ResizeGadget(#StringLatitude, PanelItemWidth-120, #PB_Ignore, #PB_Ignore, #PB_Ignore)
  ResizeGadget(#StringLongitude, PanelItemWidth-120, #PB_Ignore, #PB_Ignore, #PB_Ignore)
  ResizeGadget(#Text_4, PanelItemWidth-170, #PB_Ignore, #PB_Ignore, #PB_Ignore)
  ResizeGadget(#Gdt_AddMarker, PanelItemWidth-170, #PB_Ignore, #PB_Ignore, #PB_Ignore)
  ResizeGadget(#Gdt_Degrees, PanelItemWidth-170, #PB_Ignore, #PB_Ignore, #PB_Ignore)
  ResizeGadget(#Gdt_ClearDiskCache, PanelItemWidth-170, #PB_Ignore, #PB_Ignore, #PB_Ignore)
  ResizeGadget(#TextGeoLocationQuery, PanelItemWidth-170, #PB_Ignore, #PB_Ignore, #PB_Ignore)
  ResizeGadget(#StringGeoLocationQuery, PanelItemWidth-170, #PB_Ignore, #PB_Ignore, #PB_Ignore)
  ; Second tab:
  ResizeGadget(#Map2_Canvas, 10, 10, PanelItemWidth-198, PanelItemHeight-59)
  ResizeGadget(#Map2_Move, PanelItemWidth-170, #PB_Ignore, #PB_Ignore, #PB_Ignore)
  ResizeGadget(#Map2_Left, PanelItemWidth-150, #PB_Ignore, #PB_Ignore, #PB_Ignore)
  ResizeGadget(#Map2_Right, PanelItemWidth-90, #PB_Ignore, #PB_Ignore, #PB_Ignore)
  ResizeGadget(#Map2_Up,   PanelItemWidth-120, #PB_Ignore, #PB_Ignore, #PB_Ignore)
  ResizeGadget(#Map2_Down, PanelItemWidth-120, #PB_Ignore, #PB_Ignore, #PB_Ignore)
  ResizeGadget(#Map2_Zoom, PanelItemWidth-170, #PB_Ignore, #PB_Ignore, #PB_Ignore)
  ResizeGadget(#Map2_ZoomIn, PanelItemWidth-150, #PB_Ignore, #PB_Ignore, #PB_Ignore)
  ResizeGadget(#Map2_ZoomOut, PanelItemWidth-100, #PB_Ignore, #PB_Ignore, #PB_Ignore)
  ResizeGadget(#Map2_LatitudeText, PanelItemWidth-170, #PB_Ignore, #PB_Ignore, #PB_Ignore)
  ResizeGadget(#Map2_StringLatitude, PanelItemWidth-120, #PB_Ignore, #PB_Ignore, #PB_Ignore)
  ResizeGadget(#Map2_LongitudeText, PanelItemWidth-170, #PB_Ignore, #PB_Ignore, #PB_Ignore)  
  ResizeGadget(#Map2_StringLongitude, PanelItemWidth-120, #PB_Ignore, #PB_Ignore, #PB_Ignore)
  
  ; Refresh the PBMap:
  PBMap::Refresh()
EndProcedure

;- MAIN TEST
If OpenWindow(#Window_0, 260, 225, 720, 595, "PBMap", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_TitleBar | #PB_Window_ScreenCentered | #PB_Window_SizeGadget)
  ; ***
  Define Event.i, Gadget.i, Quit.b = #False
  Define pfValue.d
  Define Degrees = 1
  Define *Track
  Define a, ActivePanel
  
  LoadFont(0, "Arial", 12)
  LoadFont(1, "Arial", 12, #PB_Font_Bold)
  LoadFont(2, "Arial", 8)
  
  PanelGadget(#PanelGadget, 0, 0, 700, 571)
  AddGadgetItem(#PanelGadget, 0, "Map 1")
    TextGadget(#Text_1, 530, 10, 60, 15, "Movements")
    ButtonGadget(#Gdt_Left,  550, 60, 30, 30, Chr($25C4))  : SetGadgetFont(#Gdt_Left, FontID(0)) 
    ButtonGadget(#Gdt_Right, 610, 60, 30, 30, Chr($25BA))  : SetGadgetFont(#Gdt_Right, FontID(0)) 
    ButtonGadget(#Gdt_Up,    580, 030, 30, 30, Chr($25B2))  : SetGadgetFont(#Gdt_Up, FontID(0)) 
    ButtonGadget(#Gdt_Down,  580, 90, 30, 30, Chr($25BC))  : SetGadgetFont(#Gdt_Down, FontID(0)) 
    TextGadget(#Text_2, 530, 120, 60, 15, "Zoom")
    ButtonGadget(#Button_4, 550, 140, 50, 30, " + ")        : SetGadgetFont(#Button_4, FontID(1)) 
    ButtonGadget(#Button_5, 600, 140, 50, 30, " - ")        : SetGadgetFont(#Button_5, FontID(1)) 
    TextGadget(#Text_3, 530, 190, 50, 15, "Latitude ")
    StringGadget(#StringLatitude, 580, 190, 90, 20, "")
    TextGadget(#Text_4, 530, 210, 50, 15, "Longitude ")
    StringGadget(#StringLongitude, 580, 210, 90, 20, "")
    ButtonGadget(#Gdt_AddMarker, 530, 240, 150, 30, "Add Marker")
    ButtonGadget(#Gdt_Degrees, 530, 420, 150, 30, "Show/Hide Degrees", #PB_Button_Toggle)
    ButtonGadget(#Gdt_ClearDiskCache, 530, 480, 150, 30, "Clear disk cache", #PB_Button_Toggle)
    TextGadget(#TextGeoLocationQuery, 530, 515, 150, 15, "Enter an address")
    StringGadget(#StringGeoLocationQuery, 530, 530, 150, 20, "")
    SetActiveGadget(#StringGeoLocationQuery)
    
    ; Our main gadget
    PBMap::InitPBMap(#Window_0)
    PBMap::SetOption("ShowDegrees", "1") : Degrees = 0
    PBMap::SetOption("ShowDebugInfos", "1")
    PBMap::SetDebugLevel(5)
    PBMap::SetOption("Verbose", "0")
    PBMap::SetOption("ShowScale", "1")    
    PBMap::SetOption("Warning", "1")
    PBMap::SetOption("ShowMarkersLegend", "1")
    PBMap::SetOption("ShowTrackKms", "1")
    PBMap::SetOption("ColourFocus", "$FFFF00AA") 
    PBMap::MapGadget(#Map, 10, 10, 512, 512)
    PBMap::SetCallBackMainPointer(@MainPointer())                   ; To change the main pointer (center of the view)
    PBMap::SetCallBackLocation(@UpdateLocation())                   ; To obtain realtime coordinates
    PBMap::SetLocation(-36.81148, 175.08634,12)                     ; Change the PBMap coordinates
    PBMAP::SetMapScaleUnit(PBMAP::#SCALE_KM)                        ; To change the scale unit
    PBMap::AddMarker(49.0446828398, 2.0349812508, "", "", -1, @MyMarker())  ; To add a marker with a customised GFX
    PBMap::SetCallBackMarker(@MarkerMoveCallBack())
    ;PBMap::SetCallBackDrawTile(@DrawTileCallBack())
    ;PBMap::SetCallBackModifyTileFile(@ModifyTileFileCallback())
  
  AddGadgetItem(#PanelGadget, 1, "Map 2")
    TextGadget(#Map2_Move, 530, 10, 60, 15, "Movements")
    ButtonGadget(#Map2_Left,  550, 60, 30, 30, Chr($25C4))  : SetGadgetFont(#Gdt_Left, FontID(0)) 
    ButtonGadget(#Map2_Right, 610, 60, 30, 30, Chr($25BA))  : SetGadgetFont(#Gdt_Right, FontID(0)) 
    ButtonGadget(#Map2_Up,    580, 030, 30, 30, Chr($25B2))  : SetGadgetFont(#Gdt_Up, FontID(0)) 
    ButtonGadget(#Map2_Down,  580, 90, 30, 30, Chr($25BC))  : SetGadgetFont(#Gdt_Down, FontID(0)) 
    TextGadget(#Map2_Zoom, 530, 120, 60, 15, "Zoom")
    ButtonGadget(#Map2_ZoomIn, 550, 140, 50, 30, " + ")        : SetGadgetFont(#Button_4, FontID(1)) 
    ButtonGadget(#Map2_ZoomOut, 600, 140, 50, 30, " - ")        : SetGadgetFont(#Button_5, FontID(1)) 
    TextGadget(#Map2_LatitudeText, 530, 190, 50, 15, "Latitude ")
    StringGadget(#Map2_StringLatitude, 580, 190, 90, 20, "")
    TextGadget(#Map2_LongitudeText, 530, 210, 50, 15, "Longitude ")
    StringGadget(#Map2_StringLongitude, 580, 210, 90, 20, "")
    
    ; Our second map:
;    PBMap::InitPBMap(#Window_0)
    PBMap::MapGadget(#Map2_Canvas, 10, 10, 512, 512)
    PBMap::SetCallBackMainPointer(@MainPointer())                   ; To change the main pointer (center of the view)
    PBMap::SetCallBackLocation(@UpdateLocation())                   ; To obtain realtime coordinates
    PBMap::SetLocation(6.81148, 15.08634,12)                     ; Change the PBMap coordinates
    PBMAP::SetMapScaleUnit(PBMAP::#SCALE_KM)                        ; To change the scale unit
    PBMap::AddMarker(49.0446828398, 2.0349812508)
    
  CloseGadgetList()
  
  ActivePanel = 2   ; Set the current active panel (1 = Map1, 2 = Map2)
  SetGadgetState(#PanelGadget, 1)
    
  AddKeyboardShortcut(#Window_0, #PB_Shortcut_Return, #MenuEventGeoLocationStringEnter)
  ; *** TODO : code to remove when the SetActiveGadget(-1) will be fixed
  CompilerIf #PB_Compiler_OS = #PB_OS_Linux
    Define Dummy = ButtonGadget(#PB_Any, 0, 0, 1, 1, "Dummy") 
    HideGadget(Dummy, 1) 
  CompilerElse
    Define Dummy = -1
  CompilerEndIf
  
  Repeat
    Event = WaitWindowEvent()
    Select Event
      Case #PB_Event_CloseWindow : Quit = 1
      Case #PB_Event_Gadget ; {
        Gadget = EventGadget()
        Select Gadget
          Case #PanelGadget
            Select EventType()
              Case #PB_EventType_Change
                a = GetGadgetState(#PanelGadget)
                If a <> ActivePanel
                  PBMap::Quit()
                  PBMap::InitPBMap(#Window_0)
                  ActivePanel = a
                  If ActivePanel = 1
                    PBMap::MapGadget(#Map, GadgetX(#Map), GadgetY(#Map), GadgetWidth(#Map), GadgetHeight(#Map))
                  Else
                    PBMap::MapGadget(#Map2_Canvas, GadgetX(#Map2_Canvas), GadgetY(#Map2_Canvas), GadgetWidth(#Map2_Canvas), GadgetHeight(#Map2_Canvas))
                  EndIf
                EndIf
            EndSelect
          Case #Gdt_Up, #Map2_Up
            PBMap::SetLocation(10* 360 / Pow(2, PBMap::GetZoom() + 8), 0, 0, #PB_Relative)
          Case #Gdt_Down, #Map2_Down
            PBMap::SetLocation(10* -360 / Pow(2, PBMap::GetZoom() + 8), 0, 0, #PB_Relative)
          Case #Gdt_Left, #Map2_Left
            PBMap::SetLocation(0, 10* -360 / Pow(2, PBMap::GetZoom() + 8), 0, #PB_Relative)
          Case #Gdt_Right, #Map2_Right
            PBMap::SetLocation(0, 10* 360 / Pow(2, PBMap::GetZoom() + 8), 0, #PB_Relative)
          Case #Button_4, #Map2_ZoomIn
            PBMap::SetZoom(1)
          Case #Button_5, #Map2_ZoomOut
            PBMap::SetZoom( - 1)
          Case #StringLatitude, #StringLongitude, #Map2_StringLatitude, #Map2_StringLongitude
            Select EventType()
              Case #PB_EventType_Focus
                AddKeyboardShortcut(#Window_0, #PB_Shortcut_Return, #MenuEventLonLatStringEnter)
              Case #PB_EventType_LostFocus
                RemoveKeyboardShortcut(#Window_0, #PB_Shortcut_Return)
            EndSelect
          Case #Gdt_AddMarker
            PBMap::AddMarker(ValD(GetGadgetText(#StringLatitude)), ValD(GetGadgetText(#StringLongitude)), "", "Test", RGBA(Random(255), Random(255), Random(255), 255))
          Case #Gdt_Degrees
            Degrees = 1 - Degrees
            PBMap::SetOption("ShowDegrees", Str(Degrees))
            PBMap::Refresh()
            SetGadgetState(#Gdt_Degrees, Degrees)
          Case #Gdt_ClearDiskCache
            PBMap::ClearDiskCache()
          Case #StringGeoLocationQuery
            Select EventType()
              Case #PB_EventType_Focus
                AddKeyboardShortcut(#Window_0, #PB_Shortcut_Return, #MenuEventGeoLocationStringEnter)
              Case #PB_EventType_LostFocus
                RemoveKeyboardShortcut(#Window_0, #PB_Shortcut_Return)
            EndSelect
        EndSelect
      Case #PB_Event_SizeWindow
        ResizeAll()
      Case #PB_Event_Menu
        ; Receive "enter" key events
        Select EventMenu()
          Case #MenuEventGeoLocationStringEnter
            If GetGadgetText(#StringGeoLocationQuery) <> ""
              PBMap::NominatimGeoLocationQuery(GetGadgetText(#StringGeoLocationQuery))
              PBMap::Refresh()
            EndIf
            ; *** TODO : code to change when the SetActiveGadget(-1) will be fixed
            SetActiveGadget(Dummy)
            ; ***
          Case  #MenuEventLonLatStringEnter
            PBMap::SetLocation(ValD(GetGadgetText(#StringLatitude)), ValD(GetGadgetText(#StringLongitude)))                     ; Change the PBMap coordinates
            PBMap::Refresh()
        EndSelect
    EndSelect
  Until Quit = #True
  
  PBMap::Quit()
EndIf
Bye,
...André
(PureBasicTeam::Docs & Support - PureArea.net | Order:: PureBasic | PureVisionXP)
Post Reply