地图是很多项目中不可或缺的内容,在无网络环境下需要使用离线地图,如果在软件中需要使用离线地图,就需要把QT和百度离线地图相结合。
离线地图部分参考博客:百度离线地图JS API V3.0_百度地图 js api 旧版本-CSDN博客
代码及组件部分可直接下载上述大佬分享的文件。
根据百度地图开发者平台的描述,地图可以通过一个HTML来显示,因此我打算将与地图相关的功能全部通过原生HTML和JS来实现,Qt仅负责与地图的通信及显示地图。
该专栏会根据我的地图制作进度进行更新。由于项目尚处于开发阶段,暂时不会开源,只会分享部分源码和一些关键点,毕竟随时可能会发生变动。
我使用的开发工具是 Webstorm,通过谷歌浏览器查看页面时,不建议直接双击本地文件夹下的 HTML 文件来启用网页,而是应通过开发工具或在服务器环境下启动。直接双击启动可能导致某些 JavaScript 无法正常运行。其原因在于,双击启动使用的是 `file://` 协议直接打开 HTML 文件,浏览器会将尝试加载的所有资源(如 JavaScript 文件、JSON 文件、API 请求等)视为跨域请求。如果这些资源未通过 HTTP/HTTPS 协议加载,浏览器可能会拒绝访问,导致功能无法正常执行。
稍微分享一下项目的路径文件夹,按照我的来就行。自己下载的瓦片、模块等文件也按照我的路径存放,文件名保持一致。
下面是由html调用的js的一部分,关于设置中心点以及设置瓦片路径以及层级的,顺带一提,我的瓦片是淘宝买的,不贵,那个什么望远网我现在用不了了,不知道是暂时的还是怎么。
var outputPath = 'tiles/'; // 地图瓦片所在的文件夹
var fromat = ".jpg"; // 格式
var mapOptions = { // 最大和最小瓦片层级
minZoom: 12,
maxZoom: 17,
mapType: BMAP_SATELLITE_MAP
};
var map = new BMap.Map("allmap", mapOptions); // 创建地图实例
var point = new BMap.Point(118.304779,24.42505); // 创建点坐标
map.centerAndZoom(point, 16); // 初始化地图,设置中心点坐标和地图级别
//添加地图类型控件
map.addControl(new BMap.MapTypeControl({
mapTypes:[
BMAP_NORMAL_MAP,
BMAP_HYBRID_MAP
]}));
map.setCurrentCity("金门"); // 设置地图显示的城市 此项是必须设置的
map.enableScrollWheelZoom(true); // 开启鼠标滚轮缩放
// 单击获取点击的经纬度
map.addEventListener("click",function(e){
alert(e.point.lng + "," + e.point.lat);
});
点击获取经纬度用于后续在地图上画点用。
//这里面是自动运行脚本,避免定义多个自动运行脚本导致后一个覆盖前一个
window.onload = function() {
// 调用方式,确保只有标题栏可拖动
var formElement = document.getElementById("routeListForm");
var handleElement = document.getElementById("routeListFormHeader");
if (formElement && handleElement) {
makeElementDraggable(formElement, handleElement);
} else {
console.error("无法获取航线列表表单或表单头部的元素");
}
// 加载 LocalStorage 中的航线数据
loadSavedRoutesFromLocalStorage();
// 加载 LocalStorage 中的经纬度并标记到地图
loadCoordinatesAndMarkOnMap();
// 用于隐藏地图左下角百度图标,放在最后
map.addEventListener("tilesloaded", function() {
var baiduLogo = document.querySelector('.BMap_cpyCtrl');
var anchorBL = document.querySelector('.anchorBL');
if (baiduLogo) baiduLogo.style.display = 'none';
if (anchorBL) anchorBL.style.display = 'none';
});
};
在所有的JavaScript代码中,将自定义的运行脚本放在最后调用。这是因为window.onload
机制的特点,如果存在多个window.onload
,后者会覆盖前者,从而导致先前编写的代码被覆盖,无法执行。因此,将脚本置于所有内容的末尾显得尤为重要。
此外,将脚本放在最后还有另一个原因:例如“用于隐藏地图左下角百度图标”的功能,在定义过程中可能会发生元素互相覆盖的情况,导致代码虽然能够正常执行,但却未能达到预期效果。此时需要考虑是否出现了覆盖现象,并通过调整脚本位置来避免这种情况。
要检查各种图片和JS文件是否成功加载,可以通过网络请求来查看。使用方法如下:按下F12键打开开发者工具,找到“Network”选项卡,然后按Ctrl+R刷新页面,即可查看资源的加载情况。
未成功加载的资源会以红叉的形式提示,点击红叉后可以查看具体的路径,检查路径是否正确。需要注意,这里的路径是相对于项目根目录的相对路径,而非计算机的绝对路径。
Console是控制台,我们以后要经常用。
Application可以查看一些存在浏览器中的数据,因为js不能直接和本地文件进行交互,所以存在浏览器里是个很好的选择。
LocalStorage 是一种基于浏览器的 Web 存储技术,它允许网站在用户的浏览器中保存数据,并在同一域名下的所有页面之间共享这些数据。与 LocalStorage 类似的另一种 Web 存储技术是 SessionStorage。下面是两者的优缺点比较:
LocalStorage
优点:
- 持久性:LocalStorage 中的数据具有持久性,除非手动清除或通过代码删除,否则数据会一直保留。即使关闭浏览器或重启设备,数据依然存在。
- 跨页面共享:在同一域名下的所有页面都可以访问并共享 LocalStorage 中的数据,这非常适合在多个页面之间传递信息。
- 容量较大:LocalStorage 的存储容量通常为 5-10 MB,远大于传统的 Cookies,适合存储较大体量的数据。
缺点:
- 安全性隐患:由于 LocalStorage 中的数据可以通过 JavaScript 访问,因此如果网站存在 XSS(跨站脚本攻击)漏洞,LocalStorage 中的数据可能会被恶意代码窃取。
- 数据序列化/反序列化:LocalStorage 只能存储字符串类型的数据,因此需要将复杂数据结构进行序列化(通常通过 JSON.stringify)后才能存储。这增加了编码和解码的复杂性,且可能引入错误。
- 性能开销:复杂数据的序列化和反序列化过程会消耗资源,尤其是在处理复杂数据结构或大数据量时,可能导致性能下降。
- 同步操作问题:由于 LocalStorage 是同步操作,大规模的复杂数据读写可能会阻塞 UI 线程,影响用户体验。
SessionStorage
优点:
- 会话范围:SessionStorage 中的数据仅在当前会话(即当前浏览器标签页或窗口)内有效,标签页关闭后数据自动清除,适合临时性数据存储。
- 相对更高的安全性:由于数据仅限于当前会话,即使发生 XSS 攻击,攻击者也只能访问当前会话的数据。
- 无需清理:无需担心长期保存的数据,因为标签页关闭时,数据会自动消失。
缺点:
- 非持久性:SessionStorage 中的数据在会话结束后(即标签页关闭或浏览器关闭)会自动清除,不适合存储需要长期保留的数据。
- 跨页面不共享:不同的标签页或窗口无法共享 SessionStorage 中的数据,即使它们属于同一域名。
- 数据序列化/反序列化:与 LocalStorage 类似,SessionStorage 也只能存储字符串类型的数据,需要将复杂数据序列化后再存储,增加了处理复杂性的难度。
总结
LocalStorage 适用于需要长期保存并跨页面共享的数据存储,但需谨慎考虑数据序列化/反序列化所带来的性能开销及同步操作可能引发的阻塞问题。
SessionStorage 则更适合临时性的数据存储,特别是在当前会话窗口内的不同页面之间传递临时数据。虽然它不会引发数据持久性问题,但其数据无法在会话之外保留。