Поиск пересечения двух геодезических линий в широте и долготеJAVA

Программисты JAVA общаются здесь
Ответить Пред. темаСлед. тема
Anonymous
 Поиск пересечения двух геодезических линий в широте и долготе

Сообщение Anonymous »

У меня есть проблема с приведенным кодом, который не возвращает правильный ответ. Он пытается найти пересечение двух линий на поверхности Земли с учетом кривизны Земли. Я собрал это из фрагментов из сети, поэтому я не очень понимаю математику, стоящую за ней, и не уверен, в чем проблема. Правильный ответ составляет около -26.5098, но код возвращает -26.373957.import org.apache.commons.math3.geometry.euclidean.threed.Vector3D;

public class Intersection {

// WGS84 ellipsoid constants
private static final double SEMI_MAJOR_AXIS = 6378137.0; // meters
private static final double FLATTENING = 1 / 298.257223563;
private static final double SEMI_MINOR_AXIS = SEMI_MAJOR_AXIS * (1 - FLATTENING);
private static final double ECCENTRICITY_SQUARED = 2 * FLATTENING - FLATTENING * FLATTENING;

public static void main(String[] args) {
// Example geodesic lines (latitude and longitude in degrees)
double[] line1Start = {-25.0, 10.0};
double[] line1End = {-28.0, 13.0};
double[] line2Start = {-25.0, 13.0};
double[] line2End = {-28.0, 10.0};
int option = 0;

double[] intersection = findIntersection(line1Start, line1End, line2Start, line2End, option);

if (intersection != null) {
System.out.printf("Intersection Point: Latitude = %.6f, Longitude = %.6f%n",
intersection[0], intersection[1]);
} else {
System.out.println("No intersection found or lines are coincident.");
}
}

public static double[] findIntersection(double[] line1Start, double[] line1End,
double[] line2Start, double[] line2End, int option) {
// Convert geodetic coordinates to 3D Cartesian coordinates
Vector3D p1 = geodeticToCartesian2(line1Start[0], line1Start[1]);
Vector3D p2 = geodeticToCartesian2(line1End[0], line1End[1]);
Vector3D p3 = geodeticToCartesian2(line2Start[0], line2Start[1]);
Vector3D p4 = geodeticToCartesian2(line2End[0], line2End[1]);

double check[] = cartesianToGeodetic(p1);
System.out.println (String.format("Check 1: %.6f", check[0]) + String.format(" %.6f", check[1]));

// Compute normal vectors for the planes containing the geodesics
Vector3D n1 = p1.crossProduct(p2);
Vector3D n2 = p3.crossProduct(p4);

// Find the intersection line of the two planes
Vector3D intersectionLine = n1.crossProduct(n2);
check = cartesianToGeodetic(intersectionLine);
System.out.println (String.format("Check 2: %.6f", check[0]) + String.format(" %.6f", check[1]));

// Normalize the intersection line to find the intersection points on the spheroid

// These two steps are commented out as were giving very wrong results

// Vector3D intersectionPoint1 = intersectionLine.normalize();
// Vector3D intersectionPoint2 = intersectionLine.negate().normalize();
Vector3D intersectionPoint1 = intersectionLine;
Vector3D intersectionPoint2 = intersectionLine.negate();

// Convert back to geodetic coordinates
double[] geodeticPoint1 = cartesianToGeodetic(intersectionPoint1);
double[] geodeticPoint2 = cartesianToGeodetic(intersectionPoint2);
System.out.println (String.format("GP 1: %.6f", geodeticPoint1[0]) + String.format(" %.6f", geodeticPoint1[1]));
System.out.println (String.format("GP 2: %.6f", geodeticPoint2[0]) + String.format(" %.6f", geodeticPoint2[1]));

// Check which intersection point lies on both geodesics
if (isPointOnGeodesic(geodeticPoint1, line1Start, line1End) &&
isPointOnGeodesic(geodeticPoint1, line2Start, line2End)) {
return geodeticPoint1;
}
else {
System.out.println("Checking point 2");
if (isPointOnGeodesic(geodeticPoint2, line1Start, line1End) &&
isPointOnGeodesic(geodeticPoint2, line2Start, line2End)) {
return geodeticPoint2;
}
}
return null;
}

private static boolean isPointOnGeodesic(double[] gp, double[] ls, double[] le) {
// TODO Auto-generated method stub
double ah = haversine(ls[0], ls[1], gp[0], gp[1]);
double bh = haversine(gp[0], gp[1], le[0], le[1]);
double ch = haversine(ls[0], ls[1], le[0], le[1]);

System.out.println (String.format("ah : %.2f", ah) +String.format(" bh : %.2f", bh) + String.format(" ch : %.6f", ch));
System.out.println (String.format("ah + bh : %.6f", ah + bh) + String.format(" ch : %.6f", ch));
if ( (ah+bh) == ch ) return true;

return false;
}

private static double haversine(double lat1, double lon1, double lat2, double lon2) {

// Convert latitude and longitude from degrees to radians
double lat1Rad = Math.toRadians(lat1);
double lon1Rad = Math.toRadians(lon1);
double lat2Rad = Math.toRadians(lat2);
double lon2Rad = Math.toRadians(lon2);

// Haversine formula
// Why is this not using FLATTENING? Does it matter?
double dLat = lat2Rad - lat1Rad;
double dLon = lon2Rad - lon1Rad;
double a = Math.pow(Math.sin(dLat / 2), 2) +
Math.cos(lat1Rad) * Math.cos(lat2Rad) * Math.pow(Math.sin(dLon / 2), 2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));

// Distance in metres
return SEMI_MAJOR_AXIS * c;
}

private static double[] cartesianToGeodetic(Vector3D point) {
double x = point.getX();
double y = point.getY();
double z = point.getZ();
double longitude = Math.atan2(y, x); // Longitude in radians

double p = Math.sqrt(x * x + y * y);
double theta = Math.atan2(z * SEMI_MAJOR_AXIS, p * SEMI_MINOR_AXIS);

double sinTheta = Math.sin(theta);
double cosTheta = Math.cos(theta);

double latitude = Math.atan2(
z + ECCENTRICITY_SQUARED * SEMI_MINOR_AXIS * sinTheta * sinTheta * sinTheta,
p - ECCENTRICITY_SQUARED * SEMI_MAJOR_AXIS * cosTheta * cosTheta * cosTheta
);

double sinLatitude = Math.sin(latitude);
double N = SEMI_MAJOR_AXIS / Math.sqrt(1 - ECCENTRICITY_SQUARED * sinLatitude * sinLatitude);

double altitude = p / Math.cos(latitude) - N;

// Convert radians to degrees for latitude and longitude
double latitudeDegrees = Math.toDegrees(latitude);
double longitudeDegrees = Math.toDegrees(longitude);

return new double[]{latitudeDegrees, longitudeDegrees, altitude};
}

public static Vector3D geodeticToCartesian2(double latitude, double longitude) {
// Convert latitude and longitude from degrees to radians
double altitude = 0;
double latRad = Math.toRadians(latitude);
double lonRad = Math.toRadians(longitude);

// Calculate the radius of curvature in the prime vertical
double N = SEMI_MAJOR_AXIS / Math.sqrt(1 - ECCENTRICITY_SQUARED * Math.pow(Math.sin(latRad), 2));

// Calculate Cartesian coordinates
double x = (N + altitude) * Math.cos(latRad) * Math.cos(lonRad);
double y = (N + altitude) * Math.cos(latRad) * Math.sin(lonRad);
double z = ((1 - ECCENTRICITY_SQUARED) * N + altitude) * Math.sin(latRad);

return new Vector3D(x, y, z);
}
}


Подробнее здесь: https://stackoverflow.com/questions/796 ... -longitude
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Поиск пересечения двух геодезических линий в широте и долготе
    Anonymous » » в форуме JAVA
    0 Ответы
    8 Просмотры
    Последнее сообщение Anonymous
  • Поиск по широте и долготе MYSQL PDO с несколькими предложениями in
    Anonymous » » в форуме Php
    0 Ответы
    19 Просмотры
    Последнее сообщение Anonymous
  • Получить название страны по широте и долготе
    Anonymous » » в форуме Php
    0 Ответы
    8 Просмотры
    Последнее сообщение Anonymous
  • Как получить адрес по широте и долготе в Django GeoIP?
    Anonymous » » в форуме Python
    0 Ответы
    23 Просмотры
    Последнее сообщение Anonymous
  • 5x5 Проблема пересечения матрицы путем пересечения максимума 4-салона [закрыто]
    Anonymous » » в форуме Python
    0 Ответы
    8 Просмотры
    Последнее сообщение Anonymous

Вернуться в «JAVA»