高程海拔离线实时查询显示终极版/体验友好/全网首创极精简版本/可输入地址或者经纬度查询
一、前言说明
很多人用gdal读取tif文件来实现高程海拔值的读取,无奈这个库编译很费劲,一种编译器就要一个版本,很多人都知道,我做的程序,写的代码,要的就是通吃所有,而且要尽量简单,简单的同时还是实现对应的功能,于是不断的想啊想,一定要想到对应的办法,可以说我这个思路办法全网独创唯一,几百行代码就可以搞定,不用费劲巴拉的去编译gdal库,换个系统折腾的要命,比如要在安卓上运行。后面搜索各大AI来查找对应关键字,居然都是推荐我的方法,之前已经写过相关的文章,都被AI学习了。
这次的终极版是在多个用户反馈后更新的,有些用户发现有误差,后面仔细对比确实有误差,因为精度的问题,如果去官网下载更精细的tif文件的话,就是非常准确的,如果官网提供的都有问题,那就不是我的问题了。本次主要增加了直接下拉框选择地名,主动查询一些标志的地点,来快速核对海拔值是否有误差,对比了多个提供高程海拔查询的在线网站,基本上都很烂,连位置都不对,比如按照要求输入的wgs84坐标,并没有去做转换贴在高德地图上。我这起码都是自适应转换的,而且还可以直接输入中文地名,单击查询海拔后,会先查询这个地名的wgs84经纬度坐标,然后再查询海拔,瞬间完成,体验非常友好。
二、效果图

三、相关代码
#include "demread.h"
#include "qfile.h"
#include "qtextstream.h"
#include "qdatetime.h"
#include "qelapsedtimer.h"
#include "qdebug.h"
#pragma execution_character_set("utf-8")
#define TIMEMS qPrintable(QTime::currentTime().toString("HH:mm:ss zzz"))
int DemRead::width = 0;
int DemRead::height = 0;
qreal DemRead::posX = 0;
qreal DemRead::posY = 0;
qreal DemRead::scaleX = 0;
qreal DemRead::scaleY = 0;
qreal DemRead::rotateX = 0;
qreal DemRead::rotateY = 0;
bool DemRead::cancel = false;
QMap<qint16, QVector<qint16> > DemRead::datas = QMap<qint16, QVector<qint16> >();
void DemRead::readFile(const QString &fileName)
{
//ncols 6542
//nrows 4007
//xllcorner 69.578333333333
//yllcorner 14.948333333333
//cellsize 0.01
//NODATA_value -9999
//-9999 -9999 ... 158 -9999
if (datas.size() > 0) {
return;
}
//启动用时计算
QElapsedTimer time;
time.start();
QFile file(fileName);
if (!file.open(QFile::ReadOnly)) {
return;
}
qint16 index = -1;
QStringList list;
QTextStream in(&file);
while (!in.atEnd() && !cancel) {
index++;
QString line = in.readLine();
list = line.split(' ');
QString last = list.last();
if (index == 0) {
width = last.toInt();
} else if (index == 1) {
height = last.toInt();
} else if (index == 2) {
posX = last.toDouble();
} else if (index == 3) {
posY = last.toDouble();
} else if (index == 4) {
//水平方向是经度值/往右是+
//垂直方向是纬度值/往下是-
scaleX = last.toDouble();
scaleY = -scaleX;
} else if (index == 5) {
//无效值
} else {
//这里开始才是真正的高程值/逐行数据添加到队列
QVector<qint16> data;
foreach (QString l, list) {
data << (l == "x" ? -9999 : l.toInt());
}
datas.insert(index - 6, data);
}
}
//这里读到的是左下角的/需要转成左上角
posY = posY - scaleY * height;
file.close();
qDebug() << "用时:" << time.elapsed() << "信息:" << width << height << posX << posY << scaleX << scaleY << rotateX << rotateY << datas.count();
}
QPointF DemRead::getLngLat(QPoint pos)
{
int x = pos.x();
int y = pos.y();
double x2 = posX + scaleX * x + rotateX * y;
double y2 = posY + rotateY * x + scaleY * y;
return QPointF(x2, y2);
}
QPoint DemRead::getPos(QPointF lnglat)
{
double x = lnglat.x();
double y = lnglat.y();
int x2 = (scaleY * x - rotateX * y + posY * rotateX - posX * scaleY) / (scaleY * scaleX - rotateX * rotateY);
int y2 = (rotateY * x - scaleX * y + scaleX * posY - rotateY * posX) / (rotateY * rotateX - scaleX * scaleY);
return QPoint(x2, y2);
}
int DemRead::getAltitude(QPoint pos)
{
int value = -9999;
int x = pos.x();
int y = pos.y();
if (y < 0 || y >= datas.count()) {
return value;
}
QVector<qint16> data = datas.value(y);
if (x >= 0 && x < data.count()) {
value = data.at(x);
}
return value;
}
int DemRead::getAltitude(QPointF lnglat)
{
return getAltitude(getPos(lnglat));
}
四、相关地址
- 国内站点:https://gitee.com/feiyangqingyun
- 国际站点:https://github.com/feiyangqingyun
- 个人作品:https://blog.csdn.net/feiyangqingyun/article/details/97565652
- 文件地址:https://pan.baidu.com/s/1ZxG-oyUKe286LPMPxOrO2A 提取码:o05q 文件名:bin_mapwidget.zip
五、功能特点
- 支持各种地图源,包括天地图、高德地图、腾讯地图、谷歌地图、微软地图、电子海图、ArcGis、OpenStreet、360地图等。
- 同时支持WGS-84地球坐标系和GCJ-02火星坐标系,如果是天地图、谷歌地图,自动应用WGS-84坐标系,如果是高德地图、腾讯地图,自动应用GCJ-02坐标系。也可以主动设置在WGS-84坐标系加载高德地图,内部会自动处理坐标偏移。
- 同时支持默卡托投影和经纬度投影,比如天地图的地图源可以是默卡托投影或者经纬度投影。
- 每一种地图源都支持在线和离线两种场景需求,可以自定义在线瓦片地址格式和离线瓦片地址格式。
- 多线程下载和加载瓦片图片文件,多线程绘制,自动缓存瓦片文件。
- 在线模式下,可以开启是否缓存文件,指定缓存路径,将下载的瓦片文件存放到本地,默认优先从缓存文件查找,如果存在缓存文件则加载缓存文件,不存在则联网下载。
- 可以任意拖曳地图,鼠标滚轮放大和缩小地图,以鼠标所在位置作为缩放中心点,提供缩放控件手动单击进行操作,支持鼠标左键双击放大和右键双击缩小。
- 多图层机制,支持多个瓦片叠加图层和图形绘制图层,全部采用双缓冲技术,所有的图形和瓦片全部绘制到一个图片文件上,最终再将图片文件绘制到地图控件。不可见区域的图层包括覆盖物不会触发绘制,最大程度降低CPU占用。
- 动态图层机制,瓦片图层和图形图层分离,图形图层不更新的情况下,动态更新底图瓦片图层,任意切换更新多个瓦片图层。无需重新加载整个地图。
- 预加载机制,默认绘制的图层大小以当前区域往四周放大一倍,这样在鼠标拖动和缩放的时候,不会看到明显的加载过程,因为已经提前预加载好了,体验友好。
- 内置了多种图形覆盖物,包括坐标点、纯文本、标注点、折线条、多边形、矩形、圆形、雷达、点聚合、热力图等,可以设置边框颜色粗细、填充颜色和透明度等众多参数。
- 标注点支持旋转角度和提示文本,其中提示文本可以设置在标注点的相对位置,标注点图片支持gif动图,可以动态切换静态图和动图。
- 标注点和提示文本可以设置相对位置,位置包括左侧、右侧、上侧、下侧、中间、左上角、右上角、左下角、右下角。标注点默认按照底部居中对齐,一般圆形图标可以设置中心点对齐。
- 标注点提示文本可设置背景颜色,透明度、颜色边框和粗细,支持换行和多行文字。
- 所有的图形可以动态更新前景色、颜色粗细、背景颜色、颜色透明度等。
- 支持删除单个图形、删除一种类型的图形、删除所有图形、隐藏单个或者所有图形等。
- 支持动态绘制各种图形,开启后直接在地图上鼠标按下绘制,鼠标右键结束绘制,非常方便快捷。
- 在对应图形区域鼠标按下,发出图形单击信号,精准识别单击区域,比如折线以鼠标在折线条上作为判断依据,多边形区域以鼠标在整个多边形区域内为准,而不是以矩形区域,包括圆形也是以圆形内部为准。
- 可以动态启动禁用比例尺、十字线、缩放控件、地图拖曳、键盘操作、滚轮缩放、双击缩放、鼠标追踪等特性。
- 可以任意指定经纬度区域进行瓦片拼接保存成图片文件,也可以直接对整个可视区域或者缓存区域的地图图片文件保存。支持任意多边形轮廓保存成图片,比如某个行政区的瓦片保存。
- 图形可以动态设置zindex层叠顺序,值越大,越显示在前面,内部维护着一个zindex表,默认按照添加的先后顺序增加,后面添加的显示在前面,主动设置后,按照设置的zindex来绘制。
- 支持将QWidget对象作为覆盖物添加到地图控件中,跟随地图移动位置,极大提高灵活性,比如可以将自定义控件直接作为地图控件的子对象加入进去。
- 支持测距和测面积,动态绘制多边形区域,实时动态调整位置和点坐标自动重新计算,可以关闭单个测距测面的图形。
- 内置MarkerMove轨迹移动类,支持历史轨迹数据回放和实时轨迹移动,可设置图标、轨迹线的颜色和粗细、移动速度、移动间隔、平滑移动、自动中心等,支持多条轨迹线条同时移动。
- 内置MarkerLine航迹规划类,支持动态添加航迹点,显示对应箭头,可以动态拖曳调整航迹点的位置,选中点高亮显示。
- 大量使用按需绘制机制,包括内部提供合理的默认值来触发绘制,也可以手动传入参数指定是否需要立即绘制,比如删除了某个覆盖物,有些频繁的操作可以不指定立即绘制,等操作完成后再统一一起绘制,效率更高。
- 默认开启内存瓦片机制,所有加载过的瓦片文件都存储在内存中,下次再次绘制直接从内存取出来绘制,既不需要从联网获取,也不需要从缓存文件获取,直接内存取出来绘制,响应迅速效率最高体验最佳。
- 支持批量添加覆盖物,比如几万个标注点和圆形,都是瞬间完成绘制,相比web网页的方式,性能提升百倍以上。
- 支持街道图、卫星图、混合图、路网图等各种图层,可以任意叠加N个图层,甚至杂交不同地图厂家的瓦片文件。
- 内置缩放动画效果,在缩放的时候先截取上一个地图画面作为缩放动画基准图片,逐步过渡到下一个层级。
- 内置电子放大机制,瓦片图片不存在的时候,优先获取该区域上一图层的瓦片,按照规则裁切图片缩放填充,支持无极缩放。在线和离线模式都支持电子放大,在线情况下主动获取上一级的瓦片,离线情况下主动本地文件查找。
- 电子放大除了支持找上级瓦片,还支持找下级瓦片,比如地图缩小的时候,先找4张下级瓦片按照规则合并到对应区域瓦片,防止缩小的时候看到空白区域。
- 支持双指捏合缩放,在移动端或者任何可以触摸的地方,双指拉大放大地图,双指聚拢缩小地图,平滑动画过渡缩放。
- 提供离线地图下载模块,多线程高速并发下载,可框选指定区域下载瓦片,可指定任意级别下载。
- 提供高程海拔显示模块,离线识别高程海拔数据,传入经纬度即可,无需引入任何第三方模块。
- 纯QWidget绘制,非qml也非web,不依赖qml或者浏览器控件,没有任何第三方库依赖,支持极低性能的嵌入式环境。
- 原创轻量级,核心代码5000行,整体代码10000行,架构漂亮,注释详细,拓展方便,容易学习,适合各种初学者和进阶者,方便二次开发。
- 支持任意Qt版本、任意系统、任意编译器,包括嵌入式linux和各种国产电脑环境。
- 全部原创自研,古法编程,不含任何AI代码,持续迭代更新,商业级别、品质保证。

浙公网安备 33010602011771号