B4A Class Open Street Map viewer - GPS

Star-Dust

Expert
Licensed User
Longtime User
I turned the project into B4XPages. So you can also work only on one platform but all three platforms will be modified. It is not necessary to have b4i.

I have also attached the B4XLib version with some minor changes.

Thanks @spsp you have opened a very interesting path. I hope my contribution can be of help to you
 

Attachments

  • B4XOpenMap.b4xlib
    23.1 KB · Views: 498
  • B4XOpenMap.zip
    187 KB · Views: 531

AngeloR

New Member
Licensed User
 

Star-Dust

Expert
Licensed User
Longtime User
I think so
 

spsp

Active Member
Licensed User
Longtime User

It should be a bit difficult but possible to draw shape on the map. The main problem is that a map is not picture but a set of tiles.

Which geometric shape do you need ? square, rectangle, circle, polygon...?
 

spsp

Active Member
Licensed User
Longtime User

Thank you for your help.
 

Star-Dust

Expert
Licensed User
Longtime User
It should be a bit difficult but possible to draw shape on the map. The main problem is that a map is not picture but a set of tiles.

Which geometric shape do you need ? square, rectangle, circle, polygon...?
All, square, rectangle, circle, polygon
 

udg

Expert
Licensed User
Longtime User
Hi,
is it possible to draw personalized markers? I'd like to use different PNGs to mark different places.
Currently type TMapMarker seems to allow just a color and the coords.
 

spsp

Active Member
Licensed User
Longtime User
Hi,
is it possible to draw personalized markers? I'd like to use different PNGs to mark different places.
Currently type TMapMarker seems to allow just a color and the coords.

Hi, actually it's not possible

I'm now working on adding the ability to draw shape (circle, polygon, line) and image and the map.
Be patient.....

spsp
 

udg

Expert
Licensed User
Longtime User
Thank you. Take all the time you need. I just dowloaded the lib and run the B4J demo out of curiosity; BTW, great job!
 

spsp

Active Member
Licensed User
Longtime User
Thank you. Take all the time you need. I just dowloaded the lib and run the B4J demo out of curiosity; BTW, great job!
Hi, you can now add your own image (marker....) and shapes (circle, line, polygon). see Post #1 to donwload new verison
 

spsp

Active Member
Licensed User
Longtime User

Hi,

You are now able to draw geometric shape like circle, line and polygon. adding image is also supported. See post #1 to download new version.
 

udg

Expert
Licensed User
Longtime User
Hi,
just downloaded the most recent version. I wish to signal a possible bug (or the need to better explain how to use the lib).
[B4J 8.90] Using your demo "as is" . Click on a point on the map not covered by shapes (eg. Venezia, Italy). Choose "Search" option. Enter "Milano, viale Certosa 1" and choose first one of the proposed alternatives.
The program crashes with the following log
Waiting for debugger to connect...
Program started.
Call B4XPages.GetManager.LogEvents = True to enable logging B4XPages events.
lat/Lng changed : [IsInitialized=false, fLat=0.0, fLng=0.0
]
zoom level changed : 0
lat/Lng changed : [IsInitialized=false, fLat=48.0, fLng=2.0
]
zoom level changed : 5
compass changed: 0
lat/Lng changed : [IsInitialized=false, fLat=48.0, fLng=2.0
]
Index time: 1 ms (2 Items)
lat/Lng changed : [IsInitialized=false, fLat=45.497823, fLng=9.1351504
]
compass changed: 0
lat/Lng changed : [IsInitialized=false, fLat=45.497823, fLng=9.1351504
]
Error occurred on line: 401 (cvMap)
java.lang.reflect.InvocationTargetException
at sun.reflect.GeneratedMethodAccessor9.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at anywheresoftware.b4a.keywords.Common.CallSubDebug(Common.java:455)
at b4j.example.cvmap._update_shapes(cvmap.java:622)
at b4j.example.cvmap._draw(cvmap.java:118)
at b4j.example.b4xmainpage$ResumableSub_parseGeocoding.resume(b4xmainpage.java:1068)
at anywheresoftware.b4a.shell.DebugResumableSub$DelegatableResumableSub.resumeAsUserSub(DebugResumableSub.java:47)
at sun.reflect.GeneratedMethodAccessor3.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:632)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:237)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:167)
at sun.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:91)
at anywheresoftware.b4a.shell.ShellBA.raiseEvent2(ShellBA.java:98)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:78)
at anywheresoftware.b4a.shell.DebugResumableSub$DelegatableResumableSub.resume(DebugResumableSub.java:42)
at anywheresoftware.b4a.BA.checkAndRunWaitForEvent(BA.java:136)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:85)
at anywheresoftware.b4a.shell.ShellBA.raiseEvent2(ShellBA.java:98)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:78)
at anywheresoftware.b4a.keywords.Common$3.run(Common.java:1086)
at com.sun.javafx.application.PlatformImpl.lambda$null$172(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater$173(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$147(WinApplication.java:177)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at anywheresoftware.b4a.debug.Debug.CallSub4(Debug.java:134)
at anywheresoftware.b4a.debug.Debug.CallSubNew(Debug.java:78)
... 33 more
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at anywheresoftware.b4a.debug.Debug.CallSub4(Debug.java:115)
... 34 more
Caused by: java.lang.RuntimeException: Object should first be initialized (B4XView).
at anywheresoftware.b4a.AbsObjectWrapper.getObject(AbsObjectWrapper.java:32)
at anywheresoftware.b4a.objects.B4XViewWrapper.getNodeObject(B4XViewWrapper.java:120)
at anywheresoftware.b4a.objects.B4XViewWrapper.asViewWrapper(B4XViewWrapper.java:116)
at anywheresoftware.b4a.objects.B4XViewWrapper.getTag(B4XViewWrapper.java:697)
at b4j.example.cvmap._latlngtopoint(cvmap.java:2131)
at b4j.example.clmapshapecircle._draw(clmapshapecircle.java:139)
... 39 more
java.lang.RuntimeException: java.net.SocketException: Socket closed
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:120)
at anywheresoftware.b4a.shell.ShellBA.raiseEvent2(ShellBA.java:98)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:78)
at anywheresoftware.b4j.objects.PaneWrapper$5.handle(PaneWrapper.java:153)
at anywheresoftware.b4j.objects.PaneWrapper$5.handle(PaneWrapper.java:1)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3757)
at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:394)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$353(GlassViewEventHandler.java:432)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:431)
at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
at com.sun.glass.ui.View.notifyMouse(View.java:937)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$147(WinApplication.java:177)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.net.SocketException: Socket closed
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:118)
at java.net.SocketOutputStream.write(SocketOutputStream.java:155)
at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140)
at anywheresoftware.b4a.shell.ShellConnector.sendControlMessage(ShellConnector.java:55)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:189)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:167)
at sun.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:91)
... 32 more

I guess the problem derives from a specific tile (the one good for the address searched for) missing from the current DB.
In fact, if we first move the map center to the place we'll be searching for next, the error doesn't happen.
 

agraham

Expert
Licensed User
Longtime User
Nice job I am going to use both the B4J and B4A versions to display Open Street Maps alongside my own mapping programs which use Ordnance Survey mapping. I could start taking the library apart but I thought that I would take the easy way out and ask if it possible to add mouse scroll-wheel scrolling in B4J and either pinch in or out or double tap (same place to zoom in, different places to zoom out) zooming?

A couple of niggles.
a) I think the fcvMap_MenuClicked dialog title ought to be "Settings"
b) The menu button on B4J is awkwardly stuck to the right hand edge of the window but is neatly positioned in B4A.
 

spsp

Active Member
Licensed User
Longtime User

a) You're right. Title menu is now 'Settings'.
b) Corrected.

Attached files in Post #1 updated

For the mouse scroll wheel and double tap, i will take a look.
 

agraham

Expert
Licensed User
Longtime User
Because the Settings menu is too small and wraps hiding half of the text on a phone and because the dialog scrolls so slowly on the desktop that it's a pain I've changed the initialisation of fPrefDlg in B4XPage_Created
B4X:
#If b4a  
  fPrefDlg.Initialize(Root,"Map", 250dip , 350dip)
#else
  fPrefDlg.Initialize(Root,"Map",300, 600)  
#End If
 

udg

Expert
Licensed User
Longtime User
Hi,
I solved the crash illustrated at post #33 above simply inserting a "change zoom level" command before the drawing.
Your sub parseGeocoding (lines 240+) looks now:
B4X:
fcvMap.addShapeCircle(coMapUtilities.initShapeCircle(ll,15dip,d.Get("color"),True,d.Get("radius")*1dip,m.Get("display_name")))
fcvMap.CenterLatLng=ll
fcvMap.ZoomLevel = 15                'add this line
fcvMap.draw
 

Domrich_FR

New Member
Try to remove specific marker:
Public Sub removeMarker (Latitude As Double,Longitude As Double)
    Private point As TMapLatLng
    point = coMapUtilities.initLatLng(Latitude,Longitude)   
    Private image As TMapShapeImage   
    image.fLatLng = point
    image.fbitmap = fxui.LoadBitmapResize(File.DirAssets,"marker.png",20dip,25dip,True)
    image.fRotation = 0
    image.fData = "ball"         
    fcvMap.removeShape(image)   
    fcvMap.draw
End Sub
Hi
First congratulations for your very useful job.
I am writing an app to follow a stratospheric ballon (not professionnal) for students. Ballon send its position by radio
Working not to bad . I have added a pic (marker on the map with no problem but I did not succeed to remove a specific marker. I have tried fcvMap.removeShape. with exact coordinates given when adding.
Can you help? Thanks in advance.
Dominique
 

udg

Expert
Licensed User
Longtime User
Try with something like the following
B4X:
For i=0 To fMap.fShapes.Size-1
        Dim styp As String = CallSub(fMap.fShapes.Get(i),"getShape_Type")
        Dim sdat As String = CallSub(fMap.fShapes.Get(i),"getShape_Data")
        Log(styp)
        Log(sdat)
        If styp = "image" And sdat ="Marseille" Then
            fMap.fShapes.RemoveAt(i)
            Exit
        End If
    Next
and adapt it to your needs.

Update: if you need to remove based on coordinates, you may want to try somethin like the following:
B4X:
Private point As TMapLatLng
    point = coMapUtilities.initLatLng(Latitude,Longitude)
    For i=0 To fMap.fShapes.Size-1
      Dim styp As String = CallSub(fMap.fShapes.Get(i),"getShape_Type")
      If styp = "image" Then
        Dim test As TMapShapeImage = CallSub(fMap.fShapes.Get(i),"get_Shape")
        If ((test.fLatLng.fLat = point.fLat) And (test.fLatLng.fLng = point.fLng)) Then
            fMap.fShapes.RemoveAt(i)
            Exit
        End If
      End If
    Next
The above should remove the first image set at goven coord; remove the Exit and it should delete allt he images at those coords.
 
Last edited:
Cookies are required to use this site. You must accept them to continue using the site. Learn more…