This commit is contained in:
TimSpan 2024-10-16 15:02:31 +08:00
parent 4e714f4c60
commit aca5e39d18
7 changed files with 320 additions and 104 deletions

1
.gitignore vendored
View File

@ -10,6 +10,7 @@ target/
*.ipr *.ipr
### VS Code ### ### VS Code ###
public/roadmap
*.log *.log
npm-debug.log* npm-debug.log*
yarn-debug.log* yarn-debug.log*

9
package-lock.json generated
View File

@ -38,6 +38,7 @@
"js-md5": "^0.8.3", "js-md5": "^0.8.3",
"jwt-decode": "^3.1.2", "jwt-decode": "^3.1.2",
"leaflet": "^1.9.4", "leaflet": "^1.9.4",
"leaflet.markercluster": "^1.5.3",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"nprogress": "^0.2.0", "nprogress": "^0.2.0",
@ -3035,6 +3036,14 @@
"resolved": "https://registry.npmmirror.com/leaflet/-/leaflet-1.9.4.tgz", "resolved": "https://registry.npmmirror.com/leaflet/-/leaflet-1.9.4.tgz",
"integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==" "integrity": "sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA=="
}, },
"node_modules/leaflet.markercluster": {
"version": "1.5.3",
"resolved": "https://registry.npmmirror.com/leaflet.markercluster/-/leaflet.markercluster-1.5.3.tgz",
"integrity": "sha512-vPTw/Bndq7eQHjLBVlWpnGeLa3t+3zGiuM7fJwCkiMFq+nmRuG3RI3f7f4N4TDX7T4NpbAXpR2+NTRSEGfCSeA==",
"peerDependencies": {
"leaflet": "^1.3.1"
}
},
"node_modules/less": { "node_modules/less": {
"version": "4.2.0", "version": "4.2.0",
"resolved": "https://registry.npmjs.org/less/-/less-4.2.0.tgz", "resolved": "https://registry.npmjs.org/less/-/less-4.2.0.tgz",

View File

@ -46,6 +46,7 @@
"js-md5": "^0.8.3", "js-md5": "^0.8.3",
"jwt-decode": "^3.1.2", "jwt-decode": "^3.1.2",
"leaflet": "^1.9.4", "leaflet": "^1.9.4",
"leaflet.markercluster": "^1.5.3",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",
"nprogress": "^0.2.0", "nprogress": "^0.2.0",

View File

@ -11,7 +11,7 @@ import lodasha from 'lodash';
import ElementPlus from 'element-plus' import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css' import 'element-plus/dist/index.css'
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'; import zhCn from 'element-plus/dist/locale/zh-cn.mjs';
// import '@types/leaflet'
// 高德地图typescript支持 // 高德地图typescript支持
import "@amap/amap-jsapi-types"; import "@amap/amap-jsapi-types";
// vue Router // vue Router
@ -35,8 +35,8 @@ import "@/assets/iconfont/iconfont.css";
//自定义指令 //自定义指令
import vCopy from "@/directives/copy"; import vCopy from "@/directives/copy";
const vueApp = createApp(App); const vueApp = createApp(App);
vueApp.config.globalProperties.day=dayjs//全局挂载 vueApp.config.globalProperties.day = dayjs//全局挂载
vueApp.config.globalProperties.lodash=lodasha//全局挂载 vueApp.config.globalProperties.lodash = lodasha//全局挂载
vueApp.directive('copy', vCopy) vueApp.directive('copy', vCopy)
import * as ElementPlusIconsVue from '@element-plus/icons-vue' import * as ElementPlusIconsVue from '@element-plus/icons-vue'

View File

@ -1 +0,0 @@
declare module 'leaflet';

View File

@ -370,8 +370,13 @@
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
// import L, {Marker} from 'leaflet'
// import * as Leaf from 'leaflet'
import L from 'leaflet' import L from 'leaflet'
import 'leaflet/dist/leaflet.css' import 'leaflet/dist/leaflet.css'
import 'leaflet.markercluster'
import 'leaflet.markercluster/dist/MarkerCluster.Default.css'
import {JsonResult} from '@/axios' import {JsonResult} from '@/axios'
import * as _ from 'lodash' import * as _ from 'lodash'
import api from '@/axios' import api from '@/axios'
@ -690,7 +695,7 @@ onMounted(() => {
getAi() getAi()
getjingqing() getjingqing()
}) })
// let deviceInfoWindow = ref<any>(null)
const treedata = () => { const treedata = () => {
api api
.post('/multialarm/client/alarm_point/count', { .post('/multialarm/client/alarm_point/count', {
@ -706,67 +711,85 @@ const treedata = () => {
pagesize: res1.data.count pagesize: res1.data.count
}) })
.then((res: JsonResult<any>) => { .then((res: JsonResult<any>) => {
var points: any[] = [] const points: L.Marker[] = []
res.data.map((x: any) => { // MarkerClusterGroup
const marker = new AMap.Marker({ //@ts-ignore
position: new AMap.LngLat(x.longitude == null ? 0 : x.longitude, x.latitude == null ? 0 : x.latitude), const markers = L.markerClusterGroup({
offset: new AMap.Pixel(-15, -15), maxClusterRadius: 80, //
icon: new AMap.Icon({ iconCreateFunction: (cluster: any) => {
image: x.deviceType == '00' ? image3 : x.deviceType == '03' ? image1 : x.deviceType == '04' ? image2 : '', //
size: new AMap.Size(40, 46.5), const count = cluster.getChildCount()
imageSize: new AMap.Size(30, 30) // const factor = Math.pow(count / res.data.length, 1 / 18)
const size = Math.round(30 + Math.pow(count / res.data.length, 1 / 5) * 2)
const hue = 180 - factor * 180
const div = document.createElement('div')
div.style.backgroundColor = `hsla(${hue}, 100%, 50%, 0.7)`
div.style.width = div.style.height = `${size}px`
div.style.border = `solid 1px hsla(${hue}, 100%, 40%, 1)`
div.style.borderRadius = `${size / 2}px`
div.style.boxShadow = `0 0 1px hsla(${hue}, 100%, 50%, 1)`
div.innerHTML = count.toString()
div.style.lineHeight = `${size}px`
div.style.color = `hsla(${hue}, 100%, 20%, 1)`
div.style.fontSize = '14px'
div.style.textAlign = 'center'
// Leaflet divIcon
return L.divIcon({
html: div,
className: 'custom-cluster-icon',
iconSize: L.point(size, size)
})
}
})
//
res.data.forEach((x: any) => {
const lat = x.latitude ?? 0
const lng = x.longitude ?? 0
const iconUrl = x.deviceType === '00' ? image3 : x.deviceType === '03' ? image1 : x.deviceType === '04' ? image2 : ''
const marker = L.marker([lat, lng], {
icon: L.icon({
iconUrl,
iconSize: [30, 30],
iconAnchor: [15, 15]
}), }),
title: '' title: ''
}) })
marker.on('click', function () {
deviceInfoWindow.value = new AMap.InfoWindow({ //
isCustom: true, //使 marker.on('click', () => {
content: createSubstanceInfowindow2(x, '1'), console.log('deviceInfoWindow.value', deviceInfoWindow.value)
offset: new AMap.Pixel(5, -13) if (deviceInfoWindow.value) {
}) deviceInfoWindow.value.remove()
deviceInfoWindow.value.open(state.map, [x.longitude == null ? 0 : x.longitude, x.latitude == null ? 0 : x.latitude])
})
state.map.add(marker)
points.push(marker)
})
var count = points.length
//
var _renderClusterMarker = function (context: any) {
var factor = Math.pow(context.count / count, 1 / 18)
var div = document.createElement('div')
var Hue = 180 - factor * 180
var bgColor = 'hsla(' + Hue + ',100%,50%,0.7)'
var fontColor = 'hsla(' + Hue + ',100%,20%,1)'
var borderColor = 'hsla(' + Hue + ',100%,40%,1)'
var shadowColor = 'hsla(' + Hue + ',100%,50%,1)'
div.style.backgroundColor = bgColor
var size = Math.round(30 + Math.pow(context.count / count, 1 / 5) * 2)
div.style.width = div.style.height = size + 'px'
div.style.border = 'solid 1px ' + borderColor
div.style.borderRadius = size / 2 + 'px'
div.style.boxShadow = '0 0 1px ' + shadowColor
div.innerHTML = context.count
div.style.lineHeight = size + 'px'
div.style.color = fontColor
div.style.fontSize = '14px'
div.style.textAlign = 'center'
context.marker.setOffset(new AMap.Pixel(-size / 2, -size / 2))
context.marker.setContent(div)
} }
var cluster = new AMap.MarkerClusterer(state.map, points, { deviceInfoWindow.value = L.popup({
gridSize: 80, closeButton: false
maxZoom: 12,
renderClusterMarker: _renderClusterMarker
}) })
state.map.plugin(['AMap.MarkerClusterer'], () => { .setLatLng([lat, lng])
let zoom = state.map.getZoom() .setContent(createSubstanceInfowindow2(x, '1'))
.openOn(state.map)
})
points.push(marker)
markers.addLayer(marker) //
})
//
state.map.addLayer(markers)
//
state.map.on('zoomend', () => {
const zoom = state.map.getZoom()
console.log('当前地图的缩放级别是:' + zoom) console.log('当前地图的缩放级别是:' + zoom)
cluster
}) })
}) })
}) })
} }
// //
const jinbao = ref([]) const jinbao = ref([])
const getdayline = () => { const getdayline = () => {
@ -784,49 +807,56 @@ const getdayline = () => {
jinbao.value = res.data jinbao.value = res.data
if (res.data.length > 0) { if (res.data.length > 0) {
res.data.map((x: any) => { res.data.map((x: any) => {
const lat = x.latitude ?? 0
const lng = x.longitude ?? 0
if (x.state == 'close') { if (x.state == 'close') {
const marker = new AMap.Marker({ const marker = L.marker([lat, lng], {
position: new AMap.LngLat(x.longitude == null ? 0 : x.longitude, x.latitude == null ? 0 : x.latitude), icon: L.icon({
offset: new AMap.Pixel(-10, -10), iconUrl: yes,
icon: new AMap.Icon({ iconSize: [30, 30],
image: yes, iconAnchor: [15, 15]
size: new AMap.Size(40, 46.5),
imageSize: new AMap.Size(40, 46.5) //
}), }),
title: '' title: ''
}) })
marker.on('click', function () {
deviceInfoWindow.value = new AMap.InfoWindow({ //
isCustom: true, //使 marker.on('click', () => {
content: createSubstanceInfowindow(x, '1'), if (deviceInfoWindow.value) {
offset: new AMap.Pixel(5, -13) deviceInfoWindow.value.remove()
}
deviceInfoWindow.value = L.popup({
closeButton: false
}) })
deviceInfoWindow.value.open(state.map, [x.longitude == null ? 0 : x.longitude, x.latitude == null ? 0 : x.latitude]) .setLatLng([lat, lng])
.setContent(createSubstanceInfowindow(x, '1'))
.openOn(state.map)
}) })
state.map.add(marker) // marker
marker.addTo(state.map)
} else { } else {
const marker = new AMap.Marker({
position: new AMap.LngLat(x.longitude == null ? 0 : x.longitude, x.latitude == null ? 0 : x.latitude), // const marker = new AMap.Marker({
offset: new AMap.Pixel(-20, -10), // position: new AMap.LngLat(x.longitude == null ? 0 : x.longitude, x.latitude == null ? 0 : x.latitude),
content: `<div class="indexMarkerImg"> // offset: new AMap.Pixel(-20, -10),
<img style="width:30px;height:30px;left:9px;top:7px" src='${no}'> // content: `<div class="indexMarkerImg">
<div class="markerClass"> // <img style="width:30px;height:30px;left:9px;top:7px" src='${no}'>
<div></div> // <div class="markerClass">
<div></div> // <div></div>
<div></div> // <div></div>
</div> // <div></div>
</div>`, // </div>
title: '' // </div>`,
}) // title: ''
marker.on('click', function () { // })
deviceInfoWindow.value = new AMap.InfoWindow({ // marker.on('click', function () {
isCustom: true, //使 // deviceInfoWindow.value = new AMap.InfoWindow({
content: createSubstanceInfowindow1(x, '1'), // isCustom: true, //使
offset: new AMap.Pixel(5, -13) // content: createSubstanceInfowindow1(x, '1'),
}) // offset: new AMap.Pixel(5, -13)
deviceInfoWindow.value.open(state.map, [x.longitude == null ? 0 : x.longitude, x.latitude == null ? 0 : x.latitude]) // })
}) // deviceInfoWindow.value.open(state.map, [x.longitude == null ? 0 : x.longitude, x.latitude == null ? 0 : x.latitude])
state.map.add(marker) // })
// state.map.add(marker)
} }
}) })
} }
@ -886,21 +916,35 @@ const gettotal = () => {
}) })
} }
// //
let deviceInfoWindow = ref<any>()
const selectA = (selectedKeys: any, e: any) => { const selectA = (selectedKeys: any, e: any) => {
// if (selectedKeys[0].length >= 13) {
try {
console.log('selectedKeys', selectedKeys, e) console.log('selectedKeys', selectedKeys, e)
if (selectedKeys[0].length >= 13) { let targetLatLngt = [e.selectedNodes[0].latitude == null ? 0 : e.selectedNodes[0].latitude, e.selectedNodes[0].longitude == null ? 0 : e.selectedNodes[0].longitude]
let targetLangLat = [e.selectedNodes[0].longitude == null ? 0 : e.selectedNodes[0].longitude, e.selectedNodes[0].latitude == null ? 0 : e.selectedNodes[0].latitude] console.log('targetLangLat', targetLatLngt)
//
deviceInfoWindow.value = new AMap.InfoWindow({ const popupContent = createSubstanceInfowindow2(e.selectedNodes[0], '1')
isCustom: true, //使 const lat = e.selectedNodes[0].latitude ?? 0
content: createSubstanceInfowindow2(e.selectedNodes[0], '1'), const lng = e.selectedNodes[0].longitude ?? 0
offset: new AMap.Pixel(5, -13) if (deviceInfoWindow.value) {
}) deviceInfoWindow.value.remove()
deviceInfoWindow.value.open(state.map, [e.selectedNodes[0].longitude == null ? 0 : e.selectedNodes[0].longitude, e.selectedNodes[0].latitude == null ? 0 : e.selectedNodes[0].latitude])
state.map.setZoomAndCenter(205, targetLangLat)
} }
deviceInfoWindow.value = L.popup({
closeButton: false
})
.setLatLng([lat, lng])
.setContent(popupContent)
.openOn(state.map)
// setView(<LatLng> center, <Number> zoom, <Zoom/pan options> options?) LatLngLat
state.map.setView(targetLatLngt, 15)
} catch (error) {
console.log('🚀 ~ selectA ~ error:', error)
}
// state.map.setZoomAndCenter(205, targetLangLat)
// }
} }
const createSubstanceInfowindow = (obj: any, type: any) => { const createSubstanceInfowindow = (obj: any, type: any) => {
@ -917,7 +961,11 @@ const createSubstanceInfowindow = (obj: any, type: any) => {
var closeX = document.createElement('img') var closeX = document.createElement('img')
closeX.src = closeimag closeX.src = closeimag
closeX.onclick = () => { closeX.onclick = () => {
deviceInfoWindow.value.close() //
if (deviceInfoWindow.value) {
deviceInfoWindow.value.remove() //
deviceInfoWindow.value = null //
}
} }
var popMian = document.createElement('div') var popMian = document.createElement('div')
@ -948,7 +996,11 @@ const createSubstanceInfowindow1 = (obj: any, type: any) => {
var closeX = document.createElement('img') var closeX = document.createElement('img')
closeX.src = closeimag closeX.src = closeimag
closeX.onclick = () => { closeX.onclick = () => {
deviceInfoWindow.value.close() //
if (deviceInfoWindow.value) {
deviceInfoWindow.value.remove() //
deviceInfoWindow.value = null //
}
} }
var popMian = document.createElement('div') var popMian = document.createElement('div')
@ -979,7 +1031,17 @@ const createSubstanceInfowindow2 = (obj: any, type: any) => {
var closeX = document.createElement('img') var closeX = document.createElement('img')
closeX.src = closeimag closeX.src = closeimag
closeX.onclick = () => { closeX.onclick = () => {
deviceInfoWindow.value.close() //
try {
console.log('deviceInfoWindow.value', deviceInfoWindow.value)
if (deviceInfoWindow.value) {
deviceInfoWindow.value.remove() //
deviceInfoWindow.value = null //
}
} catch (error) {
console.log('🚀 ~ createSubstanceInfowindow2 ~ error:', error)
}
} }
var popMian = document.createElement('div') var popMian = document.createElement('div')
@ -1917,4 +1979,145 @@ iframe {
border-radius: 5px; border-radius: 5px;
// padding-top: 20px; // padding-top: 20px;
} }
//
:deep(.leaflet-popup-content-wrapper) {
// background: #07315e !important;
background: none;
box-shadow: none;
width: 500px;
color: #fff !important;
font-size: 14px;
padding: none;
}
:deep(.leaflet-popup-content) {
width: calc(100% - 40px) !important;
}
:deep(.leaflet-popup-content > div) {
width: 100%;
}
:deep(.leaflet-popup-content .sb_bInfo) {
width: 100%;
}
:deep(.leaflet-popup-content p) {
margin: 10px 0 !important;
}
:deep(.sb_grade > div > div) {
float: left;
width: 16%;
margin-top: 3px;
}
:deep(.sb_grade > div > div > p) {
line-height: 20px;
}
:deep(.schoolWindowInfo .sb_grade) {
margin-top: 10px;
}
:deep(.leaflet-popup-content-wrapper),
:deep(.leaflet-popup-tip) {
background: none !important;
}
:deep(.leaflet-popup-close-button) {
color: #fff !important;
width: 30px !important;
height: 30px !important;
font-size: 30px !important;
}
:deep(.warnEventInfoWindow) {
overflow: hidden;
}
:deep(.warnEventInfoWindow > p) {
float: left;
width: 120px;
}
:deep(.warnEventInfoWindow > div) {
float: left;
width: calc(100% - 130px);
margin-left: 10px;
}
:deep(.warnEventInfoWindow > p > img) {
width: 100%;
}
//
// :deep(.leaflet-popup-content-wrapper) {
// background: #07315e !important;
// width: 500px;
// color: #fff !important;
// font-size: 14px;
// }
// :deep(.leaflet-popup-content) {
// width: calc(100% - 40px) !important;
// }
// :deep(.leaflet-popup-content > div) {
// width: 100%;
// }
// :deep(.leaflet-popup-content .sb_bInfo) {
// width: 100%;
// }
// :deep(.leaflet-popup-content p) {
// margin: 10px 0 !important;
// }
// :deep(.sb_grade > div > div) {
// float: left;
// width: 16%;
// margin-top: 3px;
// }
// :deep(.sb_grade > div > div > p) {
// line-height: 20px;
// }
// :deep(.schoolWindowInfo .sb_grade) {
// margin-top: 10px;
// }
// :deep(.leaflet-popup-content-wrapper),
// :deep(.leaflet-popup-tip) {
// background: #07315e !important;
// }
// :deep(.leaflet-popup-close-button) {
// color: #fff !important;
// width: 30px !important;
// height: 30px !important;
// font-size: 30px !important;
// }
// :deep(.warnEventInfoWindow) {
// overflow: hidden;
// }
// :deep(.warnEventInfoWindow > p) {
// float: left;
// width: 120px;
// }
// :deep(.warnEventInfoWindow > div) {
// float: left;
// width: calc(100% - 130px);
// margin-left: 10px;
// }
// :deep(.warnEventInfoWindow > p > img) {
// width: 100%;
// }
</style> </style>

View File

@ -1,5 +1,8 @@
{ {
"compilerOptions": { "compilerOptions": {
// "types": [
// "leaflet"
// ],
"target": "ESNext", "target": "ESNext",
"useDefineForClassFields": true, "useDefineForClassFields": true,
"module": "ESNext", "module": "ESNext",