ui库和web端产品库合并版本(还需修复细节)
This commit is contained in:
313
ui/packages/tools/AiQMap.vue
Normal file
313
ui/packages/tools/AiQMap.vue
Normal file
@@ -0,0 +1,313 @@
|
||||
<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;
|
||||
|
||||
::v-deep.map {
|
||||
height: 100%;
|
||||
|
||||
& > div > div {
|
||||
&:nth-of-type(2), &:nth-of-type(3) {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user