Android Tutorial OSMDroid - MapView for B4A tutorial

You can find the OSMDroid library thread here: http://www.b4x.com/forum/additional...tes/16309-osmdroid-mapview-b4a.html#post92643.

AIM: Create and initialize a MapView, enable the map zoom controller and multitouch controller, set a zoom level then center the map on a location.

B4X:
Sub Process_Globals
End Sub

Sub Globals
   Dim MapView1 As MapView
End Sub

Sub Activity_Create(FirstTime As Boolean)
   If File.ExternalWritable=False Then
      '   OSMDroid requires the use of external storage to cache tiles
      '   if no external storage is available then the MapView will display no tiles
      Log("WARNING NO EXTERNAL STORAGE AVAILABLE")
   End If
   
   '   no EventName is required as we don't need to listen for MapView events
   MapView1.Initialize("")
   Activity.AddView(MapView1, 0, 0, 100%x, 100%y)
   
   '   by default the map will zoom in on a double tap and also be draggable - no other user interface features are enabled
   
   '   enable the built in zoom controller - the map can now be zoomed in and out
   MapView1.SetZoomEnabled(True)
   
   '   enable the built in multi touch controller - the map can now be 'pinch zoomed'
   MapView1.SetMultiTouchEnabled(True)
   
   '   set the zoom level BEFORE the center (otherwise unpredictable map center may be set)
   MapView1.Zoom=14
   MapView1.SetCenter(52.75192, 0.40505)
End Sub

Sub Activity_Resume
End Sub

Sub Activity_Pause (UserClosed As Boolean)
End Sub

The code is pretty self-explanatory.

I've added the code to check if the device has available external storage as OSMDroid will not display any tiles if no external storage is available.
External storage is used to save/cache all downloaded tiles - no external storage means no map!
(I'll omit that check from future tutorials but it's something to bear in mind - not that i know of any Android devices that have no external storage).

Create and initialize a MapView, add it to the Activity 100% width and 100% height.
Enable the zoom and multi-touch controller.
Zoom in to level 14 then set the MapView center to a location (sunny Norfolk, UK!).

I've found that setting the map center and then immediately setting the zoom level does not work as expected.
I think that while the MapView is setting the map center it also zooms in so the end result is unpredictable.

Pan and zoom the map, now rotate your device and you'll see the map returns to it's initial state of zoom level 14, center (52.75192, 0.40505).

I shall show you how to save and restore the MapView state next...

Martin.
 

Attachments

  • 01 - SimpleMap.zip
    5.8 KB · Views: 4,788
Last edited:

warwound

Expert
Licensed User
Longtime User
I've just uploaded a couple more example projects for the new version 4.1 library: http://b4a.martinpearman.co.uk/osmdroid/OSMDroid_v4.1_more_examples.zip.

One shows use of the 'classic' balloon infowindow to show Marker data when a Marker is clicked.

The other is similar but uses a plain b4a Label to show Marker data when a Marker is clicked.
This second example may be of interest to you.
If each of you Markers has an associated Label you could update the Label Text when the Marker is clicked for example.

Martin.
 

Spectre

Active Member
Licensed User
Longtime User
Hi ... I'm looking at the material is very nice. Unfortunately for my app is always necessary to show the point on the map with his name and not when it is clicked.
The type of example that indicates I'm already doing with this version of osmdroid.

But for the type of use of my app is essential the name on the map. Then wait developments. Whether it be the case that if I suspend the development of the app then the versions have different characteristics? PS. Do you have any idea about the problem of the compass?
 

warwound

Expert
Licensed User
Longtime User
The problem with the compass and scalebar will be as i posted.
Either you need to disable hardware acceleration using the manifest editor OR you need to change the order in which you are adding the overlays to the MapView.

I think you'll find that you need to disable hardware acceleration using the manifest editor.
What version of android are you running your app on?

Martin.
 

Spectre

Active Member
Licensed User
Longtime User
Hi! ... I do not think that's the problem. If I open your project work. If I copy the source code from your project to mine, it does not work
 

warwound

Expert
Licensed User
Longtime User
But the demo i created many months ago was created using an older version of B4A and might also have been created before the hardware acceleration manifest attribute was introduced (it was introduced with Honeycomb).

Create a new B4A project with the latest version of B4A and open the manifest editor.
Compare that to my demo project's manifest - you'll see different targetSdk versions, maybe other differences too.

Does an old targetSdk version cause the app to be run in a compatibility mode on newer devices and therefore hardware acceleration does not need to be disabled?
Compatibility mode might automatically disable hardware acceleration.

You could modify your non working project's manifest, set a targetSdk version that's the same as the targetSdk version in my working demo.
Now do you see the compass in your project?

Martin.
 

Spectre

Active Member
Licensed User
Longtime User
B4X:
'This code will be applied to the manifest file during compilation.
'You do not need to modify it in most cases.
'See this link for for more information: http://www.b4x.com/forum/showthread.php?p=78136
AddManifestText(
<uses-sdk android:minSdkVersion="4" android:targetSdkVersion="14"/>
<supports-screens android:largeScreens="true"
    android:normalScreens="true"
    android:smallScreens="true"
    android:anyDensity="true"/>)
SetApplicationAttribute(android:icon, "@drawable/icon")
SetApplicationAttribute(android:label, "$LABEL$")
'End of default text.


My app
*****************************************************************
'This code will be applied to the manifest file during compilation.
'You do not need to modify it in most cases.
'See this link for for more information: http://www.b4x.com/forum/showthread.php?p=78136
AddManifestText(
<uses-sdk android:minSdkVersion="4" />
<supports-screens android:largeScreens="true"
android:normalScreens="true"
android:smallScreens="true"
android:anyDensity="true"/>)
SetApplicationAttribute(android:icon, "@drawable/icon")
SetApplicationAttribute(android:label, "$LABEL$")
'End of default text.

Originall app
 

Spectre

Active Member
Licensed User
Longtime User
But the demo i created many months ago was created using an older version of B4A and might also have been created before the hardware acceleration manifest attribute was introduced (it was introduced with Honeycomb).

Create a new B4A project with the latest version of B4A and open the manifest editor.
Compare that to my demo project's manifest - you'll see different targetSdk versions, maybe other differences too.

Does an old targetSdk version cause the app to be run in a compatibility mode on newer devices and therefore hardware acceleration does not need to be disabled?
Compatibility mode might automatically disable hardware acceleration.

You could modify your non working project's manifest, set a targetSdk version that's the same as the targetSdk version in my working demo.
Now do you see the compass in your project?

Martin.

Hi martin.
you're right if I remove the riferimentoi to 14 SDK works ... What could lead to remove this variable in the manifest?
Or is there a way to use the compass and bar with this sdk?
 
Last edited:

Spinter

Active Member
Licensed User
Longtime User
I have problems to display the flag under that I see. I hope you understand me.
how do I display the flag below?
When I click on google maps for the second time to explain to me!
sorry im traslated by google
 
Last edited:

Spectre

Active Member
Licensed User
Longtime User
Hi!
it is possible to derive the center of the map off line automatically when it is loaded without having to specify?
Tanks...
 

Spinter

Active Member
Licensed User
Longtime User
I have problems to display the flag under that I see. I hope you understand me.
how do I display the flag below?
When I click on google maps for the second time to explain to me!
sorry im traslated by google
 

Spectre

Active Member
Licensed User
Longtime User
I have problems to display the flag under that I see. I hope you understand me.
how do I display the flag below?
When I click on google maps for the second time to explain to me!
sorry im traslated by google
Hi!

Question on the library osmdroid?
 

warwound

Expert
Licensed User
Longtime User
Hi again.

Been busy so only just had time to reply...

I'm not sure what you mean by 'display the flag'.
Is the flag an icon or Label that you're trying to display underneath the Marker?

Are you using the new version 4.1 alpha library or the existing version 3.0.8?

If you're using version 4.1 and the new ViewHost then when you initialize the ViewHost you have the Alignment parameter:

Initialize (View1 As View, GeoPoint1 As GeoPoint, OffsetX As Int, OffsetY As Int, Alignment As Int, Visible As Boolean)

Alignment is one of the OSMDroid_LayoutParams values:

ALIGN_BOTTOM_CENTER As Int
ALIGN_BOTTOM_LEFT As Int
ALIGN_BOTTOM_RIGHT As Int
ALIGN_CENTER As Int
ALIGN_CENTER_LEFT As Int
ALIGN_CENTER_RIGHT As Int
ALIGN_TOP_CENTER As Int
ALIGN_TOP_LEFT As Int
ALIGN_TOP_RIGHT As Int
MATCH_PARENT As Int
WRAP_CONTENT As Int

That along with the OffsetX and OffsetY parameters should allow you to position the ViewHost exactly what you need it relative to the GeoPoint that it is anchored to.

With version 4.1 in order to display the ScaleBarOverlay you need to add this entry using the Manifest Editor:

B4X:
SetApplicationAttribute(android:hardwareAccelerated, "false")

I'm not sure if that's also required for the CompassOverlay.
You can try that entry with version 3.0.8 and see if it makes any difference.

Hi!
it is possible to derive the center of the map off line automatically when it is loaded without having to specify?

You want to fit the map to contain an Overlay?
Most Overlay's have a method:

GetBoundingBox As BoundingBox

Which can be used with the MapView method:

ZoomToBoundingBox (BoundingBox1 As BoundingBoxE6)

That's version 4.1 syntax - version 3.0.8 has a similar syntax.

Martin.
 

Spinter

Active Member
Licensed User
Longtime User
I have trouble visualizing overlapping flags, I need to know the title of the flag created under how can I do?



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

Sub Globals
    Dim MapView1 As MapView
    Dim MarkersOverlay1 As MarkersOverlay
    Private Panel1 As Panel
 
End Sub

Sub Activity_Create(FirstTime As Boolean)

   
    MapView1.Initialize("")
    Panel1.Initialize("Panel1")
    Activity.AddView(Panel1, 0,0,100%x,100%y)
    Panel1.SetLayout(0,0,100%x,100%y)
    Panel1.AddView(MapView1, 0,0,100%x,100%y)
    MapView1.SetMultiTouchEnabled(True)
    MapView1.SetZoomEnabled(True)

    MarkersOverlay1.Initialize(MapView1, "MarkersOverlay1")
    MapView1.AddOverlay(MarkersOverlay1)
   

   
    Dim Marker1 As Marker
    Marker1.Initialize("basic1", "Test 1.", 46.373862410923564,13.304159715771675, Null)   
    Dim Marker2 As Marker
    Marker2.Initialize("basic2", "Test 2", 46.373862410923564,13.304159715771675, 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
        TileSource="CycleMap"
        MapView1.FitMapToBoundingBox(MarkersOverlay1.GetBoundingBox)
    Else
        MapView1.Zoom=ZoomLevel
        MapView1.SetCenter3(MapCenter)
    End If
End Sub

Sub Activity_Resume
End Sub

Sub Activity_Pause (UserClosed As Boolean)
    MapCenter=MapView1.GetCenter
    TileSource=MapView1.GetTileSource
    ZoomLevel=MapView1.Zoom
End Sub
Sub MarkersOverlay1_Click(Title As String, Description As String, Point As GeoPoint) As Boolean
    Log(Title&": "&Description)
    'ToastMessageShow(Title&": "&Description, True)
    Return True
End Sub
 

Spectre

Active Member
Licensed User
Longtime User
Hi again.

Been busy so only just had time to reply...

I'm not sure what you mean by 'display the flag'.
Is the flag an icon or Label that you're trying to display underneath the Marker?

Are you using the new version 4.1 alpha library or the existing version 3.0.8?

If you're using version 4.1 and the new ViewHost then when you initialize the ViewHost you have the Alignment parameter:

Initialize (View1 As View, GeoPoint1 As GeoPoint, OffsetX As Int, OffsetY As Int, Alignment As Int, Visible As Boolean)

Alignment is one of the OSMDroid_LayoutParams values:

ALIGN_BOTTOM_CENTER As Int
ALIGN_BOTTOM_LEFT As Int
ALIGN_BOTTOM_RIGHT As Int
ALIGN_CENTER As Int
ALIGN_CENTER_LEFT As Int
ALIGN_CENTER_RIGHT As Int
ALIGN_TOP_CENTER As Int
ALIGN_TOP_LEFT As Int
ALIGN_TOP_RIGHT As Int
MATCH_PARENT As Int
WRAP_CONTENT As Int

That along with the OffsetX and OffsetY parameters should allow you to position the ViewHost exactly what you need it relative to the GeoPoint that it is anchored to.

With version 4.1 in order to display the ScaleBarOverlay you need to add this entry using the Manifest Editor:

B4X:
SetApplicationAttribute(android:hardwareAccelerated, "false")

I'm not sure if that's also required for the CompassOverlay.
You can try that entry with version 3.0.8 and see if it makes any difference.



You want to fit the map to contain an Overlay?
Most Overlay's have a method:

GetBoundingBox As BoundingBox

Which can be used with the MapView method:

ZoomToBoundingBox (BoundingBox1 As BoundingBoxE6)

That's version 4.1 syntax - version 3.0.8 has a similar syntax.

Martin.

Hi.... no find metod...

MapView1.FitMapToBoundingBox(LabelsOverlay.GetBoundingBox)

Overley unique as property are those that contain the marker and baloon. does not contain these points can not give me the fit of the map.
 
Last edited:

warwound

Expert
Licensed User
Longtime User

warwound

Expert
Licensed User
Longtime User
slf4j-android-1.6.1-rc1.jar can be found in the archive you presumably downloaded a few days back?

http://b4a.martinpearman.co.uk/osmdroid/MultiViewHost-20140323.zip

You need the updated library files from http://b4a.martinpearman.co.uk/osmdroid/OSMDroid_v4.1-20140329.zip and slf4j-android-1.6.1-rc1.jar from http://b4a.martinpearman.co.uk/osmdroid/MultiViewHost-20140323.zip.
Do not use the now out of date OSMDroid_4_1.jar and OSMDroid_4_1.xml files from http://b4a.martinpearman.co.uk/osmdroid/MultiViewHost-20140323.zip.

Martin.
 
Top