forked from qiushanhe/dm-manage-web
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
232 lines
6.9 KiB
232 lines
6.9 KiB
<template >
|
|
<div>
|
|
<el-form>
|
|
<el-form-item label="显示场地">
|
|
<el-radio-group v-model="mapPlaceType" @change="createMarkersInMap">
|
|
<el-radio :label="0">自营场地</el-radio>
|
|
<el-radio :label="1">全部场地</el-radio>
|
|
</el-radio-group>
|
|
</el-form-item>
|
|
</el-form>
|
|
<div id="map" style="height: 600px; width: 100%;"></div>
|
|
<el-collapse class="box-card">
|
|
<el-collapse-item title="附近驾校">
|
|
<div style="padding: 10px">
|
|
<div slot="header">附近驾校</div>
|
|
<div v-if="nearbySchoolSearching">正在搜索中...</div>
|
|
<template v-else>
|
|
<div v-for="p in nearbySchoolList" :key="p.index">
|
|
<div class="hover-pointer" style="font-size: 14px; color: blue" @click="getClassType(p)">
|
|
<i v-if="p.recommend" class="el-icon-star-off" />
|
|
驾校: {{ p.deptName }}-{{ p.name }}
|
|
</div>
|
|
<div class="mt5">地址:{{ p.address }}</div>
|
|
<div class="mt5">
|
|
直线距离: {{ p.distance }} 公里;
|
|
<span class="ml0">步行距离:{{ p.walkdistance }}</span>
|
|
</div>
|
|
<el-divider style="margin: 6px 0 !important;" />
|
|
</div>
|
|
</template>
|
|
</div>
|
|
</el-collapse-item>
|
|
</el-collapse>
|
|
|
|
<ClassTypeDialog v-if="classVisible" ref="classTypeDialog" :dialog-visible="classVisible" />
|
|
</div>
|
|
</template>
|
|
<script>
|
|
import AMap from 'AMap';
|
|
import ClassTypeDialog from './ClassTypeDialog.vue';
|
|
|
|
export default {
|
|
name: 'PlaceMap',
|
|
components: {
|
|
ClassTypeDialog
|
|
},
|
|
data() {
|
|
return {
|
|
mapPlaceType: 0,
|
|
nearbySchoolSearching: true,
|
|
nearbySchoolList: [],
|
|
amap: null,
|
|
locationMarker: null,
|
|
geocoder: null,
|
|
placeList: [],
|
|
classVisible: false,
|
|
}
|
|
},
|
|
mounted() {
|
|
this.initMap();
|
|
},
|
|
created() {
|
|
|
|
},
|
|
beforeDestroy() {
|
|
console.log("placemap----beforeDestroy")
|
|
this.geocoder = null;
|
|
this.locationMarker = null;
|
|
this.amap && this.amap.clearMap();
|
|
this.amap && this.amap.destroy();
|
|
this.amap = null;
|
|
},
|
|
methods: {
|
|
// 初始化地图
|
|
initMap() {
|
|
if (!this.amap) {
|
|
this.amap = new AMap.Map('map', {
|
|
zoom: 12,
|
|
center: [117.226095, 31.814372],
|
|
resizeEnable: true
|
|
});
|
|
// 地图坐标点定位
|
|
|
|
// this.getAllPlaces();
|
|
|
|
// this.createMarkersInMap()
|
|
}
|
|
},
|
|
setMapCenter(info) {
|
|
if (info.lat && info.lng) {
|
|
this.locationMarker && this.amap.remove(this.locationMarker);
|
|
this.locationMarker = new AMap.Marker({
|
|
position: [info.lng, info.lat],
|
|
icon: require(`@/assets/images/place/flag_red.png`)
|
|
});
|
|
this.amap.add(this.locationMarker);
|
|
this.amap.setCenter([info.lng, info.lat]);
|
|
this.amap.setZoom(14);
|
|
|
|
this.getNearbySchool(info);
|
|
}
|
|
},
|
|
//获取附近驾校
|
|
getNearbySchool(info) {
|
|
if (info.lng && info.lat) {
|
|
this.nearbySchoolList = [];
|
|
this.nearbySchoolSearching = true;
|
|
// 推荐的场地
|
|
let places1 = [];
|
|
// 普通的场地
|
|
let places2 = [];
|
|
|
|
const p2 = [info.lng, info.lat];
|
|
for (let i = 0; i < this.placeList.length; i++) {
|
|
const element = this.placeList[i];
|
|
const p1 = [element.lng, element.lat];
|
|
// 计算直线距离
|
|
element.distance = (window.AMap.GeometryUtil.distance(p1, p2) / 1000).toFixed(2);
|
|
element.recommend ? places1.push(element) : places2.push(element);
|
|
}
|
|
// 按直线距离排序
|
|
// 排序
|
|
if (places1.length > 1) {
|
|
places1 = places1.sort((a, b) => a.distance - b.distance);
|
|
}
|
|
// 排序
|
|
if (places2.length > 1) {
|
|
places2 = places2.sort((a, b) => a.distance - b.distance);
|
|
}
|
|
// 取普通场地和推荐场地,组合, 取四个
|
|
this.nearbySchoolList = [];
|
|
for (let i = 0; i < 4; i++) {
|
|
places1.length > i && this.nearbySchoolList.push(places1[i]);
|
|
places2.length > i && this.nearbySchoolList.push(places2[i]);
|
|
if (this.nearbySchoolList.length === 4) {
|
|
break;
|
|
}
|
|
}
|
|
// 计算步行距离
|
|
this.nearbySchoolList.map(async (item) => {
|
|
const p1 = [item.lng, item.lat];
|
|
const resp = await this.getWalkingDistance(p1, p2);
|
|
item.walkdistance = resp;
|
|
this.$forceUpdate();
|
|
});
|
|
this.nearbySchoolSearching = false;
|
|
}
|
|
},
|
|
// 获取两点之间的步行距离
|
|
async getWalkingDistance(start, end) {
|
|
return new Promise((resolve, reject) => {
|
|
window.AMap.plugin('AMap.Walking', () => {
|
|
const walking = new AMap.Walking();
|
|
let num = 0;
|
|
walking.search(start, end, (status, result) => {
|
|
if (status === 'complete') {
|
|
result.routes.forEach((item) => {
|
|
num += item.distance;
|
|
});
|
|
resolve(
|
|
num > 1000 ? `${(num / 1000).toFixed(2)} 公里` : `${num} 米`
|
|
);
|
|
} else {
|
|
resolve('步行数据无法确定');
|
|
}
|
|
});
|
|
});
|
|
});
|
|
},
|
|
handleMarkers(places) {
|
|
this.placeList = places;
|
|
this.createMarkersInMap();
|
|
},
|
|
//创建地图点标记
|
|
createMarkersInMap() {
|
|
let arr = this.placeList;
|
|
if (this.mapPlaceType === 0) {
|
|
arr = arr.filter((item) => item.recommend);
|
|
}
|
|
this.amap && this.amap.clearMap();
|
|
this.locationMarker && this.amap.add(this.locationMarker);
|
|
for (let i = 0; i < arr.length; i++) {
|
|
const element = arr[i];
|
|
const tmpMarker = new AMap.Marker({
|
|
map: this.amap,
|
|
position: [element.lng, element.lat],
|
|
label: {
|
|
content: element.name,
|
|
direction: 'left'
|
|
},
|
|
icon: require(`@/assets/images/place/position_${element.flagColor}.png`),
|
|
extData: element,
|
|
clickable: true
|
|
});
|
|
tmpMarker.on('click', (ev) => this.getClassType(ev.target.getExtData()));
|
|
}
|
|
},
|
|
// 查询该场地下的班型报价
|
|
getClassType(item) {
|
|
console.log(item)
|
|
// this.classType = [];
|
|
// getClassTypes({
|
|
// schoolId: item.deptId,
|
|
// placeId: item.placeId,
|
|
// status: '0'
|
|
// }).then((resp) => {
|
|
// if (resp && resp.code === 200 && resp.data) {
|
|
// this.classType = resp.data;
|
|
// this.innerVisible = true;
|
|
// }
|
|
// });
|
|
this.classVisible = true;
|
|
this.$nextTick(() => {
|
|
this.$refs.classTypeDialog.init(item);
|
|
});
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
</script>
|
|
<style scoped>
|
|
.box-card {
|
|
position: absolute;
|
|
right: 30px;
|
|
top: 45px;
|
|
width: 400px;
|
|
}
|
|
::v-deep .el-divider--horizontal {
|
|
margin: 6px 0 !important;
|
|
}
|
|
</style> |