maptalks添加指南针控件(新版本已经支持指南针控件,无需再单独开发)
参考文章 https://blog.youkuaiyun.com/lhjuejiang/article/details/126426437
与openlayers添加指南针控件不同的是,三维的指南针控件需要能满足地图交互的功能,不仅要在点击控件的时候联动地图,还要在操作地图(旋转)的时候联动控件.由于地图上bear的范围是[0, 180]和[0, -180],在旋转到右下角(六点钟)时,bear会从180变成-180或者从-180变成180,此时需要特殊处理指南针的旋转角度…
- 指南针组件
<!--
* @Author: CharlesLeocc 1015057518@qq.com
* @Date: 2023-01-30 15:30:51
* @LastEditors: CharlesLeocc 1015057518@qq.com
* @LastEditTime: 2023-01-31 10:36:56
* @FilePath: \examples\src\webapp\webgis\tools\mapCompass.vue
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<template>
<div class="compass">
<button title="逆时针转动"
class="leftRow"
@click="leftRowClick"
></button>
<button title="恢复正北方向"
class="centerRow"
@click="centerRowClick"
></button>
<button title="顺时针转动"
class="rightRow"
@click="rightRowClick"
></button>
</div>
</template>
<script lang="ts" setup>
import {
computed,
} from 'vue';
import { MapNavStore } from '../store'
import { EventBus } from '@/tlw/core'
import { MAPTOOLS } from '../utils/EventNames'
//#region 变量定义
const rotateDeg = computed(():string => MapNavStore.getRotateDeg + 'deg')
//#endregion 变量定义
//#region 生命周期
//#endregion 生命周期
//#region Function
const leftRowClick = () => {
MapNavStore.setRotateDeg(-90 + MapNavStore.getRotateDeg)
EventBus.$emit(MAPTOOLS.CHANGE_BEARING, -90)
}
const centerRowClick = () => {
const rotateAngel = MapNavStore.getRotateDeg
const index = rotateAngel % 360
if(index !== 0){ // 复位
let dis = 360 - Math.abs(index)
let dis1 = Math.abs(index)
dis = dis > dis1 ? dis1 : dis
if(dis == 180) dis = -180
MapNavStore.setRotateDeg((rotateAngel + dis)%360 == 0? rotateAngel + dis : rotateAngel - dis)
EventBus.$emit(MAPTOOLS.CHANGE_BEARING, 0)
}
}
const rightRowClick = () => {
MapNavStore.setRotateDeg(90 + MapNavStore.getRotateDeg)
EventBus.$emit(MAPTOOLS.CHANGE_BEARING, 90)
}
//#endregion Function
</script>
<style lang="less" scoped>
.compass{
position: absolute;
z-index: 5;
bottom: 130px;
right: 50px;
width: 52px;
height: 54px;
background: url('../assets/images/earth-navi-control-pc4.png') 0% 0% / 266px no-repeat;
.leftRow{
position: absolute;
outline: none;
border: none;
background: url('../assets/images/earth-navi-control-pc4.png') -75px -5px / 266px no-repeat;
cursor: pointer;
left: 4px;
top: 0px;
z-index: 1;
width: 15px;
height: 42px;
opacity: 1;
&:hover{
background: url('../assets/images/earth-navi-control-pc4.png') -89px -5px / 266px no-repeat;
}
}
.centerRow{
position: absolute;
outline: none;
border: none;
background: url('../assets/images/earth-navi-control-pc4.png') -56px -2px no-repeat;
cursor: pointer;
left: 19px;
top: 2px;
width: 14px;
height: 44px;
transition: all .3s ease-out;
transform-origin: 7px 24px;
transform: rotate(v-bind(rotateDeg));
opacity: 1;
}
.rightRow{
position: absolute;
outline: none;
border: none;
background: url('../assets/images/earth-navi-control-pc4.png') -75px -5px / 266px no-repeat;
cursor: pointer;
right: 2px;
top: 0px;
z-index: 1;
width: 15px;
height: 42px;
transform: scaleX(-1);
opacity: 1;
&:hover{
background: url('../assets/images/earth-navi-control-pc4.png') -89px -5px / 266px no-repeat;
}
}
}
</style>
- 使用pinia存储旋转角度,角度可以不用store存储,这个就随意发挥了
- 地图响应旋转
EventBus.$on(MAPTOOLS.CHANGE_BEARING, (bearing) => {
let bear = data.map.getBearing() + bearing
if (bearing === 0) {
bear = 0
}
data.map.animateTo({
bearing: bear,
},{
duration : 2000,
easing : 'out'
})
})```
4. 地图操作联动控件旋转
```javascript
tMap.on("dragrotatestart dragrotating dragrotateend", e => {
const rotateAngel = MapNavStore.getRotateDeg
if (e.type === 'dragrotatestart') {
lastBear = data.map.getBearing()
console.log(lastBear, 'lastBear');
}else if(e.type === 'dragrotating'){
const rotatingBear:number = data.map.getBearing()
let deBear = null
if (rotatingBear < 0 && lastBear > 0) { // 顺时针旋转,转过180°时,rotatingBear会变成负值
deBear = lastBear + rotatingBear
} else if (rotatingBear > 0 && lastBear < 0) { // 逆时针旋转,转过-180°时,rotatingBear会变成正值
deBear = ~(rotatingBear + lastBear) // rotatingBear + lastBear 的值为正,因为是逆时针旋转,所以需要取反
} else { // 其他情况(在0 - 180或0 - -180之间的情况)
deBear = rotatingBear - lastBear
}
MapNavStore.setRotateDeg(rotateAngel + deBear)
console.log(rotatingBear, 'rotatingBear');
lastBear = rotatingBear
}else if(e.type === 'dragrotateend') {
const currentBear = data.map.getBearing()
lastBear = currentBear
}
})
maptalks指南针控件