Files
dvcp_v2_webapp/ui/packages/tools/AiQMap.vue
2022-12-01 09:35:20 +08:00

314 lines
7.8 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<section class="AiTMap">
<div ref="tmap" class="map"/>
</section>
</template>
<script>
export default {
name: 'AiQMap',
props: {
areaId: String,
ops: {
default: () => {
return {}
}
},
libraries: {
default: () => ['service']
},
markerIcon: {
type: String
},
is3dAround: {
type: Boolean,
default: false
},
is3d: {
type: Boolean,
default: false
},
limitArea: {
type: Boolean,
default: false
},
map: Object,
lib: Object,
markers: {
type: Array,
default: () => []
}
},
watch: {
markers: {
handler (v) {
if (window.TMap && v.length) {
this.addMarkers(v)
}
},
deep: true,
immediate: true
}
},
data () {
return {
tmap: null,
mapLib: null,
marker: null,
keyframe: [
{
percentage: 0,
rotation: 0
},
{
percentage: 0.2,
rotation: 72
},
{
percentage: 0.4,
rotation: 144
},
{
percentage: 0.6,
rotation: 216
},
{
percentage: 0.8,
rotation: 288
},
{
percentage: 1,
rotation: 360
}
]
}
},
computed: {
key () {
return process.env.NODE_ENV == 'production' ? 'RWWBZ-64BEJ-MVLFJ-FTHLQ-JTR6J-SAB2S' : '3RZBZ-LZUCF-CT6J5-NWKZH-FCWOQ-UUFKY'
}
},
mounted () {
if (!window.TMap) {
window.initTMap = this.initTMap
this.injectLib(`https://map.qq.com/api/gljs?v=1.exp&key=${this.key}&libraries=${this.libraries.toString()}&callback=initTMap`)
} else {
this.initTMap()
}
},
methods: {
injectLib (url, cb) {
const script = document.createElement('script')
script.type = 'text/javascript'
script.id = 'aiqmap'
script.src = url
script.addEventListener('load', () => {
cb && cb()
})
document.body.appendChild(script)
},
setMarkersCenter () {
var bounds = new TMap.LatLngBounds()
this.markers.forEach(item => {
if (bounds.isEmpty() || !bounds.contains(new TMap.LatLng(item.lat, item.lng))) {
bounds.extend(new TMap.LatLng(item.lat, item.lng))
}
})
this.tmap.fitBounds(bounds, {
padding: 100
})
},
addMarkers (v) {
if (this.marker) {
this.marker.setMap(null)
}
this.marker = new TMap.MultiMarker({
id: 'markers',
map: this.tmap,
styles: {
marker: new TMap.MarkerStyle({
width: 25,
height: 35,
color: '#333',
size: 16,
offset: { x: 0, y: 8 },
anchor: { x: 17, y: 23 },
direction: 'bottom',
strokeWidth: 2,
src: this.markerIcon
})
},
geometries: v.map(v => {
return {
...v,
styleId: 'marker',
position: new TMap.LatLng(v.lat, v.lng)
}
})
})
this.setMarkersCenter()
this.marker.on('click', e => {
this.$emit('markerClick', e.geometry)
})
},
initTMap () {
this.mapLib = TMap
this.tmap = new TMap.Map(this.$refs.tmap, {
zoom: 11,
...this.ops,
viewMode: this.is3d ? '3d' : '2d',
pitch: this.is3d ? 40 : 0,
// mapStyleId: 'style1',
baseMap: this.limitArea ? [
{ type: 'vector', features: ['base'] },
{
type: 'traffic',
opacity: 1,
}
] : [
{ type: 'vector' },
],
renderOptions: {
enableBloom: true, // 是否启用泛光效果 注为true才会有效果
}
})
this.tmap.on('click', e => {
this.$emit('click', e)
})
if (this.markers.length) {
this.addMarkers(this.markers)
}
this.$emit('loaded')
this.$emit('update:lib', TMap)
this.$emit('update:map', this.tmap)
this.areaId && this.getMapArea()
},
getMapArea () {
let {mapLib, areaId, tmap: map} = this, keyword = areaId.substring(0, 6)
const fitBounds = latLngList => {
if (latLngList.length === 0) {
return null
}
let boundsN = latLngList[0].getLat()
let boundsS = boundsN
let boundsW = latLngList[0].getLng()
let boundsE = boundsW
latLngList.forEach((point) => {
point.getLat() > boundsN && (boundsN = point.getLat())
point.getLat() < boundsS && (boundsS = point.getLat())
point.getLng() > boundsE && (boundsE = point.getLng())
point.getLng() < boundsW && (boundsW = point.getLng())
})
return new TMap.LatLngBounds(
new TMap.LatLng(boundsS, boundsW),
new TMap.LatLng(boundsN, boundsE)
)
}
if (!this.limitArea) return
let polygons = new TMap.MultiPolygon({map, geometries: []})
new mapLib.service.District({
polygon: 2,
maxOffset: 100
}).search({keyword}).then(res => {
if (res?.result) {
console.log(res.result[0][0].polygon)
let center = res.result[0][0].location
this.tmap.enableAreaHighlight({
paths: res.result[0][0].polygon,
highlightColor: 'rgba(0,0,0,0)',
shadeColor: 'rgba(0,0,0,1)'
})
this.tmap.setCenter(center)
new TMap.MultiPolyline({
map: this.tmap,
styles: {
polyline: new TMap.PolylineStyle({
color: '#017cf7', // 线条填充色,
width: 8,
lineCap: 'round',
enableBloom: true, // 是否启用泛光 注为true才会有效果
}),
},
geometries: [
{
styleId: 'polyline', // 样式id
paths: res.result[0][0].polygon
}
]
})
res.result.forEach((level) => {
level.forEach((place) => {
let bounds = []
let newGeometries = place.polygon.map((polygon, index) => {
bounds.push(fitBounds(polygon))
return {
id: `${place.id}_${index}`,
paths: polygon
}
})
bounds = bounds.reduce((a, b) => {
return fitBounds([
a.getNorthEast(),
a.getSouthWest(),
b.getNorthEast(),
b.getSouthWest()
])
})
// polygons.updateGeometries(newGeometries)
this.tmap.fitBounds(bounds)
})
})
setTimeout(() => {
this.is3dAround && this.tmap.startAnimation(this.keyframe, {
duration: 16000,
loop: Infinity
})
}, 600)
}
})
}
},
destroyed () {
this.tmap.destroy()
}
}
</script>
<style lang="scss" scoped>
.AiTMap {
width: 100%;
height: 100%;
flex: 1;
min-width: 0;
min-height: 0;
:deep(.map ){
height: 100%;
& > div > div {
&:nth-of-type(2), &:nth-of-type(3) {
display: none;
}
}
}
}
</style>