Android Question GMaps zoom

clooney48

Active Member
Licensed User
Longtime User
Is it possible to define the zoom level when I show markers in GMaps? For example in this part of the code or is "gmap.CameraPosition.Zoom" sth. different?
B4X:
If i > 0 Then
              Dim cp As CameraPosition
              cp.Initialize(Lat1, Lon1, gmap.CameraPosition.Zoom)
              gmap.AnimateCamera(cp)
End If
 

warwound

Expert
Licensed User
Longtime User
Do you want to pan and zoom the map to fit the bounds of your markers?
If so then look at the GoogleMapsExtras method:
AnimateToBounds (GoogleMap1 As GoogleMap, LatLngBounds1 As LatLngBounds, Padding As Int)
And the LatLngBuilder object.

Martin.
 
Upvote 0

clooney48

Active Member
Licensed User
Longtime User
The point is that when GMaps is opened now I see all the world but my markers are only in Europe. So I would like to zoom to Europe.
 
Upvote 0

clooney48

Active Member
Licensed User
Longtime User
Martin, thanks for your hint. I found it with this code:
B4X:
  Dim CameraPosition1 As CameraPosition
  CameraPosition1.Initialize(51.517900, -0.096614, 17)
  GoogleMap1.AnimateCamera(CameraPosition1)
 
Upvote 0

warwound

Expert
Licensed User
Longtime User
A more elegant solution would be something like this:

B4X:
Dim LatLngBoundsBuilder1 As LatLngBoundsBuilder
LatLngBoundsBuilder1.Initialize

Marker1=GoogleMap1.AddMarker(aLat, aLon, "Foobar")
LatLngBoundsBuilder1.Include(Marker1.Position)
     
Marker2=GoogleMap1.AddMarker(aLat2, aLon2, "Foobar2")
LatLngBoundsBuilder1.Include(Marker2.Position)

'   create more Markers and Include each Marker Position in the LatLngBoundsBuilder

Dim MarkerBounds As LatLngBounds=LatLngBoundsBuilder1.Build
GoogleMapsExtras1.AnimateToBounds(GoogleMap1, MarkerBounds, 128)

As you create each Marker add it's LatLng Position to a LatLngBoundBuilder.
Once you've created all your Markers, you get a LatLngBounds from the LatLngBoundBuilder which represents the area of the earth that your Markers cover.

Pass the LatLngBounds to the AnimateToBounds method and the map will adjust it's zoom level and center to fully display all of your Markers.
The 128 parameter is a 'padding' parameter - the map will adjust pan and zoom and then pad the area around your Markers by 128 pixels.

Martin.
 
Upvote 0

clooney48

Active Member
Licensed User
Longtime User
Hi Martin!

There is one question left for me: I have a loop to collect all the markers. It is not clear for me how to do it with your code.
Here is roughly what I mean:
B4X:
Dim LatLngBoundsBuilder1 As LatLngBoundsBuilder
LatLngBoundsBuilder1.Initialize

For i = 0 To cursor1.RowCount - 1
Dim Mark, MarkPos, j
j = i+1
Mark = "Marker" & j
MarkPos = Mark & ".Position"
Mark=GoogleMap1.AddMarker(aLat, aLon, "Foobar")
LatLngBoundsBuilder1.Include(MarkPos) '< at least this does not work
   
Next
'  create more Markers and Include each Marker Position in the LatLngBoundsBuilder

Dim MarkerBounds As LatLngBounds=LatLngBoundsBuilder1.Build
GoogleMapsExtras1.AnimateToBounds(GoogleMap1, MarkerBounds, 128)
 
Upvote 0

warwound

Expert
Licensed User
Longtime User
But look at the code you posted:

B4X:
Dim LatLngBoundsBuilder1 As LatLngBoundsBuilder
LatLngBoundsBuilder1.Initialize

For i = 0 To cursor1.RowCount - 1
Dim Mark, MarkPos, j
j = i+1
Mark = "Marker" & j
MarkPos = Mark & ".Position"
Mark=GoogleMap1.AddMarker(aLat, aLon, "Foobar")
LatLngBoundsBuilder1.Include(MarkPos) '< at least this does not work
  
Next
'  create more Markers and Include each Marker Position in the LatLngBoundsBuilder

Dim MarkerBounds As LatLngBounds=LatLngBoundsBuilder1.Build
GoogleMapsExtras1.AnimateToBounds(GoogleMap1, MarkerBounds, 128)

Mark is Dim'd as what type of object? - You have specified no object type.
B4A defaults (i think) to a String type where no type is specified.
Does that prevent the code from working...

Try this:

B4X:
Dim LatLngBoundsBuilder1 As LatLngBoundsBuilder
LatLngBoundsBuilder1.Initialize

For i = 0 To cursor1.RowCount - 1
Dim Mark As Marker ' explicitly define Mark as a Marker type
'   presumably you'll replace aLat and aLon with values from your Cursor
Mark=GoogleMap1.AddMarker(aLat, aLon, "Foobar")
LatLngBoundsBuilder1.Include(Mark.Position)
  
Next

Dim MarkerBounds As LatLngBounds=LatLngBoundsBuilder1.Build
GoogleMapsExtras1.AnimateToBounds(GoogleMap1, MarkerBounds, 128)

If the code fails then post the exception from the log.

Martin.
 
Upvote 0

clooney48

Active Member
Licensed User
Longtime User
Hier is the test code I use. Enclosed the error msg:
B4X:
    Dim LatLngBoundsBuilder1 As LatLngBoundsBuilder
    Dim GoogleMapsExtras1 As GoogleMapsExtras
    Dim j
    Dim LatLngBoundsBuilder1 As LatLngBoundsBuilder
    Dim GoogleMap1 As GoogleMap
    Dim Mark As Marker ' explicitly define Mark as a Marker type

    LatLngBoundsBuilder1.Initialize

For i = 0 To cursor1.RowCount - 1
    cursor1.Position = i
    Lat1 = cursor1.GetString("Lat")
    Lon1 = cursor1.GetString("Lon")
    Poi1 = cursor1.GetString("Name")
           
    j = i + 1
    Mark = "Marker" & j   '<< here stops the code because of type of 'Mark'
    If Poi1 <> "" Then Mark=GoogleMap1.AddMarker(Lat1, Lon1, Poi1)
    LatLngBoundsBuilder1.Include(Mark.Position)
 
Next

Dim MarkerBounds As LatLngBounds=LatLngBoundsBuilder1.Build
GoogleMapsExtras1.AnimateToBounds(GoogleMap1, MarkerBounds, 128)
 

Attachments

  • error.png
    error.png
    22.1 KB · Views: 541
Upvote 0

warwound

Expert
Licensed User
Longtime User
Yes you're not declaring Mark to be of Marker type, it defaults to a String type.
That'll work in some code but not all code.

So the error tells you that you're passing a String type when a Marker type is required.

If you explicitly Dim your Marker variable as a Marker type you won't get this error.
Eg:

B4X:
Dim Mark
' Mark is a String type

B4X:
Dim Mark As Marker
' Mark is a Marker type


Martin.
 
Upvote 0

warwound

Expert
Licensed User
Longtime User
I can only guess that after defining Mark as Marker, when you then assign it a String value it then becomes a String type.

B4X:
Mark = "Marker" & j  '<< here stops the code because of type of 'Mark'

Define a seperate variable wherever you need a seperate variable, don't try and reuse a Marker instance as a String and then try to use the same instance as a Marker.

B4X:
Dim LatLngBoundsBuilder1 As LatLngBoundsBuilder
  Dim GoogleMapsExtras1 As GoogleMapsExtras
  Dim i As Int
  Dim j As Int
  Dim LatLngBoundsBuilder1 As LatLngBoundsBuilder
  Dim GoogleMap1 As GoogleMap
  Dim Mark As Marker
  Dim AString As String

  LatLngBoundsBuilder1.Initialize

For i = 0 To cursor1.RowCount - 1
  cursor1.Position = i
  Lat1 = cursor1.GetString("Lat")
  Lon1 = cursor1.GetString("Lon")
  Poi1 = cursor1.GetString("Name")
   
  j = i + 1
  AString = "Marker" & j
  If Poi1 <> "" Then Mark=GoogleMap1.AddMarker(Lat1, Lon1, Poi1)
  LatLngBoundsBuilder1.Include(Mark.Position)
Next

Dim MarkerBounds As LatLngBounds=LatLngBoundsBuilder1.Build
GoogleMapsExtras1.AnimateToBounds(GoogleMap1, MarkerBounds, 128)

Martin.
 
Upvote 0

clooney48

Active Member
Licensed User
Longtime User
Martin,
- for what do you use now "AString"?
- how have I to initialize GoogleMap here:
B4X:
If Poi1 <> "" Then Mark=GoogleMap1.AddMarker(Lat1, Lon1, Poi1)
java.lang.RuntimeException: Object should first be initialized (GoogleMap).
 
Upvote 0

warwound

Expert
Licensed User
Longtime User
I just created the new variable AString so you could see that by not assigning a String value to Mark you would have no problem with object types.
If you don't need that String value then delete the line.

You need to look at your MapFragment Ready event Sub - this is where you can get a reference to the GoogleMap object.
Get a global reference in the Ready Sub and you can then use that reference in other Subs.

Martin.
 
Upvote 0

dibesw

Active Member
Licensed User
Longtime User
HI,
I am trying LatLngBounds and I have a question; this is the code:

B4X:
Sub display_mappa_Click
    MapPanel.Initialize("")
    Activity.AddView(MapPanel, 30%x, 0, 70%x-1dip, 90%y)
    If mFragment.IsGooglePlayServicesAvailable = False Then
      ToastMessageShow("Google Play services not available.", True)
    Else
      mFragment.Initialize("Map", MapPanel)
    End If
End Sub
Sub Map_Ready
  Dim LatLngBoundsBuilder1 As LatLngBoundsBuilder
  LatLngBoundsBuilder1.Initialize
  gmap = mFragment.GetMap
  If gmap.IsInitialized = False Then
      ToastMessageShow("Error initializing map.", True)
  Else
      Dim i As Int
      For i = 0 To listaweb.Size - 1
        Dim Marker1 As Marker
        Dim P As Ptype
        P = listaweb.Get(i)
        Marker1=gmap.AddMarker(P.latit, P.longi, "Marker #"&i)
        LatLngBoundsBuilder1.Include(Marker1.Position)
        Marker1.Draggable=True
      Next
      Dim cp As CameraPosition
      cp.Initialize(41.8767711, 12.5415491, 15)
      gmap.MoveCamera(cp)
  End If
  Msgbox("WAIT!!!","")
  Dim MarkerBounds As LatLngBounds=LatLngBoundsBuilder1.Build
  gmapEX.AnimateToBounds(gmap, MarkerBounds, 128)
End Sub

I had to insert WAIT!!! istruction because give this error:

ba43.jpg


pheraps gmap.MoveCamera takes time for execution, then gmapEX.AnimateToBounds not found yet gmap.
How do you solve this?
THANKS!
Amedeo
 
Upvote 0

warwound

Expert
Licensed User
Longtime User
At the time that you call AnimateToBounds your GoogleMap has not yet been fully rendered and has dimensions of zero pixels square (i think).

Look at the GoogleMapsExtras AnimateToBounds2 method:

AnimateToBounds2 (GoogleMap1 As GoogleMap, LatLngBounds1 As LatLngBounds, Width As Int, Height As Int, Padding As Int)
Adjust and animate the map center and zoom level so that it fully contains the LatLngBounds.
Padding is defined in units of pixels.
Width and Height should define the dimensions of the GoogleMap.

This method anticipates the GoogleMap not yet being rendered and allows you to define the dimensions of the GoogleMap.
The library then uses your supplied width and height values instead of the GoogleMap's current zero by zero dimensions and everything should work as desired...

Martin.
 
Upvote 0
Top