功能描述:
1.百度地图实现点击地图出现起点,再次点击出现终点(起点终点能拖动)绘制完终点后获取该路的路况并且起点和终点可以拖动实现实时更新(新绘制的路段的)路况
2.地点搜索
效果如下:
关键代码:
new BMapGL.DrivingRouteLine(this.bdMap, {
renderOptions: {
map: this.bdMap,
enableDragging: true,
autoViewport: true,
lineLayerStyle: {
// strokeTextureUrl: null,
showTraffic: true
}
},
onSearchComplete: searchComplete,
onPolylinesSet: () => {
this.drivingTime = drivingTime;
this.drivingDistance = this.convertDistance(drivingDistance);
this.pointsArr = deepClone(pointsArr);
},
});
完整代码:
<!--
* @Description: 百度地图自动获取路段点位 页面
* @Author: mhf
* @Date: 2024/2/21 11:55
-->
<template>
<el-dialog
width="1300px"
v-dialog-out
destroy-on-close
append-to-body
v-if="dialogVisible"
:title="title"
:visible.sync="dialogVisible"
:before-close="hideDialog"
:close-on-click-modal="false"
>
<div class="dialog-body">
<div id="map-container"></div>
<div class="dialog-body-search">
<el-input
@input="searchPlace"
@clear="searchPlace"
clearable
v-model="searchText"
size="small"
placeholder="输入关键字查询"
></el-input>
</div>
<div>
<div class="dialog-body-res" v-if="searchRes.length > 0">
<div
v-for="(item, index) in searchRes"
:key="index"
@click="chooseIt(item)"
>
<el-tooltip
effect="light"
:content="item.address + item.title"
placement="right-end"
overflow
>
<span> {{ item.address + item.title }} </span>
</el-tooltip>
</div>
</div>
<div
class="dialog-body-none"
v-else-if="searchRes.length === 0 && searchText"
>
<em> 没有搜索结果... </em>
</div>
</div>
</div>
<lineH />
<div class="dialog-footer">
<el-button @click="hideDialog">取 消</el-button>
<el-button type="primary" @click="submitPoints">确 定</el-button>
</div>
</el-dialog>
</template>
<script>
import { deepClone } from "@/utils/deepClone";
export default {
name: "bdMapDrawLinesDialog",
components: {},
props: {},
dicts: [],
data() {
return {
dialogVisible: false,
title: "",
bdMap: null,
mapCenter: {
lng: 120.73957130336815, // 经度
lat: 30.748406263284365,
}, // 地图中心点
mapZoom: 14, // 地图缩放级别
startPoint: {
lng: 120.72532015906316,
lat: 30.747761317225542,
},
endPoint: {
lng: 120.73105566952,
lat: 30.74805738479023,
},
drivingTime: 0, // 驾驶时间 分钟
drivingDistance: 0, // 行驶距离 公里
pointsArr: [
// {
// lat: 30.748406263284365,
// lng: 120.73957130336815
// },
// {
// lat: 30.748406263284365,
// lng: 120.73957130336815
// },
// {
// lat: 30.748406263284365,
// lng: 120.73957130336815
// }
], // 最终保存的点位信息 (路段中的所有点位[包含:起点,终点])
mapClickListener: null, // 地图点击事件监听器
searchText: undefined, // 查询的关键字
searchPoint: {}, // 查找到的点位
searchRes: [], // 查到结果
};
},
methods: {
showDialog(data) {
this.dialogVisible = true;
this.title = data.title;
if (data.data) {
// 回显线段和起点终点
let pointsArr = JSON.parse(data.data);
this.pointsArr = pointsArr;
this.startPoint = pointsArr[0];
this.endPoint = pointsArr[pointsArr.length - 1];
} else {
}
this.initBdMap(data.data);
},
hideDialog() {
// this.mapCenter = {
// lng: 120.73957130336815,
// lat: 30.748406263284365
// }
this.bdMap.destroy();
this.bdMap = null;
removeEventListener("click", this.mapClickListener);
this.mapClickListener = null;
this.dialogVisible = false;
this.removeSearch();
},
removeSearch() {
// if (this.searchPoint) {
// this.removeMarker("searchPoint")
// }
this.searchPoint = {};
this.searchText = undefined;
this.searchRes = [];
},
submitPoints() {
if (this.pointsArr.length < 2) this.$message.warning("请先绘制线路");
this.$emit("on-response", {
pointsArr: this.pointsArr,
km: this.drivingDistance,
});
this.hideDialog();
},
initBdMap(flag) {
this.$nextTick(() => {
this.bdMap = new BMapGL.Map("map-container");
this.bdMap.centerAndZoom(
new BMapGL.Point(this.mapCenter.lng, this.mapCenter.lat),
this.mapZoom,
);
this.bdMap.enableScrollWheelZoom(true);
if (!flag) {
// 新增则绘制起点和终点
this.drawMarker();
} else {
// 编辑或者详情则回显绘制的路线
this.drawRouteLine();
}
setTimeout(() => {
this.setViewport([this.startPoint, this.endPoint]);
}, 500);
});
},
/**
* @Event 绘制路线
* @description:
* @author: mhf
* @time: 2024-02-01 11:41:40
**/
drawRouteLine() {
let drivingTime = 0;
let drivingDistance = 0;
let pointsArr = [];
let that = this;
var searchComplete = function (results) {
if (transit.getStatus() == BMAP_STATUS_SUCCESS) {
var plan = results.getPlan(0);
drivingTime = plan.getDuration(true); //获取时间
drivingDistance = plan.getDistance(true); //获取距离
pointsArr = that.makePointsArr(plan._lines); // 路段中所有的点位数组
that.removeMarker();
}
};
var transit = new BMapGL.DrivingRouteLine(this.bdMap, {
renderOptions: {
map: this.bdMap,
enableDragging: true,
autoViewport: true,
lineLayerStyle: {
// strokeTextureUrl: null,
showTraffic: true
}
},
onSearchComplete: searchComplete,
onPolylinesSet: () => {
this.drivingTime = drivingTime;
this.drivingDistance = this.convertDistance(drivingDistance);
this.pointsArr = deepClone(pointsArr);
},
});
let start = new BMapGL.Point(this.startPoint.lng, this.startPoint.lat);
let end = new BMapGL.Point(this.endPoint.lng, this.endPoint.lat);
transit.search(start, end);
},
/**
* @Event 调整地图到最佳视野
* @param: portArr 点位数组 [pot1, pot2, pot3]
* @description:
* @author: mhf
* @time: 2024-02-01 10:12:24
**/
setViewport(portArr) {
this.bdMap.setViewport(portArr);
},
/**
* @Event 将路径单位统一成千米
* @description: 15.9公里 -> 15.9; 500米 -> 0.5
* @author: mhf
* @time: 2024-02-01 10:43:07
**/
convertDistance(distance) {
let resKm = 0;
if (distance.indexOf("公里") > -1) {
resKm = distance.substring(0, distance.indexOf("公里"));
} else if (distance.indexOf("米") > -1) {
resKm = distance.substring(0, distance.indexOf("米")) / 1000;
} else {
resKm = distance;
}
return resKm;
},
/**
* @Event 绘制点位
* @param: obj 点位对象,
* @param: myIcon 自定义图标,
* @param: customObj 自定义参数,
* @description: this.makePoint({lng: 116.404, lat: 39.119})
* @author: mhf
* @time: 2024-02-01 13:43:13
**/
makePoint(obj, myIcon, customObj) {
let point = new BMapGL.Point(obj.lng, obj.lat); // 创建点
let marker = new BMapGL.Marker(point, {
icon: myIcon ? myIcon : null,
}); // 创建标注
marker.customObj = customObj;
this.bdMap.addOverlay(marker);
marker.addEventListener("click", (e) => {});
},
/**
* @Event 将指定数组嵌套的数据转成扁平化的点位数据
* @description:
* @author: mhf
* @time: 2024-02-01 13:57:20
**/
makePointsArr(arr) {
return arr.flatMap((item) => item.points);
},
/**
* @Event: 点击地图绘制点位
* @description:
* @author: mhf
* @time: 2024-02-01 17:24:04
**/
drawMarker() {
let num = 0;
this.mapClickListener = this.bdMap.addEventListener("click", (e) => {
num++;
let obj = {
lng: e.latlng.lng,
lat: e.latlng.lat,
};
if (num === 1) {
this.startPoint = obj;
var myIcon = new BMapGL.Icon(
"/img/startPoint.png",
new BMapGL.Size(25, 40),
);
this.makePoint(obj, myIcon, { name: "startPoint" });
} else if (num === 2) {
this.endPoint = obj;
this.drawRouteLine();
}
});
},
/**
* @Event 移除点位
* @description:
* @author: mhf
* @time: 2024-02-01 19:36:52
**/
removeMarker(name = "startPoint") {
let makerArr = this.bdMap.getOverlays();
for (let i = 0; i < makerArr.length; i++) {
if (makerArr[i].customObj?.name === name) {
this.bdMap.removeOverlay(makerArr[i]); // 移除指定点位
}
}
// this.bdMap.clearOverlays() // 移除所有点位
},
/**
* @Event 输入关键字查询地点
* @description:
* @author: mhf
* @time: 2024-02-21 15:56:42
**/
searchPlace(e) {
this.searchRes = [];
if (e) {
const myFun = () => {
this.searchRes = local.getResults()._pois;
};
var local = new BMapGL.LocalSearch(this.bdMap, {
onSearchComplete: myFun,
});
local.search(e);
} else {
this.removeMarker("searchPoint");
}
},
chooseIt(item) {
this.searchPoint = item.point;
if (this.searchPoint) {
this.removeMarker("searchPoint");
}
this.makePoint(
{ lng: this.searchPoint.lng, lat: this.searchPoint.lat },
null,
{ name: "searchPoint" },
false,
);
this.bdMap.centerAndZoom(item.point, 18);
},
},
created() {},
mounted() {},
};
</script>
<style lang="scss" scoped>
::v-deep .el-dialog__body {
padding: 20px 0 0 !important;
}
.dialog-body {
padding: 0 20px 20px;
min-height: 60vh;
max-height: 65vh;
overflow-y: auto;
position: relative;
#map-container {
min-height: 60vh;
width: 100%;
::v-deep .anchorBL img {
display: none;
}
::v-deep .BMap_cpyCtrl span {
display: none !important;
}
}
&-search {
width: 300px;
position: absolute;
top: 20px;
left: 40px;
z-index: 999 !important;
}
&-res {
width: 300px;
max-height: 400px;
position: absolute;
top: 50px;
left: 40px;
z-index: 999 !important;
padding: 10px;
background: #fff;
border: 1px solid #eee;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
overflow-y: auto;
span {
display: block;
width: 278px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
line-height: 30px;
&:hover {
cursor: pointer;
border: 1px solid #409eff;
}
}
}
&-none {
width: 300px;
position: absolute;
top: 54px;
left: 40px;
z-index: 999 !important;
padding: 10px;
background: #fff;
line-height: 40px;
border: 1px solid #eee;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}
}
.dialog-footer {
text-align: center;
padding: 10px 0 18px;
}
</style>
图标:
示例数据(点击保存之后的数据)
[{"lng":112.318041,"lat":32.43625},{"lng":112.321216,"lat":32.43549},{"lng":112.322844,"lat":32.435137},{"lng":112.322844,"lat":32.435137},{"lng":112.322534,"lat":32.434416},{"lng":112.322334,"lat":32.433945},{"lng":112.322184,"lat":32.433594},{"lng":112.321984,"lat":32.433123},{"lng":112.321864,"lat":32.432823},{"lng":112.321695,"lat":32.432432},{"lng":112.321675,"lat":32.432402},{"lng":112.321395,"lat":32.431731},{"lng":112.321145,"lat":32.431129},{"lng":112.321025,"lat":32.430889},{"lng":112.321025,"lat":32.430889},{"lng":112.321055,"lat":32.430629},{"lng":112.321045,"lat":32.430529},{"lng":112.320725,"lat":32.428517},{"lng":112.320495,"lat":32.427496},{"lng":112.320114,"lat":32.425573},{"lng":112.319914,"lat":32.424242},{"lng":112.319914,"lat":32.424242},{"lng":112.319743,"lat":32.422991},{"lng":112.319713,"lat":32.422771},{"lng":112.319543,"lat":32.421839},{"lng":112.319503,"lat":32.421279},{"lng":112.319503,"lat":32.421279},{"lng":112.319652,"lat":32.42127},{"lng":112.319682,"lat":32.42127},{"lng":112.321639,"lat":32.42116},{"lng":112.323108,"lat":32.421076},{"lng":112.323467,"lat":32.421057},{"lng":112.324716,"lat":32.420989},{"lng":112.325616,"lat":32.420941},{"lng":112.325866,"lat":32.420921},{"lng":112.326286,"lat":32.420891},{"lng":112.327006,"lat":32.420841},{"lng":112.327606,"lat":32.42079},{"lng":112.329307,"lat":32.420657},{"lng":112.333542,"lat":32.420308},{"lng":112.33704,"lat":32.42002},{"lng":112.337712,"lat":32.419964},{"lng":112.342698,"lat":32.419576},{"lng":112.347669,"lat":32.419163},{"lng":112.348653,"lat":32.419088},{"lng":112.351527,"lat":32.41884},{"lng":112.355014,"lat":32.41855},{"lng":112.356984,"lat":32.418395},{"lng":112.361145,"lat":32.418023},{"lng":112.365686,"lat":32.417648},{"lng":112.365937,"lat":32.417624},{"lng":112.368237,"lat":32.41742},{"lng":112.370245,"lat":32.417242},{"lng":112.372091,"lat":32.417068},{"lng":112.372292,"lat":32.417056},{"lng":112.375782,"lat":32.416648},{"lng":112.376264,"lat":32.416594},{"lng":112.377186,"lat":32.416486},{"lng":112.377186,"lat":32.416486},{"lng":112.377146,"lat":32.416176},{"lng":112.377095,"lat":32.415837},{"lng":112.376964,"lat":32.414867},{"lng":112.376964,"lat":32.414677},{"lng":112.377054,"lat":32.414186},{"lng":112.377184,"lat":32.413855},{"lng":112.377274,"lat":32.413704},{"lng":112.377424,"lat":32.413473},{"lng":112.377704,"lat":32.413171},{"lng":112.377975,"lat":32.412949},{"lng":112.378375,"lat":32.412716},{"lng":112.378485,"lat":32.412605},{"lng":112.378616,"lat":32.412564},{"lng":112.379337,"lat":32.412329},{"lng":112.380539,"lat":32.411971},{"lng":112.380829,"lat":32.41193},{"lng":112.381119,"lat":32.411848},{"lng":112.3816,"lat":32.411706},{"lng":112.38198,"lat":32.411594},{"lng":112.38198,"lat":32.411594},{"lng":112.382671,"lat":32.411392},{"lng":112.385042,"lat":32.410685},{"lng":112.385802,"lat":32.410505},{"lng":112.386362,"lat":32.410414},{"lng":112.388041,"lat":32.410235},{"lng":112.393126,"lat":32.409744},{"lng":112.393126,"lat":32.409744},{"lng":112.395311,"lat":32.409538},{"lng":112.398492,"lat":32.409237},{"lng":112.398632,"lat":32.409229},{"lng":112.401771,"lat":32.408945},{"lng":112.403674,"lat":32.40877},{"lng":112.404162,"lat":32.408737},{"lng":112.405217,"lat":32.408642},{"lng":112.405715,"lat":32.40859},{"lng":112.406631,"lat":32.408513},{"lng":112.410264,"lat":32.408192},{"lng":112.41108,"lat":32.408036},{"lng":112.411587,"lat":32.407894},{"lng":112.412223,"lat":32.407645},{"lng":112.412631,"lat":32.407442},{"lng":112.413029,"lat":32.407219},{"lng":112.413625,"lat":32.406789},{"lng":112.417751,"lat":32.403011},{"lng":112.41954,"lat":32.401372},{"lng":112.423258,"lat":32.397945},{"lng":112.424034,"lat":32.397258},{"lng":112.42476,"lat":32.39677},{"lng":112.425496,"lat":32.396401},{"lng":112.427029,"lat":32.395895},{"lng":112.427567,"lat":32.395733},{"lng":112.428542,"lat":32.395427},{"lng":112.428901,"lat":32.395322},{"lng":112.429498,"lat":32.39514},{"lng":112.430145,"lat":32.394939},{"lng":112.430345,"lat":32.394872},{"lng":112.432596,"lat":32.394179},{"lng":112.434968,"lat":32.393445},{"lng":112.439626,"lat":32.391953},{"lng":112.439706,"lat":32.391933},{"lng":112.440205,"lat":32.391766},{"lng":112.441383,"lat":32.391392},{"lng":112.442541,"lat":32.391017},{"lng":112.44343,"lat":32.390739},{"lng":112.44343,"lat":32.390739},{"lng":112.44369,"lat":32.39111},{"lng":112.44382,"lat":32.3913},{"lng":112.44432,"lat":32.392032},{"lng":112.44447,"lat":32.392242},{"lng":112.444931,"lat":32.392913},{"lng":112.445721,"lat":32.394044},{"lng":112.446362,"lat":32.394954},{"lng":112.446662,"lat":32.395384},{"lng":112.447333,"lat":32.396344},{"lng":112.450169,"lat":32.400389},{"lng":112.451843,"lat":32.402783},{"lng":112.452676,"lat":32.403949},{"lng":112.452786,"lat":32.404118},{"lng":112.452786,"lat":32.404118},{"lng":112.452946,"lat":32.404347},{"lng":112.452946,"lat":32.404347},{"lng":112.453619,"lat":32.405183},{"lng":112.45423,"lat":32.405819},{"lng":112.454882,"lat":32.406415},{"lng":112.455554,"lat":32.40694},{"lng":112.455795,"lat":32.407128},{"lng":112.45735,"lat":32.408364},{"lng":112.459147,"lat":32.409776},{"lng":112.460965,"lat":32.411216},{"lng":112.463807,"lat":32.413459},{"lng":112.465757,"lat":32.414982},{"lng":112.465837,"lat":32.415041},{"lng":112.466581,"lat":32.415619},{"lng":112.468883,"lat":32.417414},{"lng":112.470884,"lat":32.418981},{"lng":112.471175,"lat":32.419206},{"lng":112.47204,"lat":32.419872},{"lng":112.47371,"lat":32.421283},{"lng":112.475128,"lat":32.422699},{"lng":112.475188,"lat":32.422768},{"lng":112.47559,"lat":32.423221},{"lng":112.476405,"lat":32.424196},{"lng":112.477411,"lat":32.425419},{"lng":112.479573,"lat":32.428022},{"lng":112.480287,"lat":32.428879},{"lng":112.481413,"lat":32.43026},{"lng":112.483684,"lat":32.433102},{"lng":112.484127,"lat":32.433635},{"lng":112.486678,"lat":32.436775},{"lng":112.488646,"lat":32.439206},{"lng":112.490654,"lat":32.441659},{"lng":112.491617,"lat":32.442796},{"lng":112.492078,"lat":32.44343},{"lng":112.492439,"lat":32.444146},{"lng":112.49295,"lat":32.44525},{"lng":112.493221,"lat":32.445177},{"lng":112.494034,"lat":32.444928},{"lng":112.494175,"lat":32.444886},{"lng":112.496552,"lat":32.444163},{"lng":112.505896,"lat":32.441478},{"lng":112.506616,"lat":32.441268},{"lng":112.507536,"lat":32.441008},{"lng":112.515655,"lat":32.439135},{"lng":112.520611,"lat":32.438025},{"lng":112.524467,"lat":32.437186},{"lng":112.524835,"lat":32.437111},{"lng":112.52602,"lat":32.436848},{"lng":112.526518,"lat":32.436746},{"lng":112.527424,"lat":32.43683},{"lng":112.529076,"lat":32.436977},{"lng":112.529256,"lat":32.43564},{"lng":112.529246,"lat":32.435289},{"lng":112.529226,"lat":32.435109},{"lng":112.529962,"lat":32.434991},{"lng":112.530957,"lat":32.434898},{"lng":112.530838,"lat":32.434166},{"lng":112.530718,"lat":32.431144}]