vue3引入百度地图绘制多边形,可判断点是否在多边形内,
废话不多说,有效全代码如下:
<template>
<!--mapType="BMAP_SATELLITE_MAP"-->
<baidu-map
:center="initPoint"
:dragging="dragging"
:scroll-wheel-zoom="true"
:zoom="20"
ak="lO11fl3yVyFHrWwVhfCn7oSYRhkCYnOg"
class="bm-view"
type="API"
v="3.0"
@click="baiDuMapClickPoint"
@rightclick="baiDuMapRightClick">
<!-- 缩放 -->
<bm-navigation :enableGeolocation="true" :showZoomInfo="true" anchor="BMAP_ANCHOR_TOP_RIGHT"></bm-navigation>
<!-- 比例尺 -->
<bm-scale anchor="BMAP_ANCHOR_TOP_RIGHT"></bm-scale>
<!-- 缩略图 -->
<bm-overview-map :isOpen="true" anchor="BMAP_ANCHOR_BOTTOM_RIGHT"></bm-overview-map>
<!-- 全景控件 -->
<bm-panorama anchor="BMAP_ANCHOR_TOP_LEFT"></bm-panorama>
<bm-local-search :auto-viewport="true" :keyword="keyword" :location="location"></bm-local-search>
<bm-polygon :editing="true" :path="polygonPath" :stroke-opacity="0.5" :stroke-weight="2" fill-color="red" fill-opacity=0.3 stroke-color="blue" v @lineupdate="updatePolygonPath"/>
<bm-polygon v-for="item in polygonPathList" :editing="false" :path="item" :stroke-opacity="0.5" :stroke-weight="2" fill-color="red" fill-opacity=0.3 stroke-color="blue" v @lineupdate="updatePolygonPath"/>
<bm-marker :dragging="true" :position="markerPosition" animation="BMAP_ANIMATION_BOUNCE">
</bm-marker>
</baidu-map>
<!--<label>关键词:<input v-model="keyword"></label>
<label>地区:<input v-model="location"></label>-->
<div class="buttonClass">
<el-button type="primary" @click="baiDuMapClick">绘制多边形</el-button>
<el-button type="warning" @click="baiDuMapClickCancel">取消绘制</el-button>
<el-button type="danger" @click="baiDuMapDel">删除绘制</el-button>
<el-button type="primary" @click="baiDuMapPoint">标记点</el-button>
<el-button type="primary" @click="inPolygon">判断标记点是否在多边形内</el-button>
</div>
</template>
<script setup>
import {ref} from 'vue';
import {
BaiduMap, BmNavigation, BmScale, BmOverviewMap,
BmPanorama, BmPolygon, BmLocalSearch, BmMarker, BmLabel,
} from 'vue-baidu-map-3x';
// 初始位置
const initPoint = ref({lng: 117.131236, lat: 36.684359});
const location = ref('济南');
const keyword = ref('天辰路三庆财富');
const polygonPath = ref([]);
const polygonPathList = ref([]);
const dragging = ref(true);
const clickFlag = ref(0);
const baiDuMapClickFlag = ref(false);
const updatePolygonPath = (e) => {
polygonPath.value = e.target.getPath()
};
const baiDuMapClick = (e) => {
baiDuMapClickFlag.value = true;
dragging.value = true;
polygonPath.value = [];
clickFlag.value = 1;
}
const baiDuMapClickCancel = (e) => {
dragging.value = false;
polygonPathList.value.push(polygonPath.value);
polygonPath.value = [];
clickFlag.value = 0;
}
const baiDuMapRightClick = (e) => {
// console.log(e);
/*baiDuMapClickFlag.value = !baiDuMapClickFlag.value;
if (baiDuMapClickFlag.value) {
dragging.value = true;
polygonPath.value = [];
clickFlag.value = 1;
} else {
dragging.value = false;
polygonPathList.value.push(polygonPath.value);
polygonPath.value = [];
clickFlag.value = 0;
}*/
dragging.value = false;
polygonPathList.value.push(polygonPath.value);
polygonPath.value = [];
clickFlag.value = 0;
};
// 获取点击的点
const baiDuMapClickPoint = (e) => {
if (clickFlag.value === 2) {
baiDuMapDrawPoint(e);
}
if (clickFlag.value === 1) {
if (!baiDuMapClickFlag.value) {
return;
}
// console.log(e);
const {lng, lat} = e.point;
// console.log(lng, lat);
polygonPath.value.push(e.point);
}
};
// 标记点
const markerPosition = ref({});
const baiDuMapPoint = (e) => {
clickFlag.value = 2;
}
const baiDuMapDrawPoint = (e) => {
markerPosition.value = e.point;
}
// 删除多边形
const baiDuMapDel = () => {
polygonPath.value = [];
polygonPathList.value = [];
clickFlag.value = 0;
markerPosition.value = {};
}
const inPolygon = () => {
isInPolygon(markerPosition.value, polygonPathList.value[0]);
}
// 判断点是否在多边形内(射线法)
const isInPolygon = (pointPath, polygonPath) => {
const point = new BMap.Point(pointPath.lng, pointPath.lat); // 创建要检查的点
const polygonPoints = polygonPath.map(pt => new BMap.Point(pt.lng, pt.lat)); // 多边形的顶点数组
let intersectCount = 0; // 射线与多边形边的交点数
// 遍历多边形的边
for (let i = 0; i < polygonPoints.length; i++) {
const p1 = polygonPoints[i];
const p2 = polygonPoints[(i + 1) % polygonPoints.length]; // 获取下一个点,循环回到起点
// 如果点与边的水平线有交点
if (p1.lat !== p2.lat) {
if (
(point.lat > Math.min(p1.lat, p2.lat)) &&
(point.lat <= Math.max(p1.lat, p2.lat)) &&
(point.lng <= Math.max(p1.lng, p2.lng))
) {
const xInters = (point.lat - p1.lat) * (p2.lng - p1.lng) / (p2.lat - p1.lat) + p1.lng;
if (xInters > point.lng) {
intersectCount++;
}
}
}
}
// 如果交点数为奇数,则点在多边形内
if (intersectCount % 2 === 1) {
console.log("该点在多边形内");
} else {
console.log("该点不在多边形内");
}
}
</script>
<style scoped>
/* 这里没有清除百度地图API水印 */
.bm-view {
width: 87vw;
height: calc(100vh - 61px);
margin: auto;
}
/* 去掉百度地图logo--begin */
/* 去除水印 */
::v-deep(.BMap_cpyCtrl) {
display: none;
}
::v-deep(.anchorBL) {
display: none !important;
}
/* 去掉百度地图logo--end */
.buttonClass {
position: fixed;
top: 80px;
left: 320px;
z-index: 99999;
}
</style>