Google Maps

tudorf

Active Member
Licensed User
Longtime User
Hello

I have a sample program "GoogleMapsWebView" re-programmed times so that the current position is determined by GPS and recorded. At a position change is not changed but the position of the marker. How do I change the position of the marker in motion?

Thank you Martin
 

Attachments

  • Tudorf_GoogleMapsWebView.zip
    9.5 KB · Views: 375

warwound

Expert
Licensed User
Longtime User
Hi.

First thing you need to do is to make your markerc variable into a global variable - currently is is local to your initialize() function.

Once you have made markerc global you can execute javascript to set it's position, see the Google Maps API Marker setPosition() method here: https://developers.google.com/maps/documentation/javascript/reference#Marker.

Here's the working code:

B4X:
'Activity module
Sub Process_Globals
   Dim ScaleLat, ScaleLong, Scale_Distance As Double
   Dim TileWidth, TileHeight As Int
   Dim ZoomLevel As Int
   Dim PosLat, PosLng As List
   Type CoordLongLat(Lng As Double, Lat As Double)
   Dim CenterLonLat As CoordLongLat
   Dim DispMapTypeControl As Boolean      : DispMapTypeControl = True
   Dim DispMapScaleControl As Boolean   : DispMapScaleControl = True
   Dim DispMapZoomControl As Boolean      : DispMapZoomControl = True
   Dim DispMapCenterMarker As Boolean   : DispMapCenterMarker = True
   Dim DispMapMarkers As Boolean            : DispMapMarkers = True
   Dim DispMapPolyline As Boolean         : DispMapPolyline = True
   Dim Http As HttpClient
   
   
    Dim GPS1 As GPS   
End Sub

Sub Globals
   Dim MapViewer As WebView
   Dim MapViewerExtra As WebViewExtras
   Dim lblLatitude, lblLongitude, lblZoom, lblCenterLat, lblCenterLng As Label

    Dim lblLon As Label
    Dim lblLat As Label
    Dim lblSatellites As Label

   Dim aufruf As Boolean
   aufruf = False

   Dim myLat As Double
   Dim myLon As Double   
End Sub

Sub Activity_Create(FirstTime As Boolean)
   If FirstTime Then
      Http.Initialize("Http")
   End If
   
    If FirstTime Then
        GPS1.Initialize("GPS")
    End If
   Activity.LoadLayout("map")   
      
   PosLat.Initialize
   PosLng.Initialize
   
   InitTestCoordinates
   
   MapViewer.Initialize("")
   Activity.AddView(MapViewer, 0, 0, 100%x, 100%y)
   MapViewer.Tag = "MapViewer"
   
   MapViewerExtra.addJavascriptInterface(MapViewer, "B4A")
   
   '   temporarily add a WebChromeClient to the WebView
   '   if any javascript errors occur they will be visible in the log
   '   remove the WebChromeClient when it's no longer required
   MapViewerExtra.addWebChromeClient(MapViewer, "")
   

   lblLatitude.Initialize("")   
   Activity.AddView(lblLatitude, 0, 100%y - 40dip, 35%x, 40dip)
   lblLatitude.TextColor = Colors.Red
   
   lblLongitude.Initialize("")   
   Activity.AddView(lblLongitude, 35%x, 100%y - 40dip, 35%x, 40dip)
   lblLongitude.TextColor = Colors.Red

   lblZoom.Initialize("")   
   Activity.AddView(lblZoom, 70%x, 100%y - 40dip, 30%x, 40dip)
   lblZoom.TextColor = Colors.Red

   lblCenterLat.Initialize("")   
   Activity.AddView(lblCenterLat, 0, 100%y - 70dip, 50%x, 30dip)
   lblCenterLat.TextColor = Colors.Red

   lblCenterLng.Initialize("")   
   Activity.AddView(lblCenterLng, 50%x, 100%y - 70dip, 50%x, 30dip)
   lblCenterLng.TextColor = Colors.Red
End Sub

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

Sub Activity_Pause (UserClosed As Boolean)

End Sub


Sub GPS_LocationChanged (Location1 As Location)

   myLat = Location1.Latitude
      myLon = Location1.Longitude


Log(myLat)
Log(myLon)
    lblLat.Text = "Lat = " & Location1.ConvertToMinutes(Location1.Latitude)
    lblLon.Text = "Lon = " & Location1.ConvertToMinutes(Location1.Longitude)
'    lblSpeed.Text = "Speed = " & Location1.Speed
'   Dim Location2 As Location
   'Location2.Initialize2("51:37.296", "8:41.626")
'   Location2.Initialize2("51:38.130", "8:40.004")
'    lbldis.Text = "Distance = " & Location1.DistanceTo(Location2)
'    lblgrad.Text = "Grad = " & Location1.BearingTo (Location2)

   '   change the map Marker position (Martin)
   Dim Javascript As String
   Javascript="if(typeof markerc!=='undefined'){markerc.setPosition(new google.maps.LatLng("&myLat&","&myLon&"))}"
   MapViewerExtra.executeJavascript(MapViewer, Javascript)
End Sub

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

Sub GPS_GpsStatus (Satellites As List)

    lblSatellites.Text = "Satellites:" & CRLF
    For i = 0 To Satellites.Size - 1
        Dim Satellite As GPSSatellite
        Satellite = Satellites.Get(i)
        lblSatellites.Text = lblSatellites.Text & CRLF & Satellite.Prn & _
            " " & Satellite.Snr & " " & Satellite.UsedInFix & " " & Satellite.Azimuth _ 
            & " " & Satellite.Elevation 
    Next
      
   If aufruf = False Then
      If lblLat.Text <> "Bitte warten" Then
         If lblLon.Text <> "Bitte warten" Then

            InitTestCoordinates

            ShowMap
            aufruf = True
         End If
      End If
   Else
      MapViewer_CenterChanged(NumberFormat(myLat, 1, 6), NumberFormat(myLon, 1, 6))
   End If
End Sub

Sub ShowMap
   DispMap(CenterLonLat.Lat, CenterLonLat.Lng, ZoomLevel, DispMapTypeControl, DispMapZoomControl, "LEFT_TOP", DispMapScaleControl, "TOP_LEFT", DispMapCenterMarker, PosLat, PosLng, DispMapMarkers, DispMapPolyline, "ff0000", 0.5, 3)
End Sub

Sub DispMap(CenterLat As Float, CenterLong As Float, Zoom As Int, MapTypeControl As Boolean, MapZoomControl As Boolean, ZoomControlPosition As String, MapScaleControl As Boolean, ScaleControlPosition As String, DispMarkerCenter As Boolean, MarkerLat As List, MarkerLong As List, DispMarkers As Boolean, DispPolyline As Boolean, PolyLineColor As String, PolyLineOpacity As Float, PolyLineWidth As Int)
   ' CenterLat        = latitude of map center in degrees
   ' CenterLong       = longitude of map center in degrees
   ' Zoom             = zomm index   0 - 21
   ' MapTypeControl   = true displays the map type control
   ' DispZoomControl  = true displays the zoom control otherwise false
   ' ZoomControlPosition  = position of the zoom control TOP_LEFT, TOP_CENTER, TOP_RIGHT, LEFT_CENTER, RIGHT_CENTER, BOTTOM_LEFT, BOTTOM_CENTER, BOTTOM_RIGHT
   ' ScaleControl     = true displays the zoom control otherwise false
   ' ScaleControlPosition  = position of the scale control TOP_LEFT, TOP_CENTER, TOP_RIGHT, LEFT_CENTER, RIGHT_CENTER, BOTTOM_LEFT, BOTTOM_CENTER, BOTTOM_RIGHT
   ' DispMarkerCenter = true sets a marker on the center of the map
   ' MarkerLat          = List of lat  positions of the markers 
   ' MarkerLong          = List of long positions of the markers
   ' DipsMarkers         = true displays the markers
   ' DispPolyline       = true displays a polyline with the markers as vertices
   ' PolyLineColor    = polyline color hexadecimal  #ff0000 = red  #00ff00 = green   #0000ff = blue
   ' PolyLineOpacity  = polyline opacity  0.0  transparent   1.0 full opaque
   ' PolyLineWidth    = polyline width in pixels
   
    Dim HtmlCode As String
   Dim i, j As Int
   
   '   added var markerc; to this line (Martin)
   HtmlCode = "<!DOCTYPE html><html><head><meta name='viewport' content='initial-scale=1.0, user-scalable=no' /><style type='text/css'>  html { height: 100% }  body { height: 100%; margin: 0px; padding: 0px }#map_canvas { height: 100% }</style><script type='text/javascript' src='http://maps.google.com/maps/api/js?sensor=true'></script><script type='text/javascript'>var markerc; function initialize() {var centerlatlng = new google.maps.LatLng(" & CenterLat & "," & CenterLong & "); var myOptions = { zoom: "&Zoom&", center: centerlatlng, disableDefaultUI: true, zoomControl: "& MapZoomControl & ", zoomControlOptions: {position: google.maps.ControlPosition." & ZoomControlPosition & "}, scaleControl: "& MapScaleControl & ", scaleControlOptions: {position: google.maps.ControlPosition." & ScaleControlPosition & "}, mapTypeControl: "& MapTypeControl& ", mapTypeId: google.maps.MapTypeId.ROADMAP }; var map = new google.maps.Map(document.getElementById('map_canvas'),  myOptions)" 

   ' add click event
   HtmlCode = HtmlCode & ";google.maps.event.addListener(map, 'click', function(mouseEvent){"
   HtmlCode = HtmlCode & "var lat = mouseEvent.latLng.lat();"
   HtmlCode = HtmlCode & "var lng = mouseEvent.latLng.lng();"
   HtmlCode = HtmlCode & "B4A.CallSub('MapViewer_Click', true, lat, lng); })"

   ' add zoom_changed event
   HtmlCode = HtmlCode & ";google.maps.event.addListener(map, 'zoom_changed', function() {"
   HtmlCode = HtmlCode & "var zoomLevel = map.getZoom();"
   HtmlCode = HtmlCode & "B4A.CallSub('MapViewer_ZoomChanged', true, zoomLevel);"
   HtmlCode = HtmlCode & " })"
   
   ' add center_changed event
   HtmlCode = HtmlCode & ";google.maps.event.addListener(map, 'center_changed', function() {"
   HtmlCode = HtmlCode & "var centerlatlng = map.getCenter();"
'   HtmlCode = HtmlCode & "B4A.CallSub('MapViewer_CenterChanged', true, centerlatlng.lat(), centerlatlng.lng() );"
   HtmlCode = HtmlCode & "B4A.CallSub('MapViewer_CenterChanged', true, centerlatlng.lat(), centerlatlng.lng() );"
   HtmlCode = HtmlCode & " })"
   
   ' displays a marker on the map center
   If DispMarkerCenter = True Then   
      '   removed var from this line (Martin)
      HtmlCode = HtmlCode & "; markerc = new google.maps.Marker({   position: new google.maps.LatLng(" & CenterLat & "," & CenterLong & "),map: map, title: '',clickable: false,icon: 'http://www.google.com/mapfiles/arrow.png' })"
   End If
   
   ' displays markers on the map
   If MarkerLat.Size > 0 Then
      j = MarkerLat.Size - 1
      If DispMarkers = True Then
         If j = 0 Then
            HtmlCode = HtmlCode & "; var marker0 = new google.maps.Marker({   position: new google.maps.LatLng(" & MarkerLat.Get(j) & "," & MarkerLong.Get(j) & "),map: map, title: 'Test0',clickable: true, draggable: true, icon: 'http://www.google.com/mapfiles/marker_red.png' })"
'            HtmlCode = HtmlCode & "; google.maps.event.addListener(marker0, 'click', function() {alert('Marker1')} )"
         Else If j = 1 Then
            HtmlCode = HtmlCode & "; var marker0 = new google.maps.Marker({   position: new google.maps.LatLng(" & MarkerLat.Get(0) & "," & MarkerLong.Get(0) & "),map: map, title: 'Test0',clickable: true, draggable: true, icon: 'http://www.google.com/mapfiles/marker_green.png' })"
'            HtmlCode = HtmlCode & "; google.maps.event.addListener(marker0, 'click', function() {map.set_center(marker" & i & ")} )"
            HtmlCode = HtmlCode & "; var marker1 = new google.maps.Marker({   position: new google.maps.LatLng(" & MarkerLat.Get(1) & "," & MarkerLong.Get(1) & "),map: map, title: 'Test1',clickable: true, draggable: true, icon: 'http://www.google.com/mapfiles/marker.png' })"
'            HtmlCode = HtmlCode & "; google.maps.event.addListener(marker1, 'click', function() {map.set_center(marker" & i & ")} )"
         Else
            HtmlCode = HtmlCode & "; var marker0 = new google.maps.Marker({   position: new google.maps.LatLng(" & MarkerLat.Get(0) & "," & MarkerLong.Get(0) & "),map: map, title: 'Test0',clickable: true, draggable: true, icon: 'http://www.google.com/mapfiles/marker_greenA.png' })"
'            HtmlCode = HtmlCode & "; google.maps.event.addListener(marker0, 'click', function() {alert('Marker0')} )"
            For i = 1 To j - 1 ' diplays the markers
               HtmlCode = HtmlCode & "; var marker" & i & " = new google.maps.Marker({   position: new google.maps.LatLng(" & MarkerLat.Get(i) & "," & MarkerLong.Get(i) & "),map: map, title: 'Test" & i & "',clickable: true, draggable: true, icon: 'http://www.google.com/mapfiles/marker_orange" & Chr(i + 65) & ".png' })"
'               HtmlCode = HtmlCode & "; google.maps.event.addListener(marker" & i & ", 'click', function() {map.set_center(marker" & i & ")} )"
            Next
            HtmlCode = HtmlCode & "; var marker" & (j) & " = new google.maps.Marker({   position: new google.maps.LatLng(" & MarkerLat.Get(j) & "," & MarkerLong.Get(j) & "),map: map, title: 'Test" & j & "',clickable: true, draggable: true, icon: 'http://www.google.com/mapfiles/marker" & Chr(j + 65) & ".png' })"
'            HtmlCode = HtmlCode & "; google.maps.event.addListener(marker" & j & ", 'click', function() {map.set_center(marker" & j & ")} )"
         End If
      End If
      
   ' displays a polyline between the markers
      If DispPolyline = True AND j > 0 Then
         HtmlCode = HtmlCode & "; var points = ["
         HtmlCode = HtmlCode & " new google.maps.LatLng(" & MarkerLat.Get(0) & "," & MarkerLong.Get(0) & ")"
         For i = 1 To j
            HtmlCode = HtmlCode & ", new google.maps.LatLng(" & MarkerLat.Get(i) & "," & MarkerLong.Get(i) & ")"
         Next
         HtmlCode = HtmlCode & "] "
         HtmlCode = HtmlCode & "; var polyline = new google.maps.Polyline({path: points, strokeColor: '" & PolyLineColor & "', strokeOpacity: " & PolyLineOpacity & ", strokeWeight: " & PolyLineWidth & "})"
         HtmlCode = HtmlCode & "; polyline.setMap(map)"
      End If
   End If
   
   HtmlCode = HtmlCode & "; }</script></head><body onload='initialize()'>  <div id='map_canvas' style='width:100%; height:100%'></div></body></html>"
   
   MapViewer.LoadHtml(HtmlCode)

End Sub

Sub MapViewer_Click(LatStr As String, LngStr As String)
  Dim Lat As Double
  Dim Lng As Double
  Lat=LatStr
  Lng=LngStr
   lblLatitude.Text = " Lat = " & NumberFormat(myLat, 1, 6)
   lblLongitude.Text = " Lng = " & NumberFormat(myLon, 1, 6)
End Sub

Sub MapViewer_ZoomChanged(ZoomL As String)
   ZoomLevel = ZoomL
   lblZoom.Text = "Zoom = " & ZoomLevel
End Sub

Sub MapViewer_CenterChanged(CenterLat As String, CenterLng As String)
   CenterLonLat.Lat = CenterLat
   CenterLonLat.Lng = CenterLng
   lblCenterLat.Text = " CenterLat = " & NumberFormat(CenterLat, 1, 6)
   lblCenterLng.Text = " CenterLng = " & NumberFormat(CenterLng, 1, 6)
End Sub

Sub InitTestCoordinates
'   PosLat.Add(46.1348)
'   PosLng.Add(7.113)
'   PosLat.Add(46.1363)
'   PosLng.Add(7.1122)
'   PosLat.Add(46.1379)
'   PosLng.Add(7.1152)
'   PosLat.Add(46.1386)
'   PosLng.Add(7.1148)
'   PosLat.Add(46.1395)
'   PosLng.Add(7.1171)
'   PosLat.Add(46.1409)
'   PosLng.Add(7.1188)
'   PosLat.Add(46.1400)
'   PosLng.Add(7.1201)
   
'   CenterLonLat.Lat = 46.1379
'   CenterLonLat.Lng = 7.1163

   CenterLonLat.Lat = NumberFormat(myLat, 1, 6)
   CenterLonLat.Lng = NumberFormat(myLon, 1, 6)

   ZoomLevel = 15
End Sub

I've added comments where i've updated your code.

On my device i found that the first one or two GPS fixes were being detected before the map has been created, so if you executed the javascript:

B4X:
Javascript="markerc.setPosition(new google.maps.LatLng("&myLat&","&myLon&"))"

You'd see an error in the log:

Uncaught ReferenceError: markerc is not defined in (Line: 1)

The code is trying to change the Marker position before the Marker has been created.
Checking if the Marker has been created before changing it's position prevents that error:

B4X:
Javascript="if(typeof markerc!=='undefined'){markerc.setPosition(new google.maps.LatLng("&myLat&","&myLon&"))}"

Martin.
 

Attachments

  • GoogleMapsWebView.zip
    9.7 KB · Views: 431
Upvote 0

tudorf

Active Member
Licensed User
Longtime User
Hi Martin

Thanks for the reply. The marker moves.

I've been trying to put the marker always in the middle of the window, even when moving. I have therefore inserted under GPS_LocationChanged these lines. The marker is not placed in the middle.

Dim Javascript As String
Javascript="if(typeof markerc!=='undefined'){markerc.setcenter(new google.maps.map.setCenter("&myLat&","&myLon&"))}"

MapViewerExtra.executeJavascript(MapViewer, Javascript)

Javascript="if(typeof markerc!=='undefined'){markerc.setPosition(new google.maps.LatLng("&myLat&","&myLon&"))}"

MapViewerExtra.executeJavascript(MapViewer, Javascript)

After each change in the position I wanted to move the card to the window center and the new marker set.

Martin
 
Upvote 0

warwound

Expert
Licensed User
Longtime User
Hi again.

Basically any javascript that you execute from your B4A code can only access global variables in the web page javascript.

To change the map center you need to use one of the Map setCenter() or panTo() methods.

And to do that you need to make your map variable global.

Look at this (nicely) formatted copy of your web page javascript:

B4X:
//   define globals here
 var markerc, map;
 
 function initialize() {
    var centerlatlng = new google.maps.LatLng(52.756019592285156, 0.39784398674964905);
    var myOptions = {
       zoom: 15,
       center: centerlatlng,
       disableDefaultUI: true,
       zoomControl: true,
       zoomControlOptions: {
          position: google.maps.ControlPosition.LEFT_TOP
       },
       scaleControl: true,
       scaleControlOptions: {
          position: google.maps.ControlPosition.TOP_LEFT
       },
       mapTypeControl: true,
       mapTypeId: google.maps.MapTypeId.ROADMAP
    };
   // removed var
    map = new google.maps.Map(document.getElementById('map_canvas'), myOptions);
    google.maps.event.addListener(map, 'click', function (mouseEvent) {
       var lat = mouseEvent.latLng.lat();
       var lng = mouseEvent.latLng.lng();
       B4A.CallSub('MapViewer_Click', true, lat, lng);
    });
    google.maps.event.addListener(map, 'zoom_changed', function () {
       var zoomLevel = map.getZoom();
       B4A.CallSub('MapViewer_ZoomChanged', true, zoomLevel);
    });
    google.maps.event.addListener(map, 'center_changed', function () {
       var centerlatlng = map.getCenter();
       B4A.CallSub('MapViewer_CenterChanged', true, centerlatlng.lat(), centerlatlng.lng());
    });
    markerc = new google.maps.Marker({
       position: new google.maps.LatLng(52.756019592285156, 0.39784398674964905),
       map: map,
       title: '',
       clickable: false,
       icon: 'http://www.google.com/mapfiles/arrow.png'
    });
 }

markerc and map are now both global.
As well as defining them outside of the initialize() function you don't use var when setting their values.

Now you can do something such as:

B4X:
Dim Javascript As String
Javascript="if(typeof markerc!=='undefined'){markerc.setPosition(new google.maps.LatLng("&myLat&","&myLon&"))}"
MapViewerExtra.executeJavascript(MapViewer, Javascript)
Javascript="if(typeof map!=='undefined'){map.panTo(new google.maps.LatLng("&myLat&","&myLon&"))}"
MapViewerExtra.executeJavascript(MapViewer, Javascript)

That should work but a more elegant solution would be something like this, first a new javascript function:

B4X:
 var markerc, map, mapIsInitialized=false;
 
 function initialize() {
    var centerlatlng = new google.maps.LatLng(52.756019592285156, 0.39784398674964905);
    var myOptions = {
       zoom: 15,
       center: centerlatlng,
       disableDefaultUI: true,
       zoomControl: true,
       zoomControlOptions: {
          position: google.maps.ControlPosition.LEFT_TOP
       },
       scaleControl: true,
       scaleControlOptions: {
          position: google.maps.ControlPosition.TOP_LEFT
       },
       mapTypeControl: true,
       mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    map = new google.maps.Map(document.getElementById('map_canvas'), myOptions);
    google.maps.event.addListener(map, 'click', function (mouseEvent) {
       var lat = mouseEvent.latLng.lat();
       var lng = mouseEvent.latLng.lng();
       B4A.CallSub('MapViewer_Click', true, lat, lng);
    });
    google.maps.event.addListener(map, 'zoom_changed', function () {
       var zoomLevel = map.getZoom();
       B4A.CallSub('MapViewer_ZoomChanged', true, zoomLevel);
    });
    google.maps.event.addListener(map, 'center_changed', function () {
       var centerlatlng = map.getCenter();
       B4A.CallSub('MapViewer_CenterChanged', true, centerlatlng.lat(), centerlatlng.lng());
    });
    markerc = new google.maps.Marker({
       position: new google.maps.LatLng(52.756019592285156, 0.39784398674964905),
       map: map,
       title: '',
       clickable: false,
       icon: 'http://www.google.com/mapfiles/arrow.png'
    });
   mapIsInitialized=true;
 }
 function locationChanged(latitude, longitude){
    if(mapIsInitialized){
      var latLng=new google.maps.LatLng(latitude, longitude);
      markerc.setPosition(latLng);
      map.panTo(latLng);
   }
 }

Now in B4A you can do:

B4X:
Dim Javascript As String
Javascript="locationChanged("&myLat&","&myLon&")"
MapViewerExtra.executeJavascript(MapViewer, Javascript)

Either technique should work, except for typos on my part i haven't tested the code examples!

Martin.
 
Upvote 0

tudorf

Active Member
Licensed User
Longtime User
Hi
Where I must define the variables? In the first version from you, I can´t find the Global definition of markerc. Where should I install the new version of javascrit? Is this a part of b4A? Written in a Sub_program ?

Martin
 
Upvote 0

tudorf

Active Member
Licensed User
Longtime User
Hi
The program shows no map. I think I have a problem with the brackets (){} . How can I check the brackets? Is there a tool? The debugger shows me nothing.

Martin
 

Attachments

  • Tudorf_GoogleMapsWebView 20120815.zip
    9.8 KB · Views: 292
Upvote 0

warwound

Expert
Licensed User
Longtime User
Hi.

In your DispMap Sub, right at the end add this line:

B4X:
MapViewer.LoadHtml(HtmlCode)   '   existing line
File.WriteString(File.DirRootExternal, "tudorf_map.htm", HtmlCode)

Upload tudorf_map.htm and we can fix it from there.

Martin.
 
Upvote 0

warwound

Expert
Licensed User
Longtime User
All fixed!

The problem was that the B4A code was trying to execute the locationChanged function before the WebView had fully loaded.
There were also some syntax errors.

Here's the new map javascript:

B4X:
var markerc, map;
function locationChanged(latitude, longitude) {
   var latLng = new google.maps.LatLng(latitude, longitude);
   markerc.setPosition(latLng);
   map.panTo(latLng);
}
function initialize() {
   var centerlatlng = new google.maps.LatLng(52.75613784790039, 0.3976700007915497);
   var myOptions = {
      zoom: 15,
      center: centerlatlng,
      disableDefaultUI: true,
      zoomControl: true,
      zoomControlOptions: {
         position: google.maps.ControlPosition.LEFT_TOP
      },
      scaleControl: true,
      scaleControlOptions: {
         position: google.maps.ControlPosition.TOP_LEFT
      },
      mapTypeControl: true,
      mapTypeId: google.maps.MapTypeId.ROADMAP
   };
   map = new google.maps.Map(document.getElementById('map_canvas'), myOptions);
   google.maps.event.addListener(map, 'click', function (mouseEvent) {
      var lat = mouseEvent.latLng.lat();
      var lng = mouseEvent.latLng.lng();
      B4A.CallSub('MapViewer_Click', true, lat, lng);
   });
   google.maps.event.addListener(map, 'zoom_changed', function () {
      var zoomLevel = map.getZoom();
      B4A.CallSub('MapViewer_ZoomChanged', true, zoomLevel);
   });
   google.maps.event.addListener(map, 'center_changed', function () {
      var centerlatlng = map.getCenter();
      B4A.CallSub('MapViewer_CenterChanged', true, centerlatlng.lat(), centerlatlng.lng());
   });
   markerc = new google.maps.Marker({
      position: new google.maps.LatLng(52.75613784790039, 0.3976700007915497),
      map: map,
      title: '',
      clickable: false,
      icon: 'http://www.google.com/mapfiles/arrow.png'
   });
   B4A.CallSub('MapViewer_SetInitialized', true);
}

And your B4A code:

B4X:
'Activity module
Sub Process_Globals
   Dim ScaleLat, ScaleLong, Scale_Distance As Double
   Dim TileWidth, TileHeight As Int
   Dim ZoomLevel As Int
   Dim PosLat, PosLng As List
   Type CoordLongLat(Lng As Double, Lat As Double)
   Dim CenterLonLat As CoordLongLat
   Dim DispMapTypeControl As Boolean      : DispMapTypeControl = True
   Dim DispMapScaleControl As Boolean   : DispMapScaleControl = True
   Dim DispMapZoomControl As Boolean      : DispMapZoomControl = True
   Dim DispMapCenterMarker As Boolean   : DispMapCenterMarker = True
   Dim DispMapMarkers As Boolean            : DispMapMarkers = True
   Dim DispMapPolyline As Boolean         : DispMapPolyline = True
   Dim Http As HttpClient
   
   
    Dim GPS1 As GPS   
End Sub

Sub Globals
   Dim MapViewer As WebView
   Dim MapViewerExtra As WebViewExtras
   Dim lblLatitude, lblLongitude, lblZoom, lblCenterLat, lblCenterLng As Label

    Dim lblLon As Label
    Dim lblLat As Label
    Dim lblSatellites As Label

   Dim aufruf As Boolean
   aufruf = False

   Dim myLat As Double
   Dim myLon As Double   
   
   '   added a new variable (Martin)
   Dim mapIsInitialized As Boolean : mapIsInitialized=False
End Sub

Sub Activity_Create(FirstTime As Boolean)
   If FirstTime Then
      Http.Initialize("Http")
   End If
   
    If FirstTime Then
        GPS1.Initialize("GPS")
    End If
   Activity.LoadLayout("map")   
      
   PosLat.Initialize
   PosLng.Initialize
   
   InitTestCoordinates
   
   MapViewer.Initialize("")
   Activity.AddView(MapViewer, 0, 0, 100%x, 100%y)
   MapViewer.Tag = "MapViewer"
   
   MapViewerExtra.addJavascriptInterface(MapViewer, "B4A")
   
   '   temporarily add a WebChromeClient to the WebView
   '   if any javascript errors occur they will be visible in the log
   '   remove the WebChromeClient when it's no longer required
   MapViewerExtra.addWebChromeClient(MapViewer, "")
   

   lblLatitude.Initialize("")   
   Activity.AddView(lblLatitude, 0, 100%y - 40dip, 35%x, 40dip)
   lblLatitude.TextColor = Colors.Red
   
   lblLongitude.Initialize("")   
   Activity.AddView(lblLongitude, 35%x, 100%y - 40dip, 35%x, 40dip)
   lblLongitude.TextColor = Colors.Red

   lblZoom.Initialize("")   
   Activity.AddView(lblZoom, 70%x, 100%y - 40dip, 30%x, 40dip)
   lblZoom.TextColor = Colors.Red

   lblCenterLat.Initialize("")   
   Activity.AddView(lblCenterLat, 0, 100%y - 70dip, 50%x, 30dip)
   lblCenterLat.TextColor = Colors.Red

   lblCenterLng.Initialize("")   
   Activity.AddView(lblCenterLng, 50%x, 100%y - 70dip, 50%x, 30dip)
   lblCenterLng.TextColor = Colors.Red
End Sub

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

Sub Activity_Pause (UserClosed As Boolean)

End Sub


Sub GPS_LocationChanged (Location1 As Location)

   myLat = Location1.Latitude
      myLon = Location1.Longitude


Log(myLat)
Log(myLon)
    lblLat.Text = "Lat = " & Location1.ConvertToMinutes(Location1.Latitude)
    lblLon.Text = "Lon = " & Location1.ConvertToMinutes(Location1.Longitude)
'    lblSpeed.Text = "Speed = " & Location1.Speed
'   Dim Location2 As Location
   'Location2.Initialize2("51:37.296", "8:41.626")
'   Location2.Initialize2("51:38.130", "8:40.004")
'    lbldis.Text = "Distance = " & Location1.DistanceTo(Location2)
'    lblgrad.Text = "Grad = " & Location1.BearingTo (Location2)

   If mapIsInitialized Then
      '   change the Map and Marker positions (Martin) - only if they have been created
      Dim Javascript As String
      Javascript="locationChanged("&myLat&","&myLon&")"
      MapViewerExtra.executeJavascript(MapViewer, Javascript)
   End If
End Sub

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

Sub GPS_GpsStatus (Satellites As List)

    lblSatellites.Text = "Satellites:" & CRLF
    For i = 0 To Satellites.Size - 1
        Dim Satellite As GPSSatellite
        Satellite = Satellites.Get(i)
        lblSatellites.Text = lblSatellites.Text & CRLF & Satellite.Prn & _
            " " & Satellite.Snr & " " & Satellite.UsedInFix & " " & Satellite.Azimuth _ 
            & " " & Satellite.Elevation 
    Next
      
   If aufruf = False Then
      If lblLat.Text <> "Bitte warten" Then
         If lblLon.Text <> "Bitte warten" Then

Msgbox("Aufruf","")

            InitTestCoordinates

            ShowMap
            aufruf = True
         End If
      End If
   Else
      MapViewer_CenterChanged(NumberFormat(myLat, 1, 6), NumberFormat(myLon, 1, 6))
   End If
End Sub

Sub ShowMap
   DispMap(CenterLonLat.Lat, CenterLonLat.Lng, ZoomLevel, DispMapTypeControl, DispMapZoomControl, "LEFT_TOP", DispMapScaleControl, "TOP_LEFT", DispMapCenterMarker, PosLat, PosLng, DispMapMarkers, DispMapPolyline, "ff0000", 0.5, 3)
End Sub

Sub DispMap(CenterLat As Float, CenterLong As Float, Zoom As Int, MapTypeControl As Boolean, MapZoomControl As Boolean, ZoomControlPosition As String, MapScaleControl As Boolean, ScaleControlPosition As String, DispMarkerCenter As Boolean, MarkerLat As List, MarkerLong As List, DispMarkers As Boolean, DispPolyline As Boolean, PolyLineColor As String, PolyLineOpacity As Float, PolyLineWidth As Int)
   ' CenterLat        = latitude of map center in degrees
   ' CenterLong       = longitude of map center in degrees
   ' Zoom             = zomm index   0 - 21
   ' MapTypeControl   = true displays the map type control
   ' DispZoomControl  = true displays the zoom control otherwise false
   ' ZoomControlPosition  = position of the zoom control TOP_LEFT, TOP_CENTER, TOP_RIGHT, LEFT_CENTER, RIGHT_CENTER, BOTTOM_LEFT, BOTTOM_CENTER, BOTTOM_RIGHT
   ' ScaleControl     = true displays the zoom control otherwise false
   ' ScaleControlPosition  = position of the scale control TOP_LEFT, TOP_CENTER, TOP_RIGHT, LEFT_CENTER, RIGHT_CENTER, BOTTOM_LEFT, BOTTOM_CENTER, BOTTOM_RIGHT
   ' DispMarkerCenter = true sets a marker on the center of the map
   ' MarkerLat          = List of lat  positions of the markers 
   ' MarkerLong          = List of long positions of the markers
   ' DipsMarkers         = true displays the markers
   ' DispPolyline       = true displays a polyline with the markers as vertices
   ' PolyLineColor    = polyline color hexadecimal  #ff0000 = red  #00ff00 = green   #0000ff = blue
   ' PolyLineOpacity  = polyline opacity  0.0  transparent   1.0 full opaque
   ' PolyLineWidth    = polyline width in pixels
   
    Dim HtmlCode As String
   Dim i, j As Int
   
   '   added global variables and locationChanged function to this line (Martin)
   HtmlCode = "<!DOCTYPE html><html><head><meta name='viewport' content='initial-scale=1.0, user-scalable=no' /><style type='text/css'>  html { height: 100% }  body { height: 100%; margin: 0px; padding: 0px }#map_canvas { height: 100% }</style><script type='text/javascript' src='http://maps.google.com/maps/api/js?sensor=true'></script><script type='text/javascript'>var markerc, map; function locationChanged(latitude, longitude){var latLng=new google.maps.LatLng(latitude, longitude);markerc.setPosition(latLng);map.panTo(latLng);}function initialize() {var centerlatlng = new google.maps.LatLng(" & CenterLat & "," & CenterLong & "); var myOptions = { zoom: "&Zoom&", center: centerlatlng, disableDefaultUI: true, zoomControl: "& MapZoomControl & ", zoomControlOptions: {position: google.maps.ControlPosition." & ZoomControlPosition & "}, scaleControl: "& MapScaleControl & ", scaleControlOptions: {position: google.maps.ControlPosition." & ScaleControlPosition & "}, mapTypeControl: "& MapTypeControl& ", mapTypeId: google.maps.MapTypeId.ROADMAP }; map = new google.maps.Map(document.getElementById('map_canvas'),  myOptions)" 

   ' add click event
   HtmlCode = HtmlCode & ";google.maps.event.addListener(map, 'click', function(mouseEvent){"
   HtmlCode = HtmlCode & "var lat = mouseEvent.latLng.lat();"
   HtmlCode = HtmlCode & "var lng = mouseEvent.latLng.lng();"
   HtmlCode = HtmlCode & "B4A.CallSub('MapViewer_Click', true, lat, lng); })"

   ' add zoom_changed event
   HtmlCode = HtmlCode & ";google.maps.event.addListener(map, 'zoom_changed', function() {"
   HtmlCode = HtmlCode & "var zoomLevel = map.getZoom();"
   HtmlCode = HtmlCode & "B4A.CallSub('MapViewer_ZoomChanged', true, zoomLevel);"
   HtmlCode = HtmlCode & " })"
   
   ' add center_changed event
   HtmlCode = HtmlCode & ";google.maps.event.addListener(map, 'center_changed', function() {"
   HtmlCode = HtmlCode & "var centerlatlng = map.getCenter();"
'   HtmlCode = HtmlCode & "B4A.CallSub('MapViewer_CenterChanged', true, centerlatlng.lat(), centerlatlng.lng() );"
   HtmlCode = HtmlCode & "B4A.CallSub('MapViewer_CenterChanged', true, centerlatlng.lat(), centerlatlng.lng() );"
   HtmlCode = HtmlCode & " })"
   
   
   
   ' displays a marker on the map center
   If DispMarkerCenter = True Then   
      '   removed var from this line (Martin)
      HtmlCode = HtmlCode & "; markerc = new google.maps.Marker({   position: new google.maps.LatLng(" & CenterLat & "," & CenterLong & "),map: map, title: '',clickable: false,icon: 'http://www.google.com/mapfiles/arrow.png' })"
   End If
   
   ' displays markers on the map
   If MarkerLat.Size > 0 Then
      j = MarkerLat.Size - 1
      If DispMarkers = True Then
         If j = 0 Then
            HtmlCode = HtmlCode & "; var marker0 = new google.maps.Marker({   position: new google.maps.LatLng(" & MarkerLat.Get(j) & "," & MarkerLong.Get(j) & "),map: map, title: 'Test0',clickable: true, draggable: true, icon: 'http://www.google.com/mapfiles/marker_red.png' })"
'            HtmlCode = HtmlCode & "; google.maps.event.addListener(marker0, 'click', function() {alert('Marker1')} )"
         Else If j = 1 Then
            HtmlCode = HtmlCode & "; var marker0 = new google.maps.Marker({   position: new google.maps.LatLng(" & MarkerLat.Get(0) & "," & MarkerLong.Get(0) & "),map: map, title: 'Test0',clickable: true, draggable: true, icon: 'http://www.google.com/mapfiles/marker_green.png' })"
'            HtmlCode = HtmlCode & "; google.maps.event.addListener(marker0, 'click', function() {map.set_center(marker" & i & ")} )"
            HtmlCode = HtmlCode & "; var marker1 = new google.maps.Marker({   position: new google.maps.LatLng(" & MarkerLat.Get(1) & "," & MarkerLong.Get(1) & "),map: map, title: 'Test1',clickable: true, draggable: true, icon: 'http://www.google.com/mapfiles/marker.png' })"
'            HtmlCode = HtmlCode & "; google.maps.event.addListener(marker1, 'click', function() {map.set_center(marker" & i & ")} )"
         Else
            HtmlCode = HtmlCode & "; var marker0 = new google.maps.Marker({   position: new google.maps.LatLng(" & MarkerLat.Get(0) & "," & MarkerLong.Get(0) & "),map: map, title: 'Test0',clickable: true, draggable: true, icon: 'http://www.google.com/mapfiles/marker_greenA.png' })"
'            HtmlCode = HtmlCode & "; google.maps.event.addListener(marker0, 'click', function() {alert('Marker0')} )"
            For i = 1 To j - 1 ' diplays the markers
               HtmlCode = HtmlCode & "; var marker" & i & " = new google.maps.Marker({   position: new google.maps.LatLng(" & MarkerLat.Get(i) & "," & MarkerLong.Get(i) & "),map: map, title: 'Test" & i & "',clickable: true, draggable: true, icon: 'http://www.google.com/mapfiles/marker_orange" & Chr(i + 65) & ".png' })"
'               HtmlCode = HtmlCode & "; google.maps.event.addListener(marker" & i & ", 'click', function() {map.set_center(marker" & i & ")} )"
            Next
            HtmlCode = HtmlCode & "; var marker" & (j) & " = new google.maps.Marker({   position: new google.maps.LatLng(" & MarkerLat.Get(j) & "," & MarkerLong.Get(j) & "),map: map, title: 'Test" & j & "',clickable: true, draggable: true, icon: 'http://www.google.com/mapfiles/marker" & Chr(j + 65) & ".png' })"
'            HtmlCode = HtmlCode & "; google.maps.event.addListener(marker" & j & ", 'click', function() {map.set_center(marker" & j & ")} )"
         End If
      End If
      
   ' displays a polyline between the markers
      If DispPolyline = True AND j > 0 Then
         HtmlCode = HtmlCode & "; var points = ["
         HtmlCode = HtmlCode & " new google.maps.LatLng(" & MarkerLat.Get(0) & "," & MarkerLong.Get(0) & ")"
         For i = 1 To j
            HtmlCode = HtmlCode & ", new google.maps.LatLng(" & MarkerLat.Get(i) & "," & MarkerLong.Get(i) & ")"
         Next
         HtmlCode = HtmlCode & "] "
         HtmlCode = HtmlCode & "; var polyline = new google.maps.Polyline({path: points, strokeColor: '" & PolyLineColor & "', strokeOpacity: " & PolyLineOpacity & ", strokeWeight: " & PolyLineWidth & "})"
         HtmlCode = HtmlCode & "; polyline.setMap(map)"
      End If
   End If
   
   '   the javascript will now notify the B4A code once the Map and Marker are created
   HtmlCode=HtmlCode & "; B4A.CallSub('MapViewer_SetInitialized', true)"
   
   HtmlCode = HtmlCode & "; }</script></head><body onload='initialize()'>  <div id='map_canvas' style='width:100%; height:100%'></div></body></html>"
   
   MapViewer.LoadHtml(HtmlCode)
   File.WriteString(File.DirRootExternal, "tudorf_map.htm", HtmlCode)
End Sub

Sub MapViewer_Click(LatStr As String, LngStr As String)
  Dim Lat As Double
  Dim Lng As Double
  Lat=LatStr
  Lng=LngStr
   lblLatitude.Text = " Lat = " & NumberFormat(myLat, 1, 6)
   lblLongitude.Text = " Lng = " & NumberFormat(myLon, 1, 6)
End Sub

Sub MapViewer_ZoomChanged(ZoomL As String)
   ZoomLevel = ZoomL
   lblZoom.Text = "Zoom = " & ZoomLevel
End Sub

Sub MapViewer_CenterChanged(CenterLat As String, CenterLng As String)
   CenterLonLat.Lat = CenterLat
   CenterLonLat.Lng = CenterLng
   lblCenterLat.Text = " CenterLat = " & NumberFormat(CenterLat, 1, 6)
   lblCenterLng.Text = " CenterLng = " & NumberFormat(CenterLng, 1, 6)
End Sub

Sub InitTestCoordinates
'   PosLat.Add(46.1348)
'   PosLng.Add(7.113)
'   PosLat.Add(46.1363)
'   PosLng.Add(7.1122)
'   PosLat.Add(46.1379)
'   PosLng.Add(7.1152)
'   PosLat.Add(46.1386)
'   PosLng.Add(7.1148)
'   PosLat.Add(46.1395)
'   PosLng.Add(7.1171)
'   PosLat.Add(46.1409)
'   PosLng.Add(7.1188)
'   PosLat.Add(46.1400)
'   PosLng.Add(7.1201)
   
'   CenterLonLat.Lat = 46.1379
'   CenterLonLat.Lng = 7.1163

   CenterLonLat.Lat = NumberFormat(myLat, 1, 6)
   CenterLonLat.Lng = NumberFormat(myLon, 1, 6)

   ZoomLevel = 15
End Sub

'   a new Sub which will be called by the javascript once the Map and Marker have been created
Sub MapViewer_SetInitialized
   mapIsInitialized=True
End Sub

The WebView loads the javascript and after the Map and Marker have been created, the javascript calls the B4A Sub MapViewer_SetInitialized, the Sub sets the B4A variable mapIsInitialized to True.

Now when the GPS position changes the B4A code will only try to update the Map and Marker positions if mapIsInitialized is True.

Updated project is attached, you'll want to remove line 259:

B4X:
File.WriteString(File.DirRootExternal, "tudorf_map.htm", HtmlCode)

But while that line is in place you can grab a copy of the HtmlCode - handy for debugging stuff like this.
Copy/paste the tudorf_map.htm HtmlCode into Online JavaScript beautifier and you get a nicely formatted HTML page - makes it soo much easier to find little errors.

Martin.
 

Attachments

  • GoogleMapsWebView.zip
    10.9 KB · Views: 432
Upvote 0

aptinis7

Member
Licensed User
Longtime User
i need help for google places api!

:sign0085:I try to run googleMapsview...i dot get any errors but a white screen...Actually i try to use google places api.. i register to google i get tha api key.. but i dont know how to integrate B4A code with the google places api...i try to change the androidmanifest.xml file.. but unfortunately nothing goes well. It would be help full to have a tutorial with autocomplete input text box... i look forward to seing answer from you!!
 
Upvote 0

warwound

Expert
Licensed User
Longtime User
:sign0085:I try to run googleMapsview...i dot get any errors but a white screen...Actually i try to use google places api.. i register to google i get tha api key.. but i dont know how to integrate B4A code with the google places api...i try to change the androidmanifest.xml file.. but unfortunately nothing goes well. It would be help full to have a tutorial with autocomplete input text box... i look forward to seing answer from you!!

You really ought to start a new thread for your question.

But first can i ask if you have successfully got the Google Map you have created to display in a desktop browser?
Get your map and access to Google Places API working on a desktop browser first - you'll find it much easier to debug - and once it's working look at getting it to work in a B4A WebView.

Desktop browsers generally have debugging tools built in or available as add-ons and they often show you in a moment where an error has occurred - you could take hours trying to find the same error if you try to get the same code working in a B4A WebView.

Martin.
 
Upvote 0

tudorf

Active Member
Licensed User
Longtime User
Thank you Martin. I hope I can testl it tonight. I think I have a few more questions later.

Martin
 
Upvote 0

tudorf

Active Member
Licensed User
Longtime User
Thank you. The programm ist OK. I have added a variable for switch Zoom or no-Zoom. Change with a Button. The Program works.
function locationChanged(latitude, longitude, CenterZoom)
{var latLng=new google.maps.LatLng(latitude, longitude);
markerc.setPosition(latLng);
if(CenterZoom==true)
{map.panTo(latLng);
}}
Martin
 
Upvote 0
Top