| | |
| | | const store = useStore(); |
| | | const userAreaCode = computed(() => store.state.user.userInfo.detail.areaCode); |
| | | const selectedAreaCode = computed(() => store.state.user.selectedAreaCode); |
| | | const listenerHeight = () => { |
| | | determineScaling(); |
| | | viewer.camera.moveEnd.addEventListener(determineScaling); |
| | | }; |
| | | |
| | | |
| | | // 确定缩放比例 |
| | | const determineScaling = index => { |
| | | console.log('确定缩放比例'); |
| | | const determineScaling = () => { |
| | | // console.log('确定缩放比例'); |
| | | if (!viewer) return; |
| | | let height = viewer.camera.positionCartographic.height; |
| | | // 根据高度展示对应的 gJson |
| | |
| | | active = item.name; |
| | | removeEntities(); |
| | | removeLabel(); |
| | | item.gJson ? aggregation(item) : splashed(item); |
| | | renderOutline(item); |
| | | if (!item.gJson && !item.splashedList?.length) return; |
| | | item.gJson ? aggregation(item) : splashed(item); |
| | | break; |
| | | } |
| | | } |
| | | }; |
| | | |
| | | // 转换为目录结构, 返回数组, |
| | | function convertToHierarchy(code) { |
| | | const codeStr = code.toString(); |
| | | const provinceCode = codeStr.slice(0, 2) + '0000'; |
| | |
| | | return [provinceCode, cityCode, code]; |
| | | } |
| | | |
| | | // 获取设备聚合 |
| | | function getDeviceCount(areaCode) { |
| | | return getDeviceRegionCount({ areaCode }).then(res => { |
| | | return (res?.data?.data || []).map(i=>({...i,type:'deviceAggregation'})); |
| | | return (res?.data?.data || []) |
| | | }); |
| | | } |
| | | |
| | | // 获取设备散点 |
| | | function getDeviceList(areaCode) { |
| | | return getDeviceRegion({ areaCode }).then(res => { |
| | | return (res?.data?.data || []).map(i =>({...i,type})); |
| | | }); |
| | | } |
| | | |
| | | // 事件散点 |
| | | let eventList = [] |
| | | function processChildren(childrens) { |
| | | return (childrens || []).map(item => { |
| | |
| | | total_device_count: item.number, |
| | | region_code: item.id, |
| | | region_name: item.name, |
| | | type:'eventAggregation' |
| | | }; |
| | | if (arr.length !== 0) { |
| | | returnObj.childrens = arr; |
| | |
| | | }); |
| | | } |
| | | |
| | | // 获取事件聚合 |
| | | function getMapEventCount(areaCode) { |
| | | return getMapEvents({ areaCode }).then(res => { |
| | | const resData= res?.data?.data |
| | |
| | | const injectData = (gJson, dataList) => { |
| | | return { |
| | | ...gJson, |
| | | features: gJson.features.map(item => ({ ...item, data: dataList.find(item1 => findFun(item1, item)) })), |
| | | features: gJson.features.map(item => { |
| | | const findData = dataList.find(item1 => findFun(item1, item)) |
| | | return { ...item, data: {...findData,type: type + 'Aggregation'} } |
| | | }), |
| | | }; |
| | | }; |
| | | |
| | |
| | | const splashedList = type === 'device' |
| | | ? await getDeviceList(areaCode) |
| | | : eventList.map(i=>({eventId:i.id,latitude:Number(i.latitude),longitude:Number(i.longitude),type:'event'})) |
| | | console.log(list, 'list'); |
| | | console.log(splashedList, 'splashedList'); |
| | | const hierarchy = convertToHierarchy(areaCode.slice(0, 6)); |
| | | const jsonPath = hierarchy.join('/'); |
| | | const jsonPathPre = hierarchy.slice(0, hierarchy.length - 1).join('/'); |
| | |
| | | scalingJudgment[0].gJson = null; |
| | | scalingJudgment[0].splashedList = splashedList; |
| | | active = null; |
| | | // 轮廓 |
| | | const outlineGJson = await getOutLine(jsonPathPre, hierarchy); |
| | | scalingJudgment.forEach(item => item.show && (item.outline = outlineGJson)); |
| | | // 省 |
| | | if (hierarchy.length === 1) { |
| | | const gJson1 = await getFiler(`${defaultDir}${jsonPath}/indexDistrict.json`); |
| | | const gJson2 = await getFiler(`${defaultDir}${jsonPath}/index.json`); |
| | | scalingJudgment[1].gJson = { |
| | | ...gJson1, |
| | | features: gJson1.features.map(item => ({ |
| | | ...item, |
| | | data: list.flatMap(item => item.childrens || []).find(item1 => findFun(item1, item)), |
| | | })), |
| | | features: gJson1.features.map(item => { |
| | | const findData = list.flatMap(item => item.childrens || []).find(item1 => findFun(item1, item)) |
| | | return { ...item, data: {...findData,type: type + 'Aggregation'} } |
| | | }), |
| | | }; |
| | | scalingJudgment[2].gJson = injectData(gJson2, list); |
| | | const { lng, lat } = getCenterPoint(gJson2.features.map(item => item.properties.center)); |
| | | flyTo({ longitude: lng, latitude: lat }, 0, scalingJudgment[2].height); |
| | | } |
| | | // 市 |
| | | if (hierarchy.length === 2) { |
| | |
| | | scalingJudgment[2].show = false; |
| | | const gJson1 = await getFiler(`${defaultDir}${jsonPath}/index.json`); |
| | | scalingJudgment[1].gJson = injectData(gJson1, list); |
| | | const center = getCenterPoint(gJson1.features.map(item => item.properties.center)); |
| | | flyTo({ longitude: center.lng, latitude: center.lat }, 0, scalingJudgment[1].height); |
| | | } |
| | | // 区县 |
| | | if (hierarchy.length === 3) { |
| | |
| | | scalingJudgment[1].show = false; |
| | | scalingJudgment[2].gJson = null; |
| | | scalingJudgment[2].show = false; |
| | | const outlineGJson = await getOutLine(jsonPathPre, hierarchy); |
| | | const center = outlineGJson.features[0].properties.center; |
| | | flyTo({ longitude: center[0], latitude: center[1] }, 0, scalingJudgment[0].height); |
| | | } |
| | | determineScaling() |
| | | // 轮廓 |
| | | const outlineGJson = await getOutLine(jsonPathPre, hierarchy); |
| | | scalingJudgment.forEach(item => item.show && (item.outline = outlineGJson)); |
| | | const [longitude,latitude] = outlineGJson.features[0].properties.centroid |
| | | flyTo({ longitude, latitude }, 0, scalingJudgment[(hierarchy.length-3) * (-1)].height); |
| | | }; |
| | | |
| | | watch( |
| | | selectedAreaCode, |
| | | async (newValue, oldValue) => { |
| | | initMapData(newValue); |
| | | if (!viewer) return |
| | | viewer.scene.postRender.removeEventListener(determineScaling) |
| | | initMapData(newValue).then(()=>{ |
| | | viewer.scene.postRender.addEventListener(determineScaling) |
| | | }) |
| | | }, |
| | | { deep: true } |
| | | ); |
| | | |
| | | //散点机巢 |
| | | function splashed(row) { |
| | | row.splashedList.forEach(item => { |
| | | row.splashedList.forEach((item,index) => { |
| | | viewer.entities.add({ |
| | | id: `aggregation-splashed-${index}`, |
| | | position: Cesium.Cartesian3.fromDegrees(item.longitude, item.latitude), |
| | | label: { |
| | | // 随机整数 |
| | |
| | | // 聚合机巢 |
| | | const aggregation = (item, flyTo) => { |
| | | if (!item.gJson) return; |
| | | const featuresList = item.gJson.features.map(item => ({ |
| | | name: item.properties.name, |
| | | position: item.properties.center, |
| | | data: item.data, |
| | | id: item.region_code, |
| | | })); |
| | | const featuresList = item.gJson.features.map(item1 => { |
| | | // const {lng,lat} = getCenterPoint(item1.geometry.coordinates[0][0]) |
| | | return { |
| | | name: item1.properties.name, |
| | | position: item1.properties.centroid, |
| | | data: item1.data, |
| | | id: item1.region_code, |
| | | } |
| | | }); |
| | | // 遍历特征并添加实体 |
| | | featuresList.forEach(feature => { |
| | | featuresList.forEach((feature,index) => { |
| | | if (!feature.position) return; |
| | | const position = Cesium.Cartesian3.fromDegrees(feature.position[0], feature.position[1]); |
| | | viewer.entities.add({ |
| | | position: position, |
| | | id: `aggregation-name-${index}`, |
| | | label: { |
| | | text: feature.name, |
| | | font: '14pt Source Han Sans CN', |
| | |
| | | }, |
| | | }); |
| | | viewer.entities.add({ |
| | | id: feature.id, |
| | | id: `aggregation-count-${index}`, |
| | | position: position, |
| | | label: { |
| | | text: feature.data.total_device_count.toString(), |
| | | text: (feature.data.total_device_count || 0).toString(), |
| | | font: '12pt Source Han Sans CN', |
| | | fillColor: Cesium.Color.BLACK, |
| | | outlineColor: Cesium.Color.BLACK, |
| | | style: Cesium.LabelStyle.FILL_AND_OUTLINE, |
| | | eyeOffset: new Cesium.Cartesian3(0, 0, -10), // 让label "浮" 在广告牌前面 |
| | | }, |
| | |
| | | if (!positionC3) return; |
| | | removeLabel(); |
| | | const customData = entity.properties.customData._value.data; |
| | | |
| | | console.log('customData', customData); |
| | | switch (customData.type) { |
| | | case 'deviceAggregation': |
| | | viewer.scene.postRender.addEventListener(labelBoxRender); |
| | |
| | | // 移除 点 和 gjson 实体 |
| | | const removeEntities = () => { |
| | | viewer.dataSources?.removeAll(true); |
| | | viewer.entities?.removeAll(); |
| | | // viewer.entities?.removeAll(); |
| | | const entitiesIDs = viewer.entities.values.map(i=>i.id) |
| | | entitiesIDs.forEach(item => { |
| | | item.includes('aggregation-') && viewer.entities.removeById(item) |
| | | }) |
| | | }; |
| | | // 移除弹框标签 |
| | | const removeLabel = () => { |
| | |
| | | |
| | | // 移除所有监听事件,变量置空 |
| | | const removeAll = () => { |
| | | if (!viewer) return |
| | | removeEntities(); |
| | | removeLabel(); |
| | | viewer.camera.moveEnd.removeEventListener(determineScaling); |
| | | // viewer.camera.moveEnd.removeEventListener(determineScaling); |
| | | viewer.scene.postRender.removeEventListener(determineScaling) |
| | | handler?.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK); |
| | | handler?.destroy(); |
| | | viewer = null; |
| | |
| | | currentEntity = null; |
| | | }; |
| | | const init = () => { |
| | | initMapData(selectedAreaCode.value || userAreaCode.value); |
| | | viewer = window.$viewer; |
| | | viewer.scene.postRender.removeEventListener(determineScaling) |
| | | initMapData(selectedAreaCode.value || userAreaCode.value).then(()=>{ |
| | | viewer.scene.postRender.addEventListener(determineScaling) |
| | | }) |
| | | handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas); |
| | | handler.setInputAction(singleMachineEvent, Cesium.ScreenSpaceEventType.LEFT_CLICK); |
| | | listenerHeight(); |
| | | |
| | | }; |
| | | onBeforeUnmount(() => {}); |
| | | // onMounted(() => { |
| | |
| | | // viewer = window.$viewer; |
| | | // handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas); |
| | | // handler.setInputAction(singleMachineEvent, Cesium.ScreenSpaceEventType.LEFT_CLICK); |
| | | // listenerHeight(); |
| | | // }); |
| | | // }); |
| | | |