我在现实生活中有以下项目设置:
雷达是静止的,这意味着它始终具有相同的位置。 A
- 项可以移动,其位置可以是任何位置。从雷达中我可以读取与x
相关的y
和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;
}
现在给定雷达的地理坐标,x
相对于雷达的y
和A
坐标以及雷达相对于北方的面向方向,我该怎么办?计算A
的绝对地理坐标?
地球的曲率不是问题,因为x
和/或y
的最大值不能超过几百米。
答案 0 :(得分: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);
答案 1 :(得分:2)
通常,您可以使用以下步骤:
这种转换有很多资源,请检查一下,例如: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到/来自大地测量转换的示例代码,请查看matlab代码http://www.mathworks.de/de/help/map/ref/ecef2geodetic.html, 或使用像GDAL(http://www.gdal.org/)
这样的库答案 2 :(得分:1)
我认为应该可以这样做:将x
和y
坐标转换为极坐标r
和theta
,(将雷达作为起源)。减去雷达的旋转,然后转换回笛卡尔坐标。然后你只需要转换为纬度和经度并添加雷达的坐标。
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));
}
不幸的是,这似乎不起作用,我无法弄清楚原因。
如果你想以东/西/北/南的正度表示你的坐标,你还必须检查它们是否为负并反转它们和那个方向的方向。
答案 3 :(得分:1)
答案 4 :(得分: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;
}
答案 5 :(得分:0)
您可以旋转雷达本地系统中的所有坐标-10°,然后只需将雷达的x / y坐标添加到A对象坐标。