Convert Java code to Delphi about midpoint calculation - java

I found this Java code to calculate the midpoint between two latitude and longitude:
midpoint between two latitude and longitude
public static void midPoint(double lat1,double lon1,double lat2,double lon2){
double dLon = Math.toRadians(lon2 - lon1);
//convert to radians
lat1 = Math.toRadians(lat1);
lat2 = Math.toRadians(lat2);
lon1 = Math.toRadians(lon1);
double Bx = Math.cos(lat2) * Math.cos(dLon);
double By = Math.cos(lat2) * Math.sin(dLon);
double lat3 = Math.atan2(Math.sin(lat1) + Math.sin(lat2), Math.sqrt((Math.cos(lat1) + Bx) * (Math.cos(lat1) + Bx) + By * By));
double lon3 = lon1 + Math.atan2(By, Math.cos(lat1) + Bx);
//print out in degrees
System.out.println(Math.toDegrees(lat3) + " " + Math.toDegrees(lon3));
}
Anyone can help me to convert this piece of code to Borland Delphi?
With the input like this format:
lat1 = 48.865223,
lon1 = 2.318974
lat2 = 48.865983,
lon2 = 2.321475
I am not sure if that is already in "radian".

lat1 = 48.865223, lon1 = 2.318974
lat2 = 48.865983, lon2 = 2.321475
These coordinates appear to be in degrees. The latitude is too large for radians. You can convert between degrees and radians using DegToRad and RadToDeg. Of course, it's not very hard to multiply and divide by π/180.
The trig functions, sin and cos can be found in the System unit, as can sqrt. For atan2 you need arctan2 from Math.

Related

Problem with the calculating distance between locations using Haversine formula

I am calculating the distance between two points recorded in the history of Yandex.Maps in the Android 11 app. Everything works well in the getPoints method. We write all the coordinates they were in our database to a list of arrays. I even implemented overflow, exit, and array checks. Again, up to this point, everything worked well and as expected.
public ArrayList<Double> getPoints () {
ArrayList<Double> location = new ArrayList<>();
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery("select latitude,longitude from "+Table_Name_Location,null);
if(cursor.getCount() > 0) {
while (cursor.moveToNext()) {
Double latitude = cursor.getDouble(cursor.getColumnIndex("Lat"));
Double longitude = cursor.getDouble(cursor.getColumnIndex("Longi"));
location.add(latitude);
location.add(longitude);
}
}
cursor.close();
return location;
}
However, when I try to calculate the length in the distance method, several latitudes and longitudes stored in the SQLite database incorrectly calculate the total distance, for example, 450 kilometres, and according to our data, we should get 230 km. A calculation error occurs.
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);
}
I tried to calculate the distance using the haversine formula. I also wrote functions to convert radians to degrees and vice versa. In the distance method, I calculate the distance using the haversine formula. I suspect that the error is in calculating the distance, namely in the implementation of the haversine formula.
For distance you need the reverse Haversine formula:
dlon = lon2 - lon1
dlat = lat2 - lat1
a = (sin(dlat/2))^2 + cos(lat1) * cos(lat2) * (sin(dlon/2))^2
c = 2 * atan2(sqrt(a), sqrt(1-a))
d = R * c
R = 6371 # mean radius of the Earth in km
(source of formula: link)
The implementation of this in Java would look like the following:
private double distance(double lat1, double lon1, double lat2, double lon2) {
final int R = 6371;
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));
return R * c;
}
/**
* Calculate the distance between two points in meters using the Haversine formula
*
* #param lat latitude of the first point
* #param lon longitude of the first point
* #param lat2 latitude of the second point
* #param lon2 longitude of the second point
* #return the distance between the two points in meters
**/
public static double distance(double lat, double lon, double lat2, double lon2) {
final double R = 6371e3;
final double la = lat * java.lang.Math.PI / 180;
final double laa = lat2 * java.lang.Math.PI / 180;
final double lo = (lat2 - lat) * java.lang.Math.PI / 180;
final double loo = (lon2 - lon) * java.lang.Math.PI / 180;
final double a = java.lang.Math.sin(lo / 2) * java.lang.Math.sin(lo / 2) + java.lang.Math.cos(la) * java.lang.Math.cos(laa) * java.lang.Math.sin(loo / 2) * java.lang.Math.sin(loo / 2);
final double c = 2 * java.lang.Math.atan2(java.lang.Math.sqrt(a), java.lang.Math.sqrt(1 - a));
return R * c;
}

How do I find the coordinates (latitude, longitude) at 100m in 90° direction from a known location?

37.545892, 126.978445 How do I find the coordinates (latitude, longitude) at 100m in 90 ° direction?
Find out the conclusion.
public static double[] moveLocation(double latitude, double longitude, double direction, double length){
double distRadians = length / (6372797.6);
double rbearing = direction * Math.PI / 180.0;
double lat1 = latitude * Math.PI / 180;
double lon1 = longitude * Math.PI / 180;
double lat2 = Math.asin(Math.sin(lat1) * Math.cos(distRadians) + Math.cos(lat1)
* Math.sin(distRadians) * Math.cos(rbearing));
double lon2 = lon1 + Math.atan2(Math.sin(rbearing) * Math.sin(distRadians) * Math.cos(lat1),
Math.cos(distRadians) - Math.sin(lat1) * Math.sin(lat2));
lat2 = lat2 * 180 / Math.PI;
lon2 = lon2 * 180 / Math.PI;
return new double[]{ lat2, lon2 };
}

distance not showing correctly using the latitude and longitude android

I have a app where I am showing the nearest event (place) distance in km using the Latitude and Longitude. Users latitude and longitude is variable but events latitude and longitude are fixed.However, I am not able to get the correct distance is km. for example correct distance is 6.7 km in google map but its showing 8663.90 km. I am novice in android so unable to get the solution. any help will be great!! my codes are
{ double doubleInstance = d.getDistance(Lat1, Lon1, d.getLatitude(), d.getLongitude(), "N");
String dInstance = String.format("%.2f",doubleInstance);
lblview1.setText(" " + String.valueOf(dInstance) + " Km"); }
and
{ public double getDistance(double lat1, double lon1, double lat2, double lon2, String unit) {
int Radius = 6371;// radius of earth in Km
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("####");
int kmInDec = Integer.valueOf(newFormat.format(km));
double meter = valueResult % 1000;
int meterInDec = Integer.valueOf(newFormat.format(meter));
Log.i("Radius Value", "" + valueResult + " KM " + kmInDec
+ " Meter " + meterInDec);
return Radius * c;
} }
Set your Event location. And get your current location using location manager.
double latitude=lat;
double longitude=lng;
float distance=0;
Location crntLocation=new Location("crntlocation");
crntLocation.setLatitude(currentLatitude);
crntLocation.setLongitude(currentLongitude);
Location eventLocation=new Location("eventlocation");
eventLocation.setLatitude(latitude);
eventLocation.setLongitude(longitude);
//float distance = crntLocation.distanceTo(eventLocation); in meters
distance =crntLocation.distanceTo(eventLocation) / 1000; // in kms
Use Location class method to get distance between two coordinates like;
Location.distanceBetween(obj.getLatitude(), obj.getLongitude(),
mapCircle.getCenter().latitude, mapCircle.getCenter().longitude, distance);

Calculate distance in miles only between two latitude and longitude

I have some confusion about calculation distance in miles. Whenever i am going to calculate in online it giving different result rather than i am using the below methods.
I need the distance in only miles. What the correction required in the below methods.
public double calculationByDistance(Location loc1, Location loc2) {
int Radius = 6371;// radius of earth in Km
double lat1 = loc1.getLatitude();
double lat2 = loc2.getLatitude();
double lon1 = loc1.getLongitude();
double lon2 = loc2.getLongitude();
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;
km = km * 0.62137;
DecimalFormat newFormat = new DecimalFormat("####");
int kmInDec = Integer.valueOf(newFormat.format(km));
double meter = valueResult % 1000;
int meterInDec = Integer.valueOf(newFormat.format(meter));
Log.e("Radius Value", "" + valueResult + " KM " + kmInDec
+ " Meter " + meterInDec);
return Radius * c;
}
If anyone have idea please reply.
Thanks in advance...

midpoint between two latitude and longitude

I am trying to convert the code snippet given in this http://www.movable-type.co.uk/scripts/latlong.html into java. But I am not getting same result as that of site. Here is my code to find the midpoint between two points where their latitudes and longitudes are given
midPoint(12.870672,77.658964,12.974831,77.60935);
public static void midPoint(double lat1,double lon1,double lat2,double lon2)
{
double dLon = Math.toRadians(lon2-lon1);
double Bx = Math.cos(lat2) * Math.cos(dLon);
double By = Math.cos(lat2) * Math.sin(dLon);
double lat3 = Math.atan2(Math.sin(lat1)+Math.sin(lat2),Math.sqrt( (Math.cos(lat1)+Bx)*(Math.cos(lat1)+Bx) + By*By) );
double lon3 = lon1 + Math.atan2(By, Math.cos(lat1) + Bx);
System.out.print(lat3 +" " + lon3 );
}
I am not sure whethe dLon is correct or not. So please help me guys to figure it out. P.S.I need to find the latitude and longitude of the midpoint
You need to convert to radians. Change it to the following:
public static void midPoint(double lat1,double lon1,double lat2,double lon2){
double dLon = Math.toRadians(lon2 - lon1);
//convert to radians
lat1 = Math.toRadians(lat1);
lat2 = Math.toRadians(lat2);
lon1 = Math.toRadians(lon1);
double Bx = Math.cos(lat2) * Math.cos(dLon);
double By = Math.cos(lat2) * Math.sin(dLon);
double lat3 = Math.atan2(Math.sin(lat1) + Math.sin(lat2), Math.sqrt((Math.cos(lat1) + Bx) * (Math.cos(lat1) + Bx) + By * By));
double lon3 = lon1 + Math.atan2(By, Math.cos(lat1) + Bx);
//print out in degrees
System.out.println(Math.toDegrees(lat3) + " " + Math.toDegrees(lon3));
}
Even easier with Android Google Maps Utilities:
LatLngBounds bounds = new LatLngBounds(start, dest);
bounds.getCenter();
Update:
Better use the builder (for why see Bad Losers Answer):
LatLngBounds.builder().include(start).include(dest).build().getCenter();
Please use LatLngBounds with the builder rather than the constructor if you want to correctly handle transgression of the antimeridian (longitude +/-180).
Here is the test illustrating the problem:
LatLng mp = midPoint(new LatLng(-43.95139,-176.56111),new LatLng(-36.397816,174.663496));
public static LatLng midPoint (LatLng SW, LatLng NE) {
LatLngBounds bounds = new LatLngBounds(SW, NE);
Log.d("BAD!", bounds.toString() + " CENTRE: " + bounds.getCenter().toString());
bounds = LatLngBounds.builder().include(SW).include(NE).build();
Log.d("GOOD", bounds.toString() + " CENTRE: " + bounds.getCenter().toString());
return bounds.getCenter();
}
Actual results:
BAD!: LatLngBounds{southwest=lat/lng: (-43.95139,-176.56111), northeast=lat/lng: (-36.397816,174.663496)} CENTRE: lat/lng: (-40.174603,-0.948807)
GOOD: LatLngBounds{southwest=lat/lng: (-43.95139,174.663496), northeast=lat/lng: (-36.397816,-176.56111)} CENTRE: lat/lng: (-40.174603,179.051193)
The constructor technique produces a central longitude out by 180 degrees!
You need to convert you lat and lon values used in the other formulas to Radians also. You can see this in the code ~3/5ths of the way down the page. The clue was given at the end of the spherical law of cosines distance formula:
(Note that here and in all subsequent code fragments, for simplicity I do not show conversions from degrees to radians; see below for complete versions).
Here's #dogbane's Java code converted to TypeScript.
type LatLng = {
lat: number;
lng: number;
};
function calculateMidPoint(latLngA: LatLng, latLngB: LatLng) {
function toRadians(degress: number): number {
return degress * (Math.PI / 180);
}
function toDegrees(radians: number): string {
return (radians * (180 / Math.PI)).toFixed(4);
}
const lngDiff = toRadians(latLngB.lng - latLngA.lng);
const latA = toRadians(latLngA.lat);
const latB = toRadians(latLngB.lat);
const lngA = toRadians(latLngA.lng);
const bx = Math.cos(latB) * Math.cos(lngDiff);
const by = Math.cos(latB) * Math.sin(lngDiff);
const latMidway = toDegrees(
Math.atan2(
Math.sin(latA) + Math.sin(latB),
Math.sqrt((Math.cos(latA) + bx) * (Math.cos(latA) + bx) + by * by)
)
);
const lngMidway = toDegrees(lngA + Math.atan2(by, Math.cos(latA) + bx));
console.log(
`Midway point between ${latLngA} and ${latLngB} is: Lat: ${latMidway}, lng: ${lngMidway}`
);
}
Following is #dogbane 's java code converted to Kotlin:
private fun midPoint(lat1: Double, lon1: Double, lat2: Double, lon2: Double) : String {
var lat1 = lat1
var lon1 = lon1
var lat2 = lat2
val dLon: Double = Math.toRadians(lon2 - lon1)
//convert to radians
lat1 = Math.toRadians(lat1)
lat2 = Math.toRadians(lat2)
lon1 = Math.toRadians(lon1)
val Bx: Double = Math.cos(lat2) * Math.cos(dLon)
val By: Double = Math.cos(lat2) * Math.sin(dLon)
val lat3: Double = Math.atan2(Math.sin(lat1) + Math.sin(lat2), Math.sqrt((Math.cos(lat1) + Bx) * (Math.cos(lat1) + Bx) + By * By))
val lon3: Double = lon1 + Math.atan2(By, Math.cos(lat1) + Bx)
var result: String = ""
result = Math.toDegrees(lat3).toString() + "," + Math.toDegrees(lon3).toString()
return result;
}
My last job I made a tracking module and I was using this formula to calculate the distance between 2 coordinates.
//Location lat and lon
double locLat = -23.548333;
double locLon = -46.636111;
//Destination lat and lon
double dstLat = -22.902778;
double dstLon = -43.206667;
double arcoAB = 90 - (dstLat);
double arcoAC = 90 - (locLat);
double difLon = locLon - (dstLon);
double cosA = Math.cos(Math.toRadians(arcoAC)) * Math.cos(Math.toRadians(arcoAB)) + Math.sin(Math.toRadians(arcoAC)) * Math.sin(Math.toRadians(arcoAB)) * Math.cos(Math.toRadians(difLon));
double acosCosA = Math.toDegrees(Math.acos(cosA));
double raio = 2 * Math.PI * 6371;
double distance = (raio * acosCosA) / 360;
return distance; //Distance in KM, convert to anything else (miles, meters..) if you need..
You can get the mid point dividing the distance by 2.
Ah, this another formula works too:
double dLat = Math.toRadians(dstLat - locLat);
double dLon = Math.toRadians(dstLon - locLon);
double a = Math.sin(dLat / 2) * Math.sin(dLat / 2)
+ Math.cos(Math.toRadians(locLat)) * Math.cos(Math.toRadians(dstLat))
* Math.sin(dLon / 2) * Math.sin(dLon / 2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
double d = 6371 * c;
return d; //Distance in KM

Categories