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,624
Last edited:

Sam H

Member
Licensed User
Longtime User
Ok, not to worry, do you have an example of the TileSourceSpinner using OSMDroid_4_1 as I can only find the one for the older version which I can't get to work since Mapview1.SetTileSource() requires an Object rather than a string "" like the old version.

How would I define "mapnik", "CycleMap", "OSMPublicTransport", "MapquestOSM" etc. as OSMDroid_MapTile's?

Thanks

Sam
 

warwound

Expert
Licensed User
Longtime User
@Sam H

Attached is the updated 'select a TileSource' demo, updated to work with OSMDroid 4.1.
Tested and working here on my Moto G (KitKat).

B4X:
Sub Process_Globals
	Dim InitialTileSourceName As String="Mapnik"
	Dim MapCenter As OSMDroid_GeoPoint
	Dim SelectedTileSource As OSMDroid_TileSource
	Dim ZoomLevel As Int
End Sub

Sub Globals
	Dim MapView1 As OSMDroid_MapView
	Dim TileSourceFactory1 As OSMDroid_TileSourceFactory
	Dim TileSourceSpinner As Spinner
End Sub

Sub Activity_Create(FirstTime As Boolean)
	If FirstTime Then
		MapCenter.Initialize(52.75192, 0.40505)
		ZoomLevel=14
		
		'	set the default initial TileSource
		SelectedTileSource=TileSourceFactory1.GetTileSource(InitialTileSourceName)
	End If
	
	MapView1.Initialize("")
	
	MapView1.SetBuiltInZoomControls(True)
	MapView1.SetMultiTouchControls(True)
	
	MapView1.GetController.SetZoom(ZoomLevel)
	MapView1.GetController.SetCenter(MapCenter)
	
	Activity.AddView(MapView1, 0, 48dip, 100%x, 100%y-48dip)
	
	TileSourceSpinner.Initialize("TileSourceSelect")
	
	Dim TileSourceFactory1 As OSMDroid_TileSourceFactory
	Dim AvailableTileSources() As OSMDroid_TileSource
	AvailableTileSources=TileSourceFactory1.GetTileSources
	
	For Each AvailableTileSource As OSMDroid_TileSource In AvailableTileSources
		TileSourceSpinner.Add(AvailableTileSource.Name)
	Next
	
	TileSourceSpinner.Prompt="Select a TileSource"
	TileSourceSpinner.SelectedIndex=TileSourceSpinner.IndexOf(SelectedTileSource.Name)
	Activity.AddView(TileSourceSpinner, 0, 0, 100%x, 48dip)
	
	'	manually call the Spinner ItemClick Sub to sync the MapView TileSource with the spinner SelectedIndex
	TileSourceSelect_ItemClick(TileSourceSpinner.SelectedIndex, TileSourceSpinner.SelectedItem)
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)
	MapCenter=MapView1.GetMapCenter
	ZoomLevel=MapView1.GetZoomLevel
End Sub

Sub TileSourceSelect_ItemClick (Position As Int, Value As Object)
	'	set the MapView TileSource
	Dim TileSourceName As String=Value
	SelectedTileSource=TileSourceFactory1.GetTileSource(TileSourceName)
	MapView1.SetTileSource(SelectedTileSource)
End Sub

Martin.
 

Attachments

  • SimpleMapTileSources.zip
    6.6 KB · Views: 489

Sam H

Member
Licensed User
Longtime User
Thanks again for such a quick response, I have got it working on my Nexus 7 (Android Jelly Bean). Some of the tileSources that are displayed on the spinner such as "base", "topo" and "hills" don't show anything, although I was able to remove them.

Thanks

Sam
 

PABLO2013

Well-Known Member
Licensed User
Longtime User
greetings martin
few weeks back , i post to how how could see the scala overlay again in my projects ... I can not make it look ... I have followed the forum about it can be a problem in the manifest file, but do not I can fix, I use windows 7, jdk1.7.0_67 \ bin \ javac.exe, android-10 \ android.jar, osm 3.6 (I tried 4.0 with no result) B4A 3.82, tks , plz helpme.
 

jamesnz

Active Member
Licensed User
Longtime User
Is there a possibility of setting up a custom tile server. I have made customised tiles ( way too many to store on device) . How would one store these on a web server and have the mapview make the appropriate requests. I'm presuming I could set up a directory on my server and designthe file structure the same as the x/y calls
 

warwound

Expert
Licensed User
Longtime User
Is there a possibility of setting up a custom tile server. I have made customised tiles ( way too many to store on device) . How would one store these on a web server and have the mapview make the appropriate requests. I'm presuming I could set up a directory on my server and designthe file structure the same as the x/y calls

How are your customised tiles named?
Are they named using the slippy map tile naming convention:

folder named after zoom level > folder named after tile x parameter > tile named after tile y parameter.

If so move all the folders named after the zoom level to a single new folder.
Now add this new folder to a new zip archive and upload it to your server.
Your server hopefully has a control panel where you can now unzip the archive.

Nothing special needs to be done, just establish the path to the un-zipped tiles on your server and update your OSMDroid code to use the online custom tiles.

If your server has no way for you to unzip an archive then you'll have to upload all your custom tiles one by one using FTP and that will take a long while if you have lots of tiles.

Martin.
 

jamesnz

Active Member
Licensed User
Longtime User
yes , I just use the standard slippymap convention.( tiles made by maperative ).png
Question was how to tell the mapview what my server address is eg "www.myserver.co.nz/mymaptiles"/x/y/etc
I assume I have to change the tile source factory to a custom address somehow ?
 

jamesnz

Active Member
Licensed User
Longtime User
:)

If you don't understand the example code that initializes the custom tile server URL then take a look at this post: http://www.b4x.com/android/forum/threads/google-maps-android-v2-tutorial.24415/page-3#post-152010.
It refers to the GoogleMapsExtras TilesOverlay but should apply also to the OSMDroid example.

Martin.
I have zoom 18 tiles so I just changed the maximum zoom in the mytilesource.initialize to 0,18,256
works fine - and I'm still ftping to the server :)
cheers for the help :)
 

PABLO2013

Well-Known Member
Licensed User
Longtime User
greetings martin
few weeks back , i post to how how could see the scala overlay again in my projects ... I can not make it look ... I have followed the forum about it can be a problem in the manifest file, but do not I can fix, I use windows 7, jdk1.7.0_67 \ bin \ javac.exe, android-10 \ android.jar, osm 3.6 (I tried 4.0 with no result) B4A 3.82, tks , plz helpme.
 

georm

Member
Licensed User
Longtime User
Hello
About OSMDroid_UrlTileSource. I'd use the server tiles from IGN (French service). The url use a key, i's not a problem, but use an authentication with user and password.
When I program in Microsoft .Net. I use a HttpWebRequest object with a NetworkCredential to pass the User and the Password.
Is there a equivalence en b4a, I'm a beginner.
Sample IGN url:

B4X:
https://gpp3-wxs.ign.fr/my_ignkey/wmts?LAYER=ORTHOIMAGERY.ORTHOPHOTOS&EXCEPTIONS=text/xml&FORMAT=image/jpeg&SERVICE=WMTS&VERSION=1.0.0&REQUEST=GetTile&STYLE=normal&TILEMATRIXSET=PM&TILEMATRIX=18&TILEROW=90241&TILECOL=132877

Thanks
Laurent
 

warwound

Expert
Licensed User
Longtime User
@georm

Are you saying that you send the auth username and password to the tileserver using an HTTP request and you get a 'token' back.
And then when you request a tile, that token must be part of the tile request url?
 

georm

Member
Licensed User
Longtime User
I must just use HTTP with ExecuteCredentials and pass a httpRequest with username and password and recup the taskid ?

Thanks
 
Top