B4A Library OSMDroid - MapView for B4A

Here we have my latest library - OSMDroid provides a MapView for B4A.

More info on the original (native Android) OSMDroid project can be found here: osmdroid - OpenStreetMap-Tools for Android - Google Project Hosting.

Library reference is no longer included in this post due to limits on the number of characters allowed in a single post.

I have created some tutorials to show basic usage of the library and will update this thread with a link to them as soon as i have them all uploaded.

** Your attention is drawn to the included file Apache License Version 2.0.txt, which is a copy of the Apache License Version 2.0 under which the native Android OSMDroid library is released **

Martin.
 

Attachments

  • OSMDroid_3_0_8_v3.60.zip
    361.9 KB · Views: 4,080
Last edited:

warwound

Expert
Licensed User
Longtime User
I've just tried this on my Galaxy S3 and it works fine.
There is just a single read-only image file my_icon.png in the drawable-nodpi folder.

B4X:
Sub Process_Globals
   Dim MapCenter As GeoPoint
   Dim ZoomLevel As Int
End Sub

Sub Globals
   Dim AndroidResources1 As AndroidResources
   Dim MapView1 As MapView
   Dim MarkersOverlay1 As MarkersOverlay
End Sub

Sub Activity_Create(FirstTime As Boolean)
   MapView1.Initialize("")
   Activity.AddView(MapView1, 0, 0, 100%x, 100%y)
   
   MapView1.SetMultiTouchEnabled(True)
   MapView1.SetZoomEnabled(True)
   
   MarkersOverlay1.Initialize(MapView1, "MarkersOverlay1")
   MapView1.AddOverlay(MarkersOverlay1)
   
   Dim Icon As BitmapDrawable
   Icon=AndroidResources1.GetApplicationDrawable("my_icon")
   
   Dim Marker1 As Marker
   Marker1.Initialize("Home sweet home", "Lorem ipsum dolor sit amet, consectetur adipiscing elit.", 52.75610, 0.39748, Icon)
   
   '   Marker2 will display the default OSMDroid icon
   '   the default icon is used if Null is passed as the Icon parameter
   Dim Marker2 As Marker
   Marker2.Initialize("Elsewhere", "Downham Market", 52.60801, 0.39047, Null)
   
   '   create a List and initialize it with the 2 Markers
   Dim Markers As List
   
   Markers.Initialize2(Array As Object(Marker1, Marker2))
   
   '   add the List of Markers to the MarkersOverlay
   MarkersOverlay1.AddMarkers(Markers)
   
   If FirstTime Then
      '   fit the MapView to the MarkersOverlay
      MapView1.FitMapToBoundingBox(MarkersOverlay1.GetBoundingBox)
   Else
      '   restore saved zoom level and map center
      MapView1.Zoom=ZoomLevel
      MapView1.SetCenter3(MapCenter)
   End If
   
End Sub

Sub Activity_Resume
End Sub

Sub Activity_Pause (UserClosed As Boolean)
   MapCenter=MapView1.GetCenter
   ZoomLevel=MapView1.Zoom
End Sub

Project is attached.

Martin.
 

Attachments

  • drawable-nodpi.zip
    7.2 KB · Views: 254

yonson

Active Member
Licensed User
Longtime User
thanks for the example I worked it out anyway I was calling getAndroidDrawable not GetApplicationDrawable.

But that example is really useful - much appreciated, thanks again.
 

warwound

Expert
Licensed User
Longtime User
How would I go about showing no icon on the MyLocationOverlay?

I'd first try setting the PersonIcon property to Null.
If that fails - it might raise an exception and crash your app - then the only other solution would be to set the PersonIcon to a small fully transparent image.
A one pixel sqaure fully transparent PNG would be ideal.

Martin.
 

ValDog

Active Member
Licensed User
Longtime User
I'd first try setting the PersonIcon property to Null.
If that fails - it might raise an exception and crash your app - then the only other solution would be to set the PersonIcon to a small fully transparent image.
A one pixel sqaure fully transparent PNG would be ideal.

Martin.


Martin, Thanks! Setting PersonIcon property to Null did crash my app, but the one pixel square fully transparent PNG seems to work just fine.
 

ValDog

Active Member
Licensed User
Longtime User
On my MyLocation overlay I set the LocationUpdateMinTime to 10000 msec (10 sec), but it does not fire the LocationChanged sub as it should at that frequency. Any idea as to why it is misbehaving?


Oops! Looks like I had my time and distance variables transposed - sorry about that!
 
Last edited:

ValDog

Active Member
Licensed User
Longtime User
Martin,

Using the MarkersBalloonOverlay with the FocusedMarker functionality, my application crashes when I change orientation and the app tries to restore an open balloon. Any suggestions?


Oops - sorry again. After carefully comparing my code to your BalloonMarkersOverlay Demo code I found my problem...
 
Last edited:

padvou

Active Member
Licensed User
Longtime User
I'm trying to make a solution to take addresses from an sqlite db and show multiple markers on a map. Any ideas please on how to do this?
I managed to take the data one by one by means of a reader query, but where to go next?
 

warwound

Expert
Licensed User
Longtime User
I'm trying to make a solution to take addresses from an sqlite db and show multiple markers on a map. Any ideas please on how to do this?
I managed to take the data one by one by means of a reader query, but where to go next?

Have you worked your way through any of the OSMDroid examples?

The MarkersBalloonOverlay is likely to be what you want to create an instance of and add to your MapView.

You can then add Markers to the MarkersBalloonOverlay using a For loop to iterate through your database query result set.

You can customise the balloon in two ways:
  • Customise the balloon so that each Marker when clicked displays the same customised balloon.
  • Use the BalloonMarker (instead of Marker) and show different customised balloons for different BalloonMarkers when clicked.

Martin.
 

padvou

Active Member
Licensed User
Longtime User
Have you worked your way through any of the OSMDroid examples?

The MarkersBalloonOverlay is likely to be what you want to create an instance of and add to your MapView.

You can then add Markers to the MarkersBalloonOverlay using a For loop to iterate through your database query result set.

You can customise the balloon in two ways:
  • Customise the balloon so that each Marker when clicked displays the same customised balloon.
  • Use the BalloonMarker (instead of Marker) and show different customised balloons for different BalloonMarkers when clicked.

Martin.
Thank you for answering.
I was looking at the example you pointed to me but where in the following code snippet should the loop be and how?
B4X:
Marker1.Initialize("Home sweet home", "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi egestas suscipit convallis. Etiam pellentesque gravida est, quis luctus nunc commodo at. Nam et risus orci. Integer malesuada lorem dolor. Maecenas vestibulum cursus enim, tincidunt luctus libero placerat non. In vitae metus tellus, nec euismod nibh. Phasellus ut quam vitae justo sagittis auctor. Sed vel sapien dolor. Etiam ut sem id dolor iaculis ullamcorper. Aenean eget sem nibh, a tempor augue. Nulla interdum luctus molestie.", 52.75610, 0.39748, Icon)
      '  Marker2 will display the default OSMDroid icon
      '  the default icon is used if Null is passed as the Icon parameter
      Marker2.Initialize("Elsewhere", "Downham Market", 52.60801, 0.39047, Null)
      Marker3.Initialize("Title but no description", "", 52.6959, 0.606, Null)
      Marker4.Initialize("", "Description but no title", 52.8440, 0.506, Null)

The total numbers of markers is known only during rutinme after the relevant query is executed and returns its data.
 

warwound

Expert
Licensed User
Longtime User
Have a look at this (untested) code example:

B4X:
Dim Markers As List
Markers.Initialize

Dim Cursor1 As Cursor
Cursor1 = SQL1.ExecQuery("SELECT title, desc, lat, lng FROM my_table")
For i = 0 To Cursor1.RowCount - 1
  Cursor1.Position = i
   
   Dim Marker1 As Marker
   Dim Title As String=Cursor1.GetString("title")
   Dim Description As String=Cursor1.GetString("desc")
   Dim Latitude As Double=Cursor1.GetDouble("lat")
   Dim Longitude As Double=Cursor1.GetDouble("lng")
   
   Marker1.Initialize(Title, Description, Latitude, Longitude, Null)
   Markers.Add(Marker1)
Next
Cursor1.Close

MarkersBalloonOverlay1.AddMarkers(Markers)

'   optionally adjust the map center and zoom level to fully display all Markers
MapView1.FitMapToBoundingBox(MarkersBalloonOverlay1.GetBoundingBox)

Replace MapView1, MarkersBalloonOverlay1 and SQL1 in the code example with the names you are using for the same objects in your code (if they are different).
And update the query column names to match your database schema.

I've created and initialized a List to store all Markers created in the loop.
Queried the database, then looped through the query results creating a new Marker for each row in the query result.
Added each new Marker to the List and then when all rows in the query result have been processed, added the List of Markers to the MarkersBalloonOverlay.

Martin.
 

synapse

Member
Licensed User
Longtime User
I have been trying to specify and maximum and minimum zoom level without success in an exercise using location, map and markers without any success and wondered if anyone could help me preserve what little hair I have left. I do not seem able to stop the user zooming beyond the last zoom level offered by tiles in this offline system. Any help would be greatly appreciated!
 

warwound

Expert
Licensed User
Longtime User
If you log the values returned by the MapView methods GetMaxZoomLevel and GetMinZoomLevel what do you see?

You have an offline tile archive and use the MapView SetTileSource method to select your offline tiles i guess?
(You're not using a method that allows you to define minimum and maximum zoom levels?)

Martin.
 

synapse

Member
Licensed User
Longtime User
If you log the values returned by the MapView methods GetMaxZoomLevel and GetMinZoomLevel what do you see?

You have an offline tile archive and use the MapView SetTileSource method to select your offline tiles i guess?
(You're not using a method that allows you to define minimum and maximum zoom levels?)

Martin.
Thanks for your reply!

Minzoom is 0 and Maxzoom is 18. I am using maperitive to generate tiles (setting max and min zoom in generate-tiles) using a snippet of map imported from openstreetmap...
 

synapse

Member
Licensed User
Longtime User
Thanks for your reply!

Minzoom is 0 and Maxzoom is 18. I am using maperitive to generate tiles (setting max and min zoom in generate-tiles) using a snippet of map imported from openstreetmap...
I'm sorry I wasn't very precise. I am generating tiles offline and compiling them into the files directory of the project but not specifying the settilesource..
 

warwound

Expert
Licensed User
Longtime User
Looks like the MapView is using it's default minimum and maximum zoom levels for your offline tile archive.
And it also looks as though there's no way to override these minimum and maximum zoom levels :(.

I think your only option is to listen for the MapView ZoomChanged event, in the Sub that listens for this event check the current map zoom level and if it's outside of the levels contained by your offline tiles then adjust the zoom level so it is covered by your offline tiles.

Martin.
 

synapse

Member
Licensed User
Longtime User
Looks like the MapView is using it's default minimum and maximum zoom levels for your offline tile archive.
And it also looks as though there's no way to override these minimum and maximum zoom levels :(.

I think your only option is to listen for the MapView ZoomChanged event, in the Sub that listens for this event check the current map zoom level and if it's outside of the levels contained by your offline tiles then adjust the zoom level so it is covered by your offline tiles.

Martin.
Thanks for taking the trouble....
 

merlin2049er

Well-Known Member
Licensed User
Longtime User
Awesome, I got my offline maps extracted using mobac as a zip file copied it over to the external sd memory spot and got it up and running. (Just had to adjust the zoom level). Just a quick question, are there markers I can use that will trigger an event?

Oh, and another; I've got a sqlite table, is there an easy way to generate a list of waypoints that I can import into it?

Thanks,
Joe
 

warwound

Expert
Licensed User
Longtime User
Just a quick question, are there markers I can use that will trigger an event?

Look at the MarkersBalloonOverlay object, it should do as you require.

Oh, and another; I've got a sqlite table, is there an easy way to generate a list of waypoints that I can import into it?

Not sure what you mean here, do you have a list of coords in some other format and want a way to quickly import them into a SQLite table?

Martin.
 
Top