Tracking in Geofence radious - android

I have Created application for geo fence.
I implement location listener which sends me current Lat and Long.
I have array of Lat Long and i created Geofence from this array.
I want to check that Current lat long are within my Geofence Region or not?
Code For Geofence:-
private void createGeofence(double latitude, double longitude, int radius,
String geofenceType, String title) {
Marker stopMarker = googleMap.addMarker(new MarkerOptions()
.draggable(true)
.position(new LatLng(latitude, longitude))
.title(title)
);
googleMap.addCircle(new CircleOptions()
.center(new LatLng(latitude, longitude)).radius(radius)
.fillColor(Color.parseColor("#B2A9F6")));
}
Lat Long from Listener:-
#Override
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
Lat=location.getLatitude();
Lng=location.getLongitude();
Geocoder geocoder;
List<Address> addresses;
geocoder = new Geocoder(this, Locale.getDefault());
try {
addresses = geocoder.getFromLocation(Lat, Lng, 1);
address = addresses.get(0).getAddressLine(0);
city = addresses.get(0).getAddressLine(1);
country = addresses.get(0).getAddressLine(2);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Lat Long is "+ Lat + " " + Lng);
}
Please help for this.

You could use the harvesine formula:
public static final double R = 6372.8; // In kilometers
public static double haversine(double lat1, double lon1, double lat2, double lon2) {
double dLat = Math.toRadians(lat2 - lat1);
double dLon = Math.toRadians(lon2 - lon1);
lat1 = Math.toRadians(lat1);
lat2 = Math.toRadians(lat2);
double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2);
double c = 2 * Math.asin(Math.sqrt(a));
return R * c;
}
That will give you the distance between the two locations. After that you could compare that distance with the geofence region radius to know if is inside the region.
Note: This distance will be in kilometers if your radius is on meters then just multiply the haversine method result with 1000 so that it's converted to meters.
Reference

Related

Calculate nearest location Google Map Android Studio

I know how to find the distance between two location on android studio google map but how to calculate which distance is the nearest one compering with 3 or 4 found location?
public void onDirectionFinderSuccess(List<Route> routes) {
progressDialog.dismiss();
polylinePaths = new ArrayList<>();
originMarkers = new ArrayList<>();
destinationMarkers = new ArrayList<>();
for (Route route : routes) {
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(route.startLocation, 16));
((TextView) findViewById(R.id.tvDuration)).setText(route.duration.text);
((TextView) findViewById(R.id.tvDistance)).setText(route.distance.text);
originMarkers.add(mMap.addMarker(new MarkerOptions()
.icon(BitmapDescriptorFactory.fromResource(R.drawable.start_blue))
.title(route.startAddress)
.position(route.startLocation)));
destinationMarkers.add(mMap.addMarker(new MarkerOptions()
.icon(BitmapDescriptorFactory.fromResource(R.drawable.end_green))
.title(route.endAddress)
.position(route.endLocation)));
PolylineOptions polylineOptions = new PolylineOptions().
geodesic(true).
color(Color.BLUE).
width(10);
for (int i = 0; i < route.points.size(); i++)
polylineOptions.add(route.points.get(i));
polylinePaths.add(mMap.addPolyline(polylineOptions));
}
}
If you want to calculate the distance,you can calculate like this way
private double caldistance(double lat1, double lon1, double lat2, double lon2) {
double theta = lon1 - lon2;
double dist = Math.sin(deg2rad(lat1)) * Math.sin(deg2rad(lat2)) + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.cos(deg2rad(theta));
dist = Math.acos(dist);
dist = rad2deg(dist);
dist = dist * 60 * 1.1515;
return (dist);
}
private double deg2rad(double deg) {
return (deg * Math.PI / 180.0);
}
private double rad2deg(double rad) {
return (rad * 180.0 / Math.PI);
}
Calculate the distance for all found locations and having smallest distance will be the nearest location.
public double distance(double lat1, double lat2, double lon1,
double lon2, double el1, double el2) {
final int R = 6371; // Radius of the earth
Double latDistance = Math.toRadians(lat2 - lat1);
Double lonDistance = Math.toRadians(lon2 - lon1);
Double a = Math.sin(latDistance / 2) * Math.sin(latDistance / 2)
+ Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2))
* 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
double height = el1 - el2;
distance = Math.pow(distance, 2) + Math.pow(height, 2);
return Math.sqrt(distance);
}
If you want to get all the nearest locations
Create two Locations like this:
Location source = new Location("");
Location destination = new Location("");
source.setLatitude(src_lat);
source.setLongitude(src_lng);
destination.setLatitude(dest_lat);
destination.setLongitude(dest_lng);
if(source.distanceTo(destination)<3000){ // 3000 meters = 3 km
// do something ...
}

Show closest result of a Geocoder on map

I've been stuck on the problem. i'm searching for Tesco stores in this geocoder. Is there anyway way of getting only the closest result of the geo.getFromLocationName?
private void setUpMap() throws IOException {
Geocoder geo = new Geocoder(getApplicationContext(), Locale.getDefault());
List<Address> addressList= geo.getFromLocationName("Tesco",1);
Address add = addressList.get(0);
String locality = add.getLocality();
double lat = addressList.get(0).getLatitude();
double lng = addressList.get(0).getLongitude();
mMap.addMarker(new MarkerOptions().position(new LatLng(lat,lng)).title("Waitrose"));
}
Modify your method like this:
private void setUpMap() throws IOException {
Geocoder geo = new Geocoder(getApplicationContext(), Locale.getDefault());
List<Address> addressList= geo.getFromLocationName("Tesco",1);
Address yourAddress = // get your location or the address to compare
Address closest = findClosest(addressList, yourAddress);
// do what you need
}
To create the findClosest you have to create a function that iterates over results and use haversine formula to calculate the distance to your location (or the desired one).
public double rad(double x)
{
return x*Math.PI/180.;
}
public Address findClosest( List<Address> addressList, Address yourAddress )
{
double lat = yourAddress.getLatitude(); // your (or desired) latitude
double lng = yourAddress.getLongitude(); // your (or desired) longitude
double R = 6371.; // radius of earth in km
double[] distances = new double[addressList.lenght];
var closest = -1;
for( i=0;i<addressList.lenght; i++ ) {
double mlat = addressList.get(i).getLatitude();
double mlng = addressList.get(i).getLongitude();
double dLat = rad(mlat - lat);
double dLong = rad(mlng - lng);
double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(rad(lat)) * Math.cos(rad(lat)) * Math.sin(dLong/2) * Math.sin(dLong/2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
double d = R * c;
distances[i] = d;
if ( closest == -1 || d < distances[closest] ) {
closest = i;
}
}
return addressList.get(closest);
}

Display title of closest marker from my current position Google Maps v2

I get the data from my database which contains, TITLE, SNIPPET and LOCATION and tried to test to check the distances between my currentlocation. I'm confused how to display the title of the closest marker to my position.
List<MyMarkerObj> m = data.getMyMarkers();
for (int i = 0; i < m.size(); i++) {
String[] slatlng = m.get(i).getPosition().split(" ");
LatLng lat = new LatLng(Double.valueOf(slatlng[0]), Double.valueOf(slatlng[1]));
map.addMarker(new MarkerOptions()
.title(m.get(i).getTitle())
.snippet(m.get(i).getSnippet())
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE))
.position(lat)
);
float[] distance = new float[1];
Location.distanceBetween(currentlat, currentlong,Double.valueOf(slatlng[0]), Double.valueOf(slatlng[1]), distance);
Toast.makeText(getActivity(), "Marker Distance: "+ m.get(i).getTitle() +" "+distance[0], Toast.LENGTH_LONG).show();
}
I made few changes here. Try it..
List<MyMarkerObj> m = data.getMyMarkers();
float mindist;
int pos=0;
for (int i = 0; i < m.size(); i++) {
String[] slatlng = m.get(i).getPosition().split(" ");
LatLng lat = new LatLng(Double.valueOf(slatlng[0]), Double.valueOf(slatlng[1]));
map.addMarker(new MarkerOptions()
.title(m.get(i).getTitle())
.snippet(m.get(i).getSnippet())
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE))
.position(lat)
);
float[] distance = new float[1];
Location.distanceBetween(currentlat, currentlong,Double.valueOf(slatlng[0]), Double.valueOf(slatlng[1]), distance);
if(i==0) mindist=distance[0];
else if(mindist>distance[0]) {
mindist=distance[0];
pos=i;
}
}
Toast.makeText(getActivity(), "Closest Marker Distance: "+ m.get(pos).getTitle() +" "+mindist, Toast.LENGTH_LONG).show();
You can use this simple function to calculate distance between two points in latitude and longitude format it works like a charm, and you can then check for which distance is closest from your location. just pass the latitude and longitude of both location in it
public double distanceFrom(double lat1, double lng1, double lat2, double lng2) {
double earthRadius = 3958.75;
double dLat = Math.toRadians(lat2-lat1);
double dLng = Math.toRadians(lng2-lng1);
double a = Math.sin(dLat/2) * Math.sin(dLat/2) + Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) * Math.sin(dLng/2) * Math.sin(dLng/2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
double dist = earthRadius * c;
int meterConversion = 1609;
return new Double(dist * meterConversion).floatValue(); // this will return distance
}

GeoPoint and current Location

how I can get current GeoPoint from my location.
I am on :
Longitude: 21.760029
Latitude: 54.035795
But when I use getLatitude(), I have 54.0
but I want 54.035795.
Here's a method for converting a latitude, longitude pair to a GeoPoint object:
public static GeoPoint convert(double latitude, double longitude)
{
int lat = (int)(latitude * 1E6);
int lng = (int)(longitude * 1E6);
return new GeoPoint(lat, lng);
}

How to calculate distance between two locations using their longitude and latitude value

Here my code I used below code to calculate the distance between two location using their latitude and longitude. It is giving wrong distance. sometimes getting right and sometimes getting irrelevant distance.
We are getting lat1 and lng1 from database.
//getting lat2 and lng2 from GPS as below
public class MyLocationListener implements LocationListener {
#Override
public void onLocationChanged(Location loc)
{
lat2=loc.getLatitude();
lng2=loc.getLongitude();
String Text = "My current location is: " +"Latitud = "+ loc.getLatitude() +"Longitud = " + loc.getLongitude();
//System.out.println("Lat & Lang form Loc"+Text);
//Toast.makeText( getApplicationContext(), Text,Toast.LENGTH_SHORT).show();
}
#Override
public void onProviderDisabled(String provider)
{
}
#Override
public void onProviderEnabled(String provider)
{
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras)
{
}
//Calculating distance
double earthRadius = 3958.75;
double dLat = Math.toRadians(lat1-lat2);
double dLng = Math.toRadians(lng1-lng2);
double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(Math.toRadians(lat2)) * Math.cos(Math.toRadians(lat1)) *
Math.sin(dLng/2) * Math.sin(dLng/2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
double dist = earthRadius * c;
There is an android.location.Location.distanceBetween() method which does this quite well.
Android Developer Docs: Location
Here getting distance in miles (mi)
private double distance(double lat1, double lon1, double lat2, double lon2) {
double theta = lon1 - lon2;
double dist = Math.sin(deg2rad(lat1))
* Math.sin(deg2rad(lat2))
+ Math.cos(deg2rad(lat1))
* Math.cos(deg2rad(lat2))
* Math.cos(deg2rad(theta));
dist = Math.acos(dist);
dist = rad2deg(dist);
dist = dist * 60 * 1.1515;
return (dist);
}
private double deg2rad(double deg) {
return (deg * Math.PI / 180.0);
}
private double rad2deg(double rad) {
return (rad * 180.0 / Math.PI);
}
Try this code.
startPoint.distanceTo(endPoint) function returns the distance between those places in meters.
Location startPoint=new Location("locationA");
startPoint.setLatitude(17.372102);
startPoint.setLongitude(78.484196);
Location endPoint=new Location("locationA");
endPoint.setLatitude(17.375775);
endPoint.setLongitude(78.469218);
double distance=startPoint.distanceTo(endPoint);
here "distance" is our required result in Meters. I hope it will work for android.
in build.gradle:
compile 'com.google.maps.android:android-maps-utils:0.4'
and then:
public static Double distanceBetween(LatLng point1, LatLng point2) {
if (point1 == null || point2 == null) {
return null;
}
return SphericalUtil.computeDistanceBetween(point1, point2);
}
If you have two Location Objects Location loc1 and Location loc2 you do
float distance = loc1.distanceTo(loc2);
If you have longitude and latitude values you use the static distanceBetween() function
float[] results = new float[1];
Location.distanceBetween(startLatitude, startLongitude,
endLatitude, endLongitude, results);
float distance = results[0];
private String getDistanceOnRoad(double latitude, double longitude,
double prelatitute, double prelongitude) {
String result_in_kms = "";
String url = "http://maps.google.com/maps/api/directions/xml?origin="
+ latitude + "," + longitude + "&destination=" + prelatitute
+ "," + prelongitude + "&sensor=false&units=metric";
String tag[] = { "text" };
HttpResponse response = null;
try {
HttpClient httpClient = new DefaultHttpClient();
HttpContext localContext = new BasicHttpContext();
HttpPost httpPost = new HttpPost(url);
response = httpClient.execute(httpPost, localContext);
InputStream is = response.getEntity().getContent();
DocumentBuilder builder = DocumentBuilderFactory.newInstance()
.newDocumentBuilder();
Document doc = builder.parse(is);
if (doc != null) {
NodeList nl;
ArrayList args = new ArrayList();
for (String s : tag) {
nl = doc.getElementsByTagName(s);
if (nl.getLength() > 0) {
Node node = nl.item(nl.getLength() - 1);
args.add(node.getTextContent());
} else {
args.add(" - ");
}
}
result_in_kms = String.format("%s", args.get(0));
}
} catch (Exception e) {
e.printStackTrace();
}
return result_in_kms;
}
In Kotlin
private fun distanceInMeter(startLat: Double, startLon: Double, endLat: Double, endLon: Double): Float {
var results = FloatArray(1)
Location.distanceBetween(startLat,startLon,endLat,endLon,results)
return results[0]
}
private float distanceFrom_in_Km(float lat1, float lng1, float lat2, float lng2) {
if (lat1== null || lng1== null || lat2== null || lng2== null)
{
return null;
}
double earthRadius = 6371000; //meters
double dLat = Math.toRadians(lat2-lat1);
double dLng = Math.toRadians(lng2-lng1);
double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *
Math.sin(dLng/2) * Math.sin(dLng/2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
float dist = (float) (earthRadius * c);
return dist;
}
Use the below method for calculating the distance of two different locations.
public double getKilometers(double lat1, double long1, double lat2, double long2) {
double PI_RAD = Math.PI / 180.0;
double phi1 = lat1 * PI_RAD;
double phi2 = lat2 * PI_RAD;
double lam1 = long1 * PI_RAD;
double lam2 = long2 * PI_RAD;
return 6371.01 * acos(sin(phi1) * sin(phi2) + cos(phi1) * cos(phi2) * cos(lam2 - lam1));}
Try This below method code to get the distance in meter between two location, hope it will help for you
public static double distance(LatLng start, LatLng end){
try {
Location location1 = new Location("locationA");
location1.setLatitude(start.latitude);
location1.setLongitude(start.longitude);
Location location2 = new Location("locationB");
location2.setLatitude(end.latitude);
location2.setLongitude(end.longitude);
double distance = location1.distanceTo(location2);
return distance;
} catch (Exception e) {
e.printStackTrace();
}
return 0;
}
Why are you writing the code for calculating the distance by yourself?
Check the api's in Location class
You should use Haversine Distance Formulas
Haversine Formulas used to calculate the great distance between two points on the earth.
public void haversine(double lat1, double lon1, double lat2, double lon2) {
double Rad = 6372.8; //Earth's Radius In kilometers
// TODO Auto-generated method stub
double dLat = Math.toRadians(lat2 - lat1);
double dLon = Math.toRadians(lon2 - lon1);
lat1 = Math.toRadians(lat1);
lat2 = Math.toRadians(lat2);
double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2);
double c = 2 * Math.asin(Math.sqrt(a));
haverdistanceKM = Rad * c;
}
Updated on October 8, 2021
Returns the approximate distance in meters between this location and the given location. Distance is defined using the WGS84 ellipsoid.
Java
public float getDistance(double startLat,double startLang,double endLat,double endLang) {
Location locStart = new Location("");
locStart.setLatitude(startLat);
locStart.setLongitude(startLang);
Location locEnd = new Location("");
locEnd.setLatitude(endLat);
locEnd.setLongitude(endLang);
return locStart.distanceTo(locEnd);
}
Kotlin
private fun getDistance(
startLat: Double,
startLang: Double,
endLat: Double,
endLang: Double
): Float {
val locStart = Location("")
locStart.latitude = startLat
locStart.longitude = startLang
val locEnd = Location("")
locEnd.latitude = endLat
locEnd.longitude = endLang
return locStart.distanceTo(locEnd)
}
Returns the approximate distance in meters between this location and the given location. Distance is defined using the WGS84 ellipsoid.
public float getMesureLatLang(double lat,double lang) {
Location loc1 = new Location("");
loc1.setLatitude(getLatitute());// current latitude
loc1.setLongitude(getLangitute());//current Longitude
Location loc2 = new Location("");
loc2.setLatitude(lat);
loc2.setLongitude(lang);
return loc1.distanceTo(loc2);
// return distance(getLatitute(),getLangitute(),lat,lang);
}

Categories

Resources