求助:基于Google Maps API实现当前位置与三个点位的最近距离筛选
Hey there! Let's solve this problem of finding the nearest point from your three LatLngs to the user's current location. Here's a straightforward, robust implementation:
Step 1: Add Dependencies (Optional but Recommended)
Google provides a handy utility library to calculate distances between geographic points accurately. Add this to your app-level build.gradle (Module level):
implementation 'com.google.maps.android:android-maps-utils:2.2.0'
This gives us access to SphericalUtil.computeDistanceBetween(), which calculates the distance between two LatLng points in meters.
Step 2: Fix Initial Setup
First, make sure you add your three LatLng points to the arrayList—your original code creates them but doesn't populate the list:
ArrayList<LatLng> arrayList = new ArrayList<>(); LatLng near = new LatLng(33.549232, 73.125256); LatLng pass = new LatLng(33.549844, 73.125849); LatLng qareeb = new LatLng(33.549603, 73.124201); // Add points to the list arrayList.add(near); arrayList.add(pass); arrayList.add(qareeb);
Step 3: Implement the Closest Point Calculation
Create a helper method to compute the nearest LatLng to the current location:
private LatLng findClosestLatLng(LatLng currentLocation, List<LatLng> points) { if (currentLocation == null || points == null || points.isEmpty()) { return null; // Handle null/empty cases to avoid crashes } LatLng closestPoint = null; double smallestDistance = Double.MAX_VALUE; for (LatLng point : points) { // Calculate distance between current location and the point (in meters) double distance = SphericalUtil.computeDistanceBetween(currentLocation, point); // Update closest point if this distance is smaller than the current smallest if (distance < smallestDistance) { smallestDistance = distance; closestPoint = point; } } return closestPoint; }
Step 4: Integrate with Your onMapReady Method
Now use this helper in your onMapReady method. I've also cleaned up redundant camera operations from your original code:
public void onMapReady(GoogleMap googleMap) { mMap = googleMap; // First, ensure currentLocation is not null (handle location permissions/fetching first!) if (currentLocation == null) { // Show a toast or handle the case where location isn't available yet Toast.makeText(getContext(), "Current location not available", Toast.LENGTH_SHORT).show(); return; } // Add all markers first for (LatLng point : arrayList) { mMap.addMarker(new MarkerOptions() .position(point) .title("Marker") .snippet("and snippet") .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_ORANGE))); } // Add current location marker MarkerOptions currentMarker = new MarkerOptions() .position(currentLocation) .title("Main Yahan hn"); mMap.addMarker(currentMarker); // Find the closest point LatLng closestPoint = findClosestLatLng(currentLocation, arrayList); if (closestPoint != null) { // Animate camera to the closest point with smooth zoom mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(closestPoint, 15), 2000, null); // Optional: Highlight the closest marker (e.g., change its color) // You can track markers in a list when adding them, then update the closest one's icon later } }
Key Notes:
- Location Permissions: Make sure you've requested and granted
ACCESS_FINE_LOCATIONorACCESS_COARSE_LOCATIONpermissions before fetching the current location. - Null Safety: Always check if
currentLocationis not null—location fetching can take time, so you might need to listen for location updates usingFusedLocationProviderClientif you haven't already. - Alternative Without Utility Library: If you don't want to use the maps utils library, you can implement the Haversine formula manually to calculate distance:
private double calculateDistance(LatLng latLng1, LatLng latLng2) { final int R = 6371; // Radius of the earth in km double latDistance = Math.toRadians(latLng2.latitude - latLng1.latitude); double lonDistance = Math.toRadians(latLng2.longitude - latLng1.longitude); double a = Math.sin(latDistance / 2) * Math.sin(latDistance / 2) + Math.cos(Math.toRadians(latLng1.latitude)) * Math.cos(Math.toRadians(latLng2.latitude)) * Math.sin(lonDistance / 2) * Math.sin(lonDistance / 2); double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); double distance = R * c * 1000; // Convert to meters return distance; }
Just replace SphericalUtil.computeDistanceBetween() with this method in the helper function.
内容的提问来源于stack exchange,提问作者Sofix

