I have a Problem to get the right way to get the distanceTo from my 2 Geo Points. How to get it work?
from the gps class:
double latitude; // latitude
String mlat;
latitude = location.getLatitude();
mlat = String.valueOf(latitude);
from the ListView:
// Get distance
String mReportA;
double mLocB;
int distance;
mReportA = e.getString("lat");
mReportA = e.getString("lon");
mLocB = gps.latitude;
mLocB = gps.longitude;
distance = mReportA.distanceTo(mLocB);
Error in Eclipse: The method distanceTo(double) is undefined for the type String
I get e.getString("lat"); from json
To calculate distance between two geopoint you can follow the below example.
double currentLatitude = location.getLatitude();
double currentLongitude = location.getLongitude();
double endLatitude = lat;
double endLongitude = lng;
float[] results = new float[3];
Location.distanceBetween(currentLatitude, currentLongitude,endLatitude, endLongitude, results);
BigDecimal bd = new BigDecimal(results[0]);// results in meters
BigDecimal rounded = bd.setScale(2, RoundingMode.HALF_UP);
double values = rounded.doubleValue();
EDIT
if (values > 1000) {
values = (Double) (values * 0.001f);// convert meters to Kilometers
bd = new BigDecimal(values);
rounded = bd.setScale(2, RoundingMode.HALF_UP);
values = rounded.doubleValue();
}
// Here is the code to find out the distance between two locations
float distance;
Location locationA = new Location("A");
locationA.setLatitude(latA);
locationA.setLongitude(lngA);
Location locationB = new Location("B");
locationB.setLatitude(latB);
LocationB.setLongitude(lngB);
distance = locationA.distanceTo(locationB);
Related
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);
}
I'm trying to sum up the total distance between an array of LatLng but failing hard. Here's what I've got so far:
private double sumDistance() {
Location loc = new Location("distance provider");
double previousLatitude;
double previousLongitude;
float[] results = new float[1];
for (LatLng latLng : mMapList) {
previousLatitude = latLng.latitude;
previousLongitude = latLng.longitude;
loc.distanceBetween(previousLatitude, previousLongitude, latLng.latitude, latLng.longitude, results);
}
return 0;
}
The problem with this is that the latlng for both are the same. Is there some way I can get the previous latlng or a cleaner way to do this that I'm not thinking of?
Why don't you assign the "previous variable" after you've calculated the distance? Something like this should work
private double sumDistance() {
Location loc = new Location("distance provider");
double previousLatitude = mMapList.get(0).latitude;
double previousLongitude = mMapList.get(0).longitude;
float[] results;
for (int i=1;i<mMapList.size();i++) {
loc.distanceBetween(previousLatitude, previousLongitude, mMapList.get(i).latitude, mMapList.get(i).longitude, results);
previousLatitude = mMapList[i].latitude;
previousLongitude = mMapList[i].longitude;
}
return 0;
}
double previousLatitude;
double previousLongitude;
float[] results;
for (int i=0; i<mMapList.size(); ++i) {
LatLng latLng = mMapList.get(i);
if (i == 0) {
// Previous weren't set yet, nothing to measure
// Set them and skip loop
previousLatitude = latLng.latitude;
previousLongitude = latLng.longitude;
continue;
}
// Measure previous with current
loc.distanceBetween(previousLatitude, previousLongitude, latLng.latitude, latLng.longitude, results);
// ~ Use the distance
// Modify the previous ones
previousLatitude = latLng.latitude;
previousLongitude = latLng.longitude;
}
I am trying to make a application,which is take latitude and longitude on current place of the user. And count momentary,what distance is travel the user in km.
The "currentLat" and "currentLon" is current latitude and longitude of the user.But I don't know what latitude and longitude to put for "endLat" and "ednLon".
Sorry for my bad english.
Thanks in advance.
///////////////////////////////////
I made it the app,but now have just one little problem.
When I started first time the program,I get value 5536 and when I restarted the program I get normal value 0.0
Again sorry for my bad english. :)
And guys thanks for helping me,you are the best :)
public class Gps extends Activity {
TextView display;
double currentLon=0 ;
double currentLat=0 ;
double lastLon = 0;
double lastLat = 0;
double distance;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
display = (TextView) findViewById(R.id.info);
LocationManager lm =(LocationManager) getSystemService(LOCATION_SERVICE);
lm.requestLocationUpdates(lm.GPS_PROVIDER, 0,0, Loclist);
Location loc = lm.getLastKnownLocation(lm.GPS_PROVIDER);
if(loc==null){
display.setText("No GPS location found");
}
else{
//set Current latitude and longitude
currentLon=loc.getLongitude();
currentLat=loc.getLatitude();
}
//Set the last latitude and longitude
lastLat=currentLat;
lastLon=currentLon ;
}
LocationListener Loclist = new LocationListener(){
#Override
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
//start location manager
LocationManager lm =(LocationManager) getSystemService(LOCATION_SERVICE);
//Get last location
Location loc = lm.getLastKnownLocation(lm.GPS_PROVIDER);
//Request new location
lm.requestLocationUpdates(lm.GPS_PROVIDER, 0,0, Loclist);
//Get new location
Location loc2 = lm.getLastKnownLocation(lm.GPS_PROVIDER);
//get the current lat and long
currentLat = loc.getLatitude();
currentLon = loc.getLongitude();
Location locationA = new Location("point A");
locationA.setLatitude(lastLat);
locationA.setLongitude(lastLon);
Location locationB = new Location("point B");
locationB.setLatitude(currentLat);
locationB.setLongitude(currentLon);
double distanceMeters = locationA.distanceTo(locationB);
double distanceKm = distanceMeters / 1000f;
display.setText(String.format("%.2f Km",distanceKm ));
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
};
}
Since you have two locations, why don't you consider using distanceTo:
float distanceMeters = location1.distanceTo(location2);
float distanceKm = distanceMeters / 1000f;
But I don't know what latitude and longitude to put for "endLat" and "ednLon".
endLat, endLon is a confusing name:
You should have lastLat, lastLon: the lat,lon received in the previous call of onGpsUpdate, save that into your e.g distanceCalculator.lastLat
where distanceCalculator is an object where you store that lastLat, and lastLon
Then you should have curLat, curLon: current lat, lon delivered in onGPSUpdate
Then calculate the distance from (lastLat, lastLon) -> (curLat, curLon),
and update your distanceCalculator.lastLat and lastLon.
Link
var R = 6371; // Radius of the earth in km
var dLat = (lat2-lat1).toRad(); // Javascript functions in radians
var dLon = (lon2-lon1).toRad();
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(lat1.toRad()) * Math.cos(lat2.toRad()) *
Math.sin(dLon/2) * Math.sin(dLon/2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
var d = R * c; // Distance in km.
I am having trouble in converting the latitude and longitude values into android esri arcGIS map Point. Here's my code to get latitude and longitude values from GPS coordinates:
LocationManager lm;
String towers;
double lat;
double longi;
TextView txt;
lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Criteria crit = new Criteria();
towers = lm.getBestProvider(crit, false);
Location location = lm.getLastKnownLocation(towers);
if(location != null)
{
lat = location.getLatitude();
longi = location.getLongitude();
}
now I have the latitude and longitude values. Now all I need is to convert these values into valid esri arcGIS MapPoint. Can anyone help me?
Thanks in advance.
Assuming you're using the ESRI Android API? If so, create a graphics layer on your map. Then create a point object
com.esri.core.geometry.Point
Point myPoint = new Point();
then set the x/y values:
myPoint.setX(longi);
myPoint.setY(lat);
then add myPoint to the graphics object.
http://help.arcgis.com/en/arcgismobile/10.0/apis/android/api/index.html
Yes, it is possible. But you don't use the locationmanager in ArcGis.
ArcGIS has the predefined method like LocationListener, that is: OnStatusChangedListener.
See the below code for converting location latitude and longitude into esri arcGIS MapPoint.
mMapView.setOnStatusChangedListener(new OnStatusChangedListener() {
/**
*
*/
private static final long serialVersionUID = 1L;
public void onStatusChanged(Object source, STATUS status) {
if (source == mMapView && status == STATUS.INITIALIZED) {
LocationService ls = mMapView.getLocationService();
ls.setAutoPan(false);
ls.setLocationListener(new LocationListener() {
boolean locationChanged = false;
// Zooms to the current location when first GPS fix
// arrives.
public void onLocationChanged(Location loc) {
if (!locationChanged) {
locationChanged = true;
double locy = loc.getLatitude();
double locx = loc.getLongitude();
Point wgspoint = new Point(locx, locy);
Point mapPoint = (Point) GeometryEngine.project(wgspoint,
SpatialReference.create(4326),
mMapView.getSpatialReference());
Unit mapUnit = mMapView.getSpatialReference().getUnit();
double zoomWidth = Unit.convertUnits(
SEARCH_RADIUS, Unit.create(LinearUnit.Code.MILE_US), mapUnit);
Envelope zoomExtent = new Envelope(mapPoint, zoomWidth, zoomWidth);
mMapView.setExtent(zoomExtent);
GraphicsLayer gLayer = new GraphicsLayer();
PictureMarkerSymbol symbol = new
PictureMarkerSymbol(getResources().getDrawable(R.drawable.twiz_car_red));
Graphic graphic = new Graphic(mapPoint, symbol);
//Graphic point=new Graphic(new Point(x, y),new
SimpleMarkerSymbol(Color.CYAN,20,STYLE.CIRCLE));
gLayer.addGraphic(graphic);
mMapView .addLayer(gLayer);
}
}
public void onProviderDisabled(String arg0) {
}
public void onProviderEnabled(String arg0) {
}
public void onStatusChanged(String arg0, int arg1,
Bundle arg2) {
}
});
ls.start();
}
}
});
I've borrowed some code from here
private Point ToGeographic(Point pnt)
{
double mercatorX_lon = pnt.getX();
double mercatorY_lat = pnt.getY();
if (Math.abs(mercatorX_lon) < 180 && Math.abs(mercatorY_lat) < 90)
return pnt;
if ((Math.abs(mercatorX_lon) > 20037508.3427892) || (Math.abs(mercatorY_lat) > 20037508.3427892))
return pnt;
double x = mercatorX_lon;
double y = mercatorY_lat;
double num3 = x / 6378137.0;
double num4 = num3 * 57.295779513082323;
double num5 = Math.floor((double)((num4 + 180.0) / 360.0));
double num6 = num4 - (num5 * 360.0);
double num7 = 1.5707963267948966 - (2.0 * Math.atan(Math.exp((-1.0 * y) / 6378137.0)));
mercatorX_lon = num6;
mercatorY_lat = num7 * 57.295779513082323;
return new Point(mercatorX_lon, mercatorY_lat);
}
private Point ToWebMercator(Point pnt)
{
double mercatorX_lon = pnt.getX();
double mercatorY_lat = pnt.getY();
if ((Math.abs(mercatorX_lon) > 180 || Math.abs(mercatorY_lat) > 90))
return pnt;
double num = mercatorX_lon * 0.017453292519943295;
double x = 6378137.0 * num;
double a = mercatorY_lat * 0.017453292519943295;
mercatorX_lon = x;
mercatorY_lat = 3189068.5 * Math.log((1.0 + Math.sin(a)) / (1.0 - Math.sin(a)));
return new Point(mercatorX_lon, mercatorY_lat);
}
I make no claims of efficiency, but it's a starting point at least.
Disclaimer: I'm not an expert in this, but want to try to help. :)
There is now an ArcGIS Stack Exchange site. There's more information being added all the time and is a nice consolidated resource compared to what is out there disbursed on the interwebs.
For frameworks, I recommend GeoTools for Android.
As an aside, QGIS for Android is an interesting project from Marco Bernasocchi which you may find helpful as a reference.
Hope you can find what you're looking for!
i made a function that converts the two parameters of a location point to arcgis point :
private Point ConvertMyLocationPoint(final double x, final double y) {
Point wgspoint = new Point(x, y);
Point mapPoint = (Point) GeometryEngine.project(wgspoint, SpatialReference.create(4326),
mMapView.getSpatialReference());
return mapPoint;
}
//convert longitude and latitude to map point X Y
- (AGSPoint *)agsPointFromLatitude:(double)latitude longitude:(double)longitude
{
double mercatorX = longitude * 0.017453292519943295 * 6378137.0;
double a = latitude * 0.017453292519943295;
double mercatorY = 3189068.5 * log((1.0 + sin(a))/(1.0 - sin(a)));
AGSPoint *obj = [AGSPoint pointWithX:mercatorX y:mercatorY spatialReference: [AGSSpatialReference wgs84SpatialReference]];
return obj;
}
i have researched this for hours and the only answers i see point me to
http://developer.android.com/reference/android/location/Location.html
and to use the Method
public static void distanceBetween (double startLatitude, double startLongitude, double endLatitude, double endLongitude, float[] results)
i need help understanding how this works in relation to my app. this is how i am retrieving my location.
LocationManager locationManager;
String context = Context.LOCATION_SERVICE;
locationManager = (LocationManager)getSystemService(context);
String provider = LocationManager.GPS_PROVIDER;
Location location = locationManager.getLastKnownLocation(provider);
updateWithNewLocation(location);
}
private void updateWithNewLocation(Location location) {
String latLongString;
TextView myLocationText;
myLocationText = (TextView)findViewById(R.id.myLocationText);
if (location != null) {
double lat = location.getLatitude();
double lng = location.getLongitude();
latLongString = "Lat:" + lat + "\nLong:" + lng;
} else {
latLongString = "No location found";
}
myLocationText.setText("Your Current Position is:\n" +
latLongString);
}
Can someone please help me out a little in understanding how to import my current location into this equation and then having the distance shown in my app?
thank you
public double calcdist()
{
int MILLION = 1000000;
int EARTH_RADIUS_KM = 6371;
double lat1 = la1 / MILLION;// latitude of location 1
double lon1 = lo1 / MILLION; //longitude of location 1
double lat2 = la2 / MILLION; //latitude of location 2
double lon2 = lo2 / MILLION;//longitude of location 2
double lat1Rad = Math.toRadians(lat1);
double lat2Rad = Math.toRadians(lat2);
double deltaLonRad = Math.toRadians(lon2 - lon1);
double dist = Math.acos(Math.sin(lat1Rad) * Math.sin(lat2Rad) + Math.cos(lat1Rad) * Math.cos(lat2Rad)
* Math.cos(deltaLonRad))
* EARTH_RADIUS_KM;
return dist;
}
You can use this code if you already got latitude and longitude of both the locations.
Create a location listener
Method isAccurateForUse is a custom method that simply checks accuracy of a location.
This should work:
public boolean locChanged = false;
public LocationManager locMgr = null;
public Location referenceL = null; // Your reference location
public Location currentKL = null; // Current known location
public Location currentLKL = null; // Current last known location
//Initialise the GPS listener
locMgr = (LocationManager) appCtx.getSystemService(Context.LOCATION_SERVICE);
locMgr.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, fixGpsListener);
currentLKL = locMgr.getLastKnownLocation(LocationManager.GPS_PROVIDER);
//Define the GPS listener
LocationListener fixGpsListener = new LocationListener()
{
public void onLocationChanged(Location location)
{
locChanged = true;
if (currentKL == null)
currentKL = location;
else if (isAccurateForUse())
{
currentLKL = currentKL;
currentKL = location;
updateDistance(meterToKilometer(currentKL.distanceTo(referenceL)));
}
}
public void onProviderDisabled(String provider)
{}
public void onProviderEnabled(String provider)
{}
public void onStatusChanged(String provider, int status, Bundle extras)
{}
};
currentKL.distanceTo(referenceL) >> gives the distance in meters
meterToKilometer >> converts meters to kilo-meters
updateDistance >> this method takes a string and updates a text-view that shows distance.
Cheers