Android Question Selecting a Survey Point on Google Maps

Terradrones

Active Member
Licensed User
Hi All

I have coordinate points plotted on Google Maps. I convert the coordinates to Lats & longs and then plot them on the Google Map. The conversion is correct, as the points are plotted in the correct position. I use the EPSG database to convert them.

The next thing that I want to do is to tap on a point and the name of the selected point comes up. The program then goes to another Panel, where the User can stake the selected point.

My problem is that sometimes my routine works and other times not. Why?

Here is my code:
B4X:
[/

Sub GetPoints
    ProgressDialogShow2("Loading Points...",False)
    Sleep(10)
    Try
        AveY = 0
        AveX = 0
        Try
            Dim Rs As ResultSet
            If CGlobals.CoordCode = 1 Then
                Rs = CGlobals.sql1.ExecQuery("SELECT Name, East, North, Elevation, Description FROM SCoords")
            Else If CGlobals.CoordCode = 2 Then
                Rs = CGlobals.sql1.ExecQuery("SELECT Name, East, North, Elevation, Description FROM GCoords")
            Else
                Rs = CGlobals.sql1.ExecQuery("SELECT Name, East, North, Elevation, Description FROM Coords")
            End If
        Catch
            Log(LastException)
        End Try

        i = 0
        PointList.Initialize
        Do While Rs.NextRow
            Dim row(4) As Object
            row(0) = Rs.GetString("Name")
            row(1) = NumberFormat2(Rs.GetDouble("East"), 1, 3, 3, False)
            row(2) = NumberFormat2(Rs.GetDouble("North"), 1, 3, 3, False)
            row(3) = NumberFormat2(Rs.GetDouble("Elevation"), 1, 3, 3, False)
            Geo.get_point_From_local(row(1), row(2))
            
            If Engine.Lat <> "0" And Engine.Lon <> "0" Then
                ' Draw the circle
                 Dim pt As Map
                pt.Initialize
                pt.Put("Name", row(0))
                pt.Put("Lat", Engine.Lat)
                pt.Put("Lon", Engine.Lon)
                pt.Put("East", row(1))
                pt.Put("North",row(2))
                pt.Put("Ele", row(3))
                PointList.Add(pt)
                i = i + 1
                AveY = AveY + row(1)
                AveX = AveX + row(2)
            End If
        Loop
        Rs.Close
        
        If i > 0 Then
            AveY = AveY / i
            AveX = AveX / i
        End If
        
        If (AveY <> 0 Or AveX <> 0) Then
            ' Zoom in to center of points
            CenterMap
        End If
'        FirstDraw=False
        PlotPoints
    Catch
        Log(LastException)
    End Try
    ProgressDialogHide
End Sub

Sub PlotPoints
    Try
        ProgressDialogShow2("Plotting Data...", False)
        Sleep(10)
        Gmap.Clear

        ' Initialize polyline for alignment
        Aline = Gmap.AddPolyline
        Apoints.Initialize
        LSpoints.Initialize
        RSpoints.Initialize

        Aline.Color = Colors.Red
        Aline.Geodesic = True
        Aline.Visible = True
        Aline.Width = 1

        LSline = Gmap.AddPolyline  
        LSline.Color = Colors.Red
        LSline.Geodesic = True
        LSline.Visible = True
        LSline.Width = 1

        RSline = Gmap.AddPolyline  
        RSline.Color = Colors.Red
        RSline.Geodesic = True
        RSline.Visible = True
        RSline.Width = 1

        
        Co.Initialize
        Co.StrokeWidth(2)
        CircleList.Initialize
        closestPoint.Initialize
        CircleData.Initialize

        ' Plot Benchmarks
        For Each pt As Map In PointList
            Dim name As String = pt.Get("Name")
            Dim lat As Double = pt.Get("Lat")
            Dim lon As Double = pt.Get("Lon")
            Dim Ele As Double = pt.Get("Ele")

            If lat <> 0 And lon <> 0 Then
                Dim Circle As JavaObject = AddCircle(Gmap, lat, lon, CircleSize.SelectedItem, xui.Color_Red, xui.Color_Transparent, True)
                Circle.RunMethod("setTag", Array(pt))
                Dim CircleData As Map
                CircleData.Initialize
                CircleData.Put("Circle", Circle)
                CircleData.Put("Radius", CircleSize.SelectedItem)
                CircleList.Add(CircleData)
            If ShowFeature.Checked Then
                Dim LatLngName As LatLng
                LatLngName.Initialize(lat + 0.000005, lon)
                DrawTextOnMap(Gmap, LatLngName, name, TextSize.SelectedIndex*2, 0)
            End If

            If ShowElev.Checked Then
                Dim LatLngElev As LatLng
                LatLngElev.Initialize(lat - 0.00001, lon)
                DrawTextOnMap(Gmap, LatLngElev, Ele, TextSize.SelectedIndex*2, 0)
            End If
            End If
        Next

        ' Plot Alignment as Polyline
        If PlotRoad = 1 Then
            Dim i As Int = 0
            Try
                Apoints.Initialize
                For Each pa As Map In Engine.AlignList
                    Dim lat As Double = pa.Get("Lat")
                    Dim lon As Double = pa.Get("Lon")
                    Dim name As String = pa.Get("Name") 

                    If lat <> 0 And lon <> 0 Then
                        Dim pt1 As LatLng
                        pt1.Initialize(lat, lon)
                        Apoints.Add(pt1)
                        i = i + 1
                        If i = 5 Then
                            Dim LatLngName As LatLng
                            LatLngName.Initialize(lat, lon)
                            DrawTextOnMap(Gmap, LatLngName, name, TextSize.SelectedIndex * 2, 0)
                            i = 0
                        End If
                    End If
                Next
                Aline.Points = Apoints
            Catch
                Log(LastException)
            End Try
            
            'Left SBP
            Try
            LSpoints.Initialize
            For Each pa As Map In Engine.LSList
                Dim lat As Double = pa.Get("Lat")
                Dim lon As Double = pa.Get("Lon")
                If lat <> 0 And lon <> 0 Then
                    Dim pt1 As LatLng
                    pt1.Initialize(lat, lon)
                    LSpoints.Add(pt1)
                End If
            Next
            LSline.Points = LSpoints
                    
    '        'Right SBP
            RSpoints.Initialize
            For Each pa As Map In Engine.RSList
                Dim lat As Double = pa.Get("Lat")
                Dim lon As Double = pa.Get("Lon")
                If lat <> 0 And lon <> 0 Then
                    Dim pt1 As LatLng
                    pt1.Initialize(lat, lon)
                    RSpoints.Add(pt1)
                End If
            Next
            RSline.Points = RSpoints
        Catch
            Log(LastException)
        End Try
    End If

    Catch
        Log(LastException)
    End Try
    ProgressDialogHide
End Sub

Sub MapReady
    Gmap = CoordMap.GetMap
    Dim jo As JavaObject = Gmap
    Dim uiSettings As JavaObject = jo.RunMethod("getUiSettings", Null)
    uiSettings.RunMethod("setZoomGesturesEnabled", Array(True))
    uiSettings.RunMethod("setScrollGesturesEnabled", Array(True))
    uiSettings.RunMethod("setRotateGesturesEnabled", Array(True))
    uiSettings.RunMethod("setTiltGesturesEnabled", Array(True))
    Sleep(500)
    AddMapClickListener(Gmap) 'This activates the click listener
'    AddCicleListener(Gmap)
End Sub

Private Sub AddCircle (Map As GoogleMap, Latitude As Double, Longitude As Double, RadiusMeters As Double, _
    FillColor As Int, StrokeColor As Int, Clickable As Boolean) As JavaObject
    Dim Opt10 As JavaObject
    Opt10.InitializeNewInstance("com/google/android/gms/maps/model/CircleOptions".Replace("/", "."), Null)
    Dim ll As LatLng
    ll.Initialize(Latitude, Longitude)
    Opt10.RunMethod("center", Array(ll))
    Opt10.RunMethod("radius", Array(RadiusMeters))
    Opt10.RunMethod("fillColor", Array(FillColor))
    Opt10.RunMethod("strokeColor", Array(StrokeColor))
    Opt10.RunMethod("clickable", Array(Clickable))
    Return Map.As(JavaObject).RunMethod("addCircle", Array(Opt10))
End Sub

Private Sub AddMapClickListener(Map As GoogleMap)
    Dim event As Object = Map.As(JavaObject).CreateEventFromUI("com.google.android.gms.maps.GoogleMap$OnMapClickListener", "MapClick", Null)
    Map.As(JavaObject).RunMethod("setOnMapClickListener", Array(event))
End Sub

Private Sub MapClick_Event(MethodName As String, Args() As Object) As Object
    If MethodName = "onMapClick" Then
        Dim clickedLatLng As LatLng = Args(0)
        Dim clickedLat As Double = clickedLatLng.Latitude
        Dim clickedLon As Double = clickedLatLng.Longitude

        ' Reset previous selection if exists
        If LastSelectedCircle.IsInitialized And LastSelectedCenter.IsInitialized Then
            Dim joCircle As JavaObject = LastSelectedCircle
            joCircle.RunMethod("remove", Null)
            Dim resetCircle As JavaObject = AddCircle(Gmap, LastSelectedCenter.Latitude, LastSelectedCenter.Longitude, LastSelectedRadius, xui.Color_Red, xui.Color_Transparent, True)
            resetCircle.RunMethod("setTag", Array(LastSelectedTag))
        End If

        ' Find nearest circle within threshold
        Dim result As Map = FindClosestCircle(clickedLat, clickedLon, 50) ' 20 meters threshold

        If result.Size > 0 Then
            Dim closestCircle As JavaObject = result.Get("Circle")
            Dim closestCenter As LatLng = result.Get("Center")
            Dim closestRadius As Double = result.Get("Radius")
            Dim closestTag1 As Map = result.Get("Tag")

            ' Highlight new selection
            closestCircle.RunMethod("remove", Null)
            Dim newCircle As JavaObject = AddCircle(Gmap, closestCenter.Latitude, closestCenter.Longitude, closestRadius, xui.Color_Blue, xui.Color_ARGB(50, 0, 0, 255), True)
            newCircle.RunMethod("setTag", Array(closestTag1))

            LastSelectedCircle = newCircle
            LastSelectedRadius = closestRadius
            LastSelectedCenter = closestCenter
            LastSelectedTag = closestTag1

            ' Update global coordinates
            If closestTag1.IsInitialized Then
                Try
                    CGlobals.Y5 = closestTag1.Get("East")
                    CGlobals.X5 = closestTag1.Get("North")
                    CGlobals.Z5 = closestTag1.Get("Ele")
                    YCoord.Text = CGlobals.Y5
                    XCoord.Text = CGlobals.X5
                    If CadType <> 40 And CadType <> 41 And CadType <> 50 And CadType <> 20 Then
                        Label15.Text = closestTag1.Get("Name")
                        Label29.Text = Label15.Text
                    Else
                        PntName = closestTag1.Get("Name")
                    End If
                    If CadType = 40 Or CadType = 41 Then
                        If CadType = 41 Then
                            Engine.Join_Polar(CGlobals.Y4, CGlobals.X4, CGlobals.Y5, CGlobals.X5, 1)
                            Engine.Convert_Angle(Engine.CB, 2)
                            Msgbox2Async("From: " & PntName1 & CRLF & "To: " & PntName & CRLF & "Dist: " & NumberFormat2(Engine.CD, 1, 3, 3, False) & CRLF & "Bear: " & NumberFormat2(Engine.ZCK, 1, 3, 3, False), "Join Calc", "OK", "", "", Null, False)
                            CadType = 40
                        Else If CadType = 40 Then
                            CGlobals.Y4 = CGlobals.Y5
                            CGlobals.X4 = CGlobals.X5
                            CGlobals.Z4 = CGlobals.Z5
                            PntName1 = PntName
                            CadType = 41
                        End If
                    Else If CadType = 50 Then
                        Msgbox2Async("Name: " & PntName & CRLF & "East: " & NumberFormat2(CGlobals.Y5, 1, 3, 3, False) & CRLF & "North: " & NumberFormat2(CGlobals.X5, 1, 3, 3, False) & CRLF & "Elev: " & NumberFormat2(CGlobals.Z5, 1, 3, 3, False), "Coord Info", "OK", "", "", Null, False)
                    Else If CadType = 20 Then
                        'RemovePointByName(PntName)
                    End If
                Catch
                    Log("Error extracting tag data: " & LastException)
                End Try
            End If
        Else
            Log("No valid circle found near clicked location.")
            ToastMessageShow("No nearby point found.", False)
        End If
    End If
    Return Null
End Sub

Private Sub CalculateDistance(lat1 As Double, lon1 As Double, lat2 As Double, lon2 As Double) As Double
    Dim R As Double = 6371000 ' Earth radius in meters
    Dim dLat As Double = (lat2 - lat1) * cPI / 180
    Dim dLon As Double = (lon2 - lon1) * cPI / 180
    Dim a As Double = Power(Sin(dLat / 2), 2) + Cos(lat1 * cPI / 180) * Cos(lat2 * cPI / 180) * Power(Sin(dLon / 2), 2)
    Dim c As Double = 2 * ATan2(Sqrt(a), Sqrt(1 - a))
    Return R * c
End Sub

Private Sub FindClosestCircle(clickedLat As Double, clickedLon As Double, maxDistanceMeters As Double) As Map
    Dim result As Map
    result.Initialize

    Dim minDistance As Double = 99999999
    Dim closestCircle As JavaObject
    Dim closestCenter As LatLng
    Dim closestRadius As Double
    Dim closestTag As Map
    closestTag.Initialize

    For Each CircleData As Map In CircleList
        Dim c As JavaObject = CircleData.Get("Circle")
        Dim center As LatLng = c.RunMethod("getCenter", Null)
        If center.IsInitialized Then
            Dim Dist As Double = CalculateDistance(clickedLat, clickedLon, center.Latitude, center.Longitude)
            If Dist < minDistance Then
                minDistance = Dist
                closestCircle = c
                closestCenter = center
                closestRadius = CircleData.Get("Radius")

                Dim tagObj As Object = c.RunMethod("getTag", Null)
                If tagObj Is Map Then
                    closestTag = tagObj
                End If
            End If
        End If
    Next

    If minDistance <= maxDistanceMeters And closestCircle.IsInitialized Then
        result.Put("Circle", closestCircle)
        result.Put("Center", closestCenter)
        result.Put("Radius", closestRadius)
        result.Put("Tag", closestTag)
        result.Put("Distance", minDistance)
    End If

    Return result
End Sub
]
 
Cookies are required to use this site. You must accept them to continue using the site. Learn more…