标准答案例图
就是想让下面帮助代码中的效果像蜜雪冰城一样点击左边的地址,然后在右边百度地图中显示左边地址对应的坐标并显示位置
以下是帮助代码的示例图
!需求是点击了地图下面的七星山和梁子镇,然后地图中的代表坐标的那个红圆角能移动到七星山和梁子镇上面
以下代码=代码文件为cshtml格式,注意不是html
<div id="surrounding" v-clock>
<div id="mapContainerForSurrounding" class="bm-view"></div>
<div>七星山</div>
<div>梁子镇</div>
<div id="searchCtrl" v-show="!config.isLoading">
<div class="panel panel-default">
<div class="panel-body">
<div class="search-container">
<ul class="nav nav-tabs" id="info">
<li v-for="x in filterType" @@click="showTab(x)" :class="[ x.key === type ? 'active' : '']"
style="width: 25%; text-align: center">
<a :href="'#sd_' + x.key" data-toggle="tab">{{ x.name }}</a>
</li>
</ul>
<div class="tab-pane fade in">
<div class="header">
<input type="text" class="form-control input-sm" v-model="filter.keyword" :placeholder="totalCount" />
</div>
<div class="body">
<div v-if="config.isSearching[type]">
加载中...
</div>
<div v-else class="item" v-for="y in filterResult" :key="y.index" @@click="openInfoWin(y)">
<div class="header">{{ y.index }}</div>
<div class="content" :title="y.title">{{ y.title | short(14) }}</div>
<div class="description">{{ y.distance }}米</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
function initBMap() {
return new Promise(function (resolve, reject) {
window.onBMapCallback = function () {
resolve(BMap)
}
var script = document.createElement('script')
script.type = 'text/javascript'
script.src = `https://api.map.baidu.com/api?v=3.0&ak=TyRPRXdH3tDd3VAVYObG2E9BpKlGMwYQ&callback=onBMapCallback&s=1`
script.onerror = reject
document.head.appendChild(script)
})
}
const filterType = [
{ id: 1, name: '商业', kw: ['银行', '便利店', '超市'], key: '0', tab: '商业' },
{ id: 2, name: '交通', kw: ['地铁站', '公交', '火车站', '机场', '长途车站'], key: '1', tab: '交通' },
{ id: 3, name: '教育', kw: ['幼儿园', '小学', '中学', '大学'], key: '2', tab: '教育' },
{ id: 4, name: '医疗', kw: ['医院', '社康中心'], key: '3', tab: '医疗' },
]
const surrounding = new Vue({
el: '#surrounding',
data: {
lng: 114.569,
lat: 30.25698,
content: '',
radius: 3000,
config: {
isLoading: true,
isSearching: {
"0": true,
"1": true,
"2": true,
"3": true,
}
},
filter: {
keyword: ''
},
filterType: filterType,
type: '0',
point: {},
zoom: 14,
map: undefined,
searchModel: [],
searchResult: [],
},
filters: {
short(value, length = 10) {
if (!value) {
return ''
}
if (value.length >= length) {
return value.substring(0, length) + '...'
}
return value
}
},
created() {
this.init()
},
computed: {
searchBy() {
return this.filterType.find(x => x.key === this.type).kw
},
dataSource() {
return this.searchResult.filter(x => x.type === this.type)
},
filterResult() {
return this.dataSource.filter(x => x.title.indexOf(this.filter.keyword) != -1)
},
totalCount() {
return this.config.isSearching[this.type] ? '加载中...' : `共有${this.dataSource.length}条结果`
}
},
methods: {
init() {
const _self = this
if (this.map === undefined) {
this.config.isLoading = true
initBMap().then(res => {
_self.config.isLoading = false
_self.map = new BMap.Map('mapContainerForSurrounding')
_self.point = new BMap.Point(this.lng, this.lat)
_self.map.centerAndZoom(_self.point, _self.zoom)
_self.map.panBy(-100, 0)
const circle = new BMap.Circle(_self.point, _self.radius, { strokeWeight: 1, fillOpacity: 0.3, strokeOpacity: 0.3, enableMassClear: false });
_self.map.addOverlay(circle);
_self.map.addOverlay(new BMap.Marker(_self.point, { enableMassClear: false }))
_self.content && _self.initContent()
_self.map.addControl(new BMap.ScaleControl())
_self.map.addControl(new BMap.NavigationControl())
_self.loadControl()
_self.search(_self.type)
}).catch(e => {
console.log(e)
})
}
},
search(type) {
const _self = this
if (this.searchModel[type] === undefined) {
this.searchModel[type] = new BMap.LocalSearch(this.map, {
onSearchComplete: function (results) {
if (_self.searchModel[type].getStatus() == BMAP_STATUS_SUCCESS) {
let index = 1
for (var i = 0; i < results.length; i++) {
for (let m = 0; m < results[i].getCurrentNumPois(); m++) {
const ele = results[i].getPoi(m);
const distance = _self.calculateForDistance(_self.point.lat, _self.point.lng, ele.point.lat, ele.point.lng)
if (distance <= _self.radius) {
const data = { ...ele, distance: distance, index: index, type: type }
_self.searchResult.push(data)
index++
}
}
}
}
_self.config.isSearching[type] = false
_self.loadMarks()
_self.$forceUpdate()
}
});
this.config.isSearching[type] = true
this.searchModel[type].searchNearby(this.searchBy, this.point, this.radius);
} else {
this.loadMarks()
}
},
initContent() {
const opts = {
position: this.point, // 指定文本标注所在的地理位置
offset: new BMap.Size(-30, -30), // 设置文本偏移量
enableMassClear: false
};
// 创建文本标注对象
const label = new BMap.Label(this.content, opts);
// 自定义文本标注样式
label.setStyle({
padding: '0px 5px',
borderColor: '#ccc',
fontSize: '14px',
height: '30px',
lineHeight: '30px',
fontFamily: '微软雅黑',
opacity: 0.9,
background: '#2776f9',
color: '#fff'
});
this.map.addOverlay(label);
},
loadMarks() {
this.map.clearOverlays()
// 创建标注对象并添加到地图
const _self = this
for (var i = 0; i < _self.dataSource.length; i++) {
const data = _self.dataSource[i]
const point = data.point
const marker = new BMap.Marker(point)
const label = new BMap.Label(data.index, {
offset: new BMap.Size(data.index > 9 ? 0 : 5, 4)
})
label.setStyle({
background: 'none',
color: '#fff',
border: 'none'
})
marker.setLabel(label)
this.map.addOverlay(marker)
//给标注点添加点击事件。使用立即执行函数和闭包
marker.addEventListener("click", function (e) {
_self.openInfoWin(data)
});
}
},
loadControl() {
const _self = this
//定义一个控件类
function SearchControl() {
this.defaultAnchor = BMAP_ANCHOR_TOP_RIGHT;
this.defaultOffset = new BMap.Size(20, 20)
}
//通过JavaScript的prototype属性继承于BMap.Control
SearchControl.prototype = new BMap.Control();
//自定义控件必须实现自己的initialize方法,并且将控件的DOM元素返回
//在本方法中创建个div元素作为控件的容器,并将其添加到地图容器中
SearchControl.prototype.initialize = function (map) {
//创建一个dom元素
var div = document.getElementById("searchCtrl")
// 添加DOM元素到地图中
_self.map.getContainer().appendChild(div);
// 将DOM元素返回
return div;
}
//添加到地图中
_self.map.addControl(new SearchControl());
},
openInfoWin(x) {
const str = (x.title || "").length >= 12 ? `${x.title.substring(0, 12)}...` : x.title
const titleHtml = `<div style="font-weight:bold;color:#CE5521;font-size:14px">${str}</div>`
const opts = {
width: 200,
height: 50,
title: titleHtml
}
const infoWindow = new BMap.InfoWindow('地址:' + (x.address || (x.title || "")), opts);
this.map.openInfoWindow(infoWindow, x.point)
},
calculateForDistance(lat1, lon1, lat2, lon2) {
const DEF_PI = 3.14159265359; // PI
const DEF_2PI = 6.28318530712; // 2*PI
const DEF_PI180 = 0.01745329252; // PI/180.0
const DEF_R = 6370693.5; // radius of earth
// 角度转换为弧度
const ew1 = lon1 * DEF_PI180;
const ns1 = lat1 * DEF_PI180;
const ew2 = lon2 * DEF_PI180;
const ns2 = lat2 * DEF_PI180;
// 经度差
let dew = ew1 - ew2;
// 若跨东经和西经180 度,进行调整
if (dew > DEF_PI)
dew = DEF_2PI - dew;
else if (dew < -DEF_PI)
dew = DEF_2PI + dew;
const dx = DEF_R * Math.cos(ns1) * dew; // 东西方向长度(在纬度圈上的投影长度)
const dy = DEF_R * (ns1 - ns2); // 南北方向长度(在经度圈上的投影长度)
// 勾股定理求斜边长
let distance = Math.sqrt(dx * dx + dy * dy).toFixed(0);
return ++distance;
},
showTab(x) {
this.type = x.key;
this.search(this.type)
}
}
})
</script>