I've an app that gets the current user's location from a location service. When i get the lon and lat from the location object, they are as follows
lat = 53.653770446777344
lon = -1.520833969116211
.
I then store these in a GeoPoint object which is passed to a query string for Google Servers. This eventually plots a polyline between the current location and a destination.
It all works fine and the polyline is drawn, however it is drawn incorrectly as the current location is set about 100 mile away. I've logged out some values and there is a loss of precision when the lon and lat get passed to the geopoint.
How can i get around this.
#Override
public void onLocationChanged(Location location) {
lati = (location.getLatitude());
lngi = (location.getLongitude());
startAddr = new GeoPoint((int)lati, (int)lngi);
Log.e(TAG, "lat = " + lati);
Log.e(TAG, "lon = " + lngi);
Log.e(TAG, "lat after cast = " + (int)(lati * 1000000));
Log.e(TAG, "lon after cast = " + (int)(lngi * 1000000));
locationManager.removeUpdates(this);
StringBuilder sb = new StringBuilder();
sb.append("http://maps.google.com/maps/api/directions/json?origin=");
sb.append(startAddr);
sb.append("&destination=");
sb.append(endAddr);
sb.append("&sensor=false");
stringUrl = sb.toString();
Log.e(TAG, "url = " + stringUrl);
AsyncGetRoute agr = new AsyncGetRoute();
agr.execute();
.
11-15 12:45:17.280: E/GetClientDirections(23220): lat = 53.653770446777344
11-15 12:45:17.280: E/GetClientDirections(23220): lon = -1.520833969116211
11-15 12:45:17.280: E/GetClientDirections(23220): lat after cast = 53653770
11-15 12:45:17.280: E/GetClientDirections(23220): lon after cast = -1520833
11-15 12:45:17.290: E/GetClientDirections(23220): url = http://maps.google.com/maps/api/directions/json?origin=53,-1&destination=AL73EZ&sensor=false
This is the problem:
startAddr = new GeoPoint((int)lati, (int)lngi);
This truncates the fractions, so effectively for your input, your result is:
startAddr = new GeoPoint(53, -1);
As the API doc says, the GeoPoint accepts integer values: the two angles multiplied by 10^6. And because of this, the coordinates given would correspond to these values:
Latitude: 0.000053
Longitude: -0.000001
You should multiply first with 10^6, then truncate, so you should try:
startAddr = new GeoPoint((int)(lati*1000000.0), (int)(lngi*1000000.0));
Related
How can i have bot the lat and log in one textview separated with a comma?
I tried as below and i am getting the "do not concatenate text displayed with settext" warning!
gpsTracker = new GpsTracker( MainActivity.this);
if(gpsTracker.canGetLocation()){
double latitude = gpsTracker.getLatitude();
double longitude = gpsTracker.getLongitude();
textviewGPSLocation.setText(String.valueOf(latitude) + "/," + String.valueOf ( longitude ));
You can format your string like this
double latitude = gpsTracker.getLatitude();
double longitude = gpsTracker.getLongitude();
String text = String.format("%1$2f / %2$2f", latitude, longitude);
textviewGPSLocation.setText(text);
My goal is to do autocomplete prediction using Google Places API, and now I want to make some kind algorithm that will take current location lat and lng, and make a prediction of places only in 100-200 km diameter.
So, at this moment I get user's current location lat and lng, how to set 100-200 km?
private void getCurrentLocation() {
mLastLocation = LocationServices.FusedLocationApi
.getLastLocation(mGoogleApiClient);
if (mLastLocation != null) {
double latitude = mLastLocation.getLatitude();
double longitude = mLastLocation.getLongitude();
mLatLonBounds = new LatLngBounds(new LatLng(latitude,longitude),
new LatLng(latitude,longitude));
Log.d("myTag","lat = "+mLatLonBounds.northeast.latitude+" ,lon = "+mLatLonBounds.northeast.longitude);
//Log.d("myTag","lat = "+mLatLonBounds.southwest.latitude+" ,lon = "+mLatLonBounds.southwest.longitude);
}else {
//some code
}
}
Here is how I set bounds to auto prediction:
#Nullable
private ArrayList<AutoCompletePlace> getAutocomplete(CharSequence constraint) {
if (mGoogleApiClient.isConnected()) {
Log.i(Constants.AUTO_COMPLETE_TAG, "Starting autocomplete query for: " + constraint);
// Submit the query to the autocomplete API and retrieve a PendingResult that will
// contain the results when the query completes.
PendingResult<AutocompletePredictionBuffer> results = Places.GeoDataApi
.getAutocompletePredictions(mGoogleApiClient, constraint.toString(),
**mBounds**, mPlaceFilter);
// This method should have been called off the main UI thread. Block and wait for at most 60s
// for a result from the API.
AutocompletePredictionBuffer autocompletePredictions = results.await(60, TimeUnit.SECONDS);
// Confirm that the query completed successfully, otherwise return null
final Status status = autocompletePredictions.getStatus();
if (!status.isSuccess()) {
Toast.makeText(getContext(), "Error contacting API: " + status.toString(),
Toast.LENGTH_SHORT).show();
Log.e(Constants.AUTO_COMPLETE_TAG, "Error getting autocomplete prediction API call: " + status.toString());
autocompletePredictions.release();
return null;
}
Log.i(Constants.AUTO_COMPLETE_TAG, "Query completed. Received " + autocompletePredictions.getCount()
+ " predictions.");
// Copy the results into our own data structure, because we can't hold onto the buffer.
// AutocompletePrediction objects encapsulate the API response (place ID and description).
Iterator<AutocompletePrediction> iterator = autocompletePredictions.iterator();
ArrayList resultList = new ArrayList<>(autocompletePredictions.getCount());
while (iterator.hasNext()) {
AutocompletePrediction prediction = iterator.next();
// Get the details of this prediction and copy it into a new PlaceAutocomplete object.
resultList.add(new AutoCompletePlace(prediction.getPlaceId(),
prediction.getDescription()));
}
// Release the buffer now that all data has been copied.
autocompletePredictions.release();
return resultList;
}
Log.e(Constants.AUTO_COMPLETE_TAG, "Google API client is not connected for autocomplete query.");
return null;
Example my current location 48.6180288,22.2984587.
UPDATE: Before the Francois Wouts give me the answer, I found another solution on stackoverflow, you can use it too.
public static final LatLngBounds setBounds(Location location, int mDistanceInMeters ){
double latRadian = Math.toRadians(location.getLatitude());
double degLatKm = 110.574235;
double degLongKm = 110.572833 * Math.cos(latRadian);
double deltaLat = mDistanceInMeters / 1000.0 / degLatKm;
double deltaLong = mDistanceInMeters / 1000.0 / degLongKm;
double minLat = location.getLatitude() - deltaLat;
double minLong = location.getLongitude() - deltaLong;
double maxLat = location.getLatitude() + deltaLat;
double maxLong = location.getLongitude() + deltaLong;
Log.d("Location", "Min: " + Double.toString(minLat) + "," + Double.toString(minLong));
Log.d("Location","Max: "+Double.toString(maxLat)+","+Double.toString(maxLong));
// Set up the adapter that will retrieve suggestions from the Places Geo Data API that cover
// the entire world.
return new LatLngBounds(new LatLng(minLat,minLong),new LatLng(maxLat,maxLong));
According to Wikipedia, you probably want to allow around 1 degree in each direction around the user's location to cover 100-200km. The exact area covered will depend on where the user is, but this should be a good enough approximation for most use cases.
Try the following, for example:
double radiusDegrees = 1.0;
LatLng center = /* the user's location */;
LatLng northEast = new LatLng(center.latitude + radiusDegrees, center.longitude + radiusDegrees);
LatLng southWest = new LatLng(center.latitude - radiusDegrees, center.longitude - radiusDegrees);
LatLngBounds bounds = LatLngBounds.builder()
.include(northEast)
.include(southWest)
.build();
I believe this should work correctly even across the antemeridian. Let me know how you go!
I have an SQLITE3 database where I defined lat and long as text.
I need to use those lat, and long as the final destination in a map.
The intent is defined as:
if(locationMap != null){
Intent theIntent = new Intent(getApplication(), displayMap.class);
theIntent.putExtra("_Id", locationMap.get("_Id"));
theIntent.putExtra("locCode", locationMap.get("locCode"));
theIntent.putExtra("locDesc", locationMap.get("locDesc"));
theIntent.putExtra("locLat", locationMap.get("locLat"));
theIntent.putExtra("locLong", locationMap.get("locLong"));
theIntent.putExtra("locTelephone", locationMap.get("locTelephone"));
theIntent.putExtra("locComments", locationMap.get("locComments"));
startActivity(theIntent); // display map with coordinates
}
In the next activity I recover the values in the On create method:
// Parameters
String locCode = i.getStringExtra("locCode");
String locDesc = i.getStringExtra("locDesc");
String locLat = i.getStringExtra("locLat");
String locLong = i.getStringExtra("locLong");
String locTelephone = i.getStringExtra("locTelephone");
String locComments = i.getStringExtra("locComments");
String Text = "Current location is: " +
i.getStringExtra("locLat");
Toast.makeText( getApplicationContext(),Text,
Toast.LENGTH_SHORT).show();
System.out.println("locCode: " + locCode);
System.out.println("LocDesc: " + locDesc);
System.out.println("LocLat: " + locLat);
System.out.println("LocLong: " + locLong);
System.out.println("LocTelephone: " + locTelephone);
System.out.println("LocComment: " + locComments);
getLocation(ORIGIN);
setContentView(R.layout.map);
if (mLastSelectedMarker != null && mLastSelectedMarker.isInfoWindowShown()) {
// Refresh the info window when the info window's content has changed.
mLastSelectedMarker.showInfoWindow();
}
setUpMapIfNeeded();
}
I need to use those locLat and Loclong instead of the numbers:
public class displayMap extends FragmentActivity implements
OnMarkerClickListener,
OnInfoWindowClickListener {
public LatLng ORIGIN = new LatLng(34.02143074239393, -117.61349469423294);
public LatLng DESTINY = new LatLng(34.022365269080886, -117.61271852999926);
private GoogleMap mMap;
private Marker mDestiny;
private Marker mOrigin;
private Marker mLastSelectedMarker; // keeps track of last selected marker
I've tried transforming the text to double and It won't allow me to.
I've tried many solutions I found on stack overflow, but no luck yet.
I appreciate any help
Thanks in advance.
You need to parse the latitude and longitude from String to double to use in new LatLng();
double latitude = Double.parseDouble(locLat);
double longitude = Double.parseDouble(locLong);
and then,
public LatLng ORIGIN = new LatLng(latitude, longitude);
you need cast them into double. As GPRathour says.
Change the type of Lat Long Text to REAL in your SQL Lite,
when inserting values use this
values.put(Latitude_Column, ORIGIN.latitude);
values.put(Longitude__Column,ORIGIN.longitude);
And for retrieving values
LatLng origin = new LatLng(cursor.getDouble(cursor.getColumnIndex(Latitude_Column)),cursor.getDouble(cursor.getColumnIndex(Longitude__Column)));
No need to parsing values
I trying to match hardcoded latitude an longitude with dynamic latitude and longitude, but its not showing correct output, can anyone help me to sort out this error
My code is
String Log = "-122.084095";
String Lat = "37.422005";
try {
if ((Lat.equals(latitude)) && (Log.equals(longitude))) {
AudioManager audiM = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
audiM.setRingerMode(AudioManager.RINGER_MODE_SILENT);
Toast.makeText(getApplicationContext(),
"You are at home",
Toast.LENGTH_LONG).show();
} else {
AudioManager auMa = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
auMa.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
Toast.makeText(getApplicationContext(),
"You are at office ", Toast.LENGTH_LONG)
.show();
}
} catch (Exception e) {
e.printStackTrace();
}
it always goes for else part...
You don't want to use a String comparison here as you can't guarantee the level of accuracy with the real-time location.
The best way to handle this would be to determine the distance between the points and then determine if it's close enough for you to consider, approx, the same.
For this, we use distanceBetween or distanceTo
Docs are here and here
Examples can be found here. Here's one of those examples:
Location locationA = new Location("point A");
locationA.setLatitude(pointA.getLatitudeE6() / 1E6);
locationA.setLongitude(pointA.getLongitudeE6() / 1E6);
Location locationB = new Location("point B");
locationB.setLatitude(pointB.getLatitudeE6() / 1E6);
locationB.setLongitude(pointB.getLongitudeE6() / 1E6);
double distance = locationA.distanceTo(locationB);
The latitude and longitude are variables which vary from point to point, matter of fact they keep on changing while standing on the same spot, because it is not precise.
Instead of comparing the Strings, take a rounded value of the lat and long (in long or float ) and check those values within a certain range. That will help you out with the "Home" and "Office " thing.
For e.g :
String Log = "22.084095";
String Lat = "37.422005";
double lng=Double.parseDouble(Log);
double lat=Double.parseDouble(Lat);
double upprLogHome=22.1;
double lwrLogHome=21.9;
double upprLatHome=37.5;
double lwrLatHome=37.3;
// double upprLogOfc=;
// double lwrLogOfc=;
// double upprLatOfc=;
// double lwrLatOfc=;
if(lng<upprLogHome && lng>lwrLogHome && lat<upprLatHome &&lat>lwrLatHome )
{
System.out.println("You are Home");
}
/* else if(lng<upprLogOfc && lng>lwrLogOfc && lat<upprLatOfc &&lat>lwrLatOfc )
{
System.out.println("You are Home");
}*/
else
System.out.println("You are neither Home nor Ofc");
But for the negative lat long you have to reverse the process of checking.
your matching is okay but you probably should not check for a gps location like this.
You should convert the location to something where you can check that you are in 10m radius of the location.
A nicer way would be to leave the long/lat as doubles and compare the numbers.
if(lat > HOME_LAT - 0.1 && lat < HOME_LAT + 0.1 && ...same for lon... ){}
Try this,
Use google map api to pass lat and long value you will get formatted address. And also pass dynamic lat and lng value same google api you will get formatted address. And then match two formatted address you will get result. i suggest this way you can try this
Use this google api. http://maps.googleapis.com/maps/api/geocode/json?latlng=11.029494,76.954422&sensor=true
Reena, its very easy, Check out below code. You need to use "equalsIgnoreCase()" instead of
"equals".
if ((Lat.equalsIgnoreCase(latitude)) && (Log.equalsIgnoreCase(longitude))) {
should work
Example below :
// Demonstrate equals() and equalsIgnoreCase().
class equalsDemo {
public static void main(String args[]) {
String s1 = "Hello";
String s2 = "Hello";
String s3 = "Good-bye";
String s4 = "HELLO";
System.out.println(s1 + " equals " + s2 + " -> " +
s1.equals(s2));
System.out.println(s1 + " equals " + s3 + " -> " +
s1.equals(s3));
System.out.println(s1 + " equals " + s4 + " -> " +
s1.equals(s4));
System.out.println(s1 + " equalsIgnoreCase " + s4 + " -> " +
s1.equalsIgnoreCase(s4));
}
}
You can print dynamice Latitute and Longitute to Logcat and check with hardcoded Latitute and Longitute
I Have an address that I would like to know the coordinates of. For instance the address is "Skillman Ave" Queens, NY. The coordinates is: 40.747281, -73.9283169 according to maps.google.com. In my app I have a function like this:
public GeoPoint addressToGeo(String adr) {
Geocoder coder = new Geocoder(this);
List<Address> address = null;
GeoPoint coordinates;
try {
address = coder.getFromLocationName(adr, 1);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (address == null) {
return null;
}
Address location = address.get(0);
location.getLatitude();
location.getLongitude();
coordinates = new GeoPoint((int) (location.getLatitude() *1E6),
(int) (location.getLongitude() * 1E6));
return coordinates;
}
Which takes an address as parameter, and hopefully it will return the coordinates. My debugger says the the first element in the list adress contains this information:
[Address[addressLines=[0:"Skillman Ave",1:"Queens, New York",2:"Amerikas forente stater"],feature=Skillman Ave,admin=New York,sub-admin=Queens,locality=Queens,thoroughfare=Skillman Ave,postalCode=null,countryCode=US,countryName=Amerikas forente stater,hasLatitude=true,latitude=40.747281,hasLongitude=true,longitude=-73.9283169,phone=null,url=null,extras=null]]
which seems correct if you look at the latitude and longitude variables. But when I type in this code:
GeoPoint test;
test = addressToGeo("Skillman Ave");
double latitude = test.getLatitudeE6();
double longitude = test.getLongitudeE6();
String lat = Double.toString(latitude);
String lng = Double.toString(longitude);
String total = lat + " " + lng;
toAdress.setText(total);
the toAdress textField will contain 4.0747281E7, -7.3928316E7 The comma is not in the right spot, and what is the E7 in the end of each double?
'E7' is notation meaning that you need to multiply by 10^7 to get the actual number. In this case it would give you 40747281. You then need to format that into a proper coordinate.
Ankit's code looks like it might do that, but test to make sure.
Try this.
String lat = Double.toString(latitude);
String lng = Double.toString(longitude);
lat= (float) (lat / 1E6);
lng = (float)(lon / 1E6);
System.out.println("lat :" + (float) lat / 1E6);
System.out.println("lon :" + (float) lon / 1E6);
You've got all the right data, so this question is really about formatting a double. Use DecimalFormat.
Use this to display the lat/lon points in your test:
DecimalFormat formatter = new DecimalFormat("0.0000000");
String lat = formatter.format(test.getLatitudeE6() / 1E6);
String lon = formatter.format(test.getLongitudeE6() / 1E6);
toAddress.setText(lat + " " + lon);