熱力圖與百度地圖擴展實例

  最近公司老總讓作一個某某地區的熱點分佈圖,一開始沒想到使用百度地圖API就能完成,恰恰走了彎路,使用了Echarts和百度地圖結合完成的,不過也是一個不錯的經歷啊javascript

讓我既能更加熟悉Echarts和百度地圖的使用(之前用過一點),在互聯網這個時代,誰不會用成熟的API呢,做爲小白咱們更應該會使用。接下來我會講講本身在使用過程當中的html

遇到的問題,可供參考!java

一.項目效果圖以下:jquery

下圖是測試數據的效果:json

下圖是真實數據的動態加載並帶有查詢功能的顯示圖:api

 

二.瞭解百度地圖和Echarts數組

百度地圖API:http://developer.baidu.com/map/jsdemo.htm#a1_2(地圖利器)app

EchartsAPI:http://echarts.baidu.com/ (作報表的一個利器)echarts

不懂的先看看。dom

三.項目思路

1.參考EchartsAPI中關於熱點圖的代碼,在本身的項目中加載地圖。

在這一步中你可能遇到這樣的問題?

不用擔憂我直接給出:http://echarts.baidu.com/data/asset/data/hangzhou-tracks.json,將此文件下載下來,放到本身的項目中,而後替換成本身的路徑。

可是你仍是會遇到「...map屬性沒有找到的問題...」?

解決方法:

var data = eval("("+data+")");

$.get()方法,後面添加數據格式,'text'。

後期把數據換成動態數據,在後臺編寫方法按照他的格式構造數據,而後傳遞到前臺。

2.加載地圖覆蓋物,參考百度地圖API

3.百度地圖和Echarts結合點

百度地圖和Echarts結合點,怎麼結合?這個須要考慮吧

<!-- 地圖開始 -->
       <div id="container" style="height: 90%"></div>
<!-- 地圖結束 -->

       <!-- 新添加的jQuery -->
       <script type="text/javascript" src="${pageContext.request.contextPath}/js/jquery.2.1.4.min.js"></script>
       <!-- End -->
         
       /****************************地圖開始************************************/
       	  var dom = document.getElementById("container");
          var myChart = echarts.init(dom);
          var app = {};
          option = null;
          app.title = '熱力圖與百度地圖擴展';
          $.get('${pageContext.request.contextPath}/background/hotspotmap/hotspotMap.html', function (data) {
             var data = data.broadBandHotData;
             //var data = eval("("+data+")");
             console.log(data);
              var points = [].concat.apply([], data.map(function (track) {
                  return track.map(function (seg) {
                      return seg.coord.concat([1]);
                  });
              }));
              myChart.setOption(option = {
                  animation: false,
                  bmap: {
                      center: [108.962783, 34.360491],
                      zoom: 12,
                      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: points,
                      pointSize: 20,
                      blurSize: 5
                  }]
              });
              if (!app.inNode) {
            	  //百度地圖相關代碼在此處編寫
                  var bmap = myChart.getModel().getComponent('bmap').getBMap();
                  bmap.addControl(new BMap.MapTypeControl());
                  。。。。。
              }
          },"json");
          if (option && typeof option === "object") {
              myChart.setOption(option, true);
          }
          /*************************地圖結束*****************************/
		
       </script>

 4.經緯度查詢(使用百度地圖)

申請百度地圖帳號,會的到一個ak,這個很重要!

提供一個根據地名查詢經緯度的類:

public class MapLngLat {
     /**
     * 返回輸入地址的經緯度座標 key lng(經度),lat(緯度)
     */
    public static Map<String, String> getGeocoderLatitude(String address) {
        BufferedReader in = null;
        try {
            Map paramsMap = new LinkedHashMap<String, String>();
            paramsMap.put("address", address);
            paramsMap.put("output", "json");
            paramsMap.put("ak", "cW4AmdztXTI0xeYGZxDXG7tWA96qkQLi");
            String quest = GetLatitude.toQueryString(paramsMap);
            URL tirc = new URL(
                    "http://api.map.baidu.com/geocoder/v2/?" + quest + "&sn=" + GetLatitude.result(paramsMap));

            in = new BufferedReader(new InputStreamReader(tirc.openStream(), "UTF-8"));
            String res;
            StringBuilder sb = new StringBuilder("");
            while ((res = in.readLine()) != null) {
                sb.append(res.trim());
            }
            String str = sb.toString();
            Map<String, String> map = null;
            if (StringUtils.isNotEmpty(str)) {
                int lngStart = str.indexOf("lng\":");
                int lngEnd = str.indexOf(",\"lat");
                int latEnd = str.indexOf("},\"precise");
                if (lngStart > 0 && lngEnd > 0 && latEnd > 0) {
                    String lng = str.substring(lngStart + 5, lngEnd);
                    String lat = str.substring(lngEnd + 7, latEnd);
                    map = new HashMap<String, String>();
                    map.put("lng", lng);
                    map.put("lat", lat);
                    return map;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
    public static void main(String args[]) {
        try {
            Map<String, String> json = MapLngLat.getGeocoderLatitude("陝西省戶縣七一路紙廠家眷區");
            System.out.println("lng : " + json.get("lng"));
            System.out.println("lat : " + json.get("lat"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

另外一個輔助類:

public class GetLatitude {
    /**
     * 對Map內全部value做utf8編碼,拼接返回結果
     * @param data 參數的封裝
     * @return 拼接的訪問字符串的一部分如:address=%E7%99%BE%E5%BA%A6%E5%A4%A7%E5%8E%A6&output=json&ak=yourakyoursk
     * @throws UnsupportedEncodingException
     */
    public static String toQueryString(Map<?, ?> data) throws UnsupportedEncodingException {
        StringBuffer queryString = new StringBuffer();
        for (Entry<?, ?> pair : data.entrySet()) {
            queryString.append(pair.getKey() + "=");
            queryString.append(URLEncoder.encode((String) pair.getValue(), "UTF-8") + "&");
        }
        if (queryString.length() > 0) {
            queryString.deleteCharAt(queryString.length() - 1);
        }
        return queryString.toString();
    }

    /**
     * 來自stackoverflow的MD5計算方法,調用了MessageDigest庫函數,並把byte數組結果轉換成16進制
     * @param md5
     * @return
     */
    private static String MD5(String md5) {
        try {
            java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
            byte[] array = md.digest(md5.getBytes());
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < array.length; ++i) {
                sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).substring(1, 3));
            }
            return sb.toString();
        } catch (java.security.NoSuchAlgorithmException e) {
        }
        return null;
    }
    /**
     * 計算sn的值
     * @param paramsMap
     * @return
     * @throws UnsupportedEncodingException
     */
    public static String result(Map paramsMap) throws UnsupportedEncodingException {
        /**
         * 計算sn跟參數對出現順序有關,get請求請使用LinkedHashMap保存
         * <key,value>,該方法根據key的插入順序排序;post請使用TreeMap保存
         * <key,value>,該方法會自動將key按照字母a-z順序排序。因此get請求可自定義參數順序(sn參數必須在最後)發送請求,
         * 可是post請求必須按照字母a-z順序填充body(sn參數必須在最後)。以get請求爲例:http://api.map.baidu.
         * com/geocoder/v2/?address=百度大廈&output=json&ak=yourak,
         * paramsMap中先放入address,再放output,而後放ak,放入順序必須跟get請求中對應參數的出現順序保持一致。
         */
        // 調用下面的toQueryString方法,對LinkedHashMap內全部value做utf8編碼,拼接返回結果address=%E7%99%BE%E5%BA%A6%E5%A4%A7%E5%8E%A6&output=json&ak=yourak
        String paramsStr = toQueryString(paramsMap);

        // 對paramsStr前面拼接上/geocoder/v2/?,後面直接拼接yoursk獲得/geocoder/v2/?address=%E7%99%BE%E5%BA%A6%E5%A4%A7%E5%8E%A6&output=json&ak=yourakyoursk
        String wholeStr = new String("/geocoder/v2/?" + paramsStr + "FkytCBIZMi5kVhkfTBICZp02KGa1U5tk");

        // 對上面wholeStr再做utf8編碼
        String tempStr = URLEncoder.encode(wholeStr, "UTF-8");

        // 調用下面的MD5方法獲得最後的sn簽名7de5a22212ffaa9e326444c75a58f9a0
        // System.out.println(MD5(tempStr));
        return MD5(tempStr);
    }

}

四.解決問題

1.如何修改標註邊框樣式?

    var label = new BMap.Label(「標籤內容",{offset: new BMap.Size(25,5)});
    //設置lebel樣式
    label.setStyle({
        padding:'8px',
        border:'1px solid #96c2f1',
        background:'#eff7ff',
        display:'none'
    });
         

2.如何實現覆蓋物標註信息滑動顯示和隱藏效果?

爲標註添加事件改變標籤Label:

                   //target爲標誌物對象,label標籤
                   function addClickHandler(target,label){
                        target.addEventListener("mouseover", function(){ 
                        label.setStyle({  //給label設置樣式,任意的CSS都是能夠的
                        display:"block"
                     });
                   }); 
                    target.addEventListener("mouseout", function(){ 
                       label.setStyle({  //給label設置樣式,任意的CSS都是能夠的
                       display:"none"
                    }); 
                 });
               }            

整個demo作下來,對百度地圖和Echarts就會更加了解。

有不少東西很差說,只能意會,暫時點到這裏,有須要的源碼的,留言。

相關文章
相關標籤/搜索