Share My Creation Openstreetmap Tilemapviewer

Hello!

That is my first try to develope a viewer to show the tiles of openstreetmaps. I hope that there are others, who can support this project.
I have tested it on my HTC HD2 with WVGA (480x800) and 1Ghz-chip. It runs fast enough, but I don't know, how it works on slower devices or different screensolutions.
In the first version, the map viewer has the following features:

- works with offline maptiles, which I have dowloaded with the PDATilemanager of corwin42, written in basic4ppc: AmberHome
- shows the map over the whole screen
- works in vertical and horizontal mode
- let scroll the map with the finger
- scrolls the map with navigation-buttons
- supports different zoomlevels
- set the map to the startposition

The next steps, I want to develope are:

- load maptiles from the tileserver, if they are not on the device
- shows an centered icon on a gps-position (latitude and longitude)

I think, that the code could be optimized, but i'm still working. The only problem, which I have yet is, that the application will be stopped from the android-os, if it is activated again or the device will be rotate. Perhaps, someone can find the mistake.....

To test the app, you have to download the maptiles which you want to have and save them in the root of the external-sdcard under "/osm/..". In Sub Init, you can set the zoomlevel and the starttiles:

B4X:
Sub Init
   Zoomlevel=15
   Label2.Text=Zoomlevel
   
   'StartTiles are the left and top-side of the moving map'
   StartTileX=16929
   StartTileY=10969
...
...


I will now try to load the mapiles from a tile-server. If there is someone who had an example to load a map tile from

B4X:
'URLs (Examples)
'OSM Mapnik     http://tile.openstreetmap.org/12/2047/1362.png
'OSM Osmarender/Tiles@Home    http://tah.openstreetmap.org/Tiles/tile/12/2047/1362.png
'OSM Cycle Map     http://andy.sandbox.cloudmade.com/tiles/cycle/12/2047/1362.png

it's easier for me, because i haven't worked with the http-lib until yet.

rgds
 

Attachments

  • MapViewer1.zip
    287.8 KB · Views: 1,726

schimanski

Well-Known Member
Licensed User
Longtime User
Hello DitchParrot!

It is not possible to calculate a route to the markers, because we only need pictures as foundation in the mapviewer. To calculate a route, you have to use a database.
But you can do something different:

You can show the user the distance and the bearing to the marker by an arrow. The advantage is, that you can use it also in an area, where no streets are. We use this system for a long time with basic4pcc and it runs very fine by distances under 3000 meters.

The second way is, to use the google online-navigation with the following code. You only have to installed the last version of google-maps on your device. GPS1 is the position of the device, marker is the lat and the lon of the markers, to which you want to navigate....

B4X:
If GPS1.Latitude<>0 AND GPS1.Longitude<>0 Then
  URI="http://maps.google.com/maps?f=d&hl=de&geocode=&saddr=" & GPS1.Latitude & "," & GPS1.Longitude & "&daddr=" & Marker.Latitude & "," & Marker.Longitude & "&ie=UTF8"
  Intent1.Initialize(Intent1.ACTION_VIEW,URI)
  Intent1.SetComponent("googlemaps")
  StartActivity(Intent1)
Else
  Msgbox("No Routing possible!","")
End If
 

schimanski

Well-Known Member
Licensed User
Longtime User
Problem with changing the device orientation

Hello!

In every of the codes above, I have a problem with changing the device orientation. I have tested it on several devices and on the samsung galaxy tab it it possible to change the orientation two times, before i get an error. On other devices, like motorola defy, it is not possible to change the orientation. The viewer starts in both modes and when the screen-orientation changed, I only get the following code in the logcat:

B4X:
** Activity (main) Pause, UserClosed = false **
** Activity (mapviewer) Create, isFirst = true **
** Activity (mapviewer) Resume **
  
  'here, the app stops working and will be closed'

** Activity (main) Pause, UserClosed = false **
** Activity (mapviewer) Create, isFirst = false **
** Activity (mapviewer) Resume **

   'here, the app stops working and will be closed'

Thanks for help....
 

Kalle

New Member
Licensed User
Longtime User
Scrolling Map in MapViewer

Hi Schimanski,
the MapViewer is a very good program for an Basic4Android-Newbie like me.
THANKS a lot !!!
I have learned a lot to try to understand the single steps especially the use of Canvas, Bitmap and Rects. There was a problem while scrolling the maps (via touch). I have changed the 4 following subs. Now it works.
Best wishes an THANKS again.

'Kachelleisten erstellen'
Sub Left_Tiles
For Y=0 To TileNbY-1
LoadTile(Zoomlevel, 0, y, TileX-1, TileY+y)
Next
ImageX=ImageX+TileSize
sx=sx+TileSize
' SrcRectFertig.Initialize(0,0,TileNbX*TileSize,MapHeight)
SrcRectFertig.Initialize(0,0,(TileNbX-1)*TileSize,MapHeight)
DestRectFertig.Initialize(TileSize,0,MapWidth,MapHeight)
Karte_zusammensetzen
TileX=TileX-1
End Sub

Sub Right_Tiles
For Y=0 To TileNbY-1
LoadTile(Zoomlevel, TileNbX-1, y, TileX+TileNbX, TileY+y)
Next
ImageX=ImageX-TileSize
sx=sx-TileSize

SrcRectFertig.Initialize(TileSize,0,MapWidth,MapHeight)
' DestRectFertig.Initialize(0,0,TileNbX*TileSize,MapHeight)
DestRectFertig.Initialize(0,0,(TileNbX-1)*TileSize,MapHeight)
Karte_zusammensetzen
TileX=TileX+1
End Sub

Sub Top_Tiles
For x=0 To TileNbX-1
LoadTile(Zoomlevel, x, 0, TileX+x, TileY-1)
Next
ImageY=ImageY+TileSize
sy=sy+TileSize
' SrcRectFertig.Initialize(0,0,MapWidth,TileNbY*TileSize)
SrcRectFertig.Initialize(0,0,MapWidth,(TileNbY-1)*TileSize)
DestRectFertig.Initialize(0,TileSize,MapWidth,MapHeight)
Karte_zusammensetzen
TileY=TileY-1
End Sub

Sub Bottom_Tiles
For x=0 To TileNbX-1
LoadTile(Zoomlevel, x, TileNbX-1, TileX+x, TileY+TileNbY)
Next
ImageY=ImageY-TileSize
sy=sy-TileSize

SrcRectFertig.Initialize(0,TileSize,MapWidth,MapHeight)
' DestRectFertig.Initialize(0,0,MapWidth,TileNbY*TileSize)
DestRectFertig.Initialize(0,0,MapWidth,(TileNbY-1)*TileSize)
Karte_zusammensetzen
TileY=TileY+1
End Sub
 

BarrySumpter

Active Member
Licensed User
Longtime User
Further assistance requested with German to English translation

Further assistance requested with German to English translation

Babelfish translation.
Needs more work.
Any help would be greatly appreciated.

Is a map supposed to be displayed?


Requires Core, GPS, and HTTP libraries

B4X:
'Open streept map-Tile Map Viewer'

Sub Process_Globals
    
    'MapViewer'
    Dim ProgName As String        : ProgName="MapViewer"
    Dim ProgVersion As String    : ProgVersion="V 5.1"

    Type Coord(lon As Double, lat As Double)

    Dim GPS1 As GPS 
    Dim TileSize As Int
    Dim TileNbX As Int
    Dim TileNbY As Int
    Dim MapWidth As Int
    Dim MapHeight As Int
    
    Dim ScaleX, ScaleY As Double
    
    Dim Timer2 As Timer 
    
    ' Center target variable (= moving target, which is represented centered in map) ' 
    'Center Zielvariablen (=bewegliches Ziel, das zentriert in Karte dargestellt wird)'
    
    
    
    Dim C_ZielTileX, C_ZielTileY As Int 
     Dim PositionC_ZielX, PositionC_ZielY As Int
     Dim C_ZielLat, C_ZielLon, C_ZielKurs As Double
    
    ' Map target variable (= mobile target, which is indicated in map, if it lies in the visible tile range) ' 
    'Map Zielvariablen (= bewegliches Ziel, das in Karte angezeigt wird, wenn es im sichtbaren Kachelbereich liegt)'
    
    Dim M_ZielTileX, M_ZielTileY As Int 
    Dim PositionM_ZielX, PositionM_ZielY As Int
    Dim M_ZielLat, M_ZielLon, M_ZielKurs As Double 
    
    ' Variable one for markers (= firm positions in the map)
    'Variablen für Marker (=feste Positionen in der Karte)
    
    Dim MarkerTileX, MarkerTileY As Int 
    Dim PositionMarkerX, PositionMarkerY As Int
    Dim MarkerLat, MarkerLon As Double 
    Dim MarkerPath As Path 
    Dim MarkerListe As List 
    
    'Variable for Reverse Geocoding'
    'Variablen für Reverse Geocoding'
    
    Dim URL, Land, Bundesland, Kreis, Postleitzahl, Ort, Strasse As String 
    Dim HTTPClient1 As HttpClient 
    Dim Parser As SaxParser
    Dim AdrListe As List 
    Dim Result As InputStream
    Dim Timer1 As Timer 
End Sub

Sub Globals
    Dim ButtonLeft, ButtonRight, ButtonUp, ButtonDown,  ButtonC, ButtonRGC As Button 
    Dim SrcRect, DestRect As Rect
        'Arrow 'Arrow Own
    Dim Pfeil, PfeilEigen, BitmapTile, BitmapMap, BitmapMapNew As Bitmap
    Dim ImageView1 As ImageView 
    Dim CanvasTile, CanvasMap, CanvasMapNew As Canvas 
                     'Entirely Rect      'Finished 
    Dim DestRectNew, GesamtRect, DestRectFertig, SrcRectFertig, DRectPfeil, DRectPfeilEigen As Rect 
    Dim sx, sy, ImageX, ImageY As Int
    Dim Label1, Label2, label3, Label5 As Label 
    Dim Panel1 As Panel 
    
    Dim TileX, TileY, Zoomlevel As Int

  '   Target Control      
    Dim Ziel_Steuerung As Boolean
    Ziel_Steuerung=True
    '   NightImage
    Dim NachtImage As ImageView
    
    '   Night Mode
    Dim Nachtmodus As Boolean
    Nachtmodus=True
End Sub

Sub Activity_Create(FirstTime As Boolean)
    If FirstTime Then
        GPS1.Initialize("GPS")
        Parser.Initialize
        HTTPClient1.Initialize("HttpClient1")
    End If

                                            'Examination whether high or landscape format is geutzt 
    If Activity.Height>Activity.Width Then        'Prüfung, ob Hoch- oder Querformat geutzt wird'
        Activity.LoadLayout("MapviewerPortrait.bal")
    Else
        Activity.LoadLayout("MapviewerLandScape.bal")
    End If
    
    AdrListe.Initialize
    MarkerListe.Initialize 
                                          'Timer for Reverse Geocoding (update every 3 sec.) 
    Timer1.Initialize("Timer1",3000)            'Timer für Reverse Geocoding(Update alle 3 Sek.)'
    
                                          'Timer for targets/marker in map draw' 
    Timer2.Initialize("Timer2",1000)            'Timer für Ziele/Marker in Karte zeichnen'
    'Arrow                          'Arrow 
    Pfeil.Initialize(File.DirAssets,"Pfeil.png")
    
    '                                    'arrow own 
    PfeilEigen.Initialize(File.DirAssets,"pfeilEigen.png")
    
    Init
    InitMap    
End Sub

Sub Activity_Resume
    If GPS1.GPSEnabled = False Then
        ToastMessageShow("Please enable the GPS device.", True)
        StartActivity(GPS1.LocationSettingsIntent) 'Will open the relevant settings screen.
    Else
        GPS1.Start(0, 0) 'Listen to GPS with no filters.
    End If
End Sub

Sub Activity_Pause (UserClosed As Boolean)
    GPS1.Stop
End Sub

'I N I T I A L I S I E R U N G E N'
Sub Init
    Activity.Title=ProgName&"  "&ProgVersion
    'Startposition für Ziel in Kartenmitte'
    C_ZielLat="51.00000"
    C_ZielLon="6.00000"

    'Startposition für Ziel in Karte'
    M_ZielLat="52.00000"
    M_ZielLon="7.00000"

    'Positionen der Marker'
    Init_Marker
    
    'Target zentrieren'
    ImageView1.Left=(Activity.Width/2)-75
    ImageView1.Top=(Activity.Height/2)-75
    
'    TileNbX=3
'    TileNbY=4
    TileNbX=5
    TileNbY=5
    TileSize=256
    MapWidth=TileNbX*TileSize
    MapHeight=TileNbY*TileSize
    Zoomlevel=14
    Label2.Text=Zoomlevel

                                                  'Set size of the adjustable map (4 x 4 = 16 tiles) 
    BitmapMap.InitializeMutable(MapWidth,MapHeight)    'Größe der verschiebbaren Karte setzen (4 x 4 = 16 Kacheln)
    
                                                        'Set size for the new map (4 x 4 tiles among themselves) 
    BitmapMapNew.InitializeMutable(MapWidth,MapHeight)    'Größe für die neue Karte setzen (4 x 4 Kacheln untereinander)
    
                                          'Activity background for draw prepare 
    CanvasTile.Initialize(Activity)                'Activity-Hintergrund für zeichnen vorbereiten'
    
                                          'Bit-map map for drawing prepare 
    CanvasMap.Initialize2(BitmapMap)            'BitmapMap für Zeichnen vorbereiten'
    
    'New'
    CanvasMapNew.Initialize2(BitmapMapNew)
    GesamtRect.Initialize(0,0,MapWidth,MapHeight)
    
    'Night mode 
    'Nachtmodus'
    NachtImage.Initialize("")
    Activity.AddView(NachtImage,0,0,Activity.Width,Activity.Height)
    ButtonNight_Click

    Timer1.Enabled=False
    Label5.Visible=False
    Panel1.Visible=False
    Timer2.Enabled=True
End Sub

'Markers initialize 
'Marker initialisieren'
Sub Init_Marker  
  'Marker list ADD universe (array As stringer (designation, Latitude, Longitude, color (red, green, blue)) 
    'MarkerListe.AddAll(Array As String(Bezeichnung, Latitude, Longitude, Farbe(Rot,Grün,Blau))
    MarkerListe.AddAll(Array As String("Marker 1","51.0","6.0","128","0","0"))
    MarkerListe.AddAll(Array As String("Marker 2","51.1","6.0","0","128","0"))
    MarkerListe.AddAll(Array As String("Marker 3","51.0","6.1","0","0","128"))
    MarkerListe.AddAll(Array As String("Marker 4","51.1","6.1","128","0","0"))
End Sub

'Night mode switch on and off 
'Nachtmodus ein- und ausschalten'
Sub ButtonNight_Click
    If Nachtmodus=True Then
        NachtImage.Color=Colors.Transparent
        Nachtmodus=False
    Else
        NachtImage.Color=Colors.ARGB(128,0,0,0)
        Nachtmodus=True
    End If
End Sub

'GPS'
Sub GPS_UserEnabled (Enabled As Boolean)
    ToastMessageShow("GPS device enabled = " & Enabled, True)
End Sub

Sub GPS_LocationChanged (Location1 As Location)
  'Here the GPS position is represented centered in the map. Map is adjusted. 
    'Hier wird die GPS-Position zentriert in der Karte dargestellt. Karte wird nachgeführt.'
    C_ZielLat =  Location1.Latitude
    C_ZielLon =  Location1.Longitude
    C_ZielKurs = Location1.Bearing 
    
    'Goal speed 
    ZielGeschwindigkeit = Round(Location1.Speed*3.6)
    
    'Here the GPS position is unzentriert indicated as moving target in the map, but. Map is not adjusted 
    'Hier wird die GPS-Position als bewegliches Ziel in der Karte, aber unzentriert angezeigt. Karte wird nicht nachgeführt'
    'M_ZielLat =  Location1.Latitude
    'M_ZielLon =  Location1.Longitude
    'M_ZielKurs = Location1.Bearing 
                              
                            '                            'Goal speed
    label3.text="Geschw.: " & ZielGeschwindigkeit & " km/h"
End Sub

'Map on C_Ziel again center 
'Karte auf C_Ziel wieder zentrieren'
Sub ButtonC_Click
  'A goal control 
    Ziel_Steuerung=True    
    'A goal draw in 
    Ziele_einzeichnen
End Sub

Sub Timer2_Tick
  'The moving targets are drawn in only if map is not shifted by hand 
    'Die beweglichen Ziele werden nur eingezeichnet, wenn Karte nicht von Hand verschoben wird'
    If Ziel_Steuerung=True Then 
    '    A goal draw in 
        Ziele_einzeichnen
    Else
      'Marker Draw
        MarkerZeichnen
    End If
End Sub

'The different targets into the map draw in and map in such a way align that C_Ziel lies in the center 
'Die verschiedenen Ziele in die Karte einzeichnen und Karte so ausrichten, dass C_Ziel in der Mitte liegt'
Sub Ziele_einzeichnen
    'Since the C_Ziel is to be indicated centered, only the starting tile is computed and afterwards the map with init map is drawn drumherum 
    'Da das C_Ziel zentriert angezeigt werden soll, wird erst die Startkachel berechnet und danach die Karte mit InitMap drumherum gezeichnet'
    CalculateC_ZielTileXY
    InitMap
        
    'Now the targets are drawn into the map     
    'Jetzt werden die Ziele in die Karte gezeichnet'
    'Marker Draw
    MarkerZeichnen
    M_ZielZeichnen
    C_ZielZeichnen
    
    'Here that is centered the C_Ziel and the map with Drawmap is finished aligned
    'Hier wird der das C_Ziel zentriert und die Karte mit Drawmap fertig ausgerichtet'
    ImageX=(512+PositionC_ZielX)-(Activity.Width/2)
    ImageY=(512+PositionC_ZielY)-(Activity.Height/2)
    DrawMap
End Sub

Sub CalculateC_ZielTileXY

  'Central tile compute 
    'Zentrale Kachel berechnen'
     C_ZielTileX=Floor((C_ZielLon+180)/360*Power(2,Zoomlevel))
     C_ZielTileY=Floor((1-Logarithm(TanD(C_ZielLat) + 1/CosD(C_ZielLat),cE)/cPI)/2 *Power(2,Zoomlevel))
 
 'Position on the calculated tile determine 
    'Position auf der errechneten Kachel bestimmen'
     PositionC_ZielX=Floor((((C_ZielLon+180)/360*Power(2,Zoomlevel))-C_ZielTileX) * TileSize)
     PositionC_ZielY=Floor((((1-Logarithm(TanD(C_ZielLat) + 1/CosD(C_ZielLat),cE)/cPI)/2 *Power(2,Zoomlevel))-C_ZielTileY) * TileSize)

  'Since this position is to be in the center Tile, the surrounding tiles in an educated manner with C_ZielTile -2 
    'Da diese Position im Center-Tile sein soll, werden die umliegenden Kacheln gebildet mit C_ZielTile -2'
    
    '(TileX, TileY are always left upper corner of the 5x5 large tile surface) 
    '(TileX, TileY sind immer linke obere Ecke der 5x5 großen Kachelfläche)'
    TileX = C_ZielTileX-2    
    TileY = C_ZielTileY-2
End Sub

Sub CalculateM_ZielTileXY

  'Tile for M_Ziel compute 
    'Kachel für M_Ziel berechnen'
     M_ZielTileX=Floor((M_ZielLon+180)/360*Power(2,Zoomlevel))
     M_ZielTileY=Floor((1-Logarithm(TanD(M_ZielLat) + 1/CosD(M_ZielLat),cE)/cPI)/2 *Power(2,Zoomlevel))
 
  'Position on the calculated tile determine 
    'Position auf der errechneten Kachel bestimmen'
     PositionM_ZielX=Floor((((M_ZielLon+180)/360*Power(2,Zoomlevel))-M_ZielTileX) * TileSize)
     PositionM_ZielY=Floor((((1-Logarithm(TanD(M_ZielLat) + 1/CosD(M_ZielLat),cE)/cPI)/2 *Power(2,Zoomlevel))-M_ZielTileY) * TileSize)
End Sub

Sub CalculateMarkerTileXY

  'Tile for the markers compute 
    'Kachel für die Marker berechnen'
     MarkerTileX=Floor((MarkerLon+180)/360*Power(2,Zoomlevel))
     MarkerTileY=Floor((1-Logarithm(TanD(MarkerLat) + 1/CosD(MarkerLat),cE)/cPI)/2 *Power(2,Zoomlevel))
 
  'Marker position on the tile compute 
    'Markerposition auf der Kachel berechnen'
     PositionMarkerX=Floor((((MarkerLon+180)/360*Power(2,Zoomlevel))-MarkerTileX) * TileSize)
     PositionMarkerY=Floor((((1-Logarithm(TanD(MarkerLat) + 1/CosD(MarkerLat),cE)/cPI)/2 *Power(2,Zoomlevel))-MarkerTileY) * TileSize)
End Sub

Sub C_ZielZeichnen
    ' 512 ??? KC  2*TileSize ?
    DRectPfeil.Initialize((PositionC_ZielX+512)-25,(PositionC_ZielY+512)-25,(PositionC_ZielX+512)+25,(PositionC_ZielY+512)+25)
    CanvasMap.DrawBitmapRotated(Pfeil, Null, DRectPfeil, C_ZielKurs)
End Sub

Sub M_ZielZeichnen
    Dim ZX, ZY As Int
    CalculateM_ZielTileXY
    If (M_ZielTileX>=TileX) AND (M_ZielTileX<=TileX+4) AND (M_ZielTileY>=TileY) AND (M_ZielTileY<=TileY+4) Then
        ZX=M_ZielTileX-TileX
        ZY=M_ZielTileY-TileY
        DRectPfeilEigen.Initialize((PositionM_ZielX+(ZX*TileSize))-25, (PositionM_ZielY+(ZY*TileSize))-25, (PositionM_ZielX+(ZX*TileSize))+25, (PositionM_ZielY+(ZY*TileSize))+25)
        CanvasMap.DrawBitmapRotated(PfeilEigen, Null, DRectPfeilEigen, M_ZielKurs)        
    End If
End Sub
'Since the markers are likewise computed each second again, the coordinates of all markers theoretically also each second can be changed (all markers to be able also moving targets to become) 
'Da die Marker ebenfalls jede Sekunde neu berechnet werden, können die Koordinaten aller Marker theoretisch auch jede Sekunde geändert werden (Alle Marker können auch zu beweglichen Zielen werden)'
Sub MarkerZeichnen
    Dim MX, MY As Int
    For i=0 To MarkerListe.Size-1 Step 6
        MarkerLat=MarkerListe.Get(i+1)
        MarkerLon=MarkerListe.Get(i+2)
        CalculateMarkerTileXY
        If (MarkerTileX>=TileX) AND (MarkerTileX<=TileX+4) AND (MarkerTileY>=TileY) AND (MarkerTileY<=TileY+4) Then
            MX=MarkerTileX-TileX
            MY=MarkerTileY-TileY
            
            'Logo für Marker zeichnen'
            'Logo for markers draw 
            MarkerPath.Initialize(PositionMarkerX+(MX*TileSize), PositionMarkerY+(MY*TileSize))
            MarkerPath.LineTo(PositionMarkerX+(MX*TileSize)-20, PositionMarkerY+(MY*TileSize)-40)
            MarkerPath.LineTo(PositionMarkerX+(MX*TileSize)+20, PositionMarkerY+(MY*TileSize)-40)
            MarkerPath.LineTo(PositionMarkerX+(MX*TileSize), PositionMarkerY+(MY*TileSize))
            CanvasMap.DrawPath(MarkerPath, Colors.RGB(MarkerListe.Get(i+3),MarkerListe.Get(i+4),MarkerListe.Get(i+5)) , True, 0)  
            CanvasMap.DrawText(MarkerListe.Get(i), PositionMarkerX+(MX*TileSize), PositionMarkerY+(MY*TileSize)-45, Typeface.DEFAULT, 14, Colors.Red , "CENTER")
        End If
    Next
End Sub

'MAPS - FUNCTIONS 
'K A R T E N - F U N K T I O N E N'
'New tile load 
'Neue Kachel laden'
Sub LoadTile(z,x,y, TileXs, TileYs)
    If File.Exists(File.DirRootExternal, "/OSM/tiles/OsmaRender/" & z & "/" & TileXs & "/" & TileYs & ".png.tile")=True Then
        Try
            BitmapTile.Initialize(File.DirRootExternal, "/OSM/tiles/OsmaRender/" & z & "/" & TileXs & "/" & TileYs & ".png.tile")
        Catch
            Msgbox("Error in Zoom:" & z & "  TileX:" & TileXs & "  TileY:" & TileYs,"")
        End Try
    Else
        BitmapTile.Initialize(File.DirAssets, "Dummy.png")
    End If
    DestRectNew.Initialize(x*TileSize,y*TileSize, (x*TileSize)+TileSize,(y*TileSize)+TileSize)
    CanvasMapNew.DrawBitmap(BitmapTile,Null,DestRectNew)
End Sub

'Adjustable map with tiles fill
'Verschiebbare Karte mit Kacheln füllen'
Sub InitMap
    For y=0 To TileNbY-1
        For x=0 To TileNbX-1
            LoadTile(Zoomlevel, x, y, TileX+x, TileY+y)
            DestRect.Initialize(x*TileSize,y*TileSize, (x*TileSize)+TileSize,(y*TileSize)+TileSize)
            CanvasMap.DrawBitmap(BitmapTile,Null,DestRect)
        Next
    Next
    DestRect.Initialize(0,0,Activity.Width,Activity.Height)        'Der ganze Bildschirm dient als Ausgabebildschirm für die Karte'
    DrawMap
End Sub

'Map draw 
'Karte zeichnen'
Sub DrawMap
                  'before the map is drawn, it is examined whether additional tiles are needed
    CalculateMAP        'bevor die Karte gezeichnet wird, wird geprüft, ob zusätzliche Kacheln benötigt werden' 
    CanvasTile.Initialize(Activity)
                                                                                      'Bildauschnitt of the overall view select 
    SrcRect.Initialize(ImageX,ImageY, ImageX+Activity.Width,ImageY+Activity.Height )    'Bildauschnitt vom Gesamtbild wählen'
    CanvasTile.DrawBitmap(BitmapMap,SrcRect,DestRect)
    Label2.Text=Zoomlevel
End Sub

Sub CalculateMAP
    If ImageX<0   Then Left_Tiles    'Linke Begrenzung'      'Link delimitation 
    If ImageX>288 Then Right_Tiles    'rechte Begrenzung'   'right delimitation 
    If ImageY<0   Then Top_Tiles    'obere Begrenzung'      'upper delimitation 
    If ImageY>288 Then Bottom_Tiles    'untere Begrenzung'   'lower delimitation 
End Sub





'Tile borders provide 
'Kachelleisten erstellen'
Sub Left_Tiles
    For Y=0 To TileNbY-1
        LoadTile(Zoomlevel, 0, Y, TileX-1, TileY+Y)
    Next
    ImageX=ImageX+TileSize
    sx=sx+TileSize
    
    'SrcRectFertig.Initialize (0.0, TileNbX*TileSize, MapH eight) 
    ' SrcRectFertig.Initialize(0,0,TileNbX*TileSize,MapH eight)
    SrcRectFertig.Initialize(0,0,(TileNbX-1)*TileSize,MapHeight)
    DestRectFertig.Initialize(TileSize,0,MapWidth,MapHeight)
    
    'Map build up 
    Karte_zusammensetzen
    TileX=TileX-1
End Sub

Sub Right_Tiles
    For Y=0 To TileNbY-1
        LoadTile(Zoomlevel, TileNbX-1, Y, TileX+TileNbX, TileY+Y)
    Next
    ImageX=ImageX-TileSize
    sx=sx-TileSize

    SrcRectFertig.Initialize(TileSize,0,MapWidth,MapHeight)
    'Fertig = Finished
    ' DestRectFertig.Initialize(0,0,TileNbX*TileSize,Map Height)
    
    DestRectFertig.Initialize(0,0,(TileNbX-1)*TileSize,MapHeight)
    Karte_zusammensetzen
    TileX=TileX+1
End Sub

Sub Top_Tiles
    For X=0 To TileNbX-1
        LoadTile(Zoomlevel, X, 0, TileX+X, TileY-1)
    Next
    ImageY=ImageY+TileSize
    sy=sy+TileSize
    ' SrcRectFertig.Initialize(0,0,MapWidth,TileNbY*Tile Size)
    SrcRectFertig.Initialize(0,0,MapWidth,(TileNbY-1)*TileSize)
    DestRectFertig.Initialize(0,TileSize,MapWidth,MapHeight)
    Karte_zusammensetzen
    TileY=TileY-1
End Sub

Sub Bottom_Tiles
    For x=0 To TileNbX-1
        LoadTile(Zoomlevel, x, TileNbX-1, TileX+x, TileY+TileNbY)
    Next
    ImageY=ImageY-TileSize
    sy=sy-TileSize

    SrcRectFertig.Initialize(0,TileSize,MapWidth,MapHeight)
    ' DestRectFertig.Initialize(0,0,MapWidth,TileNbY*Til eSize)
    DestRectFertig.Initialize(0,0,MapWidth,(TileNbY-1)*TileSize)
    Karte_zusammensetzen
    TileY=TileY+1
End Sub

'New map from the tile border (5 tiles) and the old 20 tiles build up 
'Neue Karte aus der Kachelleiste (5 Kacheln) und den alten 20 Kacheln zusammensetzen'
Sub Karte_zusammensetzen
                                                                  'Tile row 2.3 and 4 store 
    CanvasMapNew.DrawBitmap(BitmapMap,SrcRectFertig,DestRectFertig)    'Kachelreihe 2,3 und 4 speichern'
    
                                                        'New map at bit-map map hand over     
    CanvasMap.DrawBitmap(BitmapMapNew,Null,GesamtRect)    'Neue Karte an BitmapMap übergeben'
End Sub

'Maps Navigation
'K A R T E N - N A V I G A T I O N'

'Map with finger shift 
'Karte mit Finger verschieben'
Sub Activity_Touch (Action As Int, X As Float, Y As Float)
    Ziel_Steuerung=False
    If Action=0 Then    'MouseDown'
        sx = X + ImageX
        sy = Y + ImageY
    End If
    
    If Action=2 Then    'MouseMove'
        ImageX = sx - X
        ImageY = sy - Y
        DrawMap
    End If
    
    If Action=1 Then    'MouseUp'
        DrawMap
    End If
    
End Sub
'Map Zoom
'Karte zoomen'
Sub ZoomIn_Click
    If Zoomlevel<16 Then
        Zoomlevel=Zoomlevel+1
        Ziele_einzeichnen
    End If
End Sub

Sub ZoomOut_Click
    If Zoomlevel>7 Then
        Zoomlevel=Zoomlevel-1
        
        'targets draw in 
        Ziele_einzeichnen
    End If
End Sub

'R E V E R S E   G E O C O D I N G - F U N K T I O N E N'
Sub ButtonRGC_Click
    If Timer1.Enabled=True Then
        Label5.Visible=False
        Panel1.Visible=False
        Timer1.Enabled=False
    Else
        Label5.Visible=True
        Panel1.Visible=True
        Timer1.Enabled=True
        '            Road without names   
        Label5.Text="Straße ohne Namen"
    End If
End Sub

Sub Timer1_Tick
    URL = "http://maps.google.com/maps/geo?output=xml&oe=utf-8&ll=" & C_ZielLat & "," & C_ZielLon & "&key=asdad"
    Dim request As HttpRequest
    request.InitializeGet(URL)
    request.Timeout = 10000 'set timeout to 10 seconds
    If HTTPClient1.Execute(request, 1) = False Then Return 'Will be false if their is already a running task (with the same id).
End Sub

Sub HttpClient1_ResponseError (Reason As String, StatusCode As Int, TaskId As Int)
                   'Reverse Geocoding not possible. Examine please network connection   
    ToastMessageShow("Reverse Geocoding nicht möglich. Bitte Netzwerkverbindung prüfen.",False)
End Sub

Sub HttpClient1_ResponseSuccess (Response As HttpResponse, TaskId As Int)
    Result=Response.GetInputStream 
    Parser.Parse(Result, "Parser")
    
    If AdrListe.Size>1 Then
        Land=AdrListe.Get(6) 
        Bundesland=AdrListe.Get(7)
        Kreis=AdrListe.Get(2)
        Postleitzahl=AdrListe.Get(5)
        Ort=AdrListe.Get(3)
        Strasse=AdrListe.Get(4)
        
        Label5.Text=Strasse & ", " & Ort
    Else
                  'Road without names
        Label5.Text="Straße ohne Namen"
    End If    
    AdrListe.Clear 
End Sub

Sub GeoResponse_StreamFinish (Success As Boolean, TaskId As Int)
                                        'ADDRESS inquiry missed 
    If Success = False Then Label5.Text="Addressanfrage fehlgeschlagen!"
End Sub 

Sub Parser_EndElement (Uri As String, Name As String, Text As StringBuilder)
    If Parser.Parents.IndexOf("Placemark") > -1 Then
        
        If Parser.Parents.IndexOf("Country") > -1 Then    'Land'
            If Name = "CountryName" Then
                AdrListe.Add(Text.ToString)
            End If
        End If
        If Parser.Parents.IndexOf("AdministrativeArea") > -1 Then    'Bundesland'   'Federal state 
            If Name = "AdministrativeAreaName" Then
                AdrListe.Add(Text.ToString)
            End If
        End If
        If Parser.Parents.IndexOf("SubAdministrativeArea") > -1 Then    'Kreis'   'Circle
            If Name = "SubAdministrativeAreaName" Then
                AdrListe.Add(Text.ToString)
            End If
        End If
        If Parser.Parents.IndexOf("Locality") > -1 Then        'Ort'    'Place 
            If Name = "LocalityName" Then
                AdrListe.Add(Text.ToString)
            End If
        End If
        If Parser.Parents.IndexOf("Thoroughfare") > -1 Then        'Strasse, Hausnummer'    Road,House number 
            If Name = "ThoroughfareName" Then
                AdrListe.Add(Text.ToString)
            End If
        End If
        If Parser.Parents.IndexOf("PostalCode") > -1 Then        'Postleitzahl'  'Postal zip code 
            If Name = "PostalCodeNumber" Then
                AdrListe.Add(Text.ToString)
            End If
        End If
    End If
End Sub

Sub Panel1_Click
    If Timer1.Enabled=True Then
             '                                                             'Federal state                       'Circle                    'Postal zip code                         'Place                 'Road                                      'Coordinates 
        Msgbox("Orstinformationen:" & CRLF & CRLF & "Land: " & Land & CRLF & "Bundesland: " & Bundesland & CRLF & "Kreis: " & Kreis & CRLF & "Postleitzahl: " & Postleitzahl & CRLF & "Ort: " & Ort & CRLF & "Strasse, Nr.: " & Strasse & CRLF & CRLF & "Koordinaten:" & CRLF & CRLF & "Latitude: " & C_ZielLat & CRLF & "Longitude: " & C_ZielLon & CRLF,"MapViewer")
    Else
                                'is deactivated 
        Msgbox("Reverse Geocoding ist deaktiviert.","Mapviewer")
    End If
End Sub

Sub LonLatXYPositionOnMap(x As Float, y As Float) As Coord
    ' returns the lon/lat position on the map with the given x/y positions in pixels
    Dim x1,y1 As Int
    Dim Pnt, Pnt1, Pnt2 As Coord
    
    sx = x + ImageX
    sy = y + ImageY
    x1=TileX + Floor(sx/TileSize)
    y1=TileY + Floor(sy/TileSize)
    Pnt1=LonLatXYPositionOnTile(x1,y1)
    Pnt2=LonLatXYPositionOnTile(x1,y1+1)
    Pnt.lon=Pnt1.lon+(sx Mod TileSize)*ScaleX
    ScaleY=(Pnt1.lat-Pnt2.lat)/TileSize
    Pnt.lat=Pnt1.lat-(sy Mod TileSize)*ScaleY
    Return Pnt
 End Sub
 
Sub LonLatXYPositionOnTile(x As Double, y As Double) As Coord
    ' returns the lon/lat position on the tile with the given x/y positions in pixels
    Dim n As Double    
    Dim Pnt As Coord
    
    Pnt.lon=x/Power(2,Zoomlevel)*360-180

    n=cPI-2*cPI*y/Power(2,Zoomlevel)
    Pnt.lat=ATanD(0.5*(Power(cE,n)-Power(cE,-n)))
    Return Pnt
 End Sub
 
 
 
 
 
 'OLD routines
 
 'Kachelleisten erstellen'
'Sub Left_Tiles
'    For Y=0 To TileNbY-1
'        LoadTile(Zoomlevel, 0, Y, TileX-1, TileY+Y)
'    Next
'    ImageX=ImageX+TileSize
'    sx=sx+TileSize
'        
'    SrcRectFertig.Initialize(0,0,TileNbX*TileSize,MapHeight)
'    DestRectFertig.Initialize(TileSize,0,MapWidth,MapHeight)
'    Karte_zusammensetzen
'    TileX=TileX-1
'End Sub
'
'Sub Right_Tiles
'    For Y=0 To TileNbY-1
'        LoadTile(Zoomlevel, TileNbX-1, Y, TileX+TileNbX, TileY+Y)
'    Next
'    ImageX=ImageX-TileSize
'    sx=sx-TileSize
'        
'    SrcRectFertig.Initialize(TileSize,0,MapWidth,MapHeight)
'    DestRectFertig.Initialize(0,0,TileNbX*TileSize,MapHeight)
'    Karte_zusammensetzen
'    TileX=TileX+1
'End Sub
'
'Sub Top_Tiles
'    For x=0 To TileNbX-1
'        LoadTile(Zoomlevel, x, 0, TileX+x, TileY-1)
'    Next
'    ImageY=ImageY+TileSize
'    sy=sy+TileSize
'        
'    SrcRectFertig.Initialize(0,0,MapWidth,TileNbY*TileSize)
'    DestRectFertig.Initialize(0,TileSize,MapWidth,MapHeight)
'    Karte_zusammensetzen
'    TileY=TileY-1
'End Sub
'
'Sub Bottom_Tiles
'    For x=0 To TileNbX-1
'        LoadTile(Zoomlevel, x, TileNbX-1, TileX+x, TileY+TileNbY)
'    Next
'    ImageY=ImageY-TileSize
'    sy=sy-TileSize
'        
'    SrcRectFertig.Initialize(0,TileSize,MapWidth,MapHeight)
'    DestRectFertig.Initialize(0,0,MapWidth,TileNbY*TileSize)
'    Karte_zusammensetzen
'    TileY=TileY+1
'End Sub
 
Last edited:
Top