zoukankan      html  css  js  c++  java
  • 最全面的百度地图JavaScript离线版开发

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

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

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

    1. 如何获取离线的API

    2. 如何获取离线瓦片图

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

    解决问题过程:

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

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

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

     

    使用方法:

    复制代码
    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 } ;
            }
    }
    复制代码

    最后看项目效果截图:

     示例:http://pan.baidu.com/s/1c1DBnZq

    作者:Joanna.Yan
    出处:http://www.cnblogs.com/Joanna-Yan/
    本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利。

  • 相关阅读:
    Codeforces 177G2 Fibonacci Strings KMP 矩阵
    Codeforces Gym100187C Very Spacious Office 贪心 堆
    Codeforces 980F Cactus to Tree 仙人掌 Tarjan 树形dp 单调队列
    AtCoder SoundHound Inc. Programming Contest 2018 E + Graph (soundhound2018_summer_qual_e)
    BZOJ3622 已经没有什么好害怕的了 动态规划 容斥原理 组合数学
    NOIP2016提高组Day1T2 天天爱跑步 树链剖分 LCA 倍增 差分
    Codeforces 555C Case of Chocolate 其他
    NOIP2017提高组Day2T3 列队 洛谷P3960 线段树
    NOIP2017提高组Day2T2 宝藏 洛谷P3959 状压dp
    NOIP2017提高组Day1T3 逛公园 洛谷P3953 Tarjan 强连通缩点 SPFA 动态规划 最短路 拓扑序
  • 原文地址:https://www.cnblogs.com/armyfai/p/5861205.html
Copyright © 2011-2022 走看看