zoukankan      html  css  js  c++  java
  • 用百度地图API分析打交通大数据

    百度地图API, 文档不全,例子不细致。 在网上还没有太多有用的例子。比如说下面几个需求的解决方案就找不到:

    1. 如何用百度地图API查询一个地点的经纬度。

    2. 如何用百度地图通过一个经纬度查询商圈和地址。

    3.点击百度地图时, 获得点击位置的经纬度。

    4. 如果按照时间轴动态显示热力图的变化。 

    我昨天玩了一下午百度地图javascript API,解决了上面的几个问题,顺道用少量打车用户的抽样数据做一个数据可视化, 给大家提供一个可以参考的例子

    首先数据是来自北京市某个周日的出行数据, 其中包含出发地点和到达地点的经纬度。

    {"passenger_phone":"XXX","start_location_lng":"116.31414794922","start_location_lat":"40.080762261285","end_location_lng":"116.3363","end_location_lat":"40.07079"}

    {"passenger_phone":"XXX","start_location_lng":"116.734490","start_location_lat":"39.903438","end_location_lng":"116.735160","end_location_lat":"39.962470"}

    由于数据是从spark里查询出来放在hadoop上,是map后的一个结果, 因此每条数据的间隔符号是换行。这导致我必须在js里把数据文件命名为txt文件, 并且在js里做一些特殊处理。 

    百度地图API, 因为需要频繁在js里根据鼠标点击获得地理位置和商圈信息,  因此在html创建了一个不可见的container用来加载地图查询模块

    <div id="dummy" style ="display:none"></div>

    用来加载百度地图javascript model用来查询地理信息。 

    var bmap4search= new BMap.Map("dummy");

    var localSearch = new BMap.LocalSearch(bmap4search);

    由于需要找出鼠标点击位置五公里范围内的人数, 因此需要一个计算地理距离的函数。

    function rad(d)

    {

      return d * Math.PI / 180.0;

    }

     function getDistance(lng1,lat1, lng2,lat2)

        {

        radLat1 = rad(lat1);

      radLat2 = rad(lat2);

      a = radLat1 - radLat2;

      b = rad(lng1) - rad(lng2);

      s=2*Math.asin(

    Math.sqrt(Math.pow(Math.sin(a/2), 2.0)+

    Math.cos(radLat1)*Math.cos(radLat2)*Math.pow(Math.sin(b/2), 2.0)));

      EARTH_RADIUS = 6378.137;

      s = s * EARTH_RADIUS;

      s = Math.round(s*10000) / 10000;

      return s;

        }

    页面加载后, 首先显示用户出发热力图, 看上去回龙观还真像是北京的宇宙中心, 出行用户最密集。 

    用鼠标点击地图上的某一个点, 可以获得该点的地址信息。参考下一张图。

    用鼠标点击回龙观位置, 动态获得一个坐标后, 按钮“点击显示5公里内......”亮了。 点击按钮可以查看这些回龙观的用户, 周日出行目的地是哪里。结果发现回龙观的群众周末大多数也只在回龙观附近晃荡。 

    至于播放时间轴热力图变化的问题, 其实是通过重新设置option时间的,方法与上图完全相同

    myChart.setOption(map_option);

    下面几张图是回龙观群众在临晨1点~5点按时间轴变化的出行热力图

    临晨3点

    临晨5点

    早晨7点

     

    可以看到上面亮了几个点, 放大地图看看。

    发现分别是, 汉王大厦, 融泽嘉园售楼处, 回龙观镇医院。还有一个高速公路收费站口

    下面是部分代码。

    <!DOCTYPE html>

    <html style="height: 100%">

    <head>

        <meta charset="utf-8">

    <script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=ZUONbpqGBsYGXNIYHicvbAbM"></script>

    </head>

    <body style="height: 100%; margin: 0">

    <div style ="z-index=999">

    <input type="button" value="点击切换到出发热力图" onclick="chg(0)" disabled=disabled ID="startBtn" NAME="Button1">

    <input type="button" value="点击切换到到达热力图" onclick="chg(1)" ID="endBtn" NAME="Button1">

    </div>

    <div>

    <div id=mytips style="z-order=999;background-color:#F0F8FF;width:100;height:16;border:2px solid gray;display:none;filter:progid:DXImageTransform.Microsoft.Shadow(color=#666666,direction=135,strength=5);left:5;top:5"></div>

    <input type="button" value="点击显示5公里内嘀嘀新客的目的地或者来源" disabled=disabled onclick="showDS()" ID="src_dest_Btn" NAME="Button1">

    </div>

    <div id="dummy" style ="display:none"></div>

    <div id="container" style="height: 100%">

    </div>

    <!-- 新添加的jQuery -->

    <script type="text/javascript" src="./js/jquery-3.1.0.js"></script>

    <!-- End -->

     

    <script type="text/javascript" src="./js/echarts.js"></script>

    <script type="text/javascript" src="./js/dataTool.js"></script>

    <script type="text/javascript" src="./js/bmap.js"></script>

    <script type="text/javascript">

    var bmap4search= new BMap.Map("dummy");

    var localSearch = new BMap.LocalSearch(bmap4search);

        var dom = document.getElementById("container");

        var myChart = echarts.init(dom);

        var app = {};

        option = null;

        app.title = '热力图与百度地图扩展';

    var startPoints=[];

    var endPoints=[];

    var dsPoints=[];

    var radium=5;

    var gc = new BMap.Geocoder();

    var map_option;

    var map_status="default";//全部乘客的出发或者达到

        //$.get('./js/data/bejing_track_end.json', function (data) {

    $.get('./js/data/test.txt', function (data) {

            var array = data.split(' ');

    for(var i in array)

    {

    if(array[i]!="")

    {

    eval("temp="+array[i]);

    startPoints[i]=[temp.start_location_lng, temp.start_location_lat].concat([1]);

    endPoints[i]=[temp.end_location_lng, temp.end_location_lat].concat([1]);

    }

    }

    option_start = {

                animation: true,

                bmap: {

                    center: [116.301670, 39.971690],

                    zoom: 11,

                    roam: true

                },

                visualMap: {

                    show: false,

                    top: 'top',

                    min: 0,

                    max: 5,

                    seriesIndex: 0,

                    calculable: true,

                    inRange: {

                        color: ['blue', 'blue', 'green', 'yellow', 'red']

                    }

                },

                series: [{

                    type: 'heatmap',

                    coordinateSystem: 'bmap',

                    data: startPoints,

                    pointSize: 10,

                    blurSize: 6

                }]

            }

    option_end = {

                animation: true,

                bmap: {

                    center: [116.301670, 39.971690],

                    zoom: 11,

                    roam: true

                },

                visualMap: {

                    show: false,

                    top: 'top',

                    min: 0,

                    max: 5,

                    seriesIndex: 0,

                    calculable: true,

                    inRange: {

                        color: ['blue', 'blue', 'green', 'yellow', 'red']

                    }

                },

                series: [{

                    type: 'heatmap',

                    coordinateSystem: 'bmap',

                    data: endPoints,

                    pointSize: 10,

                    blurSize: 6

                }]

            }

    //用来展示5公里范围的人都去到那里, 或者从哪里来的。

    option_ds = {

                animation: true,

                bmap: {

                    center: [116.301670, 39.971690],

                    zoom: 11,

                    roam: true

                },

                visualMap: {

                    show: false,

                    top: 'top',

                    min: 0,

                    max: 5,

                    seriesIndex: 0,

                    calculable: true,

                    inRange: {

                        color: ['blue', 'blue', 'green', 'yellow', 'red']

                    }

                },

                series: [{

                    type: 'heatmap',

                    coordinateSystem: 'bmap',

                    data: dsPoints,

                    pointSize: 10,

                    blurSize: 6

                }]

            }

    var callback=function(center_point){

    option_start.bmap.center = [center_point.lng, center_point.lat];

    option_end.bmap.center = [center_point.lng, center_point.lat];

    option_ds.bmap.center = [center_point.lng, center_point.lat];

    map_option=option_start;

            myChart.setOption(map_option);

    var bmap = myChart.getModel().getComponent('bmap').getBMap();

    bmap.addEventListener("click", function(e){ //鼠标点击事件 

    var pt = e.point;

    if(map_status=="default")

    $("#src_dest_Btn").removeAttr("disabled");

    else

    $("#src_dest_Btn").attr("disabled","disabled");

    seashowtip(1, pt.lng,pt.lat);

    }

    );

            if (!app.inNode) {

                // 添加百度地图插件

                bmap.addControl(new BMap.MapTypeControl());

            }

    }

    searchByStationName("北京",callback);

        });

        function chg(type)

        {

        map_status="default";

        if(type==0)

        {

        map_option = option_start;

        $("#endBtn").removeAttr("disabled");

         $("#startBtn").attr("disabled","disabled");

        }else

        {

        map_option = option_end;

        $("#startBtn").removeAttr("disabled");

    $("#endBtn").attr("disabled","disabled");

        }

        $("#src_dest_Btn").attr("disabled","disabled");

    myChart.setOption(map_option);

    var my_tips=document.all.mytips;

    my_tips.style.display="none";

        };

        function showDS()

        {

        //显示5公里范围内的新客的目的地或者来源。

        if(dsPoints && dsPoints.length>0)

        {

        map_status="passenger_within5km";

        $("#startBtn").removeAttr("disabled");

        $("#endBtn").removeAttr("disabled");

        option_ds.series[0].data=dsPoints;

        map_option=option_ds;

        myChart.setOption(map_option);

        }

        }

        function calPopulationAround2(ln, la)

        {

        var result=[];

        var points = map_option.series[0].data;

      for(var i in points)

      {

      var track = points[i];

      if(getDistance(track[0],track[1], ln, la)<radium/2)

      {

      result[index] = track;

      index+=1;

      }

      }

            

        return result;

        };    

        function calPopulationAround(ln, la)

        {

        //计算5公里内的乘客坐标, 以及他们的来源或者目的地。

        if(map_status!="default")

        return calPopulationAround2(ln, la);

        var result=[];

        var points = startPoints;

        var ds_points = endPoints;

        if(!$("#startBtn").attr("disabled"))

        {

        points = endPoints;

        ds_points=startPoints;

        }

        dsPoints=[];

        var index=0;

      for(var i in points)

      {

      var track = points[i];

      if(getDistance(track[0],track[1], ln, la)<radium/2)

      {

      result[index] = track;

      dsPoints[index] = ds_points[i];

      index+=1;

      }

      }

        return result;

        };

        function seashowtip(flag,ln,la){

          var my_tips=document.all.mytips;

          var points= calPopulationAround(ln,la);

          searchByPoint(ln,la, function(result){

          var tipsName = ""+result.address+",附近商圈:("+ result.business +"),坐标("+ln+","+la+")周围"+radium+"公里范围内首单人数:"+points.length+"人";

          if(flag){

              my_tips.innerHTML=tipsName;//为div块上添加内容

              my_tips.style.display="";

              my_tips.style.width=150;

              my_tips.style.zIndex=999;

              my_tips.style.display="block";

              //my_tips.style.left=event.clientX+10+document.body.scrollLeft;

              //my_tips.style.top=event.clientY+document.body.scrollTop;

              }else{

                  my_tips.style.display="none";

          }

          });

       }

        function rad(d)

    {

      return d * Math.PI / 180.0;

    }

        function getDistance(lng1,lat1, lng2,lat2)

        {

        radLat1 = rad(lat1);

      radLat2 = rad(lat2);

      a = radLat1 - radLat2;

      b = rad(lng1) - rad(lng2);

      s=2*Math.asin(

    Math.sqrt(Math.pow(Math.sin(a/2), 2.0)+

    Math.cos(radLat1)*Math.cos(radLat2)*Math.pow(Math.sin(b/2), 2.0)));

      EARTH_RADIUS = 6378.137;

      s = s * EARTH_RADIUS;

      s = Math.round(s*10000) / 10000;

      return s;

        }

        function searchByStationName(keyword, cb) {

          //var keyword = "石景山区";

        //根据地址来查询经纬度。

          localSearch.setSearchCompleteCallback(function (searchResult) {

            var poi = searchResult.getPoi(0);

            cb(poi.point);

          });

          localSearch.search(keyword);

        }

     

        function searchByPoint(lng,lat, cb)

        {//根据经纬度查询地址

        var poi= new BMap.Point(lng,lat);

        gc.getLocation(poi, function(rs){

        cb(rs);

        });

        }

        

    </script>

    </body>

    </html>

  • 相关阅读:
    面向对象基础小结
    异常应用场景
    集合应用场景1:迭代器
    集合应用场景2——数据结构
    华为ce交换机 Bridge-Domain NVE
    linux 内核内置模块
    linux bridge 转发 ip
    iptables nat&conntrack
    loopback
    配置集中式网关部署方式的VXLAN示例(静态方式)
  • 原文地址:https://www.cnblogs.com/realzjx/p/5859831.html
Copyright © 2011-2022 走看看