百度地图canvas自定义轨迹

2020-03-18 21:20:42

参考地址 百度地图canvas自定义轨迹

   //将地图坐标转换成像素        

    //基本参数开始

    MCBAND = [12890594.86, 8362377.87, 5591021, 3481989.83, 1678043.12, 0]

    LLBAND = [75, 60, 45, 30, 15, 0]

    MC2LL = [[1.410526172116255e-8, 0.00000898305509648872, -1.9939833816331, 200.9824383106796, -187.2403703815547, 91.6087516669843, -23.38765649603339, 2.57121317296198, -0.03801003308653, 17337981.2],

        [-7.435856389565537e-9, 0.000008983055097726239, -0.78625201886289, 96.32687599759846, -1.85204757529826, -59.36935905485877, 47.40033549296737, -16.50741931063887, 2.28786674699375, 10260144.86],

        [-3.030883460898826e-8, 0.00000898305509983578, 0.30071316287616, 59.74293618442277, 7.357984074871, -25.38371002664745, 13.45380521110908, -3.29883767235584, 0.32710905363475, 6856817.37],

        [-1.981981304930552e-8, 0.000008983055099779535, 0.03278182852591, 40.31678527705744, 0.65659298677277, -4.44255534477492, 0.85341911805263, 0.12923347998204, -0.04625736007561, 4482777.06],

        [3.09191371068437e-9, 0.000008983055096812155, 0.00006995724062, 23.10934304144901, -0.00023663490511, -0.6321817810242, -0.00663494467273, 0.03430082397953, -0.00466043876332, 2555164.4],

        [2.890871144776878e-9, 0.000008983055095805407, -3.068298e-8, 7.47137025468032, -0.00000353937994, -0.02145144861037, -0.00001234426596, 0.00010322952773, -0.00000323890364, 826088.5]]

    LL2MC = [[-0.0015702102444, 111320.7020616939, 1704480524535203, -10338987376042340, 26112667856603880, -35149669176653700, 26595700718403920, -10725012454188240, 1800819912950474, 82.5],

        [0.0008277824516172526, 111320.7020463578, 647795574.6671607, -4082003173.641316, 10774905663.51142, -15171875531.51559, 12053065338.62167, -5124939663.577472, 913311935.9512032, 67.5],

        [0.00337398766765, 111320.7020202162, 4481351.045890365, -23393751.19931662, 79682215.47186455, -115964993.2797253, 97236711.15602145, -43661946.33752821, 8477230.501135234, 52.5],

        [0.00220636496208, 111320.7020209128, 51751.86112841131, 3796837.749470245, 992013.7397791013, -1221952.21711287, 1340652.697009075, -620943.6990984312, 144416.9293806241, 37.5],

        [-0.0003441963504368392, 111320.7020576856, 278.2353980772752, 2485758.690035394, 6070.750963243378, 54821.18345352118, 9540.606633304236, -2710.55326746645, 1405.483844121726, 22.5],

        [-0.0003218135878613132, 111320.7020701615, 0.00369383431289, 823725.6402795718, 0.46104986909093, 2351.343141331292, 1.58060784298199, 8.77738589078284, 0.37238884252424, 7.45]]

    //基本参数结束        

    //转换缩放级别

    var GetZoomUnits = function (zoom) {

        return Math.pow(2, (18 - zoom));

    }

    var FormatPoint = function (point) {

        var lng_lat, mc;

        point.lng = getLoop(point.lng, -180, 180);

        point.lat = getRange(point.lat, -74, 74);

        lng_lat = {

            lng: point.lng,

            lat: point.lat

        };

        for (var i = 0; i < LLBAND.length; i++) {

            if (lng_lat.lat >= LLBAND[i]) {

                mc = LL2MC[i];

                break

            }

        }

        if (!mc) {

            for (var i = LLBAND.length - 1; i >= 0; i--) {

                if (lng_lat.lat <= -LLBAND[i]) {

                    mc = LL2MC[i];

                    break

                }

            }

        }

        var cE = convertor(point, mc);

        var lng_lat = {

            lng: cE.lng.toFixed(2),

            lat: cE.lat.toFixed(2)

        };

        return lng_lat

    }

    var getLoop = function (lng, a, b) {

        while (lng > b) {

            lng -= b - a

        }

        while (lng < a) {

            lng += b - a

        }

        return lng

    }

    var getRange = function (lat, a, b) {

        if (a != null) {

            lat = Math.max(lat, a)

        }

        if (b != null) {

            lat = Math.min(lat, b)

        }

        return lat

    }

    var convertor = function (point, mc) {

        if (!point || !mc) {

            return

        }

        var lng = mc[0] + mc[1] * Math.abs(point.lng);

        var c = Math.abs(point.lat) / mc[9];

        var lat = mc[2] + mc[3] * c + mc[4] * c * c + mc[5] * c * c * c + mc[6] * c * c * c * c + mc[7] * c * c * c * c * c + mc[8] * c * c * c * c * c * c;

        lng *= (point.lng < 0 ? -1 : 1);

        lat *= (point.lat < 0 ? -1 : 1);

        return { lng: lng, lat: lat }

    };        

    //point:当前像素 var point = new BMap.Point(x, y);

    //zoom:当前地图缩放级别 var zoom = map.getZoom();

    //center:当前地图可视范围中心点坐标 var center = map.getCenter();

    //bounds:地图可视区域    var bound = map.getSize();    

    var PointToPixel = function (point, zoom, center, bounds) {

        // 坐标到像素

        if (!point) {

            return

        }

        point = FormatPoint(point);

        center = FormatPoint(center);

        var units = GetZoomUnits(zoom);

        var x = Math.round((point.lng - center.lng) / units + (parseInt(bounds.width)+2000) / 2);

        var y = Math.round((center.lat - point.lat) / units + (parseInt(bounds.height)+2000) / 2);

        return { x: x, y: y }

    }

    //  百度地图定位坐标数据

    var data_infoBeijing = [  

                         new BMap.Point(116.407854,39.921988),

                         new BMap.Point(116.466605,39.921585),

                         new BMap.Point(116.442222,39.912345),

                         new BMap.Point(116.497854,39.991988),

                         new BMap.Point(116.486605,39.921585),

                         new BMap.Point(116.502222,39.912345),

                         new BMap.Point(116.517854,39.921988),

                         new BMap.Point(116.526605,39.921585),

                         new BMap.Point(116.532222,39.912345),

                         new BMap.Point(116.547854,39.921988),

                         new BMap.Point(116.556605,39.921585),

                         new BMap.Point(116.562222,39.912345),

                         new BMap.Point(116.577854,39.921988),

                         new BMap.Point(116.586605,39.921585),

                         new BMap.Point(116.460947,39.877195),

                    ];

    var map = new BMap.Map("allmap",{enableMapClick: false});

    var point = data_infoBeijing[0];

    map.centerAndZoom(point, 13);

    var center = map.getCenter();//获取地图可视区域中心

    var bound = map.getSize();    //获取地图可视区域

    var width = bound.width+2000;       //画布的宽度

    var height =bound.height+2000;   //画布的高度    

    //画布偏移量

    var left = width/2;

    //画布偏移量    

    var topp = parseInt(height)/2;            

    // 复杂的自定义覆盖物

    function ComplexCustomOverlay(point,one){

      this._point = point;

      this._one=one;

    }

    ComplexCustomOverlay.prototype = new BMap.Overlay();

    ComplexCustomOverlay.prototype.initialize = function(map){

      var thisMain=this;    

      this._map = map;

      //  创建地图浮层

      var svg = this._svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");      

      svg.style.zIndex = BMap.Overlay.getZIndex(this._point.lat);

      svg.style.MozUserSelect = "none";

      svg.setAttribute("version","1.1");

      svg.setAttribute("xmlns","http://www.w3.org/2000/svg")

      $(svg).css({"position":"absolute","height":height,"width":width,"z-index":"99","margin":"0","padding":"0"});

      $(svg).attr({"class":this._one});

      map.getPanes().labelPane.appendChild(svg);

      //  创建运动光标的圆      

      var circleAniamte=document.createElementNS("http://www.w3.org/2000/svg", "circle");

      circleAniamte.setAttribute("r","1");

      circleAniamte.setAttribute("fill","yellow");

      circleAniamte.setAttribute("stroke","yellow");

      circleAniamte.setAttribute("stroke-width","5");

      svg.appendChild(circleAniamte);      

      var arrZ=[];

      var p=1;

      function pathMap(){

        arrZ[0]=data_infoBeijing[p-1];

        arrZ[1]=data_infoBeijing[p];    

        var a= PointToPixel(arrZ[0],13, center, bound)

        var b= PointToPixel(arrZ[1],13, center, bound)

        map.centerAndZoom(arrZ[0], 13); // 改变地图中心点

        // 线的长度

        var long = thisMain.routeLong(a.x,a.y,b.x,b.y);

        var runTime = long/0.1;

        //  运动光标圆的轨迹

        circleAniamte.setAttribute("cx",a.x);

        circleAniamte.setAttribute("cy",a.y);        

        $(circleAniamte).animate({"cx":b.x,"cy":b.y},runTime,'linear',function(){

                if(p>=data_infoBeijing.length){

                    thisMain.cir(b.x,b.y,svg);

                };

        });  

        //  创建线型运动轨迹

        thisMain.pointLineAnimation(a.x,a.y,b.x,b.y,p,runTime,svg);

        // 创建圆拐点

        thisMain.cir(a.x,a.y,svg);        

        p++;

        if(p<data_infoBeijing.length){

            setTimeout(pathMap,runTime)

        };

    };        

    pathMap()        

    };

    //两个ap之间的距离

    ComplexCustomOverlay.prototype.routeLong=function(ax,ay,bx,by){

        var x = ax-bx;            

        var y = ay-by;

        return Math.floor(Math.sqrt((x*x+y*y)));

    };    

    //  创建动画轨迹

    ComplexCustomOverlay.prototype.pointLineAnimation=function(ax,ay,bx,by,p,runTime,svg){

        //  创建线型运动轨迹

        var pat=document.createElementNS("http://www.w3.org/2000/svg", "path");

        pat.setAttribute("d","M"+ax+","+ay+" L"+bx+","+by);

        pat.setAttribute("fill","none");

        pat.setAttribute("stroke","yellow");

        pat.setAttribute("stroke-width","3");

        pat.setAttribute("class","abc"+p);

        $(pat).attr({"abc":"12345"})

        svg.appendChild(pat);

        // 运动轨迹距离长度        

        var aa=document.querySelector('.abc'+p).getTotalLength();

        pat.setAttribute("stroke-opacity","1");

        pat.setAttribute("stroke-dasharray",aa);

        pat.setAttribute("stroke-dashoffset",aa);

        pat.style.animation="dash "+runTime/1000+"s linear forwards";         

    }        

    //  创建转折点圆

    ComplexCustomOverlay.prototype.cir=function(ax,ay,svg){

        var circle=document.createElementNS("http://www.w3.org/2000/svg", "circle");

        circle.setAttribute("r","4");

        circle.setAttribute("cx",ax);

        circle.setAttribute("cy",ay);

        circle.setAttribute("fill","none");

        circle.setAttribute("stroke","green");

        circle.setAttribute("stroke-width","3");

        svg.appendChild(circle);

    }    

    // 相对定位移动浮层位置

    ComplexCustomOverlay.prototype.draw = function(){

      var map = this._map;

      var pixel = map.pointToOverlayPixel(this._point);

      this._svg.style.left = pixel.x-left+ "px";

      this._svg.style.top  = pixel.y-topp+"px";

    };        

    // 添加到地图

    var cla="disp"+2;

    var myCompOverlaythree = new ComplexCustomOverlay(data_infoBeijing[0],cla);

    map.addOverlay(myCompOverlaythree);       

    // 改变地图背景样式

    function changeMapStyle(style){

        map.setMapStyle({style:style});

    };

    changeMapStyle("midnight");  // 改变背景颜色

    map.enableScrollWheelZoom();   //启用滚轮放大缩小,默认禁用


  • 2020-01-14 00:12:22

    webpack externals详解

    在众多的webpack配置教程中,对externals这个配置选项,总是一带而过,把文档中提到的几种方式都复述一遍,但是对于开发者而言,根本没法完全理解。本文试图通过一整篇文章,详细的对externals这个参数进行讲解。

  • 2020-01-14 01:06:37

    webpack externals 深入理解

    按照官方文档的解释,如果我们想引用一个库,但是又不想让webpack打包,并且又不影响我们在程序中以CMD、AMD或者window/global全局等方式进行使用,那就可以通过配置externals。这个功能主要是用在创建一个库的时候用的,但是也可以在我们项目开发中充分使用。

  • 2020-01-14 01:08:19

    webpack用externals优化echarts

    防止将某些 import 的包(package)打包到 bundle 中,而是在运行时(runtime)再去从外部获取这些扩展依赖(external dependencies)。

  • 2020-01-16 08:52:22

    Vue函数式调用组件创建公共组件

    所有组件都需要这么去调用,就会有些许麻烦而且不太美观。像Loading、Toast等这些组件,一页面可以经常用到而且每次显示的内容都可能不一样,这样的话用js的方式【this.$xxx.show(option)】去调用就方便很多,而且代码也更整洁。