百度地图标注及结合ECharts图谱数据可视化
本示例中根据企业位置经纬度,在页面右侧百度地图中标注企业名称。同时页面左侧ECharts图谱饼状图用于统计企业行业与注册资本。当右侧百度地图缩放拖拽,左侧ECharts图谱根据右侧地图上出现的企业动态变化。详细过程如下两图所示:
本示例中有用到Vue.js,以及一个JQuery的表格插件DataTable。详细代码如下所示。
一、JSP代码
JSP中注意需要引用相关JS文件,如下所示:
1 <script src="js/jquery-3.2.1.js"></script> 2 <script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=q7IDDpeG6pBgm2vRYOCLyI9phWdUD6jY"></script> 3 <script src="js/echarts.js"></script> 4 <script type="text/javascript" src="js/jquery.dataTables.min.js"></script> 5 <script src="https://cdn.bootcss.com/vue-resource/1.3.4/vue-resource.js"></script> 6 <script src="https://cdn.bootcss.com/vuex/3.0.1/vuex.min.js"></script> 7 <script type="text/javascript" src="js/map-vue.js"></script>
前端代码仅供参考,如下所示:
1 <!--左侧信息展示、右侧地图--> 2 <div id="wholeDiv"> 3 <!--企业信息区域--> 4 <div id="mapinfo_div" style="position: absolute;top: 61px;left: 0px;width: 35%;height: 86%;"> 5 <div class="innerbox" style="position: absolute;top: 0px;left: 2px;width: 100%;height: 44%;border: 1px solid darkgray;overflow-x: auto"> 6 <div id="mapCorp1" style="position: absolute;left: 0px;top: 0px;width: 420px;height: 100%;float: left;"></div> 7 <div id="mapCorp2" style="position: absolute;left: 450px;top: 0px;width: 420px;height: 100%;float: left;"></div> 8 <font class="mapMessage" size="3" color="#808080" style="position: absolute;left: 33%;top: 45%;display: none">地图当前区域未搜到相关企业</font> 9 </div> 10 11 <div id="mapCorpList" class="innerbox" style="position: absolute;top: 45%;left: 2px;width: 100%;height: 60%;overflow-y: auto;border: 1px solid darkgray;" > 12 <ul v-for="(corp, corpIndex) in corpList"> 13 <li style="height: 100px;border-bottom:#1db5ee 1px dashed;padding-bottom:10px;margin-bottom:0px;overflow:hidden;"> 14 <a href=""><img width="90" height="90" alt="logo" v-bind:src="corp.corpLogo" style="margin-top: 5px;border:#ccc 1px solid;padding:2px;float:left;"/></a> 15 <a target="_blank" v-bind:href="'http://localhost:8080/see_details.do?corp_id='+corp.corpId" > 16 <font id = "map_corpName" style="padding:10px;" size="3"><b>{{ corp.corpName}}</b></font> 17 </a><br/> 18 <font style="padding:10px;" size="3">法人:</font> 19 <font style="padding:0px;color: gray" size="3">{{ corp.operManName}}</font> 20 <font style="padding:10px;" size="3">注册资本:</font> 21 <font style="padding:0px;color: gray" size="3">{{ corp.regCapi}}万元</font><br/> 22 <font style="padding:10px;" size="3">行业:</font> 23 <font style="padding:0px;color: gray" size="3">{{ corp.belongTrade}}</font><br/> 24 <span v-if="corp.admitMain != '——'" style="margin-left: 10px;background-color: #1db5ee;"><font size="1.5" color="#ffffff">{{ corp.admitMain}}</font></span> 25 </li> 26 </ul> 27 <font class="mapMessage" size="3" color="#808080" style="position: absolute;left: 33%;top: 45%;display: none">地图当前区域未搜到相关企业</font> 28 </div> 29 30 <div id="mapCorpTable" class="innerbox" style="position: absolute;top: 45%;left: 2px;width: 100%;height: 60%;overflow-y: auto;border: 1px solid darkgray;display: none"> 31 <table id="showCorpTable" class="display" style="margin-top: 5px"> 32 <thead> 33 <tr align="left"> 34 <th>公司名称</th> 35 <th>法人</th> 36 <th>注册资本(万)</th> 37 <th>所属行业</th> 38 <th>详细地址</th> 39 </tr> 40 </thead> 41 </table> 42 </div> 43 </div> 44 45 <!--地图区域--> 46 <div id="mapCorp_div" style="position: absolute;top: 61px;left: 36%;width: 64%;height: 90%;border: 1px solid lightgray;overflow: hidden;font-family: '微软雅黑';"> 47 <div id="allmap" style="width: 100%;height: 100%;float:left;"> 48 </div> 49 50 <div style="position: absolute;top: 38%;left: 0px;width: 50px;height: 100px;border-radius:0 50px 50px 0;background-color: darkred;opacity:0.6;float:left;"> 51 <img id = "map_right" src="/icon/map_right.png" width="60" height="50" style="margin-top: 25px"/> 52 <img id = "map_left" src="/icon/map_left.png" width="60" height="50" style="margin-top: 25px;display: none"/> 53 </div> 54 </div> 55 56 <!--搜索区域--> 57 <div id="search" style="position: fixed;top: 10%;left: 76%;width: 20%;height: 7%;background-color: white;box-shadow: 0px 4px 8px rgba(44, 35, 35, 0.6)"> 58 <input type="text" ref="cityName" placeholder="请输入城市名称" @keyup.enter="locationByCityName" 59 style="height: 35px;width: 220px;border: none;outline:none;font-size: 18px;margin-top: 7px"/> 60 <div style="position: absolute;top: 15%;left: 84%;height: 68%;width: 12%;background-image: url(/icon/map_search.png)" v-on:click="locationByCityName();"> 61 </div> 62 </div> 63 </div>
二、JavaScript代码,map-vue.js文件
1 var vm = new Vue({ 2 el: "#wholeDiv", 3 data: { 4 map: "", // 百度地图全局变量 5 //regionList: [], 6 corpList: [], 7 }, 8 mounted: function () { 9 var _this = this; 10 map = new BMap.Map("allmap"); 11 var initPoint = new BMap.Point(118.801372, 32.061892); 12 map.centerAndZoom(initPoint, 15); // 初始化地图,设置中心坐标点和地图级别 13 map.addControl(new BMap.NavigationControl({enableGeolocation: true})); // 添加比例尺控件 14 map.addControl(new BMap.ScaleControl({anchor: BMAP_ANCHOR_TOP_LEFT})); // 左上角 15 map.enableScrollWheelZoom(true); // 开启鼠标滚轮缩放 16 17 this.getMapList(); 18 19 // 监听缩放事件 20 map.addEventListener('zoomend', function (event) { 21 console.log("缩放"); 22 _this.mapResize(event.target); 23 }); 24 // 监听拖拽事件 25 map.addEventListener('dragend', function (event) { 26 console.log("拖拽"); 27 _this.mapResize(event.target); 28 }) 29 }, 30 methods: { 31 /** 32 * 根据城市名称定位 33 */ 34 locationByCityName: function () { 35 var cityName = this.$refs.cityName.value; 36 map.centerAndZoom(cityName,11); 37 var _this = this; 38 // 地图加载完成事件 39 // 不加载完成,获取的是上一次的坐标 40 map.addEventListener("tilesloaded", function (event){ 41 _this.mapResize(event.target); 42 }); 43 }, 44 /** 45 * 获取数据 46 */ 47 getMapList: function () { 48 this.getAllCorp(); 49 this.getCorpDataTable(); 50 }, 51 52 53 /** 54 * 获取所有公司坐标点 55 */ 56 getAllCorp: function () { 57 var _this = this; 58 this.$http.get("http://localhost:8080/mapCorp.do").then(function (result) { 59 var mapCorpList = result.body; 60 _this.corpList = mapCorpList; 61 for (var i = 0; i < mapCorpList.length; i++) { 62 var point = new BMap.Point(mapCorpList[i].longitude, mapCorpList[i].latitude); // 标记坐标点 63 var label = new BMap.Label(mapCorpList[i].corpName, {offset: new BMap.Size(20, -10)});// 标记说明 64 _this.addMarker(point, label); 65 } 66 _this.getTradeEcharts(mapCorpList); 67 _this.getCapiEcharts(mapCorpList); 68 }); 69 }, 70 71 72 /** 73 * 获取地图范围内的公司 74 */ 75 getCorpInsizeMap: function (leftLongitude, leftLatitude, rightLongitude, rightLatitude) { 76 var _this = this; 77 this.$http.get("http://localhost:8080/mapInside.do?leftLongitude=" + leftLongitude + 78 "&leftLatitude=" + leftLatitude + 79 "&rightLongitude=" + rightLongitude + 80 "&rightLatitude=" + rightLatitude).then(function (result) { 81 _this.corpList = result.body; 82 _this.getTradeEcharts(result.body); 83 _this.getCapiEcharts(result.body); 84 }); 85 }, 86 87 88 /** 89 * 企业行业图谱展示 90 */ 91 getTradeEcharts: function (data) { 92 var newList = data; 93 var tempJSON = []; 94 //遍历数组,并分类统计,放入tempJSON中 95 for(var i = 0; i < newList.length; i++) { 96 if(!tempJSON[newList[i].belongTrade]) { 97 var arr = []; 98 arr.push(newList[i]); 99 tempJSON[newList[i].belongTrade] = arr; 100 }else { 101 tempJSON[newList[i].belongTrade].push(newList[i]); 102 } 103 } 104 console.log(tempJSON); 105 console.log("tempJSON长度"+Object.keys(tempJSON).length); 106 107 var tradeArr = []; 108 var i = 0; 109 for(var trade in tempJSON){ 110 if(i > 4){ 111 break; 112 } 113 tradeArr[i] = { 114 value: tempJSON[trade].length, 115 name: trade 116 } 117 i++; 118 } 119 120 var myChart = echarts.init(document.getElementById('mapCorp1')); 121 option = { 122 title : { 123 text: '企业所属行业分析(TOP5)', 124 x:'center' 125 }, 126 tooltip : { 127 trigger: 'item', 128 formatter: "{a} <br/>{b} : {c} ({d}%)" 129 }, 130 series : [ 131 { 132 name: '所属行业', 133 type: 'pie', 134 radius : '55%', 135 center: ['50%', '55%'], 136 data: tradeArr, 137 itemStyle: { 138 emphasis: { 139 shadowBlur: 10, 140 shadowOffsetX: 0, 141 shadowColor: 'rgba(0, 0, 0, 0.5)' 142 } 143 } 144 } 145 ] 146 }; 147 myChart.setOption(option); 148 }, 149 150 151 /** 152 * 企业资本图谱展示 153 */ 154 getCapiEcharts: function (data) { 155 if(data.length > 0){ 156 $('#mapCorp1').css("display","block"); 157 $('#mapCorp2').css("display","block"); 158 $('.mapMessage').css("display","none"); 159 160 var class1 = 0; 161 var class2 = 0; 162 var class3 = 0; 163 var class4 = 0; 164 var class5 = 0; 165 //遍历数组,并分类统计,放入tempJSON中 166 for(var i = 0; i < data.length; i++) { 167 if( 0 < data[i].regCapi && data[i].regCapi <= 100){ 168 class1 += 1; 169 }else if( 100 < data[i].regCapi && data[i].regCapi <= 500){ 170 class2 += 1; 171 }else if( 500 < data[i].regCapi && data[i].regCapi <= 1000){ 172 class3 += 1; 173 }else if( 1000 < data[i].regCapi && data[i].regCapi <= 5000){ 174 class4 += 1; 175 }else if( 5000 < data[i].regCapi){ 176 class5 += 1; 177 } 178 } 179 180 var tradeArr = []; 181 if(class1 != 0){ 182 tradeArr[0] = { 183 value: class1, 184 name: "0-100万" 185 } 186 }; 187 if(class2 != 0){ 188 tradeArr[1] = { 189 value: class2, 190 name: "101-500万" 191 } 192 }; 193 if(class3 != 0){ 194 tradeArr[2] = { 195 value: class3, 196 name: "501-1000万" 197 } 198 }; 199 if(class4 != 0){ 200 tradeArr[3] = { 201 value: class4, 202 name: "1001-5000万" 203 } 204 }; 205 if(class5 != 0){ 206 tradeArr[4] = { 207 value: class5, 208 name: "5001万以上" 209 } 210 }; 211 212 213 var myChart = echarts.init(document.getElementById('mapCorp2')); 214 option = { 215 title : { 216 text: '企业注册资本统计', 217 x:'center' 218 }, 219 tooltip : { 220 trigger: 'item', 221 formatter: "{a} <br/>{b} : {c} ({d}%)" 222 }, 223 series : [ 224 { 225 name: '注册资本', 226 type: 'pie', 227 radius : '55%', 228 center: ['50%', '55%'], 229 data: tradeArr, 230 itemStyle: { 231 emphasis: { 232 shadowBlur: 10, 233 shadowOffsetX: 0, 234 shadowColor: 'rgba(0, 0, 0, 0.5)' 235 } 236 } 237 } 238 ] 239 }; 240 myChart.setOption(option); 241 }else{ 242 $('#mapCorp1').css("display","none"); 243 $('#mapCorp2').css("display","none"); 244 $('.mapMessage').css("display","block"); 245 } 246 }, 247 248 249 /** 250 * 表格展示 251 */ 252 getCorpDataTable: function () { 253 $('#showCorpTable').DataTable({ 254 "ajax" : "http://localhost:8080/tableCorp.do", 255 "pageLength" : 5, 256 "pagingType" : "full_numbers", 257 "language" : { 258 "emptyTable" : "无可用数据", 259 "infoEmpty" : "没有记录可以显示", 260 "loadingRecords" : "请等待,数据正在加载中......", 261 "search" : "搜索", 262 "lengthMenu" : "Show _MENU_ entries", 263 "lengthMenu" : '显示 <select>' 264 + '<option value="5">5</option>' 265 + '<option value="10">10</option>' 266 + '<option value="20">20</option>' 267 + '<option value="30">30</option>' 268 + '<option value="40">40</option>' 269 + '<option value="-1">所有</option>' 270 + '</select> 记录', 271 "info" : "第_PAGE_页(共_PAGES_页)", 272 "paginate" : { 273 "first" : '首页', 274 "previous" : '上一页', 275 "next" : '下一页', 276 "last" : '尾页' 277 }, 278 "aria" : { 279 "paginate" : { 280 "first" : 'First', 281 "previous" : 'Previous', 282 "next" : 'Next', 283 "last" : 'Last' 284 } 285 } 286 }, 287 "columns" : [ { 288 "data" : "corpName" 289 }, { 290 "data" : "operManName" 291 }, { 292 "data" : "regCapi" 293 }, { 294 "data" : "belongTrade" 295 }, { 296 "data" : "corpAddr" 297 } ] 298 }); 299 }, 300 301 302 /** 303 * 标记坐标点 304 * @param corpPoint 305 * @param corpNameLabel 306 */ 307 addMarker: function (corpPoint, corpNameLabel) { 308 var marker = new BMap.Marker(corpPoint); 309 marker.setLabel(corpNameLabel); 310 map.addOverlay(marker); 311 }, 312 313 314 /** 315 * 地图缩放 316 */ 317 mapResize: function (_map) { 318 // 获取当前地图边界 319 var bounds = _map.getBounds(), 320 southWest = bounds.getSouthWest(), // 西北角 321 northEast = bounds.getNorthEast(); // 东北角 322 323 var zoomLevel = _map.getZoom(); 324 325 params = { 326 level: zoomLevel, 327 leftLongitude: southWest.lng, // 左上角 328 leftLatitude: northEast.lat, 329 rightLongitude: northEast.lng, // 右下角 330 rightLatitude: southWest.lat 331 }; 332 333 // 搜索地图范围内的公司 334 // 每当地图大小改变,就重新搜索 335 this.getCorpInsizeMap(params.leftLongitude, params.leftLatitude, 336 params.rightLongitude, params.rightLatitude); 337 338 // 默认缩放级别为15 339 340 console.log("左上角:" + params.leftLongitude+ "," + params.leftLatitude); 341 console.log("右下角:" + params.rightLongitude + "," + params.rightLatitude); 342 } 343 } 344 });
1 $('#map_right').click(function () { 2 $(this).css("display","none"); 3 $("#map_left").css("display","block"); 4 $("#mapCorpList").css("display","none"); 5 $("#mapCorpTable").css("display","block"); 6 7 $("#mapinfo_div").width($("#mapinfo_div").width() + 400); 8 $("#mapCorp_div").width($("#mapCorp_div").width() - 400); 9 $("#mapCorp_div").css("margin-left",400); 10 }); 11 $('#map_left').click(function () { 12 $(this).css("display","none"); 13 $("#map_right").css("display","block"); 14 $("#mapCorpTable").css("display","none"); 15 $("#mapCorpList").css("display","block"); 16 17 $("#mapinfo_div").width($("#mapinfo_div").width() - 400); 18 $("#mapCorp_div").width($("#mapCorp_div").width() + 400); 19 $("#mapCorp_div").css("margin-left",0); 20 });
三、Controller层代码
1 package controller; 2 3 import entity.BaiduMapCorp; 4 import net.sf.json.JSONArray; 5 import org.springframework.beans.factory.annotation.Autowired; 6 import org.springframework.stereotype.Controller; 7 import org.springframework.web.bind.annotation.*; 8 import service.BaiduMapService; 9 10 import java.util.List; 11 12 @Controller 13 public class BaiduMapController { 14 15 @Autowired 16 BaiduMapService baiduMapService; 17 18 19 //获取地图上所有企业 20 @GetMapping("/mapCorp.do") 21 @ResponseBody 22 public List<BaiduMapCorp> mapPointList() { 23 List<BaiduMapCorp> mapList = baiduMapService.getAllMapCorp(); 24 return mapList; 25 } 26 27 28 //获得当前位置所有公司 29 @RequestMapping("/mapInside.do") 30 @ResponseBody 31 public List<BaiduMapCorp> getCorpInsideMap(@RequestParam(value = "leftLongitude") double leftLongitude, 32 @RequestParam(value = "leftLatitude") double leftLatitude, 33 @RequestParam(value = "rightLongitude") double rightLongitude, 34 @RequestParam(value = "rightLatitude") double rightLatitude) { 35 return baiduMapService.getCorpInsideMap(leftLongitude, leftLatitude, rightLongitude, rightLatitude); 36 } 37 38 //datatable获取地图上所有企业 39 @RequestMapping(value = "/tableCorp.do", produces = "text/plain;charset=UTF-8") 40 @ResponseBody 41 public String getTableCorp() { 42 List<BaiduMapCorp> mapList = baiduMapService.getTableCorp(); 43 String result = "{" +"\"data\""+":"+ JSONArray.fromObject(mapList).toString()+"}"; 44 System.out.println(result); 45 return result; 46 } 47 48 }
四、实体类
1 package entity; 2 3 /** 4 * 百度地图坐标点 5 * 6 */ 7 public class BaiduMapCorp { 8 9 private Integer id; //ID 10 11 private String corpName; //公司名称 12 13 private double longitude; //经度 14 15 private double latitude; //维度 16 17 private String corpAddr; //公司地址 18 19 private Integer corpId; //公司ID 20 21 private String operManName; //公司法人 22 23 private Integer regCapi; //注册资本 24 25 private String corpLogo; //企业logo 26 27 private String belongTrade; //所属行业 28 29 private String admitMain; //企业大类 30 31 public BaiduMapCorp() { 32 } 33 34 public Integer getId() { 35 return id; 36 } 37 38 public void setId(Integer id) { 39 this.id = id; 40 } 41 42 public String getCorpName() { 43 return corpName; 44 } 45 46 public void setCorpName(String corpName) { 47 this.corpName = corpName; 48 } 49 50 public double getLongitude() { 51 return longitude; 52 } 53 54 public void setLongitude(double longitude) { 55 this.longitude = longitude; 56 } 57 58 public double getLatitude() { 59 return latitude; 60 } 61 62 public void setLatitude(double latitude) { 63 this.latitude = latitude; 64 } 65 66 public String getCorpAddr() { 67 return corpAddr; 68 } 69 70 public void setCorpAddr(String corpAddr) { 71 this.corpAddr = corpAddr; 72 } 73 74 public Integer getCorpId() { 75 return corpId; 76 } 77 78 public void setCorpId(Integer corpId) { 79 this.corpId = corpId; 80 } 81 82 public String getOperManName() { 83 return operManName; 84 } 85 86 public void setOperManName(String operManName) { 87 this.operManName = operManName; 88 } 89 90 public Integer getRegCapi() { 91 return regCapi; 92 } 93 94 public void setRegCapi(Integer regCapi) { 95 this.regCapi = regCapi; 96 } 97 98 public String getCorpLogo() { 99 return corpLogo; 100 } 101 102 public void setCorpLogo(String corpLogo) { 103 this.corpLogo = corpLogo; 104 } 105 106 public String getBelongTrade() { 107 return belongTrade; 108 } 109 110 public void setBelongTrade(String belongTrade) { 111 this.belongTrade = belongTrade; 112 } 113 114 public String getAdmitMain() { 115 return admitMain; 116 } 117 118 public void setAdmitMain(String admitMain) { 119 this.admitMain = admitMain; 120 } 121 122 }
至此是关于百度地图标注及结合ECharts图谱数据可视化,仅供参考。
如有疏漏错误之处,还请不吝赐教!