ui库和web端产品库合并版本(还需修复细节)

This commit is contained in:
2022-11-29 18:27:14 +08:00
parent 5e4bd93238
commit 8bf6c57668
151 changed files with 28267 additions and 49 deletions

257
ui/packages/tools/AiMap.vue Normal file
View 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>