2022-11-29 18:27:14 +08:00
|
|
|
|
<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;
|
|
|
|
|
|
|
2022-12-01 09:35:20 +08:00
|
|
|
|
:deep(.map ){
|
2022-11-29 18:27:14 +08:00
|
|
|
|
height: 100%;
|
|
|
|
|
|
|
|
|
|
|
|
& > div > div {
|
|
|
|
|
|
&:nth-of-type(2), &:nth-of-type(3) {
|
|
|
|
|
|
display: none;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
</style>
|