一、经纬度基础知识
1. 经纬度表示方法
经度(Longitude): 东西方向,范围-180°到+180°
东经为正,西经为负
纬度(Latitude): 南北方向,范围-90°到+90°
北纬为正,南纬为负
2. 常见表示格式
十进制度表示法(Decimal Degrees, DD)
例如: 39.9042°N, 116.4074°E
QT中常用double类型存储
度分秒表示法(Degrees Minutes Seconds, DMS)
例如: 39°54'15.12"N, 116°24'26.64"E
度分表示法(Degrees Decimal Minutes, DDM)
例如: 39°54.252'N, 116°24.444'E
二、QT中的经纬度处理
1. 基本数据类型
// 通常使用double类型存储经纬度
double latitude = 39.9042; // 纬度
double longitude = 116.4074; // 经度
2. 格式转换函数
DD转DMS
QString convertDDtoDMS(double decimalDegrees, bool isLatitude) {
int degrees = static_cast<int>(decimalDegrees);
double remaining = abs(decimalDegrees - degrees) * 60;
int minutes = static_cast<int>(remaining);
double seconds = (remaining - minutes) * 60;
QString direction;
if(isLatitude) {
direction = decimalDegrees >= 0 ? "N" : "S";
} else {
direction = decimalDegrees >= 0 ? "E" : "W";
}
return QString("%1°%2'%3\"%4")
.arg(abs(degrees))
.arg(minutes, 2, 10, QLatin1Char('0'))
.arg(seconds, 5, 'f', 2, QLatin1Char('0'))
.arg(direction);
}
DMS转DD
double convertDMStoDD(const QString &dms) {
QRegExp rx("([+-]?\\d{1,3})[°d](\\d{1,2})['m](\\d{1,2}(?:\\.\\d+)?)[\"s]?([NSEW]?)");
if(rx.indexIn(dms) != -1) {
double degrees = rx.cap(1).toDouble();
double minutes = rx.cap(2).toDouble();
double seconds = rx.cap(3).toDouble();
QString direction = rx.cap(4);
double decimal = degrees + minutes/60.0 + seconds/3600.0;
if(direction == "S" || direction == "W") {
decimal *= -1;
}
return decimal;
}
return 0.0;
}
三、QT中的地理坐标类
1. QGeoCoordinate类(QtLocation模块)
#include <QGeoCoordinate>
// 创建坐标对象
QGeoCoordinate beijing(39.9042, 116.4074);
// 获取经纬度
double lat = beijing.latitude();
double lon = beijing.longitude();
// 计算两点间距离(米)
QGeoCoordinate shanghai(31.2304, 121.4737);
double distance = beijing.distanceTo(shanghai);
// 转换为不同格式
QString dmsString = beijing.toString(QGeoCoordinate::DegreesMinutesSecondsWithHemisphere);
2. 坐标系转换
QT中通常使用WGS84坐标系(全球GPS使用),有时需要转换到其他坐标系
// 使用QGeoProjection进行坐标转换(需要QtLocation模块)
// 例如: WGS84转Web墨卡托
QGeoCoordinate wgs84Coord(39.9042, 116.4074);
QWebMercator webMercator;
QPointF projected = webMercator.project(wgs84Coord);
四、实用功能实现
1. 验证经纬度有效性
bool isValidCoordinate(double latitude, double longitude) {
return (latitude >= -90.0 && latitude <= 90.0) &&
(longitude >= -180.0 && longitude <= 180.0);
}
2. 计算两点间距离( Haversine公式)
double calculateDistance(double lat1, double lon1, double lat2, double lon2) {
const double R = 6371000; // 地球半径(米)
double phi1 = qDegreesToRadians(lat1);
double phi2 = qDegreesToRadians(lat2);
double deltaPhi = qDegreesToRadians(lat2 - lat1);
double deltaLambda = qDegreesToRadians(lon2 - lon1);
double a = qSin(deltaPhi/2) * qSin(deltaPhi/2) +
qCos(phi1) * qCos(phi2) *
qSin(deltaLambda/2) * qSin(deltaLambda/2);
double c = 2 * qAtan2(qSqrt(a), qSqrt(1-a));
return R * c;
}
3. 在地图上显示(QQuickItem或QGraphicsView)
// 使用QML的Map组件
Map {
id: map
center: QtPositioning.coordinate(39.9042, 116.4074) // 北京坐标
zoomLevel: 12
MapItemView {
model: myModel
delegate: MapQuickItem {
coordinate: QtPositioning.coordinate(latitude, longitude)
// 其他属性...
}
}
}
五、常见问题与解决方案
精度问题
使用double而非float存储经纬度
比较坐标时使用容差范围而非直接相等
坐标偏移问题
中国地区需注意GCJ-02(火星坐标)与WGS84的转换
可使用第三方库如proj.qt进行复杂坐标转换
性能优化
大量坐标点处理时考虑空间索引(如R树)
使用QGeoRectangle进行区域筛选
国际化支持
注意不同地区的坐标显示习惯
提供多种格式选择功能
六、学习资源推荐
Qt官方文档: QtLocation模块
地理信息系统(GIS)基础理论
PROJ库: 强大的坐标转换库
EPSG坐标系数据库