vue-baidu-map-3x +vue3+ts在百度地图画线生成一个区域(4)

这里用了vue-baidu-map-3x的组件,官网文档https://map.heifa.site/doc/index.html

用了覆盖物组件--折线+多边形,我的思路是先用折线取到用户框出的点,再将这些点的坐标传给多边形,显示多边形覆盖物,然后再调整多边形区域,
这是子组件

<!-- 卫星图 -->
<baidu-map @ready="handleMapReady" @mousemove="syncPolyline" @click="paintPolyline" @rightclick="newPolyline"
    :center="center" :zoom="20" :scroll-wheel-zoom="true" mapType="BMAP_SATELLITE_MAP" :min-zoom="18">
    <!-- 闭合多边形 -->
    <bm-polygon :path="polygonPath" stroke-color="blue" :stroke-opacity="0.5" :stroke-weight="2" :editing="iseditable"
        @lineupdate="updatePolygonPath" :strokeStyle="'dashed'" />
    <!-- 折线 -->
    <bm-polyline v-if="lineshow" :path="path" v-for="path of polyline.paths" :key="path"></bm-polyline>
</baidu-map>

ts部分:

const mapInstance = ref(null)
const iseditable = ref(true)//区域是否可编辑

const handleMapReady = (map: any) => {
mapInstance.value = map
}
const center = ref({ lng: 120.2672467193475, lat: 36.349441451507516 })
const lineshow = ref(false)//是否显示折线
interface Point {
lng: number
lat: number
}
interface Polyline {
editing: boolean
paths: Point[][]
}
const polyline = reactive({
editing: false,
paths: []
});
interface BMapEvent {
point: { lng: number; lat: number }
// 可根据实际需要扩展其他字段
}
// 鼠标当前坐标
const syncPolyline = (e: BMapEvent) => {
// console.log('+++++++++++++++++++',e)
if (!polyline.editing) {
return
}

if (!polyline.paths.length) {
    return
}
const path = polyline.paths[polyline.paths.length - 1]
if (!path.length) {
    return
}
if (path.length === 1) {
    // polyline.paths[polyline.paths.length - 1].push(config.type == 'WebGL' ? e.latlng : e.point)
    polyline.paths[polyline.paths.length - 1].push(e.point)
}
// polyline.paths[polyline.paths.length - 1][path.length - 1] = config.type == 'WebGL' ? e.latlng : e.point;
polyline.paths[polyline.paths.length - 1][path.length - 1] = e.point;

}

// 右键单击结束区域选择
const newPolyline = (e: any) => {
if (!polyline.editing) {
return
}
if (!polyline.paths.length) {
polyline.paths.push([])
}
const path = polyline.paths[polyline.paths.length - 1]
path.pop()
if (path.length) {
polyline.paths.push([])
}
console.log(polyline.paths[0])
// 给多边形赋值
// polygonPath.value = polyline.value.paths[0]
const str = JSON.parse(JSON.stringify(path))
polygonPath.value = str
console.log('这是path', path)
polyline.editing = false
polyline.paths = []
lineshow.value = false
// polyline.value = { ...polyline.value, editing: false, paths: [] }
path.splice(0, path.length)
console.log('这是path2222', path)
}

// 单击
const paintPolyline = (e: any) => {
console.log('点击', e)
if (!polyline.editing) {
return
}
!polyline.paths.length && polyline.paths.push([])
polyline.paths[polyline.paths.length - 1].push(e.point)
// polyline.value.paths[polyline.value.paths.length - 1].push(config.type == 'WebGL' ? e.latlng : e.point)
}

const polygonPath = ref([])
const emit = defineEmits(['refreshPointData'])

// 拖拽多边形触发的事件
const updatePolygonPath = (e: any) => {
console.log('这是方法', e)
polygonPath.value = e.target.getPath()
console.log('这是值', polygonPath.value)
emit('refreshPointData', polygonPath.value)
};
// 清空数据
const clear = () => {
lineshow.value = false
polyline.editing = false
polyline.paths = []
polygonPath.value.splice(0, polygonPath.value.length)
emit('refreshPointData', [])
}
const init = (val?: any) => {
if (!val) return
polygonPath.value = val.route
}

defineExpose({
clear,
init,
polyline,
polygonPath,
lineshow,
iseditable,
})

父组件:

        <weilanmap @refreshPointData="refreshPointData" ref="mapRef" :style="{ height: tableHeitght + 'px' }">
        </weilanmap>

这是ts
// 获取数据坐标改变
const refreshPointData = (data: any) => {
pointList.value = data
console.log('父组件接收到', pointList.value)
}

// 按钮切换
const btnGroup2Change = (val: string) => {
btn2Active.value = val
if (val == '0') {
// 新增
ElMessage.success({
message: '鼠标右键单击结束区域选择',
duration: 2000,
})
mapRef.value.polyline.editing = true
mapRef.value.lineshow = true
selectObj.value = { no: '', name: '', id: '' }
} else if (val == '1') {
// 编辑
if (selectObj.value.id == '') {
ElMessage.warning('请选择一条数据')
btn2Active.value = '0'
return
}
mapRef.value.init(selectObj.value)
isEdit.value = true
mapRef.value.iseditable = true
} else {
// 取消
selectObj.value = { no: '', name: '', id: '' }
isEdit.value = false
addFenceDialog.value.visible = false
getDataList()
mapRef.value.polygonPath = []
mapRef.value.polyline.editing = false
mapRef.value.polyline.paths = []
addFenceForm.value = {
no: '',
name: '',
location: '',
remark: '',
}
}
}
// 选中表格行
const tableSelectFun = (val: any) => {
console.log(val)
if (val.id == selectObj.value.id) {
console.log('一样')
return
}
selectObj.value = val
selectContext.value = selectObj.value.name
isEdit.value = false
btn2Active.value = ''
mapRef.value.clear()
mapRef.value.init(selectObj.value)
mapRef.value.iseditable = false
}
// 保存
const saveAs = () => {
mapRef.value.lineshow = false
console.log('父组件看到的', mapRef.value.lineshow)
if (selectObj.value.id == '') {//没有id就是新增--保存
addFenceDialog.value.visible = true
addFenceDialog.value.title = '添加围栏'
} else {//有id就是修改--保存
selectObj.value.name = selectContext.value
selectObj.value.location = pointList.value
const params = {
no: selectObj.value.no,
name: selectObj.value.name,
location: JSON.stringify(selectObj.value.location),
flag: selectObj.value.flag,
creator: selectObj.value.creator,
updater: selectObj.value.updater,
remark: selectObj.value.remark,
id: selectObj.value.id
}
fenceApi.useFenceSubmitApi(params).then((res: any) => {
if (res.code == 0) {
ElMessage.success({
message: '围栏修改成功',
duration: 500,
onClose: () => {
getDataList()
addFenceDialog.value.visible = false
mapRef.value.polygonPath = []
mapRef.value.polyline =
{ ...mapRef.value.polyline, editing: false, paths: [] }
addFenceForm.value = {
no: '',
name: '',
location: '',
remark: '',
}
}
})
isEdit.value = false
btn2Active.value = ''
}
})
}
}

posted @ 2025-05-29 14:19  小王不要404  阅读(169)  评论(1)    收藏  举报