最全面的百度地图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 相关文章推荐
caller和callee的区别介绍及演示结果
Mar 10 Javascript
PHP PDO操作总结
Nov 17 Javascript
使用mini-define实现前端代码的模块化管理
Dec 25 Javascript
JS判断当前页面是否在微信浏览器打开的方法
Dec 08 Javascript
使用Object.defineProperty实现简单的js双向绑定
Apr 15 Javascript
如何提高javascript加载速度
Dec 26 Javascript
在js中做数字字符串补0(js补零)
Mar 25 Javascript
Webpack中publicPath路径问题详解
May 03 Javascript
微信网页授权并获取用户信息的方法
Jul 30 Javascript
Vue入门学习笔记【基本概念、对象、过滤器、指令等】
Apr 13 Javascript
jquery获取并修改触发事件的DOM元素示例【基于target 属性】
Oct 10 jQuery
浅析VUE防抖与节流
Nov 24 Vue.js
简单分析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
php ignore_user_abort与register_shutdown_function 使用方法
2009/06/14 PHP
PHP四舍五入精确小数位及取整
2014/01/14 PHP
ThinkPHP视图查询详解
2014/06/30 PHP
postfixadmin忘记密码后的修改密码方法详解
2016/07/20 PHP
PHP 应用容器化以及部署方法
2018/02/12 PHP
php使用scandir()函数扫描指定目录下所有文件示例
2019/06/08 PHP
jQuery创建平滑的页面滚动(顶部或底部)
2013/02/26 Javascript
Javascript操作表单实例讲解(下)
2016/06/20 Javascript
JS实现表单多文件上传样式美化支持选中文件后删除相关项
2016/09/30 Javascript
jQuery实现发送验证码并60秒倒计时功能
2016/11/25 Javascript
jQuery Validate格式验证功能实例代码(包括重名验证)
2017/07/18 jQuery
vue使用better-scroll实现下拉刷新、上拉加载
2018/11/23 Javascript
用Vue.js方法创建模板并使用多个模板合成
2019/06/28 Javascript
Vue登录主页动态背景短视频制作
2019/09/21 Javascript
Centos7 安装Node.js10以上版本的方法步骤
2019/10/15 Javascript
JavaScript实现图片轮播特效
2019/10/23 Javascript
[01:11]steam端dota2实名认证操作流程视频
2021/03/11 DOTA
python算法表示概念扫盲教程
2017/04/13 Python
Python操作MongoDB数据库的方法示例
2018/01/04 Python
python矩阵转换为一维数组的实例
2018/06/05 Python
在Python中实现替换字符串中的子串的示例
2018/10/31 Python
基于wxPython的GUI实现输入对话框(2)
2019/02/27 Python
python中的协程深入理解
2019/06/10 Python
python使用mitmproxy抓取浏览器请求的方法
2019/07/02 Python
python 矢量数据转栅格数据代码实例
2019/09/30 Python
python调用matplotlib模块绘制柱状图
2019/10/18 Python
使用python批量转换文件编码为UTF-8的实现
2020/04/03 Python
解决python Jupyter不能导入外部包问题
2020/04/15 Python
python正则表达式的懒惰匹配和贪婪匹配说明
2020/07/13 Python
不同浏览器对CSS3和HTML5的支持状况
2009/10/31 HTML / CSS
使用Html5实现异步上传文件,支持跨域,带有上传进度条
2016/09/17 HTML / CSS
美国顶级奢侈茶:Mighty Leaf Tea(美泰茶)
2016/11/26 全球购物
分公司经理任命书
2014/06/05 职场文书
初中体育教学随笔
2015/08/15 职场文书
如何用python识别滑块验证码中的缺口
2021/04/01 Python
Linux系统下MySQL配置主从分离的步骤
2022/03/21 MySQL