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

Applications, Games, Tools, User libs and useful stuff coded in PureBasic
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 »

Unfortunately I didn't get it managed to avoid the memory crash in the PBMap include, when using two CanvasGadgets for displaying the OSM maps... (see example above)

I can imagine two ways of fixing it:
1) Improve the "Quit" function of PBMap to really free all needed stuff / avoid the use of in-valid MemoryID, so a new OSM display (PBmap canvas) can be started from scratch during program run (via "Init" function).
2) Allow the "switching" of the complete PBMap display from one to another CanvasGadget.

Or maybe there is another solution (or a bug in my code)?

Any help is welcome! :D
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 »

I'll take a look
walbus
Addict
Addict
Posts: 929
Joined: Sat Mar 02, 2013 9:17 am

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

Post by walbus »

Very nice work !
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 »

walbus wrote:Very nice work !
Thank you !
User avatar
Michael Vogel
Addict
Addict
Posts: 2666
Joined: Thu Feb 09, 2006 11:27 pm
Contact:

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

Post by Michael Vogel »

Andre wrote: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.
I added some debug lines in the PBMap code:

Code: Select all

Line 1224 (before PostEvent(#PB_Event_Gadget, PBMap\Window, PBmap\Gadget, #PB_MAP_TILE_CLEANUP, *Tile))
Debug "Prepare freeing Mem "+*Tile

Line 1311 (after Protected *NewTile.Tile = AllocateMemory(SizeOf(Tile)))
Debug "New Memory @ "+*NewTile+", Size "+SizeOf(Tile)

Line 1329 (before FreeMemory(*NewTile))
Debug "Free Mem 'A' "+*NewTile

Line 2603 (before FreeMemory(*Tile))
Debug "Free Mem 'B' "+*Tile

Line 2653 (before FreeMemory(PBMap\MemCache\Images()\Tile))
Debug "Free Mem 'C' "+PBMap\MemCache\Images()\Tile
When doing the tab change as mentioned, the following output is seen:

Code: Select all

New Memory @ 2426280, Size 32
New Memory @ 2426320, Size 32
Prepare freeing Mem 2426280
Free Mem 'B' 2426280
Free Mem 'B' 2426280
Prepare freeing Mem 2426320
This means the same memory block is tried to be freed two times here. Maybe an array or a list variable could be used to collect all memory pointer - so it wouldn't be needed to use postevent for triggering the free memory part.
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 »

No, the problem is that the PBMap's internal structure is by now unique and so shared. I'm working on dynamically allocate it.
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 »

djes wrote:No, the problem is that the PBMap's internal structure is by now unique and so shared. I'm working on dynamically allocate it.
Nice to hear! :D
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 »

After the previously shown 'Multimedia' module of my (internal) GeoWorldEditor, a 'MapLocator' is the next module using OSM I finished this evening. Thanks to PBMap, thank you djes & Co.! :mrgreen:

Here is a screenshot: Image
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 »

Great :D
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 »

The new version is here (still buggy, WIP) : https://github.com/djes/PBMap/tree/djes

Basically, the InitPBMap() can now returns a pointer to the PBMap structure, dynamically allocated. A second parameter must be given for multiple PBMap, different for each PBMap, corresponding to the internal timer used for the automatic refresh. Obviously, it should be different than any of yours. Badly, there's no #PB_Any for timer.

Code: Select all

*PBMap1 = InitPBMap(window, 1)
*PBMap2 = InitPBMap(window, 2)
You can change the used PBMap with the new function SelectPBMap(*PBMap). Quit() function must be called for each PBMap.

Code: Select all

  PBMap::SelectPBMap(*PBMap1)
  PBMap::Quit()
  PBMap::SelectPBMap(*PBMap2)
  PBMap::Quit()
I've slightly modified your code to use it :

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
; Modified by djes : 01. March. 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
  
  Define *PBMap1, *PBMap2
  
  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
    *PBMap1 = PBMap::InitPBMap(#Window_0, 1)
    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:
    *PBMap2 = PBMap::InitPBMap(#Window_0, 2)
    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(#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 = 0
                    PBMap::SelectPBMap(*PBMap1)
                    ;PBMap::MapGadget(#Map, GadgetX(#Map), GadgetY(#Map), GadgetWidth(#Map), GadgetHeight(#Map))
                  Else
                    PBMap::SelectPBMap(*PBMap2)
                    ;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::SelectPBMap(*PBMap1)
  PBMap::Quit()
  PBMap::SelectPBMap(*PBMap2)
  PBMap::Quit()
EndIf
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 »

@djes: It looks like a good solution, to allow several PBMap instances in one window :D But unfortunately I can't compile your updated example code with the current PBMap include hosted on GitHub - it seems like the PBMap include isn't the latest version or somehow incomplete.... for example the InitPBMap() function should have now a second paramter (according to the example code), but it don't have on GitHub + also the 'ReadMe' at the top of the code states 'June 2017', while the latest version was 'July 2017' (or should be 'March 2ß18' now...). Could you take a look, please? Thank you :-)
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 »

The only modified file is this one : https://github.com/djes/PBMap/blob/djes/PBMap.pb

I'll certainly change it again, as the loading threads are still mixed and it hangs if you change view during loading. Just need a couple of hours ;)
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 »

djes wrote:The only modified file is this one : https://github.com/djes/PBMap/blob/djes/PBMap.pb

I'll certainly change it again, as the loading threads are still mixed and it hangs if you change view during loading. Just need a couple of hours ;)
Ok, I copied the PBMap include code again.

Now it compiles - but I had to comment the

Code: Select all

PBMap::SetCallBackMarker(@MarkerMoveCallBack())
in the example, as this wasn't found in the PBMap include.

After doing this the "2 panels / 2 PBMap gadgets" examples above compiles + runs fine.
But I have noticed, that in the 'Map2' panel the OSM display was only correct for a short moment, after that it's grayed (with and without switching between the 2 panels). The OSM display on the 'Map1' panel works good.

When closing the emaples window I get an 'invalid-memory' here

Code: Select all

            FreeMemory(*PBMap\MemCache\Images()\Tile)
(line 2647 in the PBMap include).

So far my actually testing / bug-report for the new and extended 'WIP' version of PBMap.
Thank you very much! :D
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 »

Thank you for your report !

I have modified https://github.com/djes/PBMap/blob/djes/PBMap.pb

Warning ! It's a major update, and breaks compatibility.
There's no more InitPBMap() and Quit(), only a MapGadget() and FreeMapGadget() as the PB's default.
All functions must now pass the gadget's number in first parameter.

I've not yet updated your two panels example, but it shouldn't be too hard. Maybe if I have time this weekend.
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 »

Thank you very much, djes! :D

It seems like we (you) have nearly reached the goal... the following code contains my updated example, adapted to your latest PBMap version (always using a MapGadgetID for each public PBMap function). It runs stable, as long no PBMap::Refresh() is needed.

This one is the important thing, which need to be fixed. I have marked the related code line in the example with 'FIXME' notes.
Probably the use of PBMap::SelectPBMap() is still needed, to have always a valid *PBMap structure?

The second thing is minor important: I noticed that a call to SetActiveGadget() during GUI declaration and PBMap initialization is bad for GetActiveWindow(), which is returning -1 then. See another 'FIXME' note in the commented line of the example.

Here is the updated example code:

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
; Modified by djes : 01. March 2018
; Adapted to new PBMap syntax by André: 02. March 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(#Map)    ; FIXME: will crash with 'Pointer is Null' error!
  PBMap::Refresh(#Map2_Canvas)
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, 720, 595)
  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)   ; FIXME: activating this code line will cause an 'invalid window ID' error in the PBMap::MapGadget() and related PBMap::BindMapGadget() function, as the used GetActiveWindow() will return '-1' there!
    
    ; Our main gadget
    PBMap::MapGadget(#Map, 10, 10, 512, 512)
    PBMap::SetOption(#Map, "ShowDegrees", "1") : Degrees = 0
    PBMap::SetOption(#Map, "ShowDebugInfos", "1")
    PBMap::SetDebugLevel(5)
    PBMap::SetOption(#Map, "Verbose", "0")
    PBMap::SetOption(#Map, "ShowScale", "1")   
    PBMap::SetOption(#Map, "Warning", "1")
    PBMap::SetOption(#Map, "ShowMarkersLegend", "1")
    PBMap::SetOption(#Map, "ShowTrackKms", "1")
    PBMap::SetOption(#Map, "ColourFocus", "$FFFF00AA")
    
    PBMap::SetCallBackMainPointer(#Map, @MainPointer())                   ; To change the main pointer (center of the view)
    PBMap::SetCallBackLocation(#Map, @UpdateLocation())                   ; To obtain realtime coordinates
    PBMap::SetLocation(#Map, -36.81148, 175.08634,12)                     ; Change the PBMap coordinates
    PBMAP::SetMapScaleUnit(#Map, PBMAP::#SCALE_KM)                        ; To change the scale unit
    PBMap::AddMarker(#Map, 49.0446828398, 2.0349812508, "", "", -1, @MyMarker())  ; To add a marker with a customised GFX
    PBMap::SetCallBackMarker(#Map, @MarkerMoveCallBack())
    PBMap::SetCallBackDrawTile(#Map, @DrawTileCallBack())
    PBMap::SetCallBackModifyTileFile(#Map, @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::MapGadget(#Map2_Canvas, 10, 10, 512, 512)
    PBMap::SetOption(#Map2_Canvas, "ShowDegrees", "1") : Degrees = 0
    PBMap::SetOption(#Map2_Canvas, "ShowDebugInfos", "1")
    PBMap::SetDebugLevel(5)
    PBMap::SetOption(#Map2_Canvas, "Verbose", "0")
    PBMap::SetOption(#Map2_Canvas, "ShowScale", "1")   
    PBMap::SetOption(#Map2_Canvas, "Warning", "1")
    PBMap::SetOption(#Map2_Canvas, "ShowMarkersLegend", "1")
    PBMap::SetOption(#Map2_Canvas, "ShowTrackKms", "1")
    PBMap::SetOption(#Map2_Canvas, "ColourFocus", "$FFFF00AA")
    PBMap::SetCallBackMainPointer(#Map2_Canvas, @MainPointer())                   ; To change the main pointer (center of the view)
    PBMap::SetCallBackLocation(#Map2_Canvas, @UpdateLocation())                   ; To obtain realtime coordinates
    PBMap::SetLocation(#Map2_Canvas, 6.81148, 15.08634,12)                     ; Change the PBMap coordinates
    PBMAP::SetMapScaleUnit(#Map2_Canvas, PBMAP::#SCALE_KM)                        ; To change the scale unit
    PBMap::AddMarker(#Map2_Canvas, 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
                  ActivePanel = a
                  If ActivePanel = 0
                    ; ....
                  Else
                    ; ....
                  EndIf
                EndIf
            EndSelect
          Case #Gdt_Up
            PBMap::SetLocation(#Map, 10* 360 / Pow(2, PBMap::GetZoom(#Map) + 8), 0, 0, #PB_Relative)
          Case #Map2_Up
            PBMap::SetLocation(#Map2_Canvas, 10* 360 / Pow(2, PBMap::GetZoom(#Map2_Canvas) + 8), 0, 0, #PB_Relative)
          Case #Gdt_Down
            PBMap::SetLocation(#Map, 10* -360 / Pow(2, PBMap::GetZoom(#Map) + 8), 0, 0, #PB_Relative)
          Case #Map2_Down
            PBMap::SetLocation(#Map2_Canvas, 10* -360 / Pow(2, PBMap::GetZoom(#Map2_Canvas) + 8), 0, 0, #PB_Relative)
          Case #Gdt_Left
            PBMap::SetLocation(#Map, 0, 10* -360 / Pow(2, PBMap::GetZoom(#Map) + 8), 0, #PB_Relative)
          Case #Map2_Left
            PBMap::SetLocation(#Map2_Canvas, 0, 10* -360 / Pow(2, PBMap::GetZoom(#Map2_Canvas) + 8), 0, #PB_Relative)
          Case #Gdt_Right
            PBMap::SetLocation(#Map, 0, 10* 360 / Pow(2, PBMap::GetZoom(#Map) + 8), 0, #PB_Relative)
          Case #Map2_Right
            PBMap::SetLocation(#Map2_Canvas, 0, 10* 360 / Pow(2, PBMap::GetZoom(#Map2_Canvas) + 8), 0, #PB_Relative)
          Case #Button_4
            PBMap::SetZoom(#Map, 1)
          Case #Map2_ZoomIn
            PBMap::SetZoom(#Map2_Canvas, 1)
          Case #Button_5
            PBMap::SetZoom(#Map, - 1)
          Case #Map2_ZoomOut
            PBMap::SetZoom(#Map2_Canvas, - 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(#Map, ValD(GetGadgetText(#StringLatitude)), ValD(GetGadgetText(#StringLongitude)), "", "Test", RGBA(Random(255), Random(255), Random(255), 255))
          Case #Gdt_Degrees
            Degrees = 1 - Degrees
            PBMap::SetOption(#Map, "ShowDegrees", Str(Degrees))
            PBMap::Refresh(#Map)    ; FIXME: will crash with a 'Pointer is Null' error!
            SetGadgetState(#Gdt_Degrees, Degrees)
          Case #Gdt_ClearDiskCache
            PBMap::ClearDiskCache(#Map)
          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(#Map, GetGadgetText(#StringGeoLocationQuery))
              PBMap::Refresh(#Map)
            EndIf
            ; *** TODO : code to change when the SetActiveGadget(-1) will be fixed
            SetActiveGadget(Dummy)
            ; ***
          Case  #MenuEventLonLatStringEnter
            PBMap::SetLocation(#Map, ValD(GetGadgetText(#StringLatitude)), ValD(GetGadgetText(#StringLongitude)))                     ; Change the PBMap coordinates
            PBMap::Refresh(#Map)
        EndSelect
    EndSelect
  Until Quit = #True
 
  PBMap::FreeMapGadget(#Map)
  PBMap::FreeMapGadget(#Map2_Canvas)
EndIf
Bye,
...André
(PureBasicTeam::Docs & Support - PureArea.net | Order:: PureBasic | PureVisionXP)
Post Reply