最全面的百度地图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 相关文章推荐
$.get获取一个文件的内容示例代码
Sep 11 Javascript
jquery及原生js获取select下拉框选中的值示例
Oct 25 Javascript
angular中使用路由和$location切换视图
Jan 23 Javascript
js获取checkbox值的方法
Jan 28 Javascript
JavaScript简单判断复选框是否选中及取出值的方法
Aug 13 Javascript
JS简单实现tab切换效果的多窗口显示功能
Sep 07 Javascript
jQuery插件FusionCharts实现的2D面积图效果示例【附demo源码下载】
Mar 06 Javascript
Vue.js 2.0和Cordova开发webApp环境搭建方法
Feb 26 Javascript
jQuery实现通过方向键控制div块上下左右移动的方法【测试可用】
Apr 26 jQuery
微信小程序城市选择及搜索功能的方法
Mar 22 Javascript
vue cli4.0项目引入typescript的方法
Jul 17 Javascript
关于Js中new操作符的作用详解
Feb 21 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
php中关于普通表单多文件上传的处理方法
2011/03/25 PHP
PHP  实现等比压缩图片尺寸和大小实例代码
2016/10/08 PHP
laravel框架中间件简单使用方法示例
2020/01/25 PHP
XP折叠菜单&amp;仿QQ2006菜单
2006/12/16 Javascript
Javascript 面向对象(二)封装代码
2012/05/23 Javascript
判断客户浏览器是否支持cookie的示例代码
2013/12/23 Javascript
JavaScript中双叹号(!!)作用示例介绍
2014/04/10 Javascript
[原创]jQuery常用的4种加载方式分析
2016/07/25 Javascript
JS中this上下文对象使用方式
2016/10/09 Javascript
JavaScript 继承详解(六)
2016/10/11 Javascript
jQuery实现点击某个div打开层,点击其他div关闭层实例分析(阻止冒泡)
2016/11/18 Javascript
详解JS对象封装的常用方式
2016/12/30 Javascript
Angular.js中ng-if、ng-show和ng-hide的区别介绍
2017/01/20 Javascript
Vue2.0使用过程常见的一些问题总结学习
2017/04/10 Javascript
详解vue2父组件传递props异步数据到子组件的问题
2017/06/29 Javascript
vue 组件中添加样式不生效的解决方法
2018/07/06 Javascript
JS获取并处理php数组的方法实例分析
2018/09/04 Javascript
Angular事件之不同组件间传递数据的方法
2018/11/15 Javascript
Vue入门之数量加减运算操作示例
2018/12/11 Javascript
如何在微信小程序里面退出小程序的方法
2019/04/28 Javascript
jQuery实现中奖播报功能(让文本滚动起来) 简单设置数值即可
2020/03/20 jQuery
Windows下python2.7.8安装图文教程
2016/05/26 Python
python 不以科学计数法输出的方法
2018/07/16 Python
解决django中form表单设置action后无法回到原页面的问题
2020/03/13 Python
Python 3.9的到来到底是意味着什么
2020/10/14 Python
HTML5教程之html 5 本地数据库(Web Sql Database)
2014/04/03 HTML / CSS
老海军美国官网:Old Navy
2016/09/05 全球购物
巴西网上药店:Drogaria Araujo
2021/01/06 全球购物
计算机软件个人的自荐信范文
2013/12/01 职场文书
前厅部经理岗位职责范文
2014/02/04 职场文书
奥巴马连任演讲稿
2014/05/15 职场文书
2014年最新领导班子整改方案
2014/09/27 职场文书
贷款承诺书
2015/01/20 职场文书
司机岗位职责范本
2015/04/10 职场文书
广告公司文案策划岗位职责
2015/04/14 职场文书
PHP 对接美团大众点评团购券(门票)的开发步骤
2021/04/03 PHP