ui库和web端产品库合并版本(还需修复细节)
This commit is contained in:
257
ui/packages/tools/AiMap.vue
Normal file
257
ui/packages/tools/AiMap.vue
Normal file
@@ -0,0 +1,257 @@
|
||||
<template>
|
||||
<section class="AiMap" :class="{mask}">
|
||||
<div ref="amap" class="map"/>
|
||||
<div v-if="mask" class="mask"/>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AMapLoader from "@amap/amap-jsapi-loader";
|
||||
|
||||
export default {
|
||||
name: "AiMap",
|
||||
props: {
|
||||
plugins: {default: () => ['AMap.DistrictSearch', 'AMap.LineSearch']},
|
||||
map: Object,
|
||||
lib: Object,
|
||||
mapStyle: String,
|
||||
areaId: String,
|
||||
is3d: Boolean,
|
||||
ops: {default: () => ({})},
|
||||
markers: {default: () => []},
|
||||
mask: Boolean,
|
||||
searchBus: {default: "2"},
|
||||
pulseLines: Boolean,
|
||||
onlyShowArea: Boolean
|
||||
},
|
||||
computed: {
|
||||
viewMode() {
|
||||
return this.is3d ? '3D' : '2D'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
amap: null,
|
||||
mapLib: null,
|
||||
loca: null
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
markers: {
|
||||
deep: true, handler() {
|
||||
this.addMarkers()
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
initMap() {
|
||||
let {plugins, viewMode, mapStyle} = this
|
||||
AMapLoader.load({
|
||||
key: '54a02a43d9828a8f9cd4f26fe281e74e',
|
||||
version: '2.0',
|
||||
plugins,
|
||||
Loca: {version: '2.0.0'}
|
||||
}).then(AMap => {
|
||||
this.mapLib = AMap
|
||||
this.amap = new AMap.Map(this.$refs.amap, {
|
||||
mapStyle,
|
||||
viewMode,
|
||||
terrain: true,
|
||||
resizeEnable: true,
|
||||
skyColor: "#082243",
|
||||
zoom: 11,
|
||||
...this.ops
|
||||
})
|
||||
this.amap.on('complete', () => {
|
||||
this.amap.setFitView();//视口自适应
|
||||
})
|
||||
this.$emit('update:lib', AMap)
|
||||
this.$emit('update:map', this.amap)
|
||||
this.$emit("loaded")
|
||||
this.mapLoaded()
|
||||
})
|
||||
},
|
||||
getMapArea() {
|
||||
const {mapLib: AMap} = this
|
||||
if (!!AMap) {
|
||||
new AMap.DistrictSearch({
|
||||
subdistrict: 0, //获取边界不需要返回下级行政区
|
||||
extensions: 'all', //返回行政区边界坐标组等具体信息
|
||||
level: 'district' //查询行政级别为 市
|
||||
}).search(this.areaId.substring(0, 6), (status, result) => {
|
||||
const area = result?.districtList?.[0],
|
||||
bounds = area?.boundaries || [];
|
||||
let polygons = []
|
||||
if (this.onlyShowArea) {
|
||||
const mask = bounds.map(e => [e])
|
||||
polygons = bounds.map(path => new AMap.Polygon({
|
||||
path: path.map(e => [e.lng, e.lat]),
|
||||
strokeWeight: 1,
|
||||
fillOpacity: 0,
|
||||
strokeStyle: 'dashed',
|
||||
strokeColor: '#0091ea'
|
||||
}))
|
||||
this.amap.setMask(mask)
|
||||
this.amap.setPitch(65)
|
||||
} else {
|
||||
polygons = bounds.map(path => new AMap.Polygon({
|
||||
strokeWeight: 1,
|
||||
path: path.map(e => [e.lng, e.lat]),
|
||||
strokeStyle: 'dashed',
|
||||
fillOpacity: 0.1,
|
||||
fillColor: '#80d8ff',
|
||||
strokeColor: '#0091ea'
|
||||
}))
|
||||
}
|
||||
this.amap.add(polygons)
|
||||
this.amap.setCenter(area.center, true)
|
||||
})
|
||||
}
|
||||
},
|
||||
mapLoaded() {
|
||||
this.areaId && this.getMapArea()
|
||||
this.addPulseLines(this.areaId?.substring(0, 6))
|
||||
this.addMarkers()
|
||||
},
|
||||
addMarkers() {
|
||||
if (this.markers.length > 0 && this.mapLib && this.amap) {
|
||||
let markers = this.markers.map(e => {
|
||||
let {label, icon = "https://cdn.cunwuyun.cn/dvcp/h5/Location2.png"} = e
|
||||
return new this.mapLib.Marker({
|
||||
content: e.content || `<div class="marker">
|
||||
<img src="${icon}"/>
|
||||
<span>${label}</span>
|
||||
</div>`,
|
||||
position: [e.lng, e.lat]
|
||||
})
|
||||
})
|
||||
this.amap.add(markers)
|
||||
}
|
||||
},
|
||||
addPulseLines(city) {
|
||||
let {amap: map, mapLib: lib, pulseLines} = this
|
||||
if (pulseLines && lib && map) {
|
||||
this.loca = new Loca.Container({map: this.amap})
|
||||
let ls = new lib.LineSearch({pageSize: 1, pageNum: 1, city}), lines = {
|
||||
type: "FeatureCollection",
|
||||
features: []
|
||||
}
|
||||
Promise.all(Array.from("0123456789").map(i => new Promise((resolve) => {
|
||||
ls.search(i, (e, res) => {
|
||||
if (e == "complete" && res.info == "OK") {
|
||||
res.lineInfo?.map(line => {
|
||||
lines.features.push({
|
||||
type: "Feature",
|
||||
properties: {},
|
||||
geometry: {
|
||||
type: "LineString",
|
||||
coordinates: line.path?.map(p => [p.lng, p.lat]) || []
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
resolve()
|
||||
})
|
||||
}))).then(() => {
|
||||
let layer = new Loca.PulseLineLayer({
|
||||
zIndex: 10,
|
||||
opacity: 1,
|
||||
visible: true,
|
||||
zooms: [2, 22],
|
||||
})
|
||||
let geo = new Loca.GeoJSONSource({data: lines})
|
||||
layer.setSource(geo)
|
||||
layer.setStyle({
|
||||
altitude: 0,
|
||||
lineWidth: 2,
|
||||
// 脉冲头颜色
|
||||
headColor: "#B5FBFF",
|
||||
// 脉冲尾颜色
|
||||
trailColor: 'rgba(0,0,0,0)',
|
||||
// 脉冲长度,0.25 表示一段脉冲占整条路的 1/4
|
||||
interval: 0.25,
|
||||
// 脉冲线的速度,几秒钟跑完整段路
|
||||
duration: 15000,
|
||||
})
|
||||
this.loca.add(layer)
|
||||
this.loca.animate.start()
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.initMap()
|
||||
},
|
||||
destroyed() {
|
||||
this.amap?.destroy()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.AiMap {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
min-height: 0;
|
||||
position: relative;
|
||||
|
||||
&.mask {
|
||||
box-shadow: 0 0 40px 20px rgba(#000, .8);
|
||||
}
|
||||
|
||||
.map {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.mask {
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
z-index: 8;
|
||||
background: radial-gradient(rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, .6) 40%, #000 100%);
|
||||
}
|
||||
|
||||
::v-deep .marker {
|
||||
position: relative;
|
||||
|
||||
& > img {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
& > span {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&:hover > span {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
bottom: 0;
|
||||
transform: translate(-50%, 100%);
|
||||
display: block;
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
::v-deep .amap-logo, ::v-deep .amap-copyright {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
::v-deep .amap-icon {
|
||||
width: 40px !important;
|
||||
height: 40px !important;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user