Android Question B4XMap (Open Street Map viewer)

RB Smissaert

Well-Known Member
Licensed User
Longtime User
Just came across this and thinking about moving to this from OSMDroid.
Trying to figure out how to download a map area based on min and max latitude and longitude and can't figure out
how to get from latitude and longitude to the Open Street Map x and y tile numbers, so I can do something like this:

B4X:
Sub DownLoadTiles(iMinX As Int, iMaxX As Int, iMinY As Int, iMaxY As Int, iMinZoom As Int, iMaxZoom As Int)
    
    Dim x As Int
    Dim y As Int
    Dim z As Int
    
    cTileManager.Initialize
    
    For z = iMinZoom To iMaxZoom
        cTileManager.DeleteTilesFromDB(iMinX, iMaxX, iMinY, iMaxY, z)
    Next
    
    For x = iMinX To iMaxX
        For y = iMinY To iMaxY
            For z = iMinZoom To iMaxZoom
                Dim rs As ResumableSub = cTileManager.getTileFromInternet(z, x, y)
                Wait For (rs) Complete (b4xbmp As B4XBitmap)
                cTileManager.setTileToDB(z, x, y, b4xbmp)
            Next
        Next
    Next
    
End Sub

Any suggestions?

RBS
 

RB Smissaert

Well-Known Member
Licensed User
Longtime User
Just came across this and thinking about moving to this from OSMDroid.
Trying to figure out how to download a map area based on min and max latitude and longitude and can't figure out
how to get from latitude and longitude to the Open Street Map x and y tile numbers, so I can do something like this:

B4X:
Sub DownLoadTiles(iMinX As Int, iMaxX As Int, iMinY As Int, iMaxY As Int, iMinZoom As Int, iMaxZoom As Int)
   
    Dim x As Int
    Dim y As Int
    Dim z As Int
   
    cTileManager.Initialize
   
    For z = iMinZoom To iMaxZoom
        cTileManager.DeleteTilesFromDB(iMinX, iMaxX, iMinY, iMaxY, z)
    Next
   
    For x = iMinX To iMaxX
        For y = iMinY To iMaxY
            For z = iMinZoom To iMaxZoom
                Dim rs As ResumableSub = cTileManager.getTileFromInternet(z, x, y)
                Wait For (rs) Complete (b4xbmp As B4XBitmap)
                cTileManager.setTileToDB(z, x, y, b4xbmp)
            Next
        Next
    Next
   
End Sub

Any suggestions?

RBS
Solved this now as I noticed this conversion is in the b4x library:

B4X:
Sub DownLoadTiles(dMinLat As Double, dMaxLat As Double, dMinLon As Double, dMaxLon As Double, iMinZoom As Int, iMaxZoom As Int)
    
    Dim x As Int
    Dim y As Int
    Dim z As Int
    Dim iMinX As Int
    Dim iMaxX As Int
    Dim iMinY As Int
    Dim iMaxY As Int
    
    cTileManager.Initialize
    cTileManager.emptyDB
    
    For z = iMinZoom To iMaxZoom
        iMinX = fcvMap.LngToTileX(dMinLon, z).fTile
        iMaxX = fcvMap.LngToTileX(dMaxLon, z).fTile
        iMinY = fcvMap.LatToTileY(dMaxLat, z).fTile
        iMaxY = fcvMap.LatToTileY(dMinLat, z).fTile
        For x = iMinX To iMaxX
            For y = iMinY To iMaxY
                Dim rs As ResumableSub = cTileManager.getTileFromInternet(z, x, y)
                Wait For (rs) Complete (b4xbmp As B4XBitmap)
                cTileManager.setTileToDB(z, x, y, b4xbmp)
            Next
        Next
    Next
    
End Sub

Working all nicely.

RBS
 
Upvote 0

roberto64

Active Member
Licensed User
Longtime User
Hi, I see that you are very fond of B4xmap, I am trying to do by downloading a map and putting it in the database even in the absence of internet only with the GPS r trace on foot the path where I walk with a line and then finished the journey repeat the same road of the line.
a greeting
 
Upvote 0

RB Smissaert

Well-Known Member
Licensed User
Longtime User
Hi, I see that you are very fond of B4xmap, I am trying to do by downloading a map and putting it in the database even in the absence of internet only with the GPS r trace on foot the path where I walk with a line and then finished the journey repeat the same road of the line.
a greeting
Yes, I think it is a very nice library.
What is your exact question?

RBS
 
Upvote 0

roberto64

Active Member
Licensed User
Longtime User
Greetings,
1 I wanted to load a gpx map;
2 from my starting position when I start walking the gps creates a line behind,
like the example attached, also marking how many Km or m made
a greeting
android-osmand-routing.png
 
Upvote 0

RB Smissaert

Well-Known Member
Licensed User
Longtime User
Greetings,
1 I wanted to load a gpx map;
2 from my starting position when I start walking the gps creates a line behind,
like the example attached, also marking how many Km or m made
a greetingView attachment 135751
1. I think I posted code to download a map area, based on coordinates you will need to provide:

B4X:
Sub DownLoadTiles(BB As TMapBoxLatLng, iMinZoom As Int, iMaxZoom As Int, bEmptyTiles As Boolean, bShowProgress As Boolean) As ResumableSub 'ignore
    
    Dim x As Int
    Dim y As Int
    Dim z As Int
    Dim n As Int
    Dim p As Int
    Dim t As Int
    Dim dMinLat As Double = BB.fRightBottom.fLat
    Dim dMaxLat As Double = BB.fLeftTop.fLat
    Dim dMinLng As Double = BB.fLeftTop.fLng
    Dim dMaxLng As Double = BB.fRightBottom.fLng
    Dim iMinX As Int
    Dim iMaxX As Int
    Dim iMinY As Int
    Dim iMaxY As Int
    Dim iTilesTotal As Int
    Dim iProgressInterval As Int
    Dim iTilesRemoved As Int 'ignore
    Dim arrLong(2) As Long
    
    General.StartSW(2)

    iTilesTotal = MapUtilities.GetTotalTiles(BB, iMinZoom, iMaxZoom)
    
    If bShowProgress Then
        If iTilesTotal < 160 Then
            iProgressInterval = 1
        Else
            iProgressInterval = iTilesTotal / 100
        End If
    End If
    
    If bEmptyTiles Then
        iTilesRemoved = emptyDB
    End If
    
    If B4XProgressBar1.IsInitialized = False Then
        mParent.LoadLayout("ProgressBar")
    End If
    
    If bShowProgress Then
        B4XProgressBar1.Show(mParent, iTilesTotal, False, 1, "Tiles to download, ", "/", " done")
    End If
    
    fDB.BeginTransaction
    
    For z = iMinZoom To iMaxZoom
        iMinX = MapUtilities.LngToTileX(dMinLng, z)
        iMaxX = MapUtilities.LngToTileX(dMaxLng, z)
        iMinY = MapUtilities.LatToTileY(dMaxLat, z)
        iMaxY = MapUtilities.LatToTileY(dMinLat, z)

        For x = iMinX To iMaxX
            For y = iMinY To iMaxY
                Dim rs As ResumableSub = getTileFromInternet(z, x, y)
                Wait For (rs) Complete (b4xbmp As B4XBitmap)
                
                If b4xbmp.IsInitialized = False Then
                    fDB.TransactionSuccessful
                    fDB.EndTransaction
                    If bShowProgress Then
                        B4XProgressBar1.Reset
                    End If
                    Return arrLong
                End If
                
                If setTileToDB(z, x, y, b4xbmp) = False Then
                    fDB.TransactionSuccessful
                    fDB.EndTransaction
                    If bShowProgress Then
                        B4XProgressBar1.Reset
                    End If
                    Return arrLong
                End If
                
                n = n + 1
                p = p + 1
                t = t + 1
                
                If n = 10000 Then
                    fDB.TransactionSuccessful
                    fDB.EndTransaction
                    n = 0
                    fDB.BeginTransaction
                End If
                
                If bShowProgress Then
                    If p = iProgressInterval Or t = 1 Then
                        B4XProgressBar1.Progress = t
                        p = 0
                        Sleep(0)
                    End If
                End If
            Next
        Next
    Next

    fDB.TransactionSuccessful
    fDB.EndTransaction
    
    If bShowProgress Then
        B4XProgressBar1.Reset
    End If
    
    arrLong(0) = t
    arrLong(1) = General.StopSW(2)
    
    Return arrLong
    
End Sub

You can take out the progress related code and also the resulting arrLong and the timer and the int variable t.
The arrLong and timer bits just monitor download times and you may not need this.

2. You will need to record you GPS position (latitude and longitude and maybe altitude) every x seconds to whatever you think is best (List, map, array or DB).
Then from this recording you can draw your path. GPS code can be in the starter module, eg:

B4X:
Process_Globals

    Public GPS1 As GPS
    Public dCurrentLatitude As Double
    Public dCurrentLongitude As Double
    Public iCurrentAltitude As Int

Sub GPS_LocationChanged(Location1 As Location)
    
    dCurrentLatitude = Location1.Latitude
    dCurrentLongitude = Location1.Longitude
    iCurrentAltitude = Location1.Altitude
    
End Sub

RBS
 
Upvote 0

RB Smissaert

Well-Known Member
Licensed User
Longtime User
Thanks for your answer, I see you use "General.StartSW (2)" and a "MapUtilities" class
Ignore (leave out) all the General.StartSW, it is just a simple timer I use.
Attached my MapUtilities code module (not a class).

RBS
 

Attachments

  • MapUtilities.bas
    12.4 KB · Views: 170
Upvote 0

roberto64

Active Member
Licensed User
Longtime User
Hi, thanks for your module, I must understand what your other instructions that you have inserted in the nodule do, I do not see my ploblem as per post # 6 that I have published, you can give you a small example of your functions that you have inserted in the module?
 
Upvote 0
Top