Android Question Cluster marker maps

Serge Nova

Member
Hello everyone, here is my code:

B4X:
#Region  Project Attributes
    #ApplicationLabel: Marker Clustering
    #VersionCode: 1
    #VersionName: 1.0
#End Region

#AdditionalJar: google-play-services
#AdditionalJar: android-maps-utils-3.8.2-javadoc

Sub Process_Globals
    Private MapFragment As MapFragment
    Private GoogleMap As GoogleMap
End Sub

Sub Globals
    Private MarkerClusterManager As JavaObject
End Sub

Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout("main")
    MapFragment.Initialize("MapFragment", 1)
    Activity.AddView(MapFragment, 0, 0, 100%x, 100%y)
End Sub

Sub MapFragment_Ready
    GoogleMap = MapFragment.GetMap
    InitializeClusterManager
    AddMarkersToCluster
End Sub

Sub InitializeClusterManager
    MarkerClusterManager = CreateClusterManager
End Sub

Sub CreateClusterManager As JavaObject
    Dim context As JavaObject
    context.InitializeContext
    Dim jo As JavaObject
    jo.InitializeNewInstance("com.google.maps.android.clustering.ClusterManager", Array(context, GoogleMap))
    Return jo
End Sub

Sub AddMarkersToCluster
    For i = 1 To 100
        Dim position As LatLng
        position.Initialize(Rnd(-90, 90), Rnd(-180, 180))
        Dim marker As JavaObject
        marker.InitializeNewInstance("com.google.maps.android.clustering.ClusterItem", Null)
        marker.SetField("mPosition", position)
        MarkerClusterManager.RunMethod("addItem", Array(marker))
    Next
    MarkerClusterManager.RunMethod("cluster", Null)
Fin Sub

but I get this error:

B4X:
java.lang.RuntimeException: java.lang.ClassNotFoundException: com.google.maps$android$clustering$ClusterManager

    at anywheresoftware.b4a.keywords.Common$13.run(Common.java:1719)

    at android.os.Handler.handleCallback(Handler.java:938)

    at android.os.Handler.dispatchMessage(Handler.java:99)

    at android.os.Looper.loopOnce(Looper.java:201)

    at android.os.Looper.loop(Looper.java:288)

    at android.app.ActivityThread.main(ActivityThread.java:7842)

    at java.lang.reflect.Method.invoke(Native Method)

    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)

    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)

Caused by: java.lang.ClassNotFoundException: com.google.maps$android$clustering$ClusterManager

    at anywheresoftware.b4j.object.JavaObject.getCorrectClassName(JavaObject.java:289)

    at anywheresoftware.b4j.object.JavaObject.InitializeNewInstance(JavaObject.java:84)

    at b4a.identity.b4xmainpage$ResumableSub_load.resume(b4xmainpage.java:352)

    at anywheresoftware.b4a.keywords.Common$13.run(Common.java:1717)

    ... 8 more

Some suggestions?
 

TILogistic

Expert
Licensed User
Longtime User
Upvote 0

salvadoro

Member
Licensed User
Longtime User
Hi I have made progress and I no longer have errors with the initialization of the clustermanager.

B4X:
#AdditionalJar: android-maps-utils-3.8.2.aar

Sub Process_Globals
    Private rp As RuntimePermissions
    Private clusterManager As JavaObject
End Sub

Sub Globals
    Private gmap As GoogleMap
    Private MapFragment1 As MapFragment
    Private joMap As JavaObject
End Sub

Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout("1")
    Wait For MapFragment1_Ready
    gmap = MapFragment1.GetMap
    rp.CheckAndRequest(rp.PERMISSION_ACCESS_FINE_LOCATION)
    Wait For Activity_PermissionResult (Permission As String, Result As Boolean)
    If Result Then
        gmap.MyLocationEnabled = True
        CreateClusterManager
    Else
         Log("no permission!")
    End If
End Sub

Sub CreateClusterManager As JavaObject
    Log("CreateClusterManager")
    joMap = gmap
    ' Move map to the position and zoom required
    Dim cp As CameraPosition
    cp.Initialize(19.0605903,-98.2979058, 8)
    gmap.MoveCamera(cp)

    ' Initialize clustermanager
    clusterManager.InitializeNewInstance("com.google.maps.android.clustering.ClusterManager", Array(GetContext, joMap))

    ' Asociate clustermanager with the map
    joMap.RunMethod("setOnCameraIdleListener", Array(clusterManager))
    joMap.RunMethod("setOnMarkerClickListener", Array(clusterManager))
    joMap.RunMethod("setOnInfoWindowClickListener", Array(clusterManager))

    'Create 10 markers
    Dim offset As Double
    Dim lat As Double = 19.0605903
    Dim lon As Double = -98.2979058
    For i = 1 To 10
        offset = i/60
        lat = lat + offset
        lon = lon + offset
        Dim Marker1 As Marker
        Marker1 = gmap.AddMarker(lat,lon,"Marker "& i)
        Dim item As JavaObject = Marker1
        clusterManager.RunMethod("addItem", Array(item))
    Next
   
    clusterManager.RunMethod("cluster",Null)

    Return clusterManager
End Sub

But now I have the next error could someone point me to the right way to add this marker to the cluster?


B4X:
Registro conectado a:  samsung SM-A546E
--------- beginning of main
*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create (first time) **
** Activity (main) Resume **
CreateClusterManager
Error occurred on line: 133 (Main)
java.lang.RuntimeException: Method: addItem not matched.
    at anywheresoftware.b4j.object.JavaObject.RunMethod(JavaObject.java:130)
    at b4a.identity.main._createclustermanager(main.java:565)
    at b4a.identity.main$ResumableSub_Activity_Create.resume(main.java:465)
    at anywheresoftware.b4a.shell.DebugResumableSub$DelegatableResumableSub.resumeAsUserSub(DebugResumableSub.java:48)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:351)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:157)
    at anywheresoftware.b4a.BA.raiseEvent(BA.java:201)
    at anywheresoftware.b4a.shell.DebugResumableSub$DelegatableResumableSub.resume(DebugResumableSub.java:43)
    at anywheresoftware.b4a.BA.checkAndRunWaitForEvent(BA.java:275)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:150)
    at anywheresoftware.b4a.BA$2.run(BA.java:395)
    at android.os.Handler.handleCallback(Handler.java:958)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loopOnce(Looper.java:230)
    at android.os.Looper.loop(Looper.java:319)
    at android.app.ActivityThread.main(ActivityThread.java:8919)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:578)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
java.lang.RuntimeException: Method: addItem not matched.
Based on the example java code
B4X:
 private void readItems() throws JSONException {
        InputStream inputStream = getResources().openRawResource(R.raw.radar_search);
        List<MyItem> items = new MyItemReader().read(inputStream);
        mClusterManager.addItems(items);
    }

the method in the clustermanager is
B4X:
manager.addItems(list)

Try to adapt and try again.
 
Upvote 0

Serge Nova

Member
Thank you very much for the help, it helped me a lot
 
Upvote 0

Serge Nova

Member
Thank you very much for the help @DonManfred, now I tell another problem that I don't really understand, the Java class is wrong to add?

B4X:
#AdditionalJar: android-maps-utils-3.8.2.aar

Sub Process_Globals
    Private GoogleMap As GoogleMap
End Sub

Sub Globals
    Private MapFragment As MapFragment
    Private MarkerClusterManager As JavaObject
    Private joMa As JavaObject
End Sub

Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout("Layout")
End Sub

Sub MapFragment_Ready
    GoogleMap = MapFragment.GetMap
    Sleep(500)
    InitializeClusterManager
    AddMarkers
End Sub

Sub InitializeClusterManager
    MarkerClusterManager = CreateClusterManager
    
    joMa = GoogleMap
    joMa.RunMethod("setOnCameraIdleListener", Array(MarkerClusterManager))
    joMa.RunMethod("setOnMarkerClickListener", Array(MarkerClusterManager))
End Sub

Sub CreateClusterManager As JavaObject
    Dim context As JavaObject
    context.InitializeContext
    Dim jo As JavaObject
    jo.InitializeNewInstance("com.google.maps.android.clustering.ClusterManager", Array(context, GoogleMap))
    Return jo
End Sub

Sub AddMarkers
    Dim items As List
    items.Initialize

    For i = 1 To 10
        Dim jo As JavaObject
        jo.InitializeNewInstance(Application.PackageName & ".MyItem", Array(LatLng(37.7749 + Rnd(0, 10) / 1000, -122.4194 + Rnd(0, 10) / 1000)))
        items.Add(jo)
    Next
    
    MarkerClusterManager.RunMethod("addItems", Array(items))
    MarkerClusterManager.RunMethod("cluster", Null)
End Sub

Sub LatLng(lat As Double, lng As Double) As JavaObject
    Dim jo As JavaObject
    jo.InitializeNewInstance("com.google.android.gms.maps.model.LatLng", Array(lat, lng))
    Return jo
End Sub

#If JAVA
import com.google.android.gms.maps.model.LatLng;
import com.google.maps.android.clustering.ClusterItem;

public class MyItem implements ClusterItem {
    private final LatLng position;
    private final String title;
    private final String snippet;

    public MyItem(double lat, double lng, String title, String snippet) {
        position = new LatLng(lat, lng);
        this.title = title;
        this.snippet = snippet;
    }
    
    @Override
    public LatLng getPosition() {
        return position;
    }
    
    @Override
    public String getTitle() {
        return title;
    }

    @Override
    public String getSnippet() {
        return snippet;
    }
    
    @Override
    public Float getZIndex() {
        return 0f;
    }
}
#End If

Here is the error I get:

B4X:
** Activity (main) Resume **
java.lang.RuntimeException: java.lang.ClassNotFoundException: marker$clustere$MyItem
    at anywheresoftware.b4a.keywords.Common$13.run(Common.java:1719)
    at android.os.Handler.handleCallback(Handler.java:938)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loopOnce(Looper.java:201)
    at android.os.Looper.loop(Looper.java:288)
    at android.app.ActivityThread.main(ActivityThread.java:7842)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
Caused by: java.lang.ClassNotFoundException: marker$clustere$MyItem

Any idea please?
 
Upvote 0

salvadoro

Member
Licensed User
Longtime User

Hi Serge, I finally managed to make it work but I ended up making a library, and I call it in the following way to insert it either marker by marker or through a list

B4X:
    ' Agrega marcadores a la lista de clustering
    For i = 0 To 1000
        Dim lat As Double = Rnd(19.0000, 32.0000)
        Dim lon As Double = Rnd(-118.0000, -86.0000)
        Dim title As String = "Marcador " & i
        Dim snippet as String = "Marcador " & i
        Dim myItem As JavaObject
        myItem.InitializeNewInstance("mx.vdl.b4a.androidmapsutils.clustering.MyItem",Array(lat,lon,title,snippet))
        markerList.Add(myItem)
        
'        ' Agrega el marcador al administrador de clustering
'        mClusterManager.RunMethod("addItem", Array(myItem))
    Next

    ' Agrega la lista de marcadores al administrador de clustering
    mClusterManager.RunMethod("addItems", Array(markerList))

Maybe someone can help you to do this without make a library I don't known how.
 
Upvote 0

TILogistic

Expert
Licensed User
Longtime User
I used this library, but we decided to create our own with B4X code to have control.
For marker cluster management, we use circles and variables (Map and Lis) that contain the cluster and marker information, and we control the clicks on the circles (cluster) and the zoom levels, etc.
 
Upvote 0

Serge Nova

Member
Yes I can do it with this method.
To save time, can you give me an extract of your code on the zoom part?
 
Upvote 0
Cookies are required to use this site. You must accept them to continue using the site. Learn more…