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:
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
]