7

我在现实生活中有以下项目设置:

我的设置

雷达是静态的,这意味着它始终具有相同的位置。-itemA可以移动,它的位置可以是任何东西。从雷达上,我可以读取与雷达相关的xy坐标A。我编写了以下类来描述每个项目的位置:

public class Position {
    public enum Direction {
        EAST, WEST, NORTH, SOUTH
    };

    public final Direction latitudeDirection, longitudeDirection;
    public final float latitude, longitude, altitude;

    public Position(Direction latitudeDirection, Direction longitudeDirection,
            float latitude, float longitude, float altitude) {
        this.latitudeDirection = latitudeDirection;
        this.longitudeDirection = longitudeDirection;
        this.latitude = latitude;
        this.longitude = longitude;
        this.altitude = altitude;
    }

    public Position(float radarX, float radarY) {
        // TODO: Implement the question here
        this.altitude = Config.RADAR_POSITION.altitude;
    }

}

class Config {
    // Position of the radar
    public static final Position RADAR_POSITION = new Position(
            Position.Direction.NORTH, // Latitude direction
            Position.Direction.EAST, // Longitude direction
            55.0f, // Latitude
            13.0f, // Longitude
            60.0f); // Altitude

    // Facing direction of the radar in degrees. 0° is north, advancing
    // clockwise.
    public static final float RADAR_FACING_DIRECTION = 10.0f;
}

现在给定雷达的地理坐标,相对于雷达的xy坐标A以及雷达相对于北方的朝向,如何计算 的绝对地理坐标A

地球的曲率不是问题,因为最大值x和/或y不能超过几百米。

4

6 回答 6

3

例如,您可以使用三角函数创建三角形来查找 A 的坐标:

使用三角函数的示例

在这种情况下,Ax = (y)(cos 10) - (x)(cos 80),您可以类似地计算出 Ay。

这样,您永远不会被困在度数中,您只是在以米为单位工作。

强大的解决方案是 Vishal 在 OP 中的评论,该评论是在我绘图和扫描时发布的:

xnew = x * cos(theta) - y * sin(theta); 
ynew = x * sin(theta) + y * cos(theta);
于 2013-03-12T18:37:39.700 回答
2

一般来说,您可以使用以下步骤:

  1. 将您的雷达位置(纬度、经度、高度)转换为公制地心地心固定 xyz 系统 (ECEF)
  2. 然后,您可以在这个公制系统中使用/组合描述雷达旋转和物体位置的任何旋转和平移参数/矩阵
  3. 将新获取的 xzy 坐标反向变换为 lat/lon/h

这种转换有很多资源,检查一下,例如:http ://www.gmat.unsw.edu.au/snap/gps/clynch_pdfs/coordcvt.pdf

如果需要,您还可以引入场景坐标系 (ENU)。这是一个很好的概述,描述了 UTM、ECEF、ENU 和大地坐标(Lat/lon/h)的关系: http ://www.dirsig.org/docs/new/coordinates.html

如果您需要 ECEF 与 Geodetic 转换的示例代码,请查看 matlab 代码http://www.mathworks.de/de/help/map/ref/ecef2geodetic.html或使用 GDAL 之类的库(http://www.gdal.org/

于 2013-03-12T18:39:45.053 回答
1

最后我解决了。代码附在下面。由于 Samuel Edwin Ward 的回答给了我灵感,我会接受他的回答。

public Position(float radarX, float radarY) {

    // Convert A's position to distance and bearing in relation to the North 
    double objDistance = (Math.hypot(radarX, radarY) / 6367500 /* Mean earth radius */);
    double objBearing = (Math.atan2(radarY, radarX) + Math.toRadians(Config.RADAR_BEARING));

    // Convert the Radar's geographic coordinates to radians
    double latitudeRadar = Math.toRadians(Config.RADAR_POSITION.latitude);
    double longitudeRadar = Math.toRadians(Config.RADAR_POSITION.longitude);

    // Calculate A's geographic coordinates in radians
    double latitudeObject = Math.asin(Math.sin(latitudeRadar)*Math.cos(objDistance) + 
            Math.cos(latitudeRadar)*Math.sin(objDistance)*Math.cos(objBearing));
    double longitudeObject = longitudeRadar + Math.atan2(Math.sin(objBearing)*Math.sin(objDistance)*Math.cos(latitudeRadar), 
            Math.cos(objDistance)-Math.sin(latitudeRadar)*Math.sin(latitudeObject));

    // Normalize to -180 ... +180 degrees
    longitudeObject = (longitudeObject+3*Math.PI) % (2*Math.PI) - Math.PI;  

    // Set the A's coordinates in degrees
    this.latitude = (float) Math.toDegrees(latitudeObject);
    this.longitude = (float) Math.toDegrees(longitudeObject);

    // Set the rest of the arguments
    this.latitudeDirection = Config.RADAR_POSITION.latitudeDirection;
    this.longitudeDirection = Config.RADAR_POSITION.longitudeDirection;
    this.altitude = Config.RADAR_POSITION.altitude;
}
于 2013-03-14T14:27:40.727 回答
1

这对转换有帮助吗? http://en.wikipedia.org/wiki/Geodetic_system#From_geodetic_to_ECEF

于 2013-03-12T18:41:27.833 回答
1

我认为应该可以这样做:将xy坐标转换为极坐标rtheta,(以雷达为原点)。减去雷达的旋转,并转换回笛卡尔坐标。然后你只需要转换为纬度和经度并添加雷达的坐标。

double r = Math.hypot(radarX, radarY);
double theta = Math.atan2(radarY, radarX);
theta -= Math.toRadians(Config.RADAR_FACING_DIRECTION);
float x = (float) r * Math.cos(theta);
float y = (float) r * Math.sin(theta);
longitude = metersToLongitude(Config.RADAR_POSITION, y) + Config.RADAR_POSITION.longitude;
latitude = metersToLatitude(Config.RADAR_POSITION, x) + Config.RADAR_POSITION.latitude;

我在维基百科上找到了纬度和经度长度的公式。纬度在任何地方都相同,但在两极附近经度变小。

static float metersToLatitude(Position near, float meters) {
    return meters / 110.6*1000;
}

static float metersToLongitude(Position near, float meters) {
    float lat = Math.toRadians(near.latitude);
    return meters /
        (111132.954 - 559.822 * Math.cos(2*lat) + 1.175 * Math.cos(4*lat));
}

不幸的是,这似乎不起作用,我不知道为什么。

如果您想以东/西/北/南的正度数表示您的坐标,您还必须检查它们是否为负数,并在这种情况下反转它们和方向。

于 2013-03-12T18:22:02.567 回答
0

您将雷达本地系统中的所有坐标旋转 -10°,然后只需将雷达的 x/y 坐标添加到 A 对象坐标即可。

于 2013-03-12T18:21:24.653 回答