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:

padvou

Active Member
Licensed User
Longtime User
Why in some devices, the map renders almost immediately and on some others it renders very slow and leaves blank spots?
 

warwound

Expert
Licensed User
Longtime User
I'd guess that devices with relatively slow processors and small amounts of memory would cause an issue such as this.

When a tile needs to be displayed it is requested and rendered in a thread of it's own. If this thread fails then it fails silently - leaving the MapView displaying a blank instead of the requested tile.
These threads are more likely to fail on low power devices.

Unfortunately there is little that you can do to solve the problem.
What devices are you experiencing the problem on?
If you pan the map slowly and wait for new tiles to render does it work - but fail if you pan the map and change zoom levels quickly?

Martin.
 

padvou

Active Member
Licensed User
Longtime User
I'd guess that devices with relatively slow processors and small amounts of memory would cause an issue such as this.

When a tile needs to be displayed it is requested and rendered in a thread of it's own. If this thread fails then it fails silently - leaving the MapView displaying a blank instead of the requested tile.
These threads are more likely to fail on low power devices.

Unfortunately there is little that you can do to solve the problem.
What devices are you experiencing the problem on?
If you pan the map slowly and wait for new tiles to render does it work - but fail if you pan the map and change zoom levels quickly?

Martin.
Good morning and thank you for such an immediate answer.
The funny thing is that it renders ok in a chinese cheap tablet with a dual core A9 processor and seems to have hick ups in an HTC Sensation with a dual core 1500Mhz processor..
Strange..
I utilize the command to autofit the markers. Sometimes zooming in or out seems to re-render the missing tiles.
What if I tried to change the zooming level?
 

warwound

Expert
Licensed User
Longtime User
Each time the MapView needs to display a tile it has to:

1) Check if the tile exists in the cache - it is already downloaded and is stored on external memory.

2) Download the tile if it is not already cached.

3) Render the tile.

This all happens in a thread of it's own, if the thread fails then the MapView ends up displaying a blank instead of a tile.
The thread might fail for various reasons:

1) Tile request fails.
Network connection might be up and working but if the tileserver is busy/overloaded and doesn't respond to the tile request within a short period of time then the request times out.
Many public tileservers get very overloaded and simply can't serve all tiles that are requested.

2) If you pan the map quickly and over a large area, and change the zoom level a lot in a short period of time then the MapView makes many requests for tiles.
Lots of requests might cause the device to run out of resources and requests will fail.
And if the tileserver is busy then many requests in a short period of time will likely result in more requests not succeeding.

Often a thread requests a tile, the request doesn't complete in a short period of time and the MapView treats the request as failed, but if the requested tile eventually gets downloaded it is still cached to external memory but NOT rendered to the MapView.
Pan the map a bit or zoom in and then out and when the MapView re-renders the area that was previously blank it now successfully gets the tile from the cache and renders it.

Look at the 'reported issues' for the native java Android OSMDroid library: Issues - osmdroid - OpenStreetMap-Tools for Android - Google Project Hosting.
You'll see there are many bugs found and reported but as OSMDroid is a project developed by individuals in their spare time these bugs get fixed as and when the developers have time to do so.

Which tileserver are you displaying tiles from?
OSMDroid supports the Cloudmade tile server, if you create a Cloudmade account and use the Cloudmade tileserver you might find tile loading improves noticeably.
(Cloudmade tileservers generally have more resources than the other free open street map tileservers).
Info on using Cloudmade tiles can be found here: http://www.b4x.com/forum/basic4andr...smdroid-mapview-b4a-tutorial-2.html#post92864.

Martin.
 

padvou

Active Member
Licensed User
Longtime User
Please take a look at the following code:
B4X:
Markers.Initialize2(Array As Object(Marker1,Marker2,Marker3,Marker4,Marker5,Marker6))

However, in my code there are booelan values which indicate which markers are used and which are not.
How could I adjust the above code so that the array will contain only the markers that it should?
Example:
B4X:
Markers.Initialize2(Array As Object(Marker1)) ' Only marker1 is used
B4X:
Markers.Initialize2(Array As Object(Marker1,Marker4,Marker5,Marker6)) 'Markers 1, 4, 5 and 6 are used
Any ideas please?
 

warwound

Expert
Licensed User
Longtime User
I don't think there's any built in method to initailize a List selectively from an Array based using any Boolean value to indicate whether or not to include them.

You'll have to loop through your Marker objects checking the Boolean value for each and adding the Marker to the List if the Boolean value is True.

Martin.
 

padvou

Active Member
Licensed User
Longtime User
I don't think there's any built in method to initailize a List selectively from an Array based using any Boolean value to indicate whether or not to include them.

You'll have to loop through your Marker objects checking the Boolean value for each and adding the Marker to the List if the Boolean value is True.

Martin.

What do you think of this:
B4X:
If domarker1=True Then
      Marker1.Initialize(mDesc1, mTitle1, wlat1, wlng1, Null)
      Markers.Add(Marker1)
   End If

   If domarker2=True Then
      Marker2.Initialize(mDesc2,mTitle2, wlat2, wlng2, Null)
      Markers.Add(Marker2)
   End If


   If domarker3=True Then
      Marker3.Initialize(mDesc3, mTitle3, wlat3, wlng3, Null)
      Markers.Add(Marker3)
   End If


   If domarker4=True Then
      Marker4.Initialize(mDesc4, mTitle4, wlat4, wlng4, Null)
      Markers.Add(Marker4)
   End If


   If domarker5=True Then
      Marker5.Initialize(mDesc5,mTitle5, wlat5, wlng5, Null)
      Markers.Add(Marker5)
   End If

   If domarker6=True Then
      Marker6.Initialize(mDesc6, mTitle6, wlat6, wlng6, Null)
      Markers.Add(Marker6)
   End If
   
   
If (domarker1 =False AND domarker2=False AND domarker3=False AND domarker4 =False AND domarker5=False AND domarker6=False) Then

   ToastMessageShow("No data entered: no markers to plot...", False)
      Return True
   End If
   MapView1.removeOverlay(MarkersBalloonOverlay1)
   MapView1.AddOverlay(MarkersBalloonOverlay1)
   MarkersBalloonOverlay1.AddMarkers(Markers)
   MapView1.FitMapToBoundingBox(MarkersBalloonOverlay1.GetBoundingBox)
   Markers.Clear
 

padvou

Active Member
Licensed User
Longtime User
Can the baloonmarkers have different colors? I mean each one to have its own.
 

warwound

Expert
Licensed User
Longtime User
The BalloonMarker's various Initialize methods allow you to pass a BitmapDrawable to be used as a custom icon, or you pass Null to use the default OSMDroid icon.

So you can't change the color of the default OSMDroid icon, but you can pass any BitmapDrawable as a custom icon.

Martin.
 

padvou

Active Member
Licensed User
Longtime User
The BalloonMarker's various Initialize methods allow you to pass a BitmapDrawable to be used as a custom icon, or you pass Null to use the default OSMDroid icon.

So you can't change the color of the default OSMDroid icon, but you can pass any BitmapDrawable as a custom icon.

Martin.

Excellent!
Thank you very much Martin and I apologize if I asked too many newbie questions...
 

padvou

Active Member
Licensed User
Longtime User
Hi again!
Is it possible to download what is needed for offline use?
 

yonson

Active Member
Licensed User
Longtime User
overlay marker images too big

Hi,

I've been working through the excellent tutorial, my only problem is that any image for the overlay markers are being rendered too large on my samsung note ii (i.e. not to correct scale / resolution),

Note that the default image, stored in the drawable-nodpi renders fine, just wondering if anyone can advise how to solve this.

I've tried loading the image bitmap scaled, or resizing it once loaded, both don't make any difference.

Any help greatly appreciated
 

warwound

Expert
Licensed User
Longtime User
You only 100% guaranteed solution is to add your images to your project's drawable-nodpi folder and use my AndroidResources library to get those drawables and pass them to OSMDroid.

A bit of a convoluted solution but a solution that should work reliably on all devices.

Martin.
 

yonson

Active Member
Licensed User
Longtime User
thanks for the help Martin - I'll give that a look and let you know if I have any problems.

Cheers again
 

yonson

Active Member
Licensed User
Longtime User
drawable-nodpi directory deleted on build

Hi Martin

thanks for your help and excellent library, its seems to do exactly what I need, however when I transferred the code from your tutorial into my project, the 'drawable-nodpi' directory is deleted when the project is built.

I checked the android manifest etc etc but couldn't see any differences, can you let me know where you specify / control this folder being removed / created during the build process?

Thanks!
 

warwound

Expert
Licensed User
Longtime User
Just re-create the drawable-nodpi folder, then put some images in it.
Select these images, right-click and select Properties.
Check the read-only checkbox.
Make sure all your images are set to read-only and now re-comile your project.

It's the read-only attribute that prevents the compiler from deleting them.
The folder won't be deleted if there are read-only files in it.

Martin.
 

yonson

Active Member
Licensed User
Longtime User
Thanks Martin appreciate the prompt response, the images still aren't showing up though, I've added an image 'mapicon.png' into drawable-nodpi but it doesn't show up on the assets list at all which I've written out to the log,

I've cleaned the project etc but they're still not showing up, any ideas?
Thanks again
 
Top