用百度地圖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('\n');

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>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM