最全面的百度地图JavaScript离线版开发


Posted in Javascript onSeptember 10, 2016

项目要求web版百度地图要离线开发。这里总结下自己的开发过程和经验。 

大概需求是:每辆车上安装有公司接收机,会实时反馈车辆的坐标、速度、转向等信息,接收到各车辆信息后在百度地图上实时画出车辆位置。作业点不一定都有网络,所以要求离线开发。 

此过程主要有三个技术点: 

1. 如何获取离线的API 

2. 如何获取离线瓦片图 

3. 如何在离线状态下将WGS坐标转换成百度地图坐标 

解决问题过程: 

1. 既然百度地图官方不支持离线地图,那么我们需要想办法把在线的代码改成离线的代码。

这里可以参考:http://my.oschina.net/smzd/blog/548538 

这里整理好了一份,其中也按照示例Demo写了一份离线的Demo。当然离线的不可能做到和在线一样完美,毕竟还是有些功能用不了的。(此版本是基于百度地图API V2.0)

最全面的百度地图JavaScript离线版开发

使用方法: 

1. 确定你用的瓦片的图片后缀,如.png, .jpg。修改 baidumap_offline_v2_load.js 中的imgext

var bdmapcfg = {
 'imgext':'.jpg', //瓦片图的后缀 ------ 根据需要修改,一般是 .png .jpg
 'tiles_dir':''  //瓦片图的目录,为空默认在 baidumap_v2/tiles/ 目录
};

2. 确定你用的瓦片的目录,默认在baidumap_v2/tiles/目录下,你也可以改成其他地址。修改 baidumap_offline_v2_load.js 中的tiles_dir

3. 参考demo编写代码, 要点如下:

 1)只需要加载load文件
    <script type="text/javascript" src="baidumapv2/baidumap_offline_v2_load.js"></script>
 2)加载css文件(貌似可不需要)
    <link rel="stylesheet" type="text/css" href="../../baidumapv2/css/baidu_map_v2.css"/>
 3)定义个放置地图的容器,并用css控制高度和宽度   
    <div id="map_demo"></div>
 4)书写js代码

<script type="text/javascript"> 
  // 百度地图API功能
  var map = new BMap.Map("map_demo");  // 创建Map实例
  map.centerAndZoom(new BMap.Point(116.404, 39.915), 8); // 初始化地图,设置中心点坐标和地图级别
  //map.addControl(new BMap.MapTypeControl());  //添加地图类型控件 离线只支持电子地图,卫星/三维不支持
  //map.setCurrentCity("北京");     // 设置地图显示的城市 离线地图不支持!!
  map.enableScrollWheelZoom(true);   //开启鼠标滚轮缩放
  map.addControl(new BMap.NavigationControl());  //缩放按钮
  </script>

2. 获取瓦片图 

这里可以参考:http://my.oschina.net/smzd/blog/619397 

当然网上也有下载工具,比如:全能电子地图下载器 

3. 直接将接收机接收到的坐标(WGS)放入百度地图中是有偏差的,这是因为百度地图为了安全做了特殊处理。其Web服务API中提供了坐标转换API,但是它是以HTTP形式提供的坐标转换接口,所以说还是无法脱离网络。这里通过一些专业的知识将WGS坐标转GCJ,再将GCJ坐标转BD百度坐标,经验证精确度几乎算很准确的了。 

public class CoorConvertUtil {
    //圆周率
    static double pi = 3.14159265358979324;
    //卫星椭球坐标投影到平面坐标系的投影因子
    static double a = 6378245.0;
    //椭球的偏心率
    static double ee = 0.00669342162296594323;
    //圆周率转换量
    public final static double x_pi = 3.14159265358979324 * 3000.0 / 180.0;
    
    public static double[] wgs2bd(double lat, double lon){
      double[] wgs2gcj = wgs2gcj(lat, lon);
      double[] gcj2bd = gcj2bd(wgs2gcj[0], wgs2gcj[1]);
      return gcj2bd;
    }
    
    /**
     * GCJ坐标转百度坐标
     * @param lat
     * @param lon
     * @return
     */
    public static double[] gcj2bd(double lat, double lon) {
      double x = lon, y = lat;
      double z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * x_pi);
      double theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * x_pi);
      double bd_lon = z * Math.cos(theta) + 0.0065;
      double bd_lat = z * Math.sin(theta) + 0.006;
      return new double[] { bd_lat, bd_lon };
    }
    
    public static double[] bd2gcj(double lat, double lon) {
      double x = lon - 0.0065, y = lat - 0.006;
      double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);
      double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);
      double gg_lon = z * Math.cos(theta);
      double gg_lat = z * Math.sin(theta);
      return new double[] { gg_lat, gg_lon };
    }
    
    /**
     * WGS坐标转GCJ坐标
     * @param lat
     * @param lon
     * @return
     */
    public static double[] wgs2gcj(double lat, double lon) {
      double dLat = transformLat(lon - 105.0, lat - 35.0);
      double dLon = transformLon(lon - 105.0, lat - 35.0);
      double radLat = lat / 180.0 * pi;
      double magic = Math.sin(radLat);
      magic = 1 - ee * magic * magic;
      double sqrtMagic = Math.sqrt(magic);
      dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
      dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);
      double mgLat = lat + dLat;
      double mgLon = lon + dLon;
      double[] loc = { mgLat, mgLon };
      return loc;
    }
    
    private static double transformLat(double lat, double lon) {
      double ret = -100.0 + 2.0 * lat + 3.0 * lon + 0.2 * lon * lon + 0.1 * lat * lon + 0.2 * Math.sqrt(Math.abs(lat));
      ret += (20.0 * Math.sin(6.0 * lat * pi) + 20.0 * Math.sin(2.0 * lat * pi)) * 2.0 / 3.0;
      ret += (20.0 * Math.sin(lon * pi) + 40.0 * Math.sin(lon / 3.0 * pi)) * 2.0 / 3.0;
      ret += (160.0 * Math.sin(lon / 12.0 * pi) + 320 * Math.sin(lon * pi/ 30.0)) * 2.0 / 3.0;
      return ret;
    }
    
    private static double transformLon(double lat, double lon) {
      double ret = 300.0 + lat + 2.0 * lon + 0.1 * lat * lat + 0.1 * lat * lon + 0.1 * Math.sqrt(Math.abs(lat));
      ret += (20.0 * Math.sin(6.0 * lat * pi) + 20.0 * Math.sin(2.0 * lat * pi)) * 2.0 / 3.0;
      ret += (20.0 * Math.sin(lat * pi) + 40.0 * Math.sin(lat / 3.0 * pi)) * 2.0 / 3.0;
      ret += (150.0 * Math.sin(lat / 12.0 * pi) + 300.0 * Math.sin(lat / 30.0 * pi)) * 2.0 / 3.0;
      return ret;
    }
    
    /**
     * 度分转度
     * @param lat 纬度 ddmm.mmmm
     * @param lon 经度 dddmm.mmmm
     * @return
     */
    public static double[] dufen2du(String lat, String lon){
      double latD=Double.parseDouble(lat.substring(0, 2));
      double latM=Double.parseDouble(lat.substring(2));
      double latNew=latD+latM/60;
      double lonD=Double.parseDouble(lon.substring(0, 3));
      double lonM=Double.parseDouble(lon.substring(3));
      double lonNew=lonD+lonM/60;
      return new double[] { latNew, lonNew } ;
    }
}

最后看项目效果截图:

 最全面的百度地图JavaScript离线版开发

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
快速解决jquery之get缓存问题的最简单方法介绍
Dec 19 Javascript
jquery中map函数与each函数的区别实例介绍
Jun 23 Javascript
jquery datatable后台封装数据示例代码
Aug 07 Javascript
DOM基础教程之模型中的模型节点
Jan 19 Javascript
jQuery动态添加及删除表单上传元素的方法(附demo源码下载)
Jan 15 Javascript
jQuery事件处理的特征(事件命名机制)
Aug 23 Javascript
javascript实现简易计算器
Feb 01 Javascript
js输入框使用正则表达式校验输入内容的实例
Feb 12 Javascript
socket.io实现在线群聊功能
Apr 07 Javascript
vue.js实例todoList项目
Jul 07 Javascript
基于vue循环列表时点击跳转页面的方法
Aug 31 Javascript
基于Vue的商品主图放大镜方案详解
Sep 19 Javascript
简单分析javascript中的函数
Sep 10 #Javascript
javascript数组常用方法汇总
Sep 10 #Javascript
JavaScript实现输入框与清空按钮联动效果
Sep 09 #Javascript
Three.js快速入门教程
Sep 09 #Javascript
jQuery动态修改字体大小的方法【测试可用】
Sep 09 #Javascript
Bootstrap菜单按钮及导航实例解析
Sep 09 #Javascript
JavaScript设计模式之单体模式全面解析
Sep 09 #Javascript
You might like
BBS(php &amp; mysql)完整版(四)
2006/10/09 PHP
安装PHP可能遇到的问题“无法载入mysql扩展” 的解决方法
2007/04/16 PHP
探讨PHP删除文件夹的三种方法
2013/06/09 PHP
基于PHP Socket配置以及实例的详细介绍
2013/06/13 PHP
CI框架学习笔记(一) - 环境安装、基本术语和框架流程
2014/10/26 PHP
php post大量数据时发现数据丢失问题解决方法
2015/06/20 PHP
javascript验证上传文件的类型限制必须为某些格式
2013/11/14 Javascript
小结Node.js中非阻塞IO和事件循环
2014/09/18 Javascript
jquery动态分页效果堪比时光网
2014/09/25 Javascript
javascript数据类型示例分享
2015/01/19 Javascript
深入理解Javascript箭头函数中的this
2017/02/13 Javascript
angularjs中的$eval方法详解
2017/04/24 Javascript
vue2.0开发入门笔记之.vue文件的生成和使用
2017/09/19 Javascript
Vue-router结合transition实现app前进后退动画切换效果的实例
2017/10/11 Javascript
vue实现类似淘宝商品评价页面星级评价及上传多张图片功能
2018/10/29 Javascript
JS去除字符串最后的逗号实例分析【四种方法】
2019/06/20 Javascript
Jquery属性的获取/设置及样式添加/删除操作技巧分析
2019/12/23 jQuery
解决echarts中横坐标值显示不全(自动隐藏)问题
2020/07/20 Javascript
Python 除法小技巧
2008/09/06 Python
python中使用OpenCV进行人脸检测的例子
2014/04/18 Python
python比较2个xml内容的方法
2015/05/11 Python
用Python设计一个经典小游戏
2017/05/15 Python
Python机器学习库scikit-learn安装与基本使用教程
2018/06/25 Python
在python里从协程返回一个值的示例
2019/02/19 Python
Centos7 下安装最新的python3.8
2019/10/28 Python
Python for循环搭配else常见问题解决
2020/02/11 Python
anello泰国官方网站:日本流行包包品牌
2019/08/08 全球购物
TCP/IP模型的分界线
2012/12/01 面试题
部队党性分析材料
2014/02/16 职场文书
继续教育个人总结
2015/03/03 职场文书
中秋晚会致辞
2015/07/31 职场文书
2016年119消防宣传日活动总结
2016/04/05 职场文书
研究生毕业登记表的自我鉴定范文
2019/07/15 职场文书
php去除deprecated的实例方法
2021/11/17 PHP
十大好看的穿越动漫排名:《瑞克和莫蒂》第一,国漫《有药》在榜
2022/03/18 日漫
奥特曼十大神器:奥特手镯在榜,第一是贝利亚的神器
2022/03/18 日漫