mirror of https://gitee.com/xiaonuobase/snowy
【更新】更新地图PR与拖动PR的代码格式
parent
0f092ba477
commit
6025d685d7
|
@ -21,227 +21,206 @@
|
|||
</a-modal>
|
||||
</template>
|
||||
<script>
|
||||
import props from './props.js'
|
||||
import props from './props.js'
|
||||
|
||||
export default {
|
||||
name: 'DragModal',
|
||||
mixins: [props],
|
||||
props: {
|
||||
// 容器的类名
|
||||
modalClass: {
|
||||
type: String,
|
||||
default: 'modal-box'
|
||||
},
|
||||
// 拖拽
|
||||
drag: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
// 缩放
|
||||
resize: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: undefined
|
||||
},
|
||||
width: {
|
||||
type: [Number, String],
|
||||
default: '70%'
|
||||
},
|
||||
footer: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
modalWidth: '',
|
||||
contain: null,
|
||||
export default {
|
||||
name: 'DragModal',
|
||||
mixins: [props],
|
||||
props: {
|
||||
// 容器的类名
|
||||
modalClass: {
|
||||
type: String,
|
||||
default: 'modal-box'
|
||||
},
|
||||
// 拖拽
|
||||
header: null,
|
||||
modalContent: null,
|
||||
mouseDownX: 0,
|
||||
mouseDownY: 0,
|
||||
deltaX: 0,
|
||||
deltaY: 0,
|
||||
sumX: 0,
|
||||
sumY: 0,
|
||||
onmousedown: false,
|
||||
drag: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
// 缩放
|
||||
modalBody: null,
|
||||
myBody: null,
|
||||
prevModalWidth: 0,
|
||||
prevModalHeight: 0,
|
||||
prevBodyWidth: 0,
|
||||
prevBodyHeight: 0,
|
||||
startX: 0,
|
||||
startY: 0
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
slotKeys() {
|
||||
return Object.keys(this.$slots)
|
||||
resize: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: undefined
|
||||
},
|
||||
width: {
|
||||
type: [Number, String],
|
||||
default: '70%'
|
||||
},
|
||||
footer: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
simpleClass() {
|
||||
return Math.random().toString(36).substring(2)
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
visible() {
|
||||
data() {
|
||||
return {
|
||||
modalWidth: '',
|
||||
contain: null,
|
||||
// 拖拽
|
||||
header: null,
|
||||
modalContent: null,
|
||||
mouseDownX: 0,
|
||||
mouseDownY: 0,
|
||||
deltaX: 0,
|
||||
deltaY: 0,
|
||||
sumX: 0,
|
||||
sumY: 0,
|
||||
onmousedown: false,
|
||||
// 缩放
|
||||
modalBody: null,
|
||||
myBody: null,
|
||||
prevModalWidth: 0,
|
||||
prevModalHeight: 0,
|
||||
prevBodyWidth: 0,
|
||||
prevBodyHeight: 0,
|
||||
startX: 0,
|
||||
startY: 0
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
slotKeys() {
|
||||
return Object.keys(this.$slots)
|
||||
},
|
||||
simpleClass() {
|
||||
return Math.random().toString(36).substring(2)
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
visible() {
|
||||
this.$nextTick(() => {
|
||||
this.initialEvent(this.visible)
|
||||
})
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
this.initialEvent(this.visible)
|
||||
})
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
this.initialEvent(this.visible)
|
||||
})
|
||||
},
|
||||
created() {},
|
||||
beforeUnmount() {
|
||||
this.removeMove()
|
||||
document.removeEventListener('mouseup', this.removeUp, false)
|
||||
this.removeResize()
|
||||
document.removeEventListener('mouseup', this.removeResize)
|
||||
},
|
||||
methods: {
|
||||
changeWidth(width) {
|
||||
this.modalWidth = width
|
||||
},
|
||||
handleOk(e) {
|
||||
this.resetNum()
|
||||
this.$emit('ok', e)
|
||||
},
|
||||
handleCancel(e) {
|
||||
this.resetNum()
|
||||
this.$emit('close', e)
|
||||
},
|
||||
resetNum() {
|
||||
this.mouseDownX = 0
|
||||
this.mouseDownY = 0
|
||||
this.deltaX = 0
|
||||
this.deltaY = 0
|
||||
this.sumX = 0
|
||||
this.sumY = 0
|
||||
|
||||
this.prevModalWidth = 0
|
||||
this.prevModalHeight = 0
|
||||
this.prevBodyWidth = 0
|
||||
this.prevBodyHeight = 0
|
||||
this.startX = 0
|
||||
this.startY = 0
|
||||
},
|
||||
initialEvent(visible) {
|
||||
// console.log('--------- 初始化')
|
||||
// console.log('simpleClass===>', this.simpleClass)
|
||||
// console.log('document===>', document)
|
||||
if (visible) {
|
||||
this.resetNum()
|
||||
// 获取控件
|
||||
document.removeEventListener('mouseup', this.removeUp, false)
|
||||
this.contain = document.getElementsByClassName(this.simpleClass)[0]
|
||||
// console.log('初始化-contain:', this.contain)
|
||||
this.changeWidth(this.$props.width)
|
||||
if (this.$props.drag === true) {
|
||||
this.header = this.contain.getElementsByClassName('ant-modal-header')[0]
|
||||
this.modalContent = this.contain.getElementsByClassName('ant-modal-content')[0]
|
||||
this.header.style.cursor = 'all-scroll'
|
||||
this.modalContent.style.left = 0
|
||||
this.modalContent.style.transform = 'translate(0px,0px)'
|
||||
// console.log('初始化-header:', this.header)
|
||||
// console.log('初始化-modalContent:', this.modalContent)
|
||||
// 拖拽事件监听
|
||||
// this.contain.onmousedown = (event) => {
|
||||
this.header.onmousedown = (event) => {
|
||||
this.onmousedown = true
|
||||
this.mouseDownX = event.pageX
|
||||
this.mouseDownY = event.pageY
|
||||
document.body.onselectstart = () => false
|
||||
document.addEventListener('mousemove', this.handleMove, false)
|
||||
}
|
||||
document.addEventListener('mouseup', this.removeUp, false)
|
||||
}
|
||||
|
||||
if (this.$props.resize === true) {
|
||||
this.modalBody = this.contain.getElementsByClassName('ant-modal-body')[0]
|
||||
this.myBody = this.contain.getElementsByClassName('my-modal-body')[0]
|
||||
this.modalBody.style.overflow = 'hidden'
|
||||
this.modalBody.style.resize = 'both'
|
||||
this.myBody.style.overflow = 'auto'
|
||||
this.myBody.style.height = 'auto'
|
||||
// console.log('初始化-modalBody:', this.modalBody)
|
||||
// console.log('初始化-myBody:', this.myBody)
|
||||
// 缩放事件监听
|
||||
this.modalBody.onmousedown = (event) => {
|
||||
event.preventDefault()
|
||||
const rect = this.modalBody.getBoundingClientRect()
|
||||
const rightBorder = rect.x + rect.width - 17
|
||||
const bottomBorder = rect.y + rect.height - 17
|
||||
// console.log('rightBorder:' + rightBorder, 'clientX:' + event.clientX)
|
||||
// console.log('bottomBorder:' + bottomBorder, 'clientY:' + event.clientY)
|
||||
if (event.clientX >= rightBorder && event.clientY >= bottomBorder) {
|
||||
this.prevModalWidth = this.modalBody.offsetWidth
|
||||
this.prevModalHeight = this.modalBody.offsetHeight
|
||||
this.prevBodyWidth = this.myBody.offsetWidth
|
||||
this.prevBodyHeight = this.myBody.offsetHeight
|
||||
this.startX = event.clientX
|
||||
this.startY = event.clientY
|
||||
|
||||
document.addEventListener('mousemove', this.handleResize)
|
||||
}
|
||||
document.addEventListener('mouseup', this.removeResize)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
handleMove(event) {
|
||||
const delta1X = event.pageX - this.mouseDownX
|
||||
const delta1Y = event.pageY - this.mouseDownY
|
||||
this.deltaX = delta1X
|
||||
this.deltaY = delta1Y
|
||||
// console.log('delta1X:' + delta1X, 'sumX:' + this.sumX, 'delta1Y:' + delta1Y, 'sumY:' + this.sumY)
|
||||
this.modalContent.style.transform = `translate(${delta1X + this.sumX}px, ${delta1Y + this.sumY}px)`
|
||||
},
|
||||
removeMove() {
|
||||
document.removeEventListener('mousemove', this.handleMove, false)
|
||||
},
|
||||
removeUp(event) {
|
||||
// console.log('removeUp')
|
||||
document.body.onselectstart = () => true
|
||||
if (this.onmousedown && !(event.pageX === this.mouseDownX && event.pageY === this.mouseDownY)) {
|
||||
this.onmousedown = false
|
||||
this.sumX = this.sumX + this.deltaX
|
||||
this.sumY = this.sumY + this.deltaY
|
||||
// console.log('sumX:' + this.sumX, 'sumY:' + this.sumY)
|
||||
}
|
||||
created() {},
|
||||
beforeUnmount() {
|
||||
this.removeMove()
|
||||
// this.checkMove()
|
||||
document.removeEventListener('mouseup', this.removeUp, false)
|
||||
this.removeResize()
|
||||
document.removeEventListener('mouseup', this.removeResize)
|
||||
},
|
||||
handleResize(event) {
|
||||
const diffX = event.clientX - this.startX
|
||||
const diffY = event.clientY - this.startY
|
||||
const minWidth = 180
|
||||
const minHeight = 0
|
||||
methods: {
|
||||
changeWidth(width) {
|
||||
this.modalWidth = width
|
||||
},
|
||||
handleOk(e) {
|
||||
this.resetNum()
|
||||
this.$emit('ok', e)
|
||||
},
|
||||
handleCancel(e) {
|
||||
this.resetNum()
|
||||
this.$emit('close', e)
|
||||
},
|
||||
resetNum() {
|
||||
this.mouseDownX = 0
|
||||
this.mouseDownY = 0
|
||||
this.deltaX = 0
|
||||
this.deltaY = 0
|
||||
this.sumX = 0
|
||||
this.sumY = 0
|
||||
|
||||
if (this.prevBodyWidth + diffX > minWidth) {
|
||||
this.changeWidth(this.prevModalWidth + diffX + 'px')
|
||||
// this.myBody.style.width = this.prevBodyWidth + diffX + 'px'
|
||||
this.prevModalWidth = 0
|
||||
this.prevModalHeight = 0
|
||||
this.prevBodyWidth = 0
|
||||
this.prevBodyHeight = 0
|
||||
this.startX = 0
|
||||
this.startY = 0
|
||||
},
|
||||
initialEvent(visible) {
|
||||
if (visible) {
|
||||
this.resetNum()
|
||||
// 获取控件
|
||||
document.removeEventListener('mouseup', this.removeUp, false)
|
||||
this.contain = document.getElementsByClassName(this.simpleClass)[0]
|
||||
this.changeWidth(this.$props.width)
|
||||
if (this.$props.drag === true) {
|
||||
this.header = this.contain.getElementsByClassName('ant-modal-header')[0]
|
||||
this.modalContent = this.contain.getElementsByClassName('ant-modal-content')[0]
|
||||
this.header.style.cursor = 'all-scroll'
|
||||
this.modalContent.style.left = 0
|
||||
this.modalContent.style.transform = 'translate(0px,0px)'
|
||||
this.header.onmousedown = (event) => {
|
||||
this.onmousedown = true
|
||||
this.mouseDownX = event.pageX
|
||||
this.mouseDownY = event.pageY
|
||||
document.body.onselectstart = () => false
|
||||
document.addEventListener('mousemove', this.handleMove, false)
|
||||
}
|
||||
document.addEventListener('mouseup', this.removeUp, false)
|
||||
}
|
||||
if (this.$props.resize === true) {
|
||||
this.modalBody = this.contain.getElementsByClassName('ant-modal-body')[0]
|
||||
this.myBody = this.contain.getElementsByClassName('my-modal-body')[0]
|
||||
this.modalBody.style.overflow = 'hidden'
|
||||
this.modalBody.style.resize = 'both'
|
||||
this.myBody.style.overflow = 'auto'
|
||||
this.myBody.style.height = 'auto'
|
||||
// 缩放事件监听
|
||||
this.modalBody.onmousedown = (event) => {
|
||||
event.preventDefault()
|
||||
const rect = this.modalBody.getBoundingClientRect()
|
||||
const rightBorder = rect.x + rect.width - 17
|
||||
const bottomBorder = rect.y + rect.height - 17
|
||||
if (event.clientX >= rightBorder && event.clientY >= bottomBorder) {
|
||||
this.prevModalWidth = this.modalBody.offsetWidth
|
||||
this.prevModalHeight = this.modalBody.offsetHeight
|
||||
this.prevBodyWidth = this.myBody.offsetWidth
|
||||
this.prevBodyHeight = this.myBody.offsetHeight
|
||||
this.startX = event.clientX
|
||||
this.startY = event.clientY
|
||||
document.addEventListener('mousemove', this.handleResize)
|
||||
}
|
||||
document.addEventListener('mouseup', this.removeResize)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
handleMove(event) {
|
||||
const delta1X = event.pageX - this.mouseDownX
|
||||
const delta1Y = event.pageY - this.mouseDownY
|
||||
this.deltaX = delta1X
|
||||
this.deltaY = delta1Y
|
||||
this.modalContent.style.transform = `translate(${delta1X + this.sumX}px, ${delta1Y + this.sumY}px)`
|
||||
},
|
||||
removeMove() {
|
||||
document.removeEventListener('mousemove', this.handleMove, false)
|
||||
},
|
||||
removeUp(event) {
|
||||
document.body.onselectstart = () => true
|
||||
if (this.onmousedown && !(event.pageX === this.mouseDownX && event.pageY === this.mouseDownY)) {
|
||||
this.onmousedown = false
|
||||
this.sumX = this.sumX + this.deltaX
|
||||
this.sumY = this.sumY + this.deltaY
|
||||
}
|
||||
this.removeMove()
|
||||
},
|
||||
handleResize(event) {
|
||||
const diffX = event.clientX - this.startX
|
||||
const diffY = event.clientY - this.startY
|
||||
const minWidth = 180
|
||||
const minHeight = 0
|
||||
if (this.prevBodyWidth + diffX > minWidth) {
|
||||
this.changeWidth(this.prevModalWidth + diffX + 'px')
|
||||
}
|
||||
if (this.prevBodyHeight + diffY > minHeight) {
|
||||
this.myBody.style.height = this.prevBodyHeight + diffY + 'px'
|
||||
}
|
||||
},
|
||||
removeResize() {
|
||||
document.removeEventListener('mousemove', this.handleResize)
|
||||
}
|
||||
if (this.prevBodyHeight + diffY > minHeight) {
|
||||
// this.modalBody.style.height = this.prevModalHeight + diffY + 'px'
|
||||
this.myBody.style.height = this.prevBodyHeight + diffY + 'px'
|
||||
}
|
||||
},
|
||||
removeResize() {
|
||||
document.removeEventListener('mousemove', this.handleResize)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -1,410 +0,0 @@
|
|||
<template>
|
||||
<div class="aMap">
|
||||
<div :id="`container-${mid}`" style="width: 100%;height: 100%;">
|
||||
地图资源加载中...
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<!--AMap官网:https://lbs.amap.com/api/javascript-api-v2/summary-->
|
||||
<script setup name="AMap">
|
||||
import {onMounted, onUnmounted, shallowRef} from 'vue'
|
||||
import AMapLoader from '@amap/amap-jsapi-loader'
|
||||
|
||||
const props = defineProps(
|
||||
{
|
||||
mid: {
|
||||
type: Number,
|
||||
default: new Date().getTime()
|
||||
},
|
||||
apiKey: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
center: {
|
||||
type: Array
|
||||
},
|
||||
plugins: {
|
||||
type: Array,
|
||||
default: [
|
||||
'AMap.ToolBar',
|
||||
'AMap.Scale',
|
||||
'AMap.HawkEye',
|
||||
'AMap.MapType',
|
||||
'AMap.Geolocation',
|
||||
'AMap.MarkerCluster'
|
||||
]
|
||||
},
|
||||
viewMode: {
|
||||
type: String,
|
||||
default: '3D',
|
||||
validator(value) {
|
||||
return ['2D', '3D'].includes(value)
|
||||
}
|
||||
},
|
||||
zoom: {
|
||||
type: Number,
|
||||
default: 12
|
||||
},
|
||||
pitch: {
|
||||
type: Number,
|
||||
default: 50
|
||||
},
|
||||
mapStyle: {
|
||||
type: String,
|
||||
default: 'normal',
|
||||
validator(value) {
|
||||
return ['normal', 'macaron', 'dark', 'fresh', 'grey'].includes(value)
|
||||
}
|
||||
},
|
||||
markerCluster: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
const emits = defineEmits(['complete', 'markerClick'])
|
||||
|
||||
const aMap = shallowRef(null)
|
||||
const aMapMarkerArr = ref([])
|
||||
const aMapInfoWindowObj = ref({})
|
||||
|
||||
const init = () => {
|
||||
AMapLoader.load({
|
||||
key: props.apiKey,
|
||||
version: '2.0',
|
||||
plugins: props.plugins,
|
||||
AMapUI: {
|
||||
version: '1.1',
|
||||
plugins: ['overlay/SimpleMarker', 'overlay/AwesomeMarker']
|
||||
}
|
||||
}).then(() => {
|
||||
initMap()
|
||||
}).catch(e => {
|
||||
console.error(e);
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化 地图
|
||||
*/
|
||||
const initMap = () => {
|
||||
aMap.value = new AMap.Map(`container-${props.mid}`, {
|
||||
viewMode: props.viewMode,
|
||||
zoom: props.zoom,
|
||||
// 地图俯仰角度
|
||||
pitch: props.pitch,
|
||||
mapStyle: `amap://styles/${props.mapStyle}`
|
||||
})
|
||||
|
||||
// 中心点
|
||||
if (props.center) {
|
||||
aMap.value.setCenter(props.center)
|
||||
}
|
||||
|
||||
// 控件
|
||||
props.plugins.length > 0 && initControlPlugin()
|
||||
|
||||
// 地图初始化完成
|
||||
aMap.value.on('complete', () => {
|
||||
emits('complete')
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化 控制控件
|
||||
*/
|
||||
const initControlPlugin = () => {
|
||||
// 工具条,控制地图的缩放、平移等
|
||||
props.plugins.includes('AMap.ToolBar') && aMap.value.addControl(new AMap.ToolBar({}))
|
||||
// 比例尺
|
||||
props.plugins.includes('AMap.Scale') && aMap.value.addControl(new AMap.Scale())
|
||||
// 鹰眼,显示缩略图
|
||||
props.plugins.includes('AMap.HawkEye') && aMap.value.addControl(new AMap.HawkEye({isOpen: true}))
|
||||
// 图层切换
|
||||
props.plugins.includes('AMap.MapType') && aMap.value.addControl(new AMap.MapType({}))
|
||||
// 定位
|
||||
props.plugins.includes('AMap.Geolocation') && aMap.value.addControl(new AMap.Geolocation({}))
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染 点标记
|
||||
* @param dataArr
|
||||
*/
|
||||
const renderMarker = (dataArr) => {
|
||||
dataArr.forEach(d => {
|
||||
const marker = new AMap.Marker({
|
||||
map: aMap.value,
|
||||
position: d.position,
|
||||
// 鼠标滑过点标记时的文字提示
|
||||
title: d.title,
|
||||
// 显示内容:content有效时,icon属性将被覆盖
|
||||
content: d.content,
|
||||
// 图标
|
||||
icon: d.icon ? d.icon : null,
|
||||
// 文本标注
|
||||
label: d.label
|
||||
})
|
||||
marker.on('click', () => {
|
||||
emits('markerClick', d.position)
|
||||
})
|
||||
aMapMarkerArr.value.push(marker)
|
||||
})
|
||||
|
||||
setFitView()
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染 圆点标记
|
||||
* @param dataArr
|
||||
*/
|
||||
const renderCircleMarker = (dataArr) => {
|
||||
dataArr.forEach(d => {
|
||||
const marker = new AMap.CircleMarker({
|
||||
map: aMap.value,
|
||||
// 圆心位置
|
||||
center: d.position,
|
||||
// 圆点半径
|
||||
radius: d.radius ? d.radius : 20,
|
||||
// 线条颜色
|
||||
strokeColor: d.strokeColor ? d.strokeColor : '#006600',
|
||||
// 轮廓线透明度
|
||||
strokeOpacity: 0.5,
|
||||
// 轮廓线宽度
|
||||
strokeWeight: 2,
|
||||
// 填充颜色
|
||||
fillColor: d.fillColor ? d.fillColor : '#006600',
|
||||
// 填充透明度
|
||||
fillOpacity: 0.5,
|
||||
cursor: 'pointer'
|
||||
})
|
||||
marker.on('click', () => {
|
||||
emits('markerClick', d.position)
|
||||
})
|
||||
aMapMarkerArr.value.push(marker)
|
||||
})
|
||||
|
||||
setFitView()
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染 简单点标记
|
||||
* @param dataArr
|
||||
* @param theme
|
||||
*/
|
||||
const renderSimpleMarker = (dataArr, theme = 'default') => {
|
||||
dataArr.forEach(d => {
|
||||
const marker = new AMapUI.SimpleMarker({
|
||||
map: aMap.value,
|
||||
position: d.position,
|
||||
// 前景文字
|
||||
iconLabel: {
|
||||
// 文本
|
||||
innerHTML: d.label,
|
||||
// 字体的样式,比如颜色,大小等
|
||||
style: d.labelStyle ? d.labelStyle : {
|
||||
color: '#333',
|
||||
fontSize: '12px'
|
||||
}
|
||||
},
|
||||
// 图标主题:default,fresh,numv1,numv2
|
||||
iconTheme: theme,
|
||||
// 背景图标样式
|
||||
iconStyle: d.style
|
||||
})
|
||||
marker.on('click', () => {
|
||||
emits('markerClick', d.position)
|
||||
})
|
||||
aMapMarkerArr.value.push(marker)
|
||||
})
|
||||
|
||||
setFitView()
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染 字体点标记
|
||||
* @param dataArr
|
||||
*/
|
||||
const renderAwesomeMarker = (dataArr) => {
|
||||
dataArr.forEach(d => {
|
||||
const marker = new AMapUI.AwesomeMarker({
|
||||
map: aMap.value,
|
||||
position: d.position,
|
||||
// 图标,参见:http://fontawesome.io/icons/
|
||||
awesomeIcon: d.awesomeIcon,
|
||||
// 字体的样式,比如颜色,大小等
|
||||
iconLabel: {
|
||||
style: d.labelStyle ? d.labelStyle : {
|
||||
color: '#333',
|
||||
fontSize: '12px'
|
||||
}
|
||||
},
|
||||
// 背景图标的样式
|
||||
iconStyle: d.style
|
||||
})
|
||||
marker.on('click', () => {
|
||||
emits('markerClick', d.position)
|
||||
})
|
||||
aMapMarkerArr.value.push(marker)
|
||||
})
|
||||
|
||||
setFitView()
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置 视图级别
|
||||
*/
|
||||
const setFitView = () => {
|
||||
// 点聚合
|
||||
props.markerCluster && new AMap.MarkerCluster(aMap.value, aMapMarkerArr.value)
|
||||
|
||||
// 根据地图上添加的覆盖物分布情况,自动缩放地图到合适的视野级别
|
||||
aMap.value.setFitView(aMapMarkerArr.value)
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染 线
|
||||
* @param dataArr
|
||||
* @param option
|
||||
*/
|
||||
const renderPolyline = (dataArr, option = {}) => {
|
||||
const path = [];
|
||||
dataArr.forEach(d => {
|
||||
path.push(new AMap.LngLat(d.position[0], d.position[1]))
|
||||
})
|
||||
|
||||
const polyline = new AMap.Polyline({
|
||||
path: path,
|
||||
strokeColor: option.strokeColor || 'blue',
|
||||
strokeWeight: option.strokeWeight || 2,
|
||||
strokeOpacity: option.strokeOpacity || 0.5,
|
||||
isOutline: option.isOutline || false,
|
||||
borderWeight: option.borderWeight || 1,
|
||||
// 折线拐点连接处样式
|
||||
lineJoin: 'round'
|
||||
})
|
||||
aMap.value.add(polyline)
|
||||
|
||||
aMap.value.setFitView([polyline])
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染 圆
|
||||
* @param position
|
||||
* @param radius
|
||||
* @param option
|
||||
*/
|
||||
const renderCircle = (position, radius, option) => {
|
||||
const circle = new AMap.Circle({
|
||||
center: new AMap.LngLat(position[0], position[1]),
|
||||
radius: radius,
|
||||
strokeColor: option.strokeColor || 'blue',
|
||||
strokeWeight: option.strokeWeight || 2,
|
||||
strokeOpacity: option.strokeOpacity || 0.5,
|
||||
fillColor: option.fillColor || 'blue',
|
||||
fillOpacity: option.fillOpacity || 0.5,
|
||||
strokeStyle: 'solid'
|
||||
})
|
||||
aMap.value.add(circle)
|
||||
|
||||
aMap.value.setFitView([circle])
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染 面
|
||||
* @param dataArr
|
||||
* @param option
|
||||
*/
|
||||
const renderPolygon = (dataArr, option = {}) => {
|
||||
const path = [];
|
||||
dataArr.forEach(d => {
|
||||
path.push(new AMap.LngLat(d.position[0], d.position[1]))
|
||||
})
|
||||
|
||||
const polygon = new AMap.Polygon({
|
||||
path: path,
|
||||
strokeColor: option.strokeColor || 'blue',
|
||||
strokeWeight: option.strokeWeight || 2,
|
||||
strokeOpacity: option.strokeOpacity || 0.5,
|
||||
fillColor: option.fillColor || 'blue',
|
||||
fillOpacity: option.fillOpacity || 0.5,
|
||||
strokeStyle: 'solid'
|
||||
})
|
||||
aMap.value.add(polygon)
|
||||
|
||||
aMap.value.setFitView([polygon])
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染 信息窗体
|
||||
* @param dataArr
|
||||
*/
|
||||
const renderInfoWindow = (dataArr) => {
|
||||
dataArr.forEach(d => {
|
||||
aMapInfoWindowObj.value[d.position] = new AMap.InfoWindow({
|
||||
// 显示内容
|
||||
content: d.content.join('<br>'),
|
||||
// 位置偏移量
|
||||
offset: new AMap.Pixel(0, -20),
|
||||
// 点击地图后关闭信息窗体
|
||||
closeWhenClickMap: true
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开 信息窗体
|
||||
* @param position
|
||||
*/
|
||||
const openInfoWindow = (position) => {
|
||||
const infoWindow = aMapInfoWindowObj.value[position]
|
||||
if (infoWindow) {
|
||||
infoWindow.open(aMap.value, position)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理 覆盖物
|
||||
*/
|
||||
const clearOverlay = () => {
|
||||
aMap.value.clearMap()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
aMap.value && aMap.value.destroy()
|
||||
})
|
||||
|
||||
defineExpose({
|
||||
renderMarker,
|
||||
renderCircleMarker,
|
||||
renderSimpleMarker,
|
||||
renderAwesomeMarker,
|
||||
renderPolyline,
|
||||
renderCircle,
|
||||
renderPolygon,
|
||||
renderInfoWindow,
|
||||
openInfoWindow,
|
||||
clearOverlay
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.aMap {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
height: 800px;
|
||||
|
||||
input[type=radio] {
|
||||
-webkit-appearance: radio;
|
||||
}
|
||||
|
||||
input[type=checkbox] {
|
||||
-webkit-appearance: checkbox;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,402 +0,0 @@
|
|||
<template>
|
||||
<div class="bMap">
|
||||
<div :id="`container-${mid}`" style="width: 100%;height: 100%;">
|
||||
地图资源加载中...
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<!--BMapGL官网:https://lbsyun.baidu.com/index.php?title=jspopularGL-->
|
||||
<script setup name="BMap">
|
||||
import {onMounted, onUnmounted, shallowRef} from "vue"
|
||||
|
||||
const props = defineProps(
|
||||
{
|
||||
mid: {
|
||||
type: Number,
|
||||
default: new Date().getTime()
|
||||
},
|
||||
apiKey: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
center: {
|
||||
type: Array
|
||||
},
|
||||
plugins: {
|
||||
type: Array,
|
||||
default: [
|
||||
'BMap.ScaleControl',
|
||||
'BMap.ZoomControl',
|
||||
'BMap.LocationControl',
|
||||
'BMap.NavigationControl3D'
|
||||
]
|
||||
},
|
||||
viewMode: {
|
||||
type: String,
|
||||
default: '3D',
|
||||
validator(value) {
|
||||
return ['2D', '3D'].includes(value)
|
||||
}
|
||||
},
|
||||
rotationAngle: {
|
||||
type: Number,
|
||||
default: 60
|
||||
},
|
||||
tiltAngle: {
|
||||
type: Number,
|
||||
default: 70
|
||||
},
|
||||
zoom: {
|
||||
type: Number,
|
||||
default: 12
|
||||
},
|
||||
mapStyle: {
|
||||
type: String
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
const emits = defineEmits(['complete', 'markerClick'])
|
||||
|
||||
const bMap = shallowRef(null)
|
||||
const bMapPointArr = ref([])
|
||||
const bMapInfoWindowObj = ref({})
|
||||
|
||||
const init = () => {
|
||||
// 创建script脚本 引入api
|
||||
const script = document.createElement('script')
|
||||
script.src = `https://api.map.baidu.com/api?v=1.0&&type=webgl&ak=${props.apiKey}&callback=initMap`
|
||||
// 加入head 加载api
|
||||
const head = document.getElementsByTagName('head')[0]
|
||||
head.appendChild(script)
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化 地图
|
||||
*/
|
||||
window.initMap = () => {
|
||||
bMap.value = new BMapGL.Map(`container-${props.mid}`)
|
||||
|
||||
// 滚轮放大缩小
|
||||
bMap.value.enableScrollWheelZoom(true)
|
||||
// 地图样式:个性化地图
|
||||
if (props.mapStyle) {
|
||||
bMap.setMapStyleV2(props.mapStyle)
|
||||
}
|
||||
|
||||
// 控件
|
||||
props.plugins.length > 0 && initControlPlugin()
|
||||
|
||||
// 中心点
|
||||
if (props.center) {
|
||||
setFitView(new BMapGL.Point(props.center[0], props.center[1]))
|
||||
|
||||
// 地图初始化完成
|
||||
emits('complete')
|
||||
} else {
|
||||
// 浏览器定位
|
||||
new BMapGL.Geolocation().getCurrentPosition((r) => {
|
||||
if (r) {
|
||||
setFitView(new BMapGL.Point(r.longitude, r.latitude))
|
||||
} else {
|
||||
console.error('getCurrentPosition fail', r)
|
||||
|
||||
setFitView()
|
||||
}
|
||||
|
||||
// 地图初始化完成
|
||||
emits('complete')
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化 控制控件
|
||||
*/
|
||||
const initControlPlugin = () => {
|
||||
// 比例尺
|
||||
props.plugins.includes('BMap.ScaleControl') && bMap.value.addControl(new BMapGL.ScaleControl())
|
||||
// 缩放
|
||||
props.plugins.includes('BMap.ZoomControl') && bMap.value.addControl(new BMapGL.ZoomControl())
|
||||
// 定位
|
||||
props.plugins.includes('BMap.LocationControl') && bMap.value.addControl(new BMapGL.LocationControl())
|
||||
// 3D控件
|
||||
props.plugins.includes('BMap.NavigationControl3D') && bMap.value.addControl(new BMapGL.NavigationControl3D())
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染 点标记
|
||||
* @param dataArr
|
||||
*/
|
||||
const renderMarker = (dataArr) => {
|
||||
dataArr.forEach(d => {
|
||||
const point = new BMapGL.Point(d.position[0], d.position[1])
|
||||
const marker = new BMapGL.Marker(
|
||||
// 坐标
|
||||
point,
|
||||
{
|
||||
// 鼠标滑过点标记时的文字提示
|
||||
title: d.title
|
||||
}
|
||||
)
|
||||
marker.addEventListener('click', () => {
|
||||
emits('markerClick', d.position)
|
||||
})
|
||||
bMap.value.addOverlay(marker)
|
||||
|
||||
bMapPointArr.value.push(point)
|
||||
})
|
||||
|
||||
setFitView()
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染 图标标记
|
||||
* @param dataArr
|
||||
*/
|
||||
const renderIconMarker = (dataArr) => {
|
||||
dataArr.forEach(d => {
|
||||
const point = new BMapGL.Point(d.position[0], d.position[1])
|
||||
const marker = new BMapGL.Marker(
|
||||
// 坐标
|
||||
point,
|
||||
{
|
||||
// 鼠标滑过点标记时的文字提示
|
||||
title: d.title,
|
||||
// 图标对象
|
||||
icon: new BMapGL.Icon(d.img,
|
||||
new BMapGL.Size(d.imgWidth ? d.imgWidth : 40, d.imgHeight ? d.imgHeight : 40)
|
||||
)
|
||||
}
|
||||
)
|
||||
marker.addEventListener('click', () => {
|
||||
emits('markerClick', d.position)
|
||||
})
|
||||
bMap.value.addOverlay(marker)
|
||||
|
||||
bMapPointArr.value.push(point)
|
||||
})
|
||||
|
||||
setFitView()
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染 3D圆点标记
|
||||
* @param dataArr
|
||||
*/
|
||||
const render3DCircleMarker = (dataArr) => {
|
||||
dataArr.forEach(d => {
|
||||
const point = new BMapGL.Point(d.position[0], d.position[1])
|
||||
const marker = new BMapGL.Marker3D(
|
||||
// 坐标
|
||||
point,
|
||||
// 高度,默认8000
|
||||
d.height ? d.height : 8000,
|
||||
// 自定义样式
|
||||
{
|
||||
// 大小,默认50
|
||||
size: d.size ? d.size : 50,
|
||||
// 形状,默认圆形
|
||||
shape: 'BMAP_SHAPE_CIRCLE',
|
||||
// 填充颜色
|
||||
fillColor: d.fillColor ? d.fillColor : '#006600',
|
||||
// 填充透明度
|
||||
fillOpacity: 0.5
|
||||
}
|
||||
)
|
||||
marker.addEventListener('click', () => {
|
||||
emits('markerClick', d.position)
|
||||
})
|
||||
bMap.value.addOverlay(marker)
|
||||
|
||||
bMapPointArr.value.push(point)
|
||||
})
|
||||
|
||||
setFitView()
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染 3D图标标记
|
||||
* @param dataArr
|
||||
*/
|
||||
const render3DIconMarker = (dataArr) => {
|
||||
dataArr.forEach(d => {
|
||||
const point = new BMapGL.Point(d.position[0], d.position[1])
|
||||
const marker = new BMapGL.Marker3D(
|
||||
// 坐标
|
||||
point,
|
||||
// 高度,默认8000
|
||||
d.height ? d.height : 8000,
|
||||
// 自定义样式
|
||||
{
|
||||
// 大小,默认50
|
||||
size: d.size ? d.size : 50,
|
||||
// 图标对象
|
||||
icon: new BMapGL.Icon(d.img,
|
||||
new BMapGL.Size(d.imgWidth ? d.imgWidth : 40, d.imgHeight ? d.imgHeight : 40)
|
||||
)
|
||||
}
|
||||
)
|
||||
marker.addEventListener('click', () => {
|
||||
emits('markerClick', d.position)
|
||||
})
|
||||
bMap.value.addOverlay(marker)
|
||||
|
||||
bMapPointArr.value.push(point)
|
||||
})
|
||||
|
||||
setFitView()
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染 线
|
||||
* @param dataArr
|
||||
* @param option
|
||||
*/
|
||||
const renderPolyline = (dataArr, option = {}) => {
|
||||
dataArr.forEach(d => {
|
||||
bMapPointArr.value.push(new BMapGL.Point(d.position[0], d.position[1]))
|
||||
})
|
||||
|
||||
const polyline = new BMapGL.Polyline(bMapPointArr.value, {
|
||||
stokeStyle: 'solid',
|
||||
strokeColor: option.strokeColor || 'blue',
|
||||
strokeWeight: option.strokeWeight || 2,
|
||||
strokeOpacity: option.strokeOpacity || 0.5
|
||||
})
|
||||
bMap.value.addOverlay(polyline)
|
||||
|
||||
setFitView()
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染 圆
|
||||
* @param position
|
||||
* @param radius
|
||||
* @param option
|
||||
*/
|
||||
const renderCircle = (position, radius, option = {}) => {
|
||||
const point = new BMapGL.Point(position[0], position[1])
|
||||
bMapPointArr.value.push(point)
|
||||
|
||||
const circle = new BMapGL.Circle(
|
||||
point,
|
||||
radius ? radius : 500,
|
||||
{
|
||||
strokeColor: option.strokeColor || 'blue',
|
||||
strokeWeight: option.strokeWeight || 2,
|
||||
strokeOpacity: option.strokeOpacity || 0.5
|
||||
})
|
||||
bMap.value.addOverlay(circle)
|
||||
|
||||
setFitView()
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染 面
|
||||
* @param dataArr
|
||||
* @param option
|
||||
*/
|
||||
const renderPolygon = (dataArr, option = {}) => {
|
||||
dataArr.forEach(d => {
|
||||
bMapPointArr.value.push(new BMapGL.Point(d.position[0], d.position[1]))
|
||||
})
|
||||
|
||||
const polygon = new BMapGL.Polygon(bMapPointArr.value, {
|
||||
stokeStyle: 'solid',
|
||||
strokeColor: option.strokeColor || 'blue',
|
||||
strokeWeight: option.strokeWeight || 2,
|
||||
strokeOpacity: option.strokeOpacity || 0.5,
|
||||
fillColor: option.fillColor || 'blue',
|
||||
fllOpacity: option.fllOpacity || 0.5
|
||||
})
|
||||
bMap.value.addOverlay(polygon)
|
||||
|
||||
setFitView()
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置 视图级别
|
||||
* @param point
|
||||
*/
|
||||
const setFitView = (point) => {
|
||||
if (!point) {
|
||||
const viewPort = bMap.value.getViewport(bMapPointArr.value)
|
||||
point = new BMapGL.Point(viewPort.center.lng, viewPort.center.lat)
|
||||
}
|
||||
bMap.value.centerAndZoom(point, props.zoom)
|
||||
|
||||
// 3D视图
|
||||
if (props.viewMode === '3D') {
|
||||
// 地图旋转角度
|
||||
bMap.value.setHeading(props.rotationAngle)
|
||||
// 地图倾斜角度
|
||||
bMap.value.setTilt(props.tiltAngle)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染 信息窗体
|
||||
* @param dataArr
|
||||
*/
|
||||
const renderInfoWindow = (dataArr) => {
|
||||
dataArr.forEach(d => {
|
||||
bMapInfoWindowObj.value[d.position] = new BMapGL.InfoWindow(
|
||||
d.content.join('<br>'),
|
||||
{
|
||||
title: d.title,
|
||||
width: d.width ? d.width : 250,
|
||||
height: d.height ? d.height : 100
|
||||
}
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开 信息窗体
|
||||
* @param position
|
||||
*/
|
||||
const openInfoWindow = (position) => {
|
||||
const infoWindow = bMapInfoWindowObj.value[position]
|
||||
if (infoWindow) {
|
||||
bMap.value.openInfoWindow(infoWindow, new BMapGL.Point(position[0], position[1]))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理 覆盖物
|
||||
*/
|
||||
const clearOverlay = () => {
|
||||
bMap.value.clearOverlays()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
bMap.value && bMap.value.destroy()
|
||||
})
|
||||
|
||||
defineExpose({
|
||||
renderMarker,
|
||||
renderIconMarker,
|
||||
render3DCircleMarker,
|
||||
render3DIconMarker,
|
||||
renderPolyline,
|
||||
renderCircle,
|
||||
renderPolygon,
|
||||
renderInfoWindow,
|
||||
openInfoWindow,
|
||||
clearOverlay
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.bMap {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
height: 800px;
|
||||
}
|
||||
</style>
|
|
@ -5,44 +5,44 @@ BMap
|
|||
|
||||
该组件由 [小诺开源技术](https://www.xiaonuo.vip) 封装
|
||||
|
||||
|
||||
### 使用方式
|
||||
|
||||
```vue
|
||||
|
||||
<template>
|
||||
<a-map ref="map" api-key="******" @complete="handleComplete"
|
||||
@marker-click="handleMarkerClick"></a-map>
|
||||
<baidu-map ref="map" api-key="******" @complete="handleComplete"
|
||||
@marker-click="handleMarkerClick" />
|
||||
</template>
|
||||
|
||||
<script setup name="exmAMap">
|
||||
import AMap from '@/components/Map/bMap/index.vue'
|
||||
import BaiduMap from '@/components/Map/baiduMap/index.vue'
|
||||
|
||||
const map = ref(null)
|
||||
const map = ref(null)
|
||||
|
||||
const handleComplete = () => {
|
||||
// 渲染 点标记
|
||||
map.value.renderMarker(
|
||||
[
|
||||
{
|
||||
position: [116.39, 39.9],
|
||||
title: 'TA',
|
||||
content: 'CA',
|
||||
label: {
|
||||
content: 'LCA'
|
||||
const handleComplete = () => {
|
||||
// 渲染 点标记
|
||||
map.value.renderMarker(
|
||||
[
|
||||
{
|
||||
position: [116.39, 39.9],
|
||||
title: 'TA',
|
||||
content: 'CA',
|
||||
label: {
|
||||
content: 'LCA'
|
||||
}
|
||||
},
|
||||
{
|
||||
position: [116.33, 39.5],
|
||||
title: 'TB',
|
||||
icon: '//vdata.amap.com/icons/b18/1/2.png'
|
||||
}
|
||||
},
|
||||
{
|
||||
position: [116.33, 39.5],
|
||||
title: 'TB',
|
||||
icon: '//vdata.amap.com/icons/b18/1/2.png'
|
||||
}
|
||||
]
|
||||
)
|
||||
}
|
||||
]
|
||||
)
|
||||
}
|
||||
|
||||
const handleMarkerClick = (position) => {
|
||||
map.value.openInfoWindow(position)
|
||||
}
|
||||
const handleMarkerClick = (position) => {
|
||||
map.value.openInfoWindow(position)
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.4 KiB |
|
@ -0,0 +1,364 @@
|
|||
<template>
|
||||
<div class="baiduMap">
|
||||
<div :id="`container-${mid}`" style="width: 100%; height: 100%">地图资源加载中...</div>
|
||||
</div>
|
||||
</template>
|
||||
<!--BMapGL官网:https://lbsyun.baidu.com/index.php?title=jspopularGL-->
|
||||
<script setup name="baiduMap">
|
||||
import { onMounted, onUnmounted, shallowRef } from 'vue'
|
||||
const props = defineProps({
|
||||
mid: {
|
||||
type: Number,
|
||||
default: new Date().getTime()
|
||||
},
|
||||
apiKey: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
center: {
|
||||
type: Array
|
||||
},
|
||||
plugins: {
|
||||
type: Array,
|
||||
default: ['BMap.ScaleControl', 'BMap.ZoomControl', 'BMap.LocationControl', 'BMap.NavigationControl3D']
|
||||
},
|
||||
viewMode: {
|
||||
type: String,
|
||||
default: '3D',
|
||||
validator(value) {
|
||||
return ['2D', '3D'].includes(value)
|
||||
}
|
||||
},
|
||||
rotationAngle: {
|
||||
type: Number,
|
||||
default: 60
|
||||
},
|
||||
tiltAngle: {
|
||||
type: Number,
|
||||
default: 70
|
||||
},
|
||||
zoom: {
|
||||
type: Number,
|
||||
default: 12
|
||||
},
|
||||
mapStyle: {
|
||||
type: String
|
||||
}
|
||||
})
|
||||
|
||||
const emits = defineEmits(['complete', 'markerClick'])
|
||||
const baiduMap = shallowRef(null)
|
||||
const baiduMapPointArr = ref([])
|
||||
const baiduMapInfoWindowObj = ref({})
|
||||
const init = () => {
|
||||
// 创建script脚本 引入api
|
||||
const script = document.createElement('script')
|
||||
script.src = `https://api.map.baidu.com/api?v=1.0&&type=webgl&ak=${props.apiKey}&callback=initMap`
|
||||
// 加入head 加载api
|
||||
const head = document.getElementsByTagName('head')[0]
|
||||
head.appendChild(script)
|
||||
}
|
||||
// 初始化 地图
|
||||
window.initMap = () => {
|
||||
baiduMap.value = new BMapGL.Map(`container-${props.mid}`)
|
||||
// 滚轮放大缩小
|
||||
baiduMap.value.enableScrollWheelZoom(true)
|
||||
// 地图样式:个性化地图
|
||||
if (props.mapStyle) {
|
||||
baiduMap.value.setMapStyleV2(props.mapStyle)
|
||||
}
|
||||
// 控件
|
||||
props.plugins.length > 0 && initControlPlugin()
|
||||
// 中心点
|
||||
if (props.center) {
|
||||
setFitView(new BMapGL.Point(props.center[0], props.center[1]))
|
||||
|
||||
// 地图初始化完成
|
||||
emits('complete')
|
||||
} else {
|
||||
// 浏览器定位
|
||||
new BMapGL.Geolocation().getCurrentPosition((r) => {
|
||||
if (r) {
|
||||
setFitView(new BMapGL.Point(r.longitude, r.latitude))
|
||||
} else {
|
||||
setFitView()
|
||||
}
|
||||
// 地图初始化完成
|
||||
emits('complete')
|
||||
})
|
||||
}
|
||||
}
|
||||
// 初始化 控制控件
|
||||
const initControlPlugin = () => {
|
||||
// 比例尺
|
||||
props.plugins.includes('BMap.ScaleControl') && baiduMap.value.addControl(new BMapGL.ScaleControl())
|
||||
// 缩放
|
||||
props.plugins.includes('BMap.ZoomControl') && baiduMap.value.addControl(new BMapGL.ZoomControl())
|
||||
// 定位
|
||||
props.plugins.includes('BMap.LocationControl') && baiduMap.value.addControl(new BMapGL.LocationControl())
|
||||
// 3D控件
|
||||
props.plugins.includes('BMap.NavigationControl3D') && baiduMap.value.addControl(new BMapGL.NavigationControl3D())
|
||||
}
|
||||
// 渲染 点标记
|
||||
const renderMarker = (dataArr) => {
|
||||
dataArr.forEach((d) => {
|
||||
const point = new BMapGL.Point(d.position[0], d.position[1])
|
||||
const marker = new BMapGL.Marker(
|
||||
// 坐标
|
||||
point,
|
||||
{
|
||||
// 鼠标滑过点标记时的文字提示
|
||||
title: d.title
|
||||
}
|
||||
)
|
||||
marker.addEventListener('click', () => {
|
||||
emits('markerClick', d.position)
|
||||
})
|
||||
baiduMap.value.addOverlay(marker)
|
||||
|
||||
baiduMapPointArr.value.push(point)
|
||||
})
|
||||
|
||||
setFitView()
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染 图标标记
|
||||
* @param dataArr
|
||||
*/
|
||||
const renderIconMarker = (dataArr) => {
|
||||
dataArr.forEach((d) => {
|
||||
const point = new BMapGL.Point(d.position[0], d.position[1])
|
||||
const marker = new BMapGL.Marker(
|
||||
// 坐标
|
||||
point,
|
||||
{
|
||||
// 鼠标滑过点标记时的文字提示
|
||||
title: d.title,
|
||||
// 图标对象
|
||||
icon: new BMapGL.Icon(d.img, new BMapGL.Size(d.imgWidth ? d.imgWidth : 40, d.imgHeight ? d.imgHeight : 40))
|
||||
}
|
||||
)
|
||||
marker.addEventListener('click', () => {
|
||||
emits('markerClick', d.position)
|
||||
})
|
||||
baiduMap.value.addOverlay(marker)
|
||||
|
||||
baiduMapPointArr.value.push(point)
|
||||
})
|
||||
|
||||
setFitView()
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染 3D圆点标记
|
||||
* @param dataArr
|
||||
*/
|
||||
const render3DCircleMarker = (dataArr) => {
|
||||
dataArr.forEach((d) => {
|
||||
const point = new BMapGL.Point(d.position[0], d.position[1])
|
||||
const marker = new BMapGL.Marker3D(
|
||||
// 坐标
|
||||
point,
|
||||
// 高度,默认8000
|
||||
d.height ? d.height : 8000,
|
||||
// 自定义样式
|
||||
{
|
||||
// 大小,默认50
|
||||
size: d.size ? d.size : 50,
|
||||
// 形状,默认圆形
|
||||
shape: 'BMAP_SHAPE_CIRCLE',
|
||||
// 填充颜色
|
||||
fillColor: d.fillColor ? d.fillColor : '#006600',
|
||||
// 填充透明度
|
||||
fillOpacity: 0.5
|
||||
}
|
||||
)
|
||||
marker.addEventListener('click', () => {
|
||||
emits('markerClick', d.position)
|
||||
})
|
||||
baiduMap.value.addOverlay(marker)
|
||||
|
||||
baiduMapPointArr.value.push(point)
|
||||
})
|
||||
|
||||
setFitView()
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染 3D图标标记
|
||||
* @param dataArr
|
||||
*/
|
||||
const render3DIconMarker = (dataArr) => {
|
||||
dataArr.forEach((d) => {
|
||||
const point = new BMapGL.Point(d.position[0], d.position[1])
|
||||
const marker = new BMapGL.Marker3D(
|
||||
// 坐标
|
||||
point,
|
||||
// 高度,默认8000
|
||||
d.height ? d.height : 8000,
|
||||
// 自定义样式
|
||||
{
|
||||
// 大小,默认50
|
||||
size: d.size ? d.size : 50,
|
||||
// 图标对象
|
||||
icon: new BMapGL.Icon(d.img, new BMapGL.Size(d.imgWidth ? d.imgWidth : 40, d.imgHeight ? d.imgHeight : 40))
|
||||
}
|
||||
)
|
||||
marker.addEventListener('click', () => {
|
||||
emits('markerClick', d.position)
|
||||
})
|
||||
baiduMap.value.addOverlay(marker)
|
||||
|
||||
baiduMapPointArr.value.push(point)
|
||||
})
|
||||
|
||||
setFitView()
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染 线
|
||||
* @param dataArr
|
||||
* @param option
|
||||
*/
|
||||
const renderPolyline = (dataArr, option = {}) => {
|
||||
dataArr.forEach((d) => {
|
||||
baiduMapPointArr.value.push(new BMapGL.Point(d.position[0], d.position[1]))
|
||||
})
|
||||
|
||||
const polyline = new BMapGL.Polyline(baiduMapPointArr.value, {
|
||||
stokeStyle: 'solid',
|
||||
strokeColor: option.strokeColor || 'blue',
|
||||
strokeWeight: option.strokeWeight || 2,
|
||||
strokeOpacity: option.strokeOpacity || 0.5
|
||||
})
|
||||
baiduMap.value.addOverlay(polyline)
|
||||
|
||||
setFitView()
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染 圆
|
||||
* @param position
|
||||
* @param radius
|
||||
* @param option
|
||||
*/
|
||||
const renderCircle = (position, radius, option = {}) => {
|
||||
const point = new BMapGL.Point(position[0], position[1])
|
||||
baiduMapPointArr.value.push(point)
|
||||
|
||||
const circle = new BMapGL.Circle(point, radius ? radius : 500, {
|
||||
strokeColor: option.strokeColor || 'blue',
|
||||
strokeWeight: option.strokeWeight || 2,
|
||||
strokeOpacity: option.strokeOpacity || 0.5
|
||||
})
|
||||
baiduMap.value.addOverlay(circle)
|
||||
|
||||
setFitView()
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染 面
|
||||
* @param dataArr
|
||||
* @param option
|
||||
*/
|
||||
const renderPolygon = (dataArr, option = {}) => {
|
||||
dataArr.forEach((d) => {
|
||||
baiduMapPointArr.value.push(new BMapGL.Point(d.position[0], d.position[1]))
|
||||
})
|
||||
|
||||
const polygon = new BMapGL.Polygon(baiduMapPointArr.value, {
|
||||
stokeStyle: 'solid',
|
||||
strokeColor: option.strokeColor || 'blue',
|
||||
strokeWeight: option.strokeWeight || 2,
|
||||
strokeOpacity: option.strokeOpacity || 0.5,
|
||||
fillColor: option.fillColor || 'blue',
|
||||
fllOpacity: option.fllOpacity || 0.5
|
||||
})
|
||||
baiduMap.value.addOverlay(polygon)
|
||||
|
||||
setFitView()
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置 视图级别
|
||||
* @param point
|
||||
*/
|
||||
const setFitView = (point) => {
|
||||
if (!point) {
|
||||
const viewPort = baiduMap.value.getViewport(baiduMapPointArr.value)
|
||||
point = new BMapGL.Point(viewPort.center.lng, viewPort.center.lat)
|
||||
}
|
||||
baiduMap.value.centerAndZoom(point, props.zoom)
|
||||
|
||||
// 3D视图
|
||||
if (props.viewMode === '3D') {
|
||||
// 地图旋转角度
|
||||
baiduMap.value.setHeading(props.rotationAngle)
|
||||
// 地图倾斜角度
|
||||
baiduMap.value.setTilt(props.tiltAngle)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染 信息窗体
|
||||
* @param dataArr
|
||||
*/
|
||||
const renderInfoWindow = (dataArr) => {
|
||||
dataArr.forEach((d) => {
|
||||
baiduMapInfoWindowObj.value[d.position] = new BMapGL.InfoWindow(d.content.join('<br>'), {
|
||||
title: d.title,
|
||||
width: d.width ? d.width : 250,
|
||||
height: d.height ? d.height : 100
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开 信息窗体
|
||||
* @param position
|
||||
*/
|
||||
const openInfoWindow = (position) => {
|
||||
const infoWindow = baiduMapInfoWindowObj.value[position]
|
||||
if (infoWindow) {
|
||||
baiduMap.value.openInfoWindow(infoWindow, new BMapGL.Point(position[0], position[1]))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理 覆盖物
|
||||
*/
|
||||
const clearOverlay = () => {
|
||||
baiduMap.value.clearOverlays()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
baiduMap.value && baiduMap.value.destroy()
|
||||
})
|
||||
|
||||
defineExpose({
|
||||
renderMarker,
|
||||
renderIconMarker,
|
||||
render3DCircleMarker,
|
||||
render3DIconMarker,
|
||||
renderPolyline,
|
||||
renderCircle,
|
||||
renderPolygon,
|
||||
renderInfoWindow,
|
||||
openInfoWindow,
|
||||
clearOverlay
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.baiduMap {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
height: 800px;
|
||||
}
|
||||
</style>
|
|
@ -5,44 +5,44 @@ AMap
|
|||
|
||||
该组件由 [小诺开源技术](https://www.xiaonuo.vip) 封装
|
||||
|
||||
|
||||
### 使用方式
|
||||
|
||||
```vue
|
||||
|
||||
<template>
|
||||
<a-map ref="map" api-key="******" @complete="handleComplete"
|
||||
@marker-click="handleMarkerClick"></a-map>
|
||||
<gaode-map ref="map" api-key="******" @complete="handleComplete"
|
||||
@marker-click="handleMarkerClick" />
|
||||
</template>
|
||||
|
||||
<script setup name="exmAMap">
|
||||
import AMap from '@/components/Map/aMap/index.vue'
|
||||
import GaodeMap from '@/components/Map/gaodeMap/index.vue'
|
||||
|
||||
const map = ref(null)
|
||||
const map = ref(null)
|
||||
|
||||
const handleComplete = () => {
|
||||
// 渲染 点标记
|
||||
map.value.renderMarker(
|
||||
[
|
||||
{
|
||||
position: [116.39, 39.9],
|
||||
title: 'TA',
|
||||
content: 'CA',
|
||||
label: {
|
||||
content: 'LCA'
|
||||
const handleComplete = () => {
|
||||
// 渲染 点标记
|
||||
map.value.renderMarker(
|
||||
[
|
||||
{
|
||||
position: [116.39, 39.9],
|
||||
title: 'TA',
|
||||
content: 'CA',
|
||||
label: {
|
||||
content: 'LCA'
|
||||
}
|
||||
},
|
||||
{
|
||||
position: [116.33, 39.5],
|
||||
title: 'TB',
|
||||
icon: '//vdata.amap.com/icons/b18/1/2.png'
|
||||
}
|
||||
},
|
||||
{
|
||||
position: [116.33, 39.5],
|
||||
title: 'TB',
|
||||
icon: '//vdata.amap.com/icons/b18/1/2.png'
|
||||
}
|
||||
]
|
||||
)
|
||||
}
|
||||
]
|
||||
)
|
||||
}
|
||||
|
||||
const handleMarkerClick = (position) => {
|
||||
map.value.openInfoWindow(position)
|
||||
}
|
||||
const handleMarkerClick = (position) => {
|
||||
map.value.openInfoWindow(position)
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
|
@ -0,0 +1,405 @@
|
|||
<template>
|
||||
<div class="gaodeMap">
|
||||
<div :id="`container-${mid}`" style="width: 100%; height: 100%">地图资源加载中...</div>
|
||||
</div>
|
||||
</template>
|
||||
<!--AMap官网:https://lbs.amap.com/api/javascript-api-v2/summary-->
|
||||
<script setup name="GaodeMap">
|
||||
import { onMounted, onUnmounted, shallowRef } from 'vue'
|
||||
import AMapLoader from '@amap/amap-jsapi-loader'
|
||||
|
||||
const props = defineProps({
|
||||
mid: {
|
||||
type: Number,
|
||||
default: new Date().getTime()
|
||||
},
|
||||
apiKey: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
center: {
|
||||
type: Array
|
||||
},
|
||||
plugins: {
|
||||
type: Array,
|
||||
default: ['AMap.ToolBar', 'AMap.Scale', 'AMap.HawkEye', 'AMap.MapType', 'AMap.Geolocation', 'AMap.MarkerCluster']
|
||||
},
|
||||
viewMode: {
|
||||
type: String,
|
||||
default: '3D',
|
||||
validator(value) {
|
||||
return ['2D', '3D'].includes(value)
|
||||
}
|
||||
},
|
||||
zoom: {
|
||||
type: Number,
|
||||
default: 12
|
||||
},
|
||||
pitch: {
|
||||
type: Number,
|
||||
default: 50
|
||||
},
|
||||
mapStyle: {
|
||||
type: String,
|
||||
default: 'normal',
|
||||
validator(value) {
|
||||
return ['normal', 'macaron', 'dark', 'fresh', 'grey'].includes(value)
|
||||
}
|
||||
},
|
||||
markerCluster: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
})
|
||||
|
||||
const emits = defineEmits(['complete', 'markerClick'])
|
||||
|
||||
const gaodeMap = shallowRef(null)
|
||||
const gaodeMapMarkerArr = ref([])
|
||||
const gaodeMapInfoWindowObj = ref({})
|
||||
|
||||
const init = () => {
|
||||
AMapLoader.load({
|
||||
key: props.apiKey,
|
||||
version: '2.0',
|
||||
plugins: props.plugins,
|
||||
AMapUI: {
|
||||
version: '1.1',
|
||||
plugins: ['overlay/SimpleMarker', 'overlay/AwesomeMarker']
|
||||
}
|
||||
})
|
||||
.then(() => {
|
||||
initMap()
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error(e)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化 地图
|
||||
*/
|
||||
const initMap = () => {
|
||||
gaodeMap.value = new AMap.Map(`container-${props.mid}`, {
|
||||
viewMode: props.viewMode,
|
||||
zoom: props.zoom,
|
||||
// 地图俯仰角度
|
||||
pitch: props.pitch,
|
||||
mapStyle: `amap://styles/${props.mapStyle}`
|
||||
})
|
||||
|
||||
// 中心点
|
||||
if (props.center) {
|
||||
gaodeMap.value.setCenter(props.center)
|
||||
}
|
||||
|
||||
// 控件
|
||||
props.plugins.length > 0 && initControlPlugin()
|
||||
|
||||
// 地图初始化完成
|
||||
gaodeMap.value.on('complete', () => {
|
||||
emits('complete')
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化 控制控件
|
||||
*/
|
||||
const initControlPlugin = () => {
|
||||
// 工具条,控制地图的缩放、平移等
|
||||
props.plugins.includes('AMap.ToolBar') && gaodeMap.value.addControl(new AMap.ToolBar({}))
|
||||
// 比例尺
|
||||
props.plugins.includes('AMap.Scale') && gaodeMap.value.addControl(new AMap.Scale())
|
||||
// 鹰眼,显示缩略图
|
||||
props.plugins.includes('AMap.HawkEye') && gaodeMap.value.addControl(new AMap.HawkEye({ isOpen: true }))
|
||||
// 图层切换
|
||||
props.plugins.includes('AMap.MapType') && gaodeMap.value.addControl(new AMap.MapType({}))
|
||||
// 定位
|
||||
props.plugins.includes('AMap.Geolocation') && gaodeMap.value.addControl(new AMap.Geolocation({}))
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染 点标记
|
||||
* @param dataArr
|
||||
*/
|
||||
const renderMarker = (dataArr) => {
|
||||
dataArr.forEach((d) => {
|
||||
const marker = new AMap.Marker({
|
||||
map: gaodeMap.value,
|
||||
position: d.position,
|
||||
// 鼠标滑过点标记时的文字提示
|
||||
title: d.title,
|
||||
// 显示内容:content有效时,icon属性将被覆盖
|
||||
content: d.content,
|
||||
// 图标
|
||||
icon: d.icon ? d.icon : null,
|
||||
// 文本标注
|
||||
label: d.label
|
||||
})
|
||||
marker.on('click', () => {
|
||||
emits('markerClick', d.position)
|
||||
})
|
||||
gaodeMapMarkerArr.value.push(marker)
|
||||
})
|
||||
|
||||
setFitView()
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染 圆点标记
|
||||
* @param dataArr
|
||||
*/
|
||||
const renderCircleMarker = (dataArr) => {
|
||||
dataArr.forEach((d) => {
|
||||
const marker = new AMap.CircleMarker({
|
||||
map: gaodeMap.value,
|
||||
// 圆心位置
|
||||
center: d.position,
|
||||
// 圆点半径
|
||||
radius: d.radius ? d.radius : 20,
|
||||
// 线条颜色
|
||||
strokeColor: d.strokeColor ? d.strokeColor : '#006600',
|
||||
// 轮廓线透明度
|
||||
strokeOpacity: 0.5,
|
||||
// 轮廓线宽度
|
||||
strokeWeight: 2,
|
||||
// 填充颜色
|
||||
fillColor: d.fillColor ? d.fillColor : '#006600',
|
||||
// 填充透明度
|
||||
fillOpacity: 0.5,
|
||||
cursor: 'pointer'
|
||||
})
|
||||
marker.on('click', () => {
|
||||
emits('markerClick', d.position)
|
||||
})
|
||||
gaodeMapMarkerArr.value.push(marker)
|
||||
})
|
||||
|
||||
setFitView()
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染 简单点标记
|
||||
* @param dataArr
|
||||
* @param theme
|
||||
*/
|
||||
const renderSimpleMarker = (dataArr, theme = 'default') => {
|
||||
dataArr.forEach((d) => {
|
||||
const marker = new AMapUI.SimpleMarker({
|
||||
map: gaodeMap.value,
|
||||
position: d.position,
|
||||
// 前景文字
|
||||
iconLabel: {
|
||||
// 文本
|
||||
innerHTML: d.label,
|
||||
// 字体的样式,比如颜色,大小等
|
||||
style: d.labelStyle
|
||||
? d.labelStyle
|
||||
: {
|
||||
color: '#333',
|
||||
fontSize: '12px'
|
||||
}
|
||||
},
|
||||
// 图标主题:default,fresh,numv1,numv2
|
||||
iconTheme: theme,
|
||||
// 背景图标样式
|
||||
iconStyle: d.style
|
||||
})
|
||||
marker.on('click', () => {
|
||||
emits('markerClick', d.position)
|
||||
})
|
||||
gaodeMapMarkerArr.value.push(marker)
|
||||
})
|
||||
|
||||
setFitView()
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染 字体点标记
|
||||
* @param dataArr
|
||||
*/
|
||||
const renderAwesomeMarker = (dataArr) => {
|
||||
dataArr.forEach((d) => {
|
||||
const marker = new AMapUI.AwesomeMarker({
|
||||
map: gaodeMap.value,
|
||||
position: d.position,
|
||||
// 图标,参见:http://fontawesome.io/icons/
|
||||
awesomeIcon: d.awesomeIcon,
|
||||
// 字体的样式,比如颜色,大小等
|
||||
iconLabel: {
|
||||
style: d.labelStyle
|
||||
? d.labelStyle
|
||||
: {
|
||||
color: '#333',
|
||||
fontSize: '12px'
|
||||
}
|
||||
},
|
||||
// 背景图标的样式
|
||||
iconStyle: d.style
|
||||
})
|
||||
marker.on('click', () => {
|
||||
emits('markerClick', d.position)
|
||||
})
|
||||
gaodeMapMarkerArr.value.push(marker)
|
||||
})
|
||||
|
||||
setFitView()
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置 视图级别
|
||||
*/
|
||||
const setFitView = () => {
|
||||
// 点聚合
|
||||
props.markerCluster && new AMap.MarkerCluster(gaodeMap.value, gaodeMapMarkerArr.value)
|
||||
|
||||
// 根据地图上添加的覆盖物分布情况,自动缩放地图到合适的视野级别
|
||||
gaodeMap.value.setFitView(gaodeMapMarkerArr.value)
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染 线
|
||||
* @param dataArr
|
||||
* @param option
|
||||
*/
|
||||
const renderPolyline = (dataArr, option = {}) => {
|
||||
const path = []
|
||||
dataArr.forEach((d) => {
|
||||
path.push(new AMap.LngLat(d.position[0], d.position[1]))
|
||||
})
|
||||
|
||||
const polyline = new AMap.Polyline({
|
||||
path: path,
|
||||
strokeColor: option.strokeColor || 'blue',
|
||||
strokeWeight: option.strokeWeight || 2,
|
||||
strokeOpacity: option.strokeOpacity || 0.5,
|
||||
isOutline: option.isOutline || false,
|
||||
borderWeight: option.borderWeight || 1,
|
||||
// 折线拐点连接处样式
|
||||
lineJoin: 'round'
|
||||
})
|
||||
gaodeMap.value.add(polyline)
|
||||
|
||||
gaodeMap.value.setFitView([polyline])
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染 圆
|
||||
* @param position
|
||||
* @param radius
|
||||
* @param option
|
||||
*/
|
||||
const renderCircle = (position, radius, option) => {
|
||||
const circle = new AMap.Circle({
|
||||
center: new AMap.LngLat(position[0], position[1]),
|
||||
radius: radius,
|
||||
strokeColor: option.strokeColor || 'blue',
|
||||
strokeWeight: option.strokeWeight || 2,
|
||||
strokeOpacity: option.strokeOpacity || 0.5,
|
||||
fillColor: option.fillColor || 'blue',
|
||||
fillOpacity: option.fillOpacity || 0.5,
|
||||
strokeStyle: 'solid'
|
||||
})
|
||||
gaodeMap.value.add(circle)
|
||||
|
||||
gaodeMap.value.setFitView([circle])
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染 面
|
||||
* @param dataArr
|
||||
* @param option
|
||||
*/
|
||||
const renderPolygon = (dataArr, option = {}) => {
|
||||
const path = []
|
||||
dataArr.forEach((d) => {
|
||||
path.push(new AMap.LngLat(d.position[0], d.position[1]))
|
||||
})
|
||||
|
||||
const polygon = new AMap.Polygon({
|
||||
path: path,
|
||||
strokeColor: option.strokeColor || 'blue',
|
||||
strokeWeight: option.strokeWeight || 2,
|
||||
strokeOpacity: option.strokeOpacity || 0.5,
|
||||
fillColor: option.fillColor || 'blue',
|
||||
fillOpacity: option.fillOpacity || 0.5,
|
||||
strokeStyle: 'solid'
|
||||
})
|
||||
gaodeMap.value.add(polygon)
|
||||
|
||||
gaodeMap.value.setFitView([polygon])
|
||||
}
|
||||
|
||||
/**
|
||||
* 渲染 信息窗体
|
||||
* @param dataArr
|
||||
*/
|
||||
const renderInfoWindow = (dataArr) => {
|
||||
dataArr.forEach((d) => {
|
||||
gaodeMapInfoWindowObj.value[d.position] = new AMap.InfoWindow({
|
||||
// 显示内容
|
||||
content: d.content.join('<br>'),
|
||||
// 位置偏移量
|
||||
offset: new AMap.Pixel(0, -20),
|
||||
// 点击地图后关闭信息窗体
|
||||
closeWhenClickMap: true
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开 信息窗体
|
||||
* @param position
|
||||
*/
|
||||
const openInfoWindow = (position) => {
|
||||
const infoWindow = gaodeMapInfoWindowObj.value[position]
|
||||
if (infoWindow) {
|
||||
infoWindow.open(gaodeMap.value, position)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理 覆盖物
|
||||
*/
|
||||
const clearOverlay = () => {
|
||||
gaodeMap.value.clearMap()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
gaodeMap.value && gaodeMap.value.destroy()
|
||||
})
|
||||
|
||||
defineExpose({
|
||||
renderMarker,
|
||||
renderCircleMarker,
|
||||
renderSimpleMarker,
|
||||
renderAwesomeMarker,
|
||||
renderPolyline,
|
||||
renderCircle,
|
||||
renderPolygon,
|
||||
renderInfoWindow,
|
||||
openInfoWindow,
|
||||
clearOverlay
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.gaodeMap {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
height: 800px;
|
||||
|
||||
input[type='radio'] {
|
||||
-webkit-appearance: radio;
|
||||
}
|
||||
|
||||
input[type='checkbox'] {
|
||||
-webkit-appearance: checkbox;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -14,7 +14,7 @@
|
|||
<script>
|
||||
import { mapState } from 'pinia'
|
||||
import { globalStore } from '@/store'
|
||||
import DragModal from "@/components/DragModal/index.vue";
|
||||
import DragModal from '@/components/DragModal/index.vue'
|
||||
|
||||
const FormContainerTypeEnum = {
|
||||
DRAWER: 'drawer',
|
||||
|
|
|
@ -1,143 +0,0 @@
|
|||
<template>
|
||||
<a-map ref="map" api-key="******" @complete="handleComplete"
|
||||
@marker-click="handleMarkerClick"></a-map>
|
||||
</template>
|
||||
|
||||
<script setup name="exmAMap">
|
||||
import AMap from '@/components/Map/aMap/index.vue'
|
||||
|
||||
const map = ref(null)
|
||||
|
||||
const handleComplete = () => {
|
||||
console.log('complete')
|
||||
|
||||
// 点标记
|
||||
map.value.renderMarker(
|
||||
[
|
||||
{
|
||||
position: [116.39, 39.9],
|
||||
title: 'TA',
|
||||
content: 'CA',
|
||||
label: {
|
||||
content: 'LCA'
|
||||
}
|
||||
},
|
||||
{
|
||||
position: [116.33, 39.5],
|
||||
title: 'TB',
|
||||
icon: '//vdata.amap.com/icons/b18/1/2.png'
|
||||
}
|
||||
]
|
||||
)
|
||||
// 圆点标记
|
||||
// map.value.renderCircleMarker(
|
||||
// [
|
||||
// {
|
||||
// position: [116.39, 39.9],
|
||||
// radius: 30,
|
||||
// strokeColor: 'green',
|
||||
// fillColor: 'green'
|
||||
// },
|
||||
// {
|
||||
// position: [116.33, 39.5],
|
||||
// radius: 10,
|
||||
// strokeColor: 'orange',
|
||||
// fillColor: 'orange'
|
||||
// }
|
||||
// ]
|
||||
// )
|
||||
// 简单点标记
|
||||
// map.value.renderSimpleMarker(
|
||||
// [
|
||||
// {
|
||||
// position: [116.39, 39.9],
|
||||
// label: 'A',
|
||||
// labelStyle: {
|
||||
// color: '#333',
|
||||
// fontSize: '15px'
|
||||
// },
|
||||
// style: 'green'
|
||||
// },
|
||||
// {
|
||||
// position: [116.33, 39.5],
|
||||
// label: 'B',
|
||||
// labelStyle: {
|
||||
// color: '#555',
|
||||
// fontSize: '15px'
|
||||
// },
|
||||
// style: 'orange'
|
||||
// }
|
||||
// ]
|
||||
// )
|
||||
// 字体点标记
|
||||
// map.value.renderAwesomeMarker(
|
||||
// [
|
||||
// {
|
||||
// position: [116.39, 39.9],
|
||||
// awesomeIcon: 'address-book-o',
|
||||
// labelStyle: {
|
||||
// color: '#333',
|
||||
// fontSize: '15px'
|
||||
// },
|
||||
// style: 'green'
|
||||
// },
|
||||
// {
|
||||
// position: [116.33, 39.5],
|
||||
// awesomeIcon: 'anchor',
|
||||
// labelStyle: {
|
||||
// color: '#333',
|
||||
// fontSize: '15px'
|
||||
// },
|
||||
// style: 'orange'
|
||||
// }
|
||||
// ]
|
||||
// )
|
||||
// 面
|
||||
// map.value.renderPolygon(
|
||||
// [
|
||||
// {
|
||||
// position: [116.39, 39.9]
|
||||
// },
|
||||
// {
|
||||
// position: [116.47, 39.8]
|
||||
// },
|
||||
// {
|
||||
// position: [116.46, 39.7]
|
||||
// },
|
||||
// {
|
||||
// position: [116.35, 39.6]
|
||||
// }
|
||||
// ]
|
||||
// )
|
||||
// 信息窗体
|
||||
map.value.renderInfoWindow(
|
||||
[
|
||||
{
|
||||
position: [116.39, 39.9],
|
||||
content: [
|
||||
"<div style='padding:0'><b>Snowy-小诺开源技术</b>",
|
||||
"网站 : https://www.xiaonuo.vip",
|
||||
"Snowy是一款国内首例国产密码算法加密框架,采用Vue3.0+AntDesignVue3.0+SpringBoot2.8前后分离技术打造,技术框架与密码的结合,让前后分离‘密’不可分!</div>"
|
||||
]
|
||||
},
|
||||
{
|
||||
position: [116.33, 39.5],
|
||||
content: [
|
||||
"<div style='padding:0'><b>Snowy-小诺开源技术</b>",
|
||||
"网站 : https://www.xiaonuo.vip",
|
||||
"Snowy是一款国内首例国产密码算法加密框架,采用Vue3.0+AntDesignVue3.0+SpringBoot2.8前后分离技术打造,技术框架与密码的结合,让前后分离‘密’不可分!</div>"
|
||||
]
|
||||
}
|
||||
]
|
||||
)
|
||||
}
|
||||
|
||||
const handleMarkerClick = (position) => {
|
||||
map.value.openInfoWindow(position)
|
||||
|
||||
console.log('marker click', position)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
</style>
|
|
@ -1,130 +0,0 @@
|
|||
<template>
|
||||
<b-map ref="map" api-key="******" @complete="handleComplete"
|
||||
@marker-click="handleMarkerClick"></b-map>
|
||||
</template>
|
||||
|
||||
<script setup name="exmBMap">
|
||||
import BMap from '@/components/Map/bMap/index.vue'
|
||||
|
||||
const map = ref(null)
|
||||
|
||||
|
||||
const handleComplete = () => {
|
||||
console.log('complete')
|
||||
|
||||
// 点标记
|
||||
map.value.renderMarker(
|
||||
[
|
||||
{
|
||||
position: [116.39, 39.9],
|
||||
title: 'BI'
|
||||
},
|
||||
{
|
||||
position: [116.33, 39.5],
|
||||
title: 'BI-2'
|
||||
}
|
||||
]
|
||||
)
|
||||
// 图标点标记
|
||||
// map.value.renderIconMarker(
|
||||
// [
|
||||
// {
|
||||
// position: [116.39, 39.9],
|
||||
// title: 'BI',
|
||||
// img: 'https://webmap0.bdimg.com/image/api/bg.png',
|
||||
// imgWidth: 40,
|
||||
// imgHeight: 40
|
||||
// },
|
||||
// {
|
||||
// position: [116.33, 39.5],
|
||||
// title: 'BI-2',
|
||||
// img: 'https://webmap0.bdimg.com/image/api/bg.png'
|
||||
// }
|
||||
// ]
|
||||
// )
|
||||
// 3D圆点标记
|
||||
// map.value.render3DCircleMarker(
|
||||
// [
|
||||
// {
|
||||
// position: [116.39, 39.9],
|
||||
// height: 7000,
|
||||
// size: 40
|
||||
// },
|
||||
// {
|
||||
// position: [116.33, 39.5],
|
||||
// height: 7000,
|
||||
// size: 40
|
||||
// }
|
||||
// ]
|
||||
// )
|
||||
// 3D图标标记
|
||||
// map.value.render3DIconMarker(
|
||||
// [
|
||||
// {
|
||||
// position: [116.39, 39.9],
|
||||
// height: 7000,
|
||||
// size: 40,
|
||||
// img: 'https://webmap0.bdimg.com/image/api/bg.png',
|
||||
// imgWidth: 40,
|
||||
// imgHeight: 40
|
||||
// },
|
||||
// {
|
||||
// position: [116.33, 39.5],
|
||||
// height: 7000,
|
||||
// img: 'https://webmap0.bdimg.com/image/api/bg.png'
|
||||
// }
|
||||
// ]
|
||||
// )
|
||||
// 面
|
||||
// map.value.renderPolygon(
|
||||
// [
|
||||
// {
|
||||
// position: [116.39, 39.9]
|
||||
// },
|
||||
// {
|
||||
// position: [116.47, 39.8]
|
||||
// },
|
||||
// {
|
||||
// position: [116.46, 39.7]
|
||||
// },
|
||||
// {
|
||||
// position: [116.35, 39.6]
|
||||
// }
|
||||
// ]
|
||||
// )
|
||||
// 信息窗体
|
||||
map.value.renderInfoWindow(
|
||||
[
|
||||
{
|
||||
position: [116.39, 39.9],
|
||||
title: 'Snowy-小诺开源技术',
|
||||
content: [
|
||||
"<div style='padding:0'>",
|
||||
"网站 : https://www.xiaonuo.vip",
|
||||
"Snowy是一款国内首例国产密码算法加密框架,采用Vue3.0+AntDesignVue3.0+SpringBoot2.8前后分离技术打造,技术框架与密码的结合,让前后分离‘密’不可分!</div>"
|
||||
]
|
||||
},
|
||||
{
|
||||
position: [116.33, 39.5],
|
||||
title: 'Snowy-小诺开源技术',
|
||||
content: [
|
||||
"<div style='padding:0'>",
|
||||
"网站 : https://www.xiaonuo.vip",
|
||||
"Snowy是一款国内首例国产密码算法加密框架,采用Vue3.0+AntDesignVue3.0+SpringBoot2.8前后分离技术打造,技术框架与密码的结合,让前后分离‘密’不可分!</div>"
|
||||
],
|
||||
width: 300,
|
||||
height: 200
|
||||
}
|
||||
]
|
||||
)
|
||||
}
|
||||
|
||||
const handleMarkerClick = (position) => {
|
||||
map.value.openInfoWindow(position)
|
||||
|
||||
console.log('marker click', position)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
</style>
|
|
@ -0,0 +1,119 @@
|
|||
<template>
|
||||
<baidu-map ref="map" api-key="NtTydKuftIVXAy526uWXZoHS86lg0KeW" @complete="handleComplete" @marker-click="handleMarkerClick" />
|
||||
</template>
|
||||
|
||||
<script setup name="exmBaiduMap">
|
||||
import BaiduMap from '@/components/Map/baiduMap/index.vue'
|
||||
// 使用该组件请再百度地图官网注册,申请应用获得key
|
||||
const map = ref(null)
|
||||
|
||||
const handleComplete = () => {
|
||||
// 点标记
|
||||
// map.value.renderMarker(
|
||||
// [
|
||||
// {
|
||||
// position: [116.39, 39.9],
|
||||
// title: 'BI'
|
||||
// },
|
||||
// {
|
||||
// position: [116.33, 39.5],
|
||||
// title: 'BI-2'
|
||||
// }
|
||||
// ]
|
||||
// )
|
||||
// 图标点标记
|
||||
// map.value.renderIconMarker(
|
||||
// [
|
||||
// {
|
||||
// position: [116.39, 39.9],
|
||||
// title: 'BI',
|
||||
// img: 'https://webmap0.bdimg.com/image/api/bg.png',
|
||||
// imgWidth: 40,
|
||||
// imgHeight: 40
|
||||
// },
|
||||
// {
|
||||
// position: [116.33, 39.5],
|
||||
// title: 'BI-2',
|
||||
// img: 'https://webmap0.bdimg.com/image/api/bg.png'
|
||||
// }
|
||||
// ]
|
||||
// )
|
||||
// 3D圆点标记
|
||||
// map.value.render3DCircleMarker(
|
||||
// [
|
||||
// {
|
||||
// position: [116.39, 39.9],
|
||||
// height: 7000,
|
||||
// size: 40
|
||||
// },
|
||||
// {
|
||||
// position: [116.33, 39.5],
|
||||
// height: 7000,
|
||||
// size: 40
|
||||
// }
|
||||
// ]
|
||||
// )
|
||||
// 3D图标标记
|
||||
// map.value.render3DIconMarker(
|
||||
// [
|
||||
// {
|
||||
// position: [116.39, 39.9],
|
||||
// height: 7000,
|
||||
// size: 40,
|
||||
// img: 'https://webmap0.bdimg.com/image/api/bg.png',
|
||||
// imgWidth: 40,
|
||||
// imgHeight: 40
|
||||
// },
|
||||
// {
|
||||
// position: [116.33, 39.5],
|
||||
// height: 7000,
|
||||
// img: 'https://webmap0.bdimg.com/image/api/bg.png'
|
||||
// }
|
||||
// ]
|
||||
// )
|
||||
// 面
|
||||
// map.value.renderPolygon(
|
||||
// [
|
||||
// {
|
||||
// position: [116.39, 39.9]
|
||||
// },
|
||||
// {
|
||||
// position: [116.47, 39.8]
|
||||
// },
|
||||
// {
|
||||
// position: [116.46, 39.7]
|
||||
// },
|
||||
// {
|
||||
// position: [116.35, 39.6]
|
||||
// }
|
||||
// ]
|
||||
// )
|
||||
// 信息窗体
|
||||
map.value.renderInfoWindow([
|
||||
{
|
||||
position: [116.39, 39.9],
|
||||
title: 'Snowy-小诺开源技术',
|
||||
content: [
|
||||
"<div style='padding:0'>",
|
||||
'网站 : https://www.xiaonuo.vip',
|
||||
'Snowy是一款国内首例国产密码算法加密框架,采用Vue3.0+AntDesignVue3.0+SpringBoot2.8前后分离技术打造,技术框架与密码的结合,让前后分离‘密’不可分!</div>'
|
||||
]
|
||||
},
|
||||
{
|
||||
position: [116.33, 39.5],
|
||||
title: 'Snowy-小诺开源技术',
|
||||
content: [
|
||||
"<div style='padding:0'>",
|
||||
'网站 : https://www.xiaonuo.vip',
|
||||
'Snowy是一款国内首例国产密码算法加密框架,采用Vue3.0+AntDesignVue3.0+SpringBoot2.8前后分离技术打造,技术框架与密码的结合,让前后分离‘密’不可分!</div>'
|
||||
],
|
||||
width: 300,
|
||||
height: 200
|
||||
}
|
||||
])
|
||||
}
|
||||
|
||||
const handleMarkerClick = (position) => {
|
||||
map.value.openInfoWindow(position)
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,133 @@
|
|||
<template>
|
||||
<gaode-map ref="map" api-key="87528cfa68513cbc7574ff94704664fc" @complete="handleComplete" @marker-click="handleMarkerClick" />
|
||||
</template>
|
||||
|
||||
<script setup name="exmGaodeMap">
|
||||
import GaodeMap from '@/components/Map/gaodeMap/index.vue'
|
||||
// 使用该组件请再高德地图官网注册,申请应用获得key
|
||||
const map = ref(null)
|
||||
|
||||
const handleComplete = () => {
|
||||
// 点标记
|
||||
// map.value.renderMarker(
|
||||
// [
|
||||
// {
|
||||
// position: [116.39, 39.9],
|
||||
// title: 'TA',
|
||||
// content: 'CA',
|
||||
// label: {
|
||||
// content: 'LCA'
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// position: [116.33, 39.5],
|
||||
// title: 'TB',
|
||||
// icon: '//vdata.amap.com/icons/b18/1/2.png'
|
||||
// }
|
||||
// ]
|
||||
// )
|
||||
// 圆点标记
|
||||
// map.value.renderCircleMarker(
|
||||
// [
|
||||
// {
|
||||
// position: [116.39, 39.9],
|
||||
// radius: 30,
|
||||
// strokeColor: 'green',
|
||||
// fillColor: 'green'
|
||||
// },
|
||||
// {
|
||||
// position: [116.33, 39.5],
|
||||
// radius: 10,
|
||||
// strokeColor: 'orange',
|
||||
// fillColor: 'orange'
|
||||
// }
|
||||
// ]
|
||||
// )
|
||||
// 简单点标记
|
||||
// map.value.renderSimpleMarker(
|
||||
// [
|
||||
// {
|
||||
// position: [116.39, 39.9],
|
||||
// label: 'A',
|
||||
// labelStyle: {
|
||||
// color: '#333',
|
||||
// fontSize: '15px'
|
||||
// },
|
||||
// style: 'green'
|
||||
// },
|
||||
// {
|
||||
// position: [116.33, 39.5],
|
||||
// label: 'B',
|
||||
// labelStyle: {
|
||||
// color: '#555',
|
||||
// fontSize: '15px'
|
||||
// },
|
||||
// style: 'orange'
|
||||
// }
|
||||
// ]
|
||||
// )
|
||||
// 字体点标记
|
||||
// map.value.renderAwesomeMarker(
|
||||
// [
|
||||
// {
|
||||
// position: [116.39, 39.9],
|
||||
// awesomeIcon: 'address-book-o',
|
||||
// labelStyle: {
|
||||
// color: '#333',
|
||||
// fontSize: '15px'
|
||||
// },
|
||||
// style: 'green'
|
||||
// },
|
||||
// {
|
||||
// position: [116.33, 39.5],
|
||||
// awesomeIcon: 'anchor',
|
||||
// labelStyle: {
|
||||
// color: '#333',
|
||||
// fontSize: '15px'
|
||||
// },
|
||||
// style: 'orange'
|
||||
// }
|
||||
// ]
|
||||
// )
|
||||
// 面
|
||||
// map.value.renderPolygon(
|
||||
// [
|
||||
// {
|
||||
// position: [116.39, 39.9]
|
||||
// },
|
||||
// {
|
||||
// position: [116.47, 39.8]
|
||||
// },
|
||||
// {
|
||||
// position: [116.46, 39.7]
|
||||
// },
|
||||
// {
|
||||
// position: [116.35, 39.6]
|
||||
// }
|
||||
// ]
|
||||
// )
|
||||
// 信息窗体
|
||||
map.value.renderInfoWindow([
|
||||
{
|
||||
position: [116.39, 39.9],
|
||||
content: [
|
||||
"<div style='padding:0'><b>Snowy-小诺开源技术</b>",
|
||||
'网站 : https://www.xiaonuo.vip',
|
||||
'Snowy是一款国内首例国产密码算法加密框架,采用Vue3.0+AntDesignVue3.0+SpringBoot2.8前后分离技术打造,技术框架与密码的结合,让前后分离‘密’不可分!</div>'
|
||||
]
|
||||
},
|
||||
{
|
||||
position: [116.33, 39.5],
|
||||
content: [
|
||||
"<div style='padding:0'><b>Snowy-小诺开源技术</b>",
|
||||
'网站 : https://www.xiaonuo.vip',
|
||||
'Snowy是一款国内首例国产密码算法加密框架,采用Vue3.0+AntDesignVue3.0+SpringBoot2.8前后分离技术打造,技术框架与密码的结合,让前后分离‘密’不可分!</div>'
|
||||
]
|
||||
}
|
||||
])
|
||||
}
|
||||
|
||||
const handleMarkerClick = (position) => {
|
||||
map.value.openInfoWindow(position)
|
||||
}
|
||||
</script>
|
Loading…
Reference in New Issue