How to get latitude, longitude maximum and minimum from a center point - android

I have a Geopoint that is the current position of the user. I know its latitude and longitude. I would like to get a square perimeter 50km around the user position so I need to know what are the min & max latitude and the min&max longitude around that given poin, in java.
May someone helps me out with that ?
Thanks in advance ?

Just found out the solution. If you have a given point P(lat, long).
If you need to get 50 km around square perimeter for example, you need to take in consideration earth radius. Below how to do it:
double R = 6371; // earth radius in km
double radius = 50; // km
double latMin = lon - Math.toDegrees(radius/R/Math.cos(Math.toRadians(lat)));
double latMax = lon + Math.toDegrees(radius/R/Math.cos(Math.toRadians(lat)));
double longMax = lat + Math.toDegrees(radius/R);
double longMin = lat - Math.toDegrees(radius/R);
The real answer is here: credit to the real answerer

Related

Getting distance between farLat, farLng and nearLat, nearLng

I am getting far and near LatLng as below :
mFarLeft = mMapView.getProjection().getVisibleRegion().farLeft;
mFarRight = mMapView.getProjection().getVisibleRegion().farRight;
mNearLeft = mMapView.getProjection().getVisibleRegion().nearLeft;
mNearRight = mMapView.getProjection().getVisibleRegion().nearRight;
Now, How can I calculate the distance between this far and near points?
Is there any method available to get distance in KM and Feet?
The fields farLeft, farRight, etc. are actually LatLng objects, according to the Android documentation. However, there is a field latLngBounds which represents the smallest bounding box including the visible region. This bounds object itself has two LatLng fields for the northeast and southwest corners of the box. Using the Haversine formula we can compute the distance between the corners of this box. For example, if you wanted to compute the height of the bounding box we can try:
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.pow(Math.sin(dLat / 2),2) + Math.pow(Math.sin(dLon / 2),2) * Math.cos(lat1) * Math.cos(lat2);
double c = 2 * Math.asin(Math.sqrt(a));
return 6372.8 * c; // in kilometers
// if you want to return feet, then use 6372.8 * 3280.84 instead
}
public static void main(String[] args) {
LatLng ne = mMapView.getProjection().getVisibleRegion().latLngBounds.northeast;
LatLng sw = mMapView.getProjection().getVisibleRegion().latLngBounds.southwest;
double latLow = sw.latitude;
double latHigh = ne.latitude;
double longitude = sw.longitude;
// now compute the "height" of the bounding box
// note that the longitude value is the same
double height = haversine(latLow, longitude, latHigh, longitude);
}
Google provides a utility library for Maps that can, among other things,
Calculate distances, areas and headings via spherical geometry
Using the spherical geometry utilities in SphericalUtil, you can compute distances, areas, and headings based on latitudes and longitudes. Here are some of the methods available in the utility:
computeDistanceBetween() – Returns the distance, in meters, between two latitude/longitude coordinates.
computeHeading() – Returns the bearing, in degrees, between two latitude/longitude coordinates.
computeArea() – Returns the area, in square meters, of a closed path on the Earth.
interpolate() – Returns the latitude/longitude coordinates of a point that lies a given fraction of the distance between two given points. You can use this to animate a marker between two points, for example.
Refer to the reference documentation for a full list of methods in the utility.
The library is available on maven central.
dependencies {
compile 'com.google.maps.android:android-maps-utils:0.5+'
}
Source: https://developers.google.com/maps/documentation/android-api/utility/

XYZ to LLA returns latitude in range -180 - 180 instead of -90 - 90

I'm working on 3D globe for Country picking. It is represented by a sphere with radius equals to 1. When user tap a screen i'm getting a point using ray object picking technique and then I'm trying to conwert it to lat, long nex way:
double alt = 1;
double lat = Math.toDegrees(Math.atan2(y, x));
double lon = Math.toDegrees(Math.acos(z/alt));
This code returns latitude in range -180 - 180 degrees but google geocoder says that it should be in range -90 - 90 degrees.
How can I fix it ?
Use atan2 for longitude and asin for latitude.
double alt = Math.sqrt(x*x+y*y+z*z);
double lon = Math.toDegrees(Math.atan2(y, x));
double lat = Math.toDegrees(Math.asin(z/alt));

Get a list of location 100 meters far from a geo point

I have a list of places in my database, they all have a latitude / longitude.
In my app, I got the user location and I want to fetch all places which are 100 meters away from him.
To do it, I add 100 meters to his latitude, and longitude
I tried to do something like this:
double radius = 100; // 100 meters
double limitLatitudeNorth = latitude + radius;
double limitLatitudeSouth = latitude - radius;
double limitLongitudeWest = longitude - radius;
double limitLongitudeEast = longitude + radius;
StringBuffer query = "latitude < '" + limitLatitudeNorth + "' AND latitude > '" + limitLatitudeSouth + "' AND longitude < '" + limitLongitudeWest + "' AND longitude > '" + limitLongitudeEast + "'";
But of course, laitude and longitude are not meters, so I don't know how make the sum.
What is the formula? I heard that it depends of the position in the globe. Let's say I'm in France.
A lot of apps do that (ie: LINE) I thought I will easily find a code for that, but I didn't: (
Any idea?
You can use the distanceTo method inside Location class. Do the following:
Location location = new Location();
location.setLatitude(latitude);
location.setLongitude(longitude);
Location locationFromDB = new Location();
locationFromDB.setLatitude(latitudeFromDB);
locationFromDB.setLongitude(longitudeFromDB);
float dist = location.distanceTo(locationFromDB);
if(dist<100f){
//do here your magic
}
For distances in latitude (which trace a great circle through the poles) then 1 minute of arc = 1 nautical mile = 1852 metres (approx). Thus 1 degree = 111.12 km
For changes in longitude you need to multiply this factor by the cosine of the latitude. So at the equator the distance change is the same as for changes in latitude, at the poles (cos 90 degrees = 0) the lines of equal longitude all converge to a point.

Only Plotting Markers Within a Drawn Circle or Perimeter Google Maps v2 Android

Basically the title says it all. Rather than plotting every single entry in my database on a map as I do at the moment, I want to query the database and only plot the entries whose co-ordinates fall within the circle drawn around the users current location, however I can't quite figure out how to do it. At the moment, I have written code that plots the users current location on the map along with the locations of all the entries stored on my database and also the circle around the current location (See picture below). Based on my picture below, I only want the three markers within the circle to be plotted.
Does anyone know if there are any ways of checking if the latlng co-ordinates stored in my database fall within the area of the circle? Or if not, could anyone suggest any alternatives that use a similar idea.
An alternative I was thinking of was using a square / rectangle rather than a circle so that I could simply compare the co-ordinates of my entries with bounds of the square / rectangle, however I don't really know how feasible that is seen as those shapes aren't supported by the Google Maps API. I also came across the LatLngBounds class which could be useful but I can't find any sample code using it. How I might do this either?
I believe the circle has a fixed Radius and a center point.
So, go with this method to get the distance between the center and some LatLng and set a condition
distance <= radius
public static String getDistance(LatLng ll_source, LatLng ll_destination,
int unit) {
int Radius = 6371;// radius of earth in Km
double lat1 = ll_source.latitude;
double lat2 = ll_destination.latitude;
double lon1 = ll_source.longitude;
double lon2 = ll_destination.longitude;
double dLat = Math.toRadians(lat2 - lat1);
double dLon = Math.toRadians(lon2 - lon1);
double a = Math.sin(dLat / 2) * Math.sin(dLat / 2)
+ Math.cos(Math.toRadians(lat1))
* Math.cos(Math.toRadians(lat2)) * Math.sin(dLon / 2)
* Math.sin(dLon / 2);
double c = 2 * Math.asin(Math.sqrt(a));
double valueResult = Radius * c;
double km = valueResult / 1;
DecimalFormat newFormat = new DecimalFormat("####");
Integer kmInDec = Integer.valueOf(newFormat.format(km));
double meter = valueResult % 1000;
Integer meterInDec = Integer.valueOf(newFormat.format(meter));
DecimalFormat df = new DecimalFormat("#.#");
return df.format(valueResult);
}
Ok, I've figured out a solution using the LatLngBounds class I referred to in my question. What it does is:
Creates a new rectangular perimeter around the user's current latitude and longitude co-ordinates (this example is roughly one square kilometer).
It then checks if the perimeter contains the co-ordinates stored in the database.
If it does, the marker is plotted on the map.
public void getNearbyMarkers(){
LatLngBounds perimeter = new LatLngBounds(new LatLng(currentLat - 0.004,
currentLon - 0.004), new LatLng(currentLat + 0.004, currentLon + 0.004));
if (perimeter.contains(LatlongFromDatabase)) {
//Plot Marker on Map
} else {
Toast.makeText(getApplicationContext(), "Co-ordinates not in perimeter!", 8).show();
}
}

Calculate longitude from distance

Found a plenty of answers to question how to calculate distance by lat/lon and nothing for a "reverse" problem.
I have a displacment in X and Y and a GPS point (lat/lon), yet need to calc coordinates for a new point.
Using formula:
double deltaLat = dy / EARTH_RADIUS;
double deltaLon = dx / EARTH_RADIUS;
double lat = locLat + Math.signum(dy) * Math.toDegrees(deltaLat); // formula correct
double lon = locLon + Math.signum(dx) * Math.toDegrees(deltaLon);
It's accurate for calculating latitude, but for longitude I get about 10–15% error.
Does anyone have the same issue? Any possible formulas to calculate longitude by displacement?
The reason you're getting 10-15% error in longitude is because for longitude you cannot use the earth's radius to compute your displacement. Instead, you need to use the radius of the "circle" at the corresponding latitude. Therefore using your formula your longitude calculations should be more like
double deltaLon = dx / (EARTH_RADIUS * cos(locLat))
However this may give you undesired results around the poles, as cos(locLat) will get close to 0, so you may want to have some special cases for the poles (or even around them). Logically, if you think about, if you're at the pole, moving any distance along the x axis will not get your anywhere anyway.
Simplest but not the best solution is:
double deltaLat = dy / EARTH_RADIUS; // up-down
double deltaLon = dx / EARTH_RADIUS ; // left-right
double lat = locLat + Math.signum(dy) * Math.toDegrees(deltaLat); // formula correct
double lon = locLon + Math.signum(dx) * Math.toDegrees(deltaLon * 1.195);

Categories

Resources