vue百度地圖實現自定義覆蓋物
阿新 • • 發佈:2020-12-01
百度地圖實現自定義覆蓋物
效果展示
實現目的:
其實這種東西完全可以去用Echars實現,人家做的散點圖很方便,但是這不是需要自定義樣式了嗎,就弄了這個,基本上就是照著人家的寫的
人家寫的https://www.cnblogs.com/zuobaiquan01/p/9626452.html
但是我覺得他寫的不好,不方便別人抄,哈哈哈
缺點:
沒有實現點聚合的功能,不能標註下有幾個位置
實現方案:
使用的就是 百度地圖的覆蓋類Overlay
覆蓋類Overlay
咋說的這個東西其實慢慢弄就行,但是就是自己的樣式有點麻煩,最好的辦法就是,照著案例去學,
原生的案例:
連結:https://pan.baidu.com/s/13O8J9a9_xaoD2NmeiLoD1g
提取碼:ixnz
複製這段內容後開啟百度網盤手機App,操作更方便哦
vue的相關介紹
我是直接寫在了一個vue檔案裡面 方便展示,應該把css 和 js 去拆開寫
template裡面放入百度地圖
<template> <div class="map"> <!-- <div id="container"></div>--> <div id="allmap" style="width:100%; height:calc(100vh - 145px);margin:0 auto;"></div> </div> </template>
在script裡面的 宣告週期裡面進行初始化
mounted() { // // eslint-disable-next-line no-undef // let map = new BMapGL.Map('container'); // 建立Map例項 // // eslint-disable-next-line no-undef // map.centerAndZoom(new BMapGL.Point(116.404, 39.915), 12); // 初始化地圖,設定中心點座標和地圖級別 // map.enableScrollWheelZoom(true); // 開啟滑鼠滾輪縮放 // eslint-disable-next-line no-undef let map = new BMap.Map("allmap"); // eslint-disable-next-line no-undef let point = new BMap.Point(110, 34.5); map.enableScrollWheelZoom(); map.centerAndZoom(point, 6); function ComplexCustomOverlay(point, item) { this._point = point; this._text = item.name; this._child = item.id this._number = item.number } // eslint-disable-next-line no-undef ComplexCustomOverlay.prototype = new BMap.Overlay(); ComplexCustomOverlay.prototype.initialize = function (map) { let that = this that._map = map; let div = that._div = document.createElement("div"); //div.style.zIndex = BMap.Overlay.getZIndex(that._point.lat); div.setAttribute('data-id', that._child); div.setAttribute('class', 'map-circle'); div.setAttribute('data-lng', that._point.lng); div.setAttribute('data-lat', that._point.lat); let pname = document.createElement("p"); pname.setAttribute('class', 'map-areaname'); pname.appendChild(document.createTextNode(that._text)); div.appendChild(pname); let pnum = document.createElement("p"); pnum.setAttribute('class', 'map-areanumber'); div.appendChild(pnum); pnum.appendChild(document.createTextNode(`${that._number}個`)); // div.onmouseover = function(){ // this.style.zIndex = 9999; // } // div.onmouseout = function(){ // this.style.zIndex = BMap.Overlay.getZIndex(that._point.lat); // } if (that._number == 0) { let tipspan = document.createElement("span"); tipspan.setAttribute('class', 'map-nodatatips'); tipspan.appendChild(document.createTextNode("暫無資料")); div.appendChild(tipspan); let itips = document.createElement("i"); itips.setAttribute('class', 'map-itips'); tipspan.appendChild(itips); } div.onclick = function () { if (that._number == 0) { return; } let curlng=parseInt(div.getAttribute('data-lng')) let curlat=parseInt(div.getAttribute('data-lat')) map.clearOverlays(); let point1 = new BMap.Point(curlng,curlat); // eslint-disable-next-line no-undef let point1 = new BMap.Point("123", "42"); map.enableScrollWheelZoom(); map.centerAndZoom(point1, 9); let districtData = [ {"lng": 123.848569, "lat": 42.302504, "name": '西大標準件大全批發商店'}, {"lng": 124.848569, "lat": 42.302504, "name": '測試地點111'}, {"lng": 122.28569, "lat": 42.22504, "name": '測試地點222'}, {"lng": 122.29569, "lat": 42.3504, "name": '測試地點333'} ] for (let i = 0; i < districtData.length; i++) { let temp2 = districtData[i] // eslint-disable-next-line no-undef let myCompOverlay2 = new ComplexCustomOverlay2(new BMap.Point(temp2.lng, temp2.lat), temp2); map.addOverlay(myCompOverlay2); } } map.getPanes().labelPane.appendChild(div); return div; } function tiaozhuan(data){ that.openProject(data) } ComplexCustomOverlay.prototype.draw = function () { let map = this._map; let pixel = map.pointToOverlayPixel(this._point); this._div.style.left = pixel.x + "px"; this._div.style.top = pixel.y + "px"; } function ComplexCustomOverlay2(point, item) { this._point = point; this._text = item.name; this._child = item.id; } // eslint-disable-next-line no-undef ComplexCustomOverlay2.prototype = new BMap.Overlay(); ComplexCustomOverlay2.prototype.initialize = function (map) { this._map = map; let div2 = this._div2 = document.createElement("a"); // div2.style.zIndex = BMap.Overlay.getZIndex(this._point.lat); div2.setAttribute('href', `www.baidu.com`); div2.setAttribute('class', 'circlebox'); div2.setAttribute('target', '_blank'); let div2Child1 = document.createElement("div"); div2Child1.setAttribute('class', 'bg-circle'); div2.appendChild(div2Child1); let div2Child2 = document.createElement("div"); div2Child2.setAttribute('class', 'sm-circle'); div2.appendChild(div2Child2); let div2Child3 = document.createElement("div"); div2Child3.setAttribute('class', 'line'); div2.appendChild(div2Child3); let div2Child4 = document.createElement("div"); div2Child4.setAttribute('class', 'ctx'); div2Child4.setAttribute('title', '點選檢視詳情'); div2Child4.appendChild(document.createTextNode(this._text)); div2.appendChild(div2Child4); div2.onmouseover = function () { div2.setAttribute('class', 'circlebox hoverbox'); } div2.onmouseout = function () { div2.setAttribute('class', 'circlebox'); } map.getPanes().labelPane.appendChild(div2); return div2; } ComplexCustomOverlay2.prototype.draw = function () { let map2 = this._map; let pixel2 = map2.pointToOverlayPixel(this._point); this._div2.style.left = pixel2.x + "px"; this._div2.style.top = pixel2.y + "px"; } let that = this //這個是初始化,也就是渲染相關的位置,proviceData 就迴圈的資料 //{"lng":116.405289,"lat":39.904987,"name":"北京","id":1,"number":123}, // 資料要處理成上邊的格式 要不然需要改好多地方 function initMap() { for (let i = 0; i < that.proviceData.length; i++) { let temp = that.proviceData[i] // eslint-disable-next-line no-undef let myCompOverlay = new ComplexCustomOverlay(new BMap.Point(temp.lng,temp.lat),temp); map.addOverlay(myCompOverlay); } } initMap() let scrollFunc = function (e) { console.log(e) e = e || window.event; // let t1=document.getElementById("allmap"); let zommValue = map.getZoom(); if (zommValue < 8) { map.clearOverlays(); // eslint-disable-next-line no-undef new BMap.Point(110, 35.2); map.centerAndZoom(point, 6); initMap() } } if (document.addEventListener) { document.addEventListener('DOMMouseScroll', scrollFunc, false); } window.onmousewheel = document.onmousewheel = scrollFunc; }
css在寫的時候style 不能加scope 要不然樣式加不上
<style>
.map {
width: 100%;
height: 100%;
}
/*引入相關css*/
html,
body,
h1,
h2,
h3,
h4,
h5,
h6,
div,
dl,
dt,
dd,
ul,
ol,
li,
p,
pre,
hr,
table,
caption,
th,
td,
form,
input,
button,
textarea {
margin: 0;
padding: 0
}
table {
border-collapse: collapse;
border-spacing: 0
}
caption,
th {
text-align: left;
font-weight: normal
}
html,
body,
img,
iframe {
border: 0
}
li {
list-style: none
}
textarea {
appearance: none;
resize: none;
overflow: auto;
}
textarea:focus {
border-color: rgba(43, 160, 43, .9) !important
}
u,
s {
text-decoration: none
}
a {
text-decoration: none;
-webkit-transition: color .3s;
-moz-transition: color .3s;
-ms-transition: color .3s;
-o-transition: color .3s;
transition: color .3s
}
a:hover {
text-decoration: none
}
body,
textarea,
input,
button,
select {
/*font: 12px/1.14 arial, \5b8b\4f53;*/
color: #333;
outline: 0;
border: 0
}
/* a {
color: #333
} */
.map-circle {
position: absolute;
height: 66px;
width: 66px;
-webkit-border-radius: 50%;
border-radius: 50%;
cursor: pointer;
font-size: 13px;
text-align: center;
color: #fff;
background: rgba(43, 160, 43, .9);
margin-top: -33px;
margin-left: -33px
}
.map-circle:hover {
background: #EE5D5B;
z-index: 99;
}
.map-circle:hover .map-nodatatips {
display: block
}
.map-circle .map-nodatatips {
position: absolute;
top: 50%;
right: -88px;
padding: 0 10px;
margin: -12px 0 0 0;
width: 60px;
cursor: pointer;
white-space: nowrap;
height: 24px;
line-height: 24px;
background: #EE5D5B;
-webkit-border-radius: 2px;
border-radius: 2px;
text-align: center;
color: #fff;
font-size: 12px;
display: none
}
.map-circle .map-nodatatips .map-itips {
position: absolute;
top: 7px;
left: -10px;
width: 0;
height: 0;
border-style: solid;
border-width: 5px;
border-color: transparent #EE5D5B transparent transparent
}
.map-areaname {
margin-top: 17px;
display: block;
word-break: keep-all;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 66px;
white-space: nowrap;
font-size: 12px;
color: #fff
}
.map-areanumber {
margin-top: 6px;
white-space: nowrap;
font-size: 14px;
color: #fff
}
.circlebox {
width: 20px;
height: 20px;
position: relative
}
.circlebox .bg-circle {
position: absolute;
left: -10px;
bottom: -10px;
width: 20px;
height: 20px;
background: #007dd4;
-webkit-border-radius: 50%;
border-radius: 50%;
opacity: .2;
filter: alpha(opacity=20)
}
.circlebox .sm-circle {
width: 6px;
height: 6px;
background: #007dd4;
-webkit-border-radius: 50%;
border-radius: 50%;
position: absolute;
top: 50%;
left: 50%;
margin: -3px 0 0 -3px
}
.circlebox .line {
width: 2px;
height: 18px;
background: #007dd4;
opacity: .6;
filter: alpha(opacity=60);
position: absolute;
bottom: 0;
left: -1px
}
.circlebox .ctx {
display: block;
position: absolute;
top: -42px;
left: 50%;
margin-left: -50px;
min-width: 80px;
padding: 0 10px;
cursor: pointer;
white-space: nowrap;
height: 24px;
line-height: 24px;
background: #007dd4;
-webkit-border-radius: 12px;
border-radius: 12px;
text-align: center;
color: #fff;
font-size: 12px
}
.circlebox.hoverbox .bg-circle {
background: #EE5D5B;
z-index: 99
}
.circlebox.hoverbox .sm-circle {
background: #EE5D5B;
z-index: 99
}
.circlebox.hoverbox .line {
background: #EE5D5B;
z-index: 99
}
.circlebox.hoverbox .ctx {
background: #EE5D5B;
z-index: 99
}
</style>
提示: 要是使用vue的話 可能有的地方需要修改,Eslint會報語法錯誤,另外裡面的程式碼我沒去加註釋,但是寫的很清楚,相關事件,都很清楚,直接改就行,還有就是如果需要互動的時候 , 有點地方會出現獲取不到值,那就可以進行語法修改 比如function 改成 ()=>{} 等等啥的 有時間我會整理一下,
看不明白的就是去原生的那個案例 慢慢看