工具功能

This commit is contained in:
2025-09-15 14:58:15 +08:00
parent a65bf8d7ca
commit 95ce872278
18 changed files with 979 additions and 164 deletions

View File

@ -163,7 +163,9 @@ export default {
authTime: '授权时间',
authCode: '授权码',
upload: '授权导入',
authexpire: '授权过期'
authexpire: '授权过期',
authTempExpire: '临时授权',
noAuthexpire: '暂未授权',
},
systemSetting: {
setLanguage: '语言设置',
@ -188,6 +190,7 @@ export default {
areaUnit: '面积单位',
heightUnit: '高度单位',
speedUnit: '速度单位',
administrativeArea: '行政区划',
skinList: {
yingguangse: '荧光色',
gonganlan: '科技蓝',

View File

@ -0,0 +1,25 @@
//路径规划
import request from '@/axios/request'
export const RouteApi = {
// 查看路径
queryRoute: async (data: any) => {
return await request.post({
url: `/graphhopper/route`,
data
});
},
//获取地图列表
getRouteList: async () => {
return await request.get({
url: `/graphhopper/list`
})
},
//加载路网数据
loadRoute: async (data: any) => {
return await request.post({
url: `/graphhopper/loadMap`,
data,
headersType: 'application/x-www-form-urlencoded'
})
},
}

View File

@ -197,7 +197,9 @@ module.exports = {
authTime: '授权时间',
authCode: '授权码',
upload: '授权导入',
authexpire: '授权过期'
authexpire: '授权过期',
authTempExpire: '临时授权',
noAuthexpire: '暂未授权'
},
service: {
offline: '离线服务',

View File

@ -52,7 +52,7 @@ export const initMapData = async (type, data) => {
break
case 'layer':
data.host = baseURL
console.log('data',data)
console.log('data', data)
entityObject = new YJ.Obj.Layer(window.earth, data)
break
case 'tileset':
@ -97,8 +97,10 @@ export const initMapData = async (type, data) => {
default:
break
}
if (entityObject) {
options = structuredClone(entityObject.options)
delete options.host
}
// options = entityObject
return options
}

View File

@ -19,6 +19,7 @@
<script setup lang="ts">
import { UploadFilled } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
const eventBus: any = inject('bus')
// 组件属性
const props = defineProps({
@ -49,7 +50,7 @@ const isUploading = ref(false)
const uploadUrl = () => {
//process.env.BASE_API +
console.log(process.env.BASE_API, 'yyyyy')
let url = 'http://192.168.110.25:8848' + '/yjearth4.0/api/v1/auth/import'
let url = 'http://127.0.0.1:8848' + '/auth/import'
return url
}
// 上传前处理
@ -68,6 +69,7 @@ const handleBeforeUpload = (file: File) => {
const handleSuccess = (response: any) => {
isUploading.value = false
ElMessage.success('文件上传成功')
eventBus.emit('upload', true)
// 可以在这里添加成功后的其他逻辑
}

View File

@ -35,6 +35,10 @@ const i18n = createI18n({
'zh-EN': zhEN
}
})
if (!localStorage.getItem("searchWay")) {
localStorage.setItem("searchWay", "poi");
}
// 注册全局指令
const setApp = createApp(App)

View File

@ -1,8 +1,13 @@
<template>
<div class="bottomMenuBox zIndex9">
<div class="animate__animated bottomMenu">
<div class="bottom_box" v-for="(item, i) of bottomMenuList" :key="i" :title="t('bottomMenu.' + item.sourceType)"
@click="addMarker(item)">
<div
class="bottom_box"
v-for="(item, i) of bottomMenuList"
:key="i"
:title="t('bottomMenu.' + item.sourceType)"
@click="addMarker(item)"
>
<svg-icon :name="item.sourceType" :size="20" color="rgba(0, 255, 255, 1)"></svg-icon>
<div class="span">
{{ t('bottomMenu.' + item.sourceType) }}
@ -62,6 +67,7 @@ const bottomMenuList = ref([
fun: () => {
let Draw = new YJ.Draw.DrawPoint(window.earth)
Draw.start(async (a, position) => {
console.log(position, 'position')
if (!position) {
return
}
@ -182,7 +188,8 @@ const bottomMenuList = ref([
opt: {
id: id,
name: name,
center: opt.center, radius: opt.radius
center: opt.center,
radius: opt.radius
}
})
})
@ -407,7 +414,7 @@ const addMarker = (item: any) => {
transform: scale(0.8);
}
>.span {
> .span {
color: #fff;
font-family: 黑体;
font-size: 1rem;

View File

@ -5,7 +5,12 @@
<span class="fankuai"></span>
{{ t('auths.authCode') }}
</div>
<div class="auth_info_text" @click="copy" style="cursor: pointer" title="点击可复制">
<div
class="auth_info_text"
@click="copy(authInfo.license_code)"
style="cursor: pointer"
title="点击可复制"
>
{{ authInfo.license_code || '23232323232323232' }}
<svg-icon name="copy" :size="20" style="margin-left: 30px"></svg-icon>
</div>
@ -15,14 +20,11 @@
<span class="fankuai"></span>
{{ t('auths.authTime') }}
</div>
<div
class="auth_info_text"
v-if="authInfo.message === '永久授权' || authInfo.message === '临时授权'"
>
<template v-if="authInfo.start_at != ''">
{{ authInfo.start_at || '2023-01-01' }}-
<div class="auth_info_text" v-if="authInfo.status != null">
<template v-if="authInfo.generateTime != ''">
{{ authInfo.generateTime || '2023-01-01' }}-
</template>
{{ authInfo.end_at || '2023-01-01' }}
{{ authInfo.expireTime || '2023-01-01' }}
</div>
<div v-else class="auth_info_text">暂无</div>
</div>
@ -31,10 +33,11 @@
<span class="fankuai"></span>
{{ t('auths.authType') }}
</div>
<div v-if="authInfo.message.includes('token')" class="auth_info_text">
{{ t('auths.authexpire') }}
<div v-if="authInfo.status != null" class="auth_info_text" style="font-size: 16px">
{{ authInfo.status ? t('auths.authTempExpire') : t('auths.authexpire') }}
</div>
<div v-else class="auth_info_text">{{ authInfo.message || '无' }}</div>
<!-- <div v-else class="auth_info_text">{{ authInfo.message || '无' }}</div> -->
<div v-else class="auth_info_text" style="font-size: 16px">{{ t('auths.noAuthexpire') }}</div>
</div>
<uploadFiles accept=".lic" :maxSize="1"></uploadFiles>
</div>
@ -44,31 +47,64 @@
import { useI18n } from 'vue-i18n'
import uploadFiles from '@/components/upload/uploadFiles.vue'
import { AuthApi } from '@/api/setting/auth'
import useClipboard from 'vue-clipboard3'
const eventBus: any = inject('bus')
const { t } = useI18n()
const authInfo = ref({
license_code: '',
//授权信息
device_serial: '', //授权码
start_at: '', //授权时间
end_at: '', //授权时间
auth_type: '无', //授权时间
message: '' //
generateTime: '', //开始时间
expireTime: '', //结束时间
authDays: null, //授权时间
status: null
})
//上传授权文件成功
eventBus.on('upload', (data) => {
if (data) {
getAuthInfo()
}
})
const { toClipboard } = useClipboard()
const getAuthInfo = async () => {
const res = await AuthApi.showAuth()
console.log(res, 'resres')
if (typeof res.data === 'object') {
authInfo.value.generateTime = res.data.generateTime
authInfo.value.expireTime = res.data.expireTime
getStatus()
}
}
const getStatus = () => {
const timestamp = new Date(authInfo.value.expireTime).getTime()
const currentTimestamp = Date.now()
if (timestamp > currentTimestamp) {
authInfo.value.status = true
} else {
authInfo.value.status = false
}
window.checkAuthIsValid = authInfo.value.status
}
const getAuthCode = async () => {
const res = await AuthApi.authInfo()
authInfo.value.license_code = res.data
console.log(res, 'resres22')
console.log(res, '')
}
getAuthInfo()
getAuthCode()
//复制
const copy = () => {
console.log(1111111)
const copy = async (text) => {
try {
await toClipboard(text)
console.log('复制成功')
} catch (e) {
console.error('复制失败', e)
}
}
</script>
@ -83,8 +119,8 @@ const copy = () => {
.auth_info_text {
color: #fff;
font-size: 18px;
font-weight: bolder;
font-size: 14px;
font-weight: 700;
margin: 7px 0 15px 15px;
display: flex;
align-items: center;

View File

@ -3,16 +3,47 @@
<div class="engineering_title">
<span class="fankuai"></span>
<span class="setting_title">工程设置</span>
<el-upload
:action="uploadUrl()"
:headers="headers"
:data="data"
:show-file-list="false"
:before-upload="handleBeforeUpload"
:on-success="handleSuccess"
:on-error="handleError"
class="simple-upload"
>
<el-button color="#004b4b" style="border: 1px solid rgba(0, 255, 255, 0.5)">
<template #icon>
<svg-icon name="road_network" />
</template>
<span>路网导入</span>
</el-button>
</el-upload>
</div>
<div class="fileList">
<div class="fileList_nav">
<div class="fileList_nav_item">
<div class="fileList_nav_item" v-for="(item, index) in routeList" :key="index">
<div class="item_left">
<div class="img">
<img
src="../../../../../../assets/images/pdf.png"
style="width: 40px; height: 50px"
/>
</div>
<div class="file_name">
<span>{{ item.fileName }}</span>
<span>{{ item.createdAt }}</span>
</div>
</div>
<div class="item_right">
<el-button color="#004b4b" style="border: 1px solid rgba(0, 255, 255, 0.5)">
<span>删除</span>
</el-button>
</div>
</div>
<!-- <div class="fileList_nav_item">
<div class="item_left">
<div class="img">
<img
@ -49,26 +80,7 @@
<span>删除</span>
</el-button>
</div>
</div>
<div class="fileList_nav_item">
<div class="item_left">
<div class="img">
<img
src="../../../../../../assets/images/pdf.png"
style="width: 40px; height: 50px"
/>
</div>
<div class="file_name">
<span>xxxxxx.pdf</span>
<span>2025-4-10 10:22</span>
</div>
</div>
<div class="item_right">
<el-button color="#004b4b" style="border: 1px solid rgba(0, 255, 255, 0.5)">
<span>删除</span>
</el-button>
</div>
</div>
</div> -->
</div>
</div>
<div class="line"></div>
@ -109,7 +121,100 @@
</div>
</template>
<script setup lang="ts"></script>
<script setup lang="ts">
import { ElMessage } from 'element-plus'
import { ref } from 'vue'
import { GisApi } from '@/api/gisApi'
import { RouteApi } from '@/api/route'
// 上传状态
const isUploading = ref(false)
const headers = ref({
// Authorization: 'Bearer ' + localStorage.getItem('access_token')
Authorization: localStorage.getItem('Authorization')
})
// 组件属性
const props = defineProps({
// 额外上传数据
data: {
type: Object,
default: () => ({})
},
// 接受的文件类型
accept: {
type: String,
default: ''
},
// 最大文件大小(MB)
maxSize: {
type: Number,
default: 0
}
})
const uploadUrl = () => {
//process.env.BASE_API +
console.log(process.env.BASE_API, 'yyyyy')
let url = 'http://192.168.110.25:8848' + '/yjearth4.0/api/v1/fileInfo/upload'
return url
}
const handleBeforeUpload = (file: File) => {
// 检查文件大小
if (props.maxSize && file.size > props.maxSize * 1024 * 1024) {
ElMessage.error(`文件大小不能超过 ${props.maxSize}MB`)
return false
}
console.log(file)
// 标记为上传中
const formData = new FormData()
// fileArray.forEach((file, index) => {
formData.append(`files`, file) // 生成files[0]格式参数
console.log(formData, 'formData')
// })
GisApi.linkFile(formData).then((res) => {
if (res.code == 0 || res.code == 200) {
ElMessage({
message: '上传成功',
type: 'success'
})
getList()
let id = routeList[routeList.length - 1].id
addRoute(id)
}
})
return false // 阻止默认上传
// isUploading.value = true
// return true
}
//获取路网列表
var routeList: any = reactive([])
const getList = async () => {
let list = await RouteApi.getRouteList()
console.log(list, 'list')
routeList.splice(0, routeList.length, ...list.data)
}
getList()
const addRoute = async (fileId) => {
let res = await RouteApi.loadRoute({ fileId })
console.log(res, 'res')
}
// 上传成功处理
const handleSuccess = (response: any) => {
isUploading.value = false
ElMessage.success('文件上传成功')
// 可以在这里添加成功后的其他逻辑
}
// 上传失败处理
const handleError = (error: Error) => {
isUploading.value = false
ElMessage.error('文件上传失败')
console.error('上传错误:', error)
}
</script>
<style lang="scss" scoped>
.engineering {
@ -119,7 +224,8 @@
.engineering_title {
width: 100%;
box-sizing: border-box;
// padding: 20px 0;
display: flex;
line-height: 32px; // padding: 20px 0;
.fankuai {
width: 10px;
height: 10px;
@ -129,6 +235,7 @@
display: inline-block;
margin-right: 5px;
margin-left: 5px;
margin-top: 11px;
}
.setting_title {
font-size: 0.9rem;

View File

@ -171,7 +171,7 @@
}}</el-button>
</div>
<div class="detailSkin1">
<span>默认数据</span>
<span>在线数据</span>
<el-button color="#005c5c" @click="setData">{{
t('systemSetting.defaultData')
}}</el-button>
@ -224,10 +224,10 @@
</el-switch>
</div>
<div class="detailSkin2">
<span>{{ t('systemSetting.showCompass') }}</span>
<span>{{ t('systemSetting.showToolBar') }}</span>
<el-switch
@change="sysChange"
v-model="systemSetting.showCompass"
v-model="systemSetting.showToolBar"
style="--el-switch-on-color: #00ffff; --el-switch-off-color: #003333"
>
</el-switch>
@ -241,13 +241,12 @@
>
</el-switch>
</div>
<div class="detailSkin2">
<span>{{ t('systemSetting.showToolBar') }}</span>
<span>{{ t('systemSetting.showMapX') }}</span>
<el-switch
@change="sysChange"
v-model="systemSetting.showToolBar"
v-model="systemSetting.showMapX"
style="--el-switch-on-color: #00ffff; --el-switch-off-color: #003333"
>
</el-switch>
@ -263,16 +262,18 @@
>
</el-switch>
</div>
<div class="detailSkin2">
<span>{{ t('systemSetting.showMapX') }}</span>
<span>{{ t('systemSetting.administrativeArea') }}</span>
<el-switch
@change="sysChange"
v-model="systemSetting.showMapX"
v-model="systemSetting.administrativeArea"
style="--el-switch-on-color: #00ffff; --el-switch-off-color: #003333"
>
</el-switch>
</div>
<div class="detailSkin2">
<span>{{ t('systemSetting.showLatitudeLongitudeNetwork') }}</span>
@ -293,6 +294,16 @@
>
</el-switch>
</div>
<div class="detailSkin2">
<span>{{ t('systemSetting.sheetIndexStatusSwitch') }}</span>
<el-switch
@change="sysChange"
v-model="systemSetting.sheetIndexStatusSwitch"
style="--el-switch-on-color: #00ffff; --el-switch-off-color: #003333"
>
</el-switch>
</div>
<div class="detailSkin2">
<span>{{ t('systemSetting.occlusion') }}</span>
@ -321,6 +332,7 @@
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import { ElMessage } from 'element-plus'
const { t } = useI18n()
@ -328,11 +340,13 @@ const systemSetting = ref({
showFangliNet: false, // 方里网
showLatitudeLongitudeNetwork: false, //经纬网
showToolBar: false, //信息栏
showCompass: false, //罗盘
showCompass: true, //罗盘
showMapX: false, //鹰眼图
occlusion: false, //点遮挡
occlusion: true, //点遮挡
showDistanceLegend: true, //比例尺
showFps: false, //比例尺
administrativeArea: false, //行政区划
sheetIndexStatusSwitch: false, //标准图幅
skinInfo: 'yingguangse', //主题色
language: '', //语言
coordinate: 'EPSG:4326' //坐标系
@ -375,12 +389,64 @@ const name_map: any = ref([])
const searchWay = ref()
const concurrentcode = ref()
const showBattery = ref()
const sysChange = () => {
console.log(11111111111)
searchWay.value = localStorage.getItem('searchWay') || 'net'
concurrentcode.value = localStorage.getItem('concurrentcode') || 10
const sysChange = async () => {
const obj = {
compass: systemSetting.value.showCompass, //罗盘
legend: systemSetting.value.showDistanceLegend, //比例尺
info: systemSetting.value.showToolBar, //信息栏
// system.showFps
frame: systemSetting.value.showFps //刷新率
}
YJ.Global.CesiumContainer(window.earth, obj)
//经纬网
YJ.Global.JwwStatusSwitch(window.earth, systemSetting.value.showLatitudeLongitudeNetwork)
//方里网
YJ.Global.FlwStatusSwitch(window.earth, systemSetting.value.showFangliNet)
//地形遮挡
YJ.Global.setGroundCover(window.earth, systemSetting.value.occlusion)
await YJ.Global.SheetIndexStatusSwitch(window.earth, systemSetting.value.sheetIndexStatusSwitch)
//鹰眼图
if (systemSetting.value.showMapX) {
YJ.Global.MapX.open(window.earth)
} else {
YJ.Global.MapX.close(window.earth)
}
}
const searchWayChange = (val) => {
localStorage.setItem('searchWay', val)
ElMessage({
message: '操作成功',
type: 'success'
})
}
const concurrentWorkloadChange = (val) => {
YJ.Global.setMaximumRequestsPerServer(val)
localStorage.setItem('concurrentcode', val)
ElMessage({
message: '操作成功',
type: 'success'
})
}
const setView = () => {
console.log('hhhhh')
let msg = '操作成功'
let view = YJ.Global.getCurrentView(window.earth)
const options = {
destination: view.position,
orientation: view.orientation
}
YJ.Global.setDefaultView(window.earth, options)
localStorage.setItem('defaultView', JSON.stringify(options))
console.log('defaultView')
ElMessage({
message: msg,
type: 'success'
})
}
const searchWayChange = () => {}
const concurrentWorkloadChange = () => {}
const setView = () => {}
const setData = () => {}
const management = () => {}
const batteryChange = () => {}

View File

@ -36,7 +36,7 @@ const logout = async () => {
console.log(res);
if (res.code === 200) {
router.push({ path: '/' })
localStorage.clear()
// localStorage.clear()
}
}
const setList = ref([

View File

@ -3,7 +3,11 @@
<div class="leftSideSecondBox">
<template v-if="obj">
<div class="menuItem" v-for="value in obj.children" @click="handleClick(value)">
<img :src="'src/assets/images/second/' + `${value}` + '.png'" style="color: rgb(255, 0, 0)" alt="" />
<img
:src="'src/assets/images/second/' + `${value}` + '.png'"
style="color: rgb(255, 0, 0)"
alt=""
/>
<span :style="{ color: !clickChange[value] ? 'var(--color-text)' : 'rgb(255,0,0)' }">{{
t(`${obj.key}.${value}`)
}}</span>
@ -31,7 +35,7 @@ import dayjs from 'dayjs'
const { t } = useI18n()
const { findParentId, findTreeIndex, cusAddNodes } = useTreeNode()
const fs = require('fs')
const obj:any = ref(null)
const obj: any = ref(null)
const isclick = ref(false)
const eventBus: any = inject('bus')
const initList = (value) => {
@ -50,7 +54,7 @@ eventBus.on('graffitiObj', (data: never) => {
function openLoading(
text = '拼命加载中...',
option:any = {
option: any = {
fullscreen: true,
background: 'rgba(0,0,0,0.63)',
lock: true
@ -61,6 +65,26 @@ function openLoading(
let loadingInstance = ElLoading.service(option)
return loadingInstance
}
// 监听键盘esc键,移出鼠标定位
const handleKeyDown = (e) => {
if (e.key === 'Escape') {
if (clickChange.mouseLocation) {
//鼠标定位
clickChange.mouseLocation = false
new YJ.Global.MouseCoordinate(window.earth, clickChange.mouseLocation)
// window.removeEventListener('keydown', handleKeyDown)
}
//视频录制
if (clickChange.videoRecord) {
methodMap['videoRecord']()
}
console.log('全局ESC监听')
}
}
window.addEventListener('keydown', handleKeyDown)
const methodMap = {
// 轨迹运动
@ -79,11 +103,11 @@ const methodMap = {
name: name,
model: {
show: true,
url: "http://localhost:5173/tank.glb",
url: 'http://localhost:5173/tank.glb'
},
line: {
show: true,
positions: positions,
positions: positions
}
}
})
@ -104,7 +128,7 @@ const methodMap = {
opt: {
id: id,
name: name,
positions: positions,
positions: positions
}
})
}
@ -130,9 +154,9 @@ const methodMap = {
circle: [
{
radius: options.radius,
color: '#ff0000',
color: '#ff0000'
}
],
]
}
})
}
@ -254,7 +278,9 @@ const methodMap = {
eventBus.emit('routePlanningDialog')
},
//路径清除
clearRoute() { },
clearRoute() {
new YJ.ClearAllRoutePlanning()
},
//涂鸦
graffiti() {
eventBus.emit('graffitiDialog')
@ -277,6 +303,12 @@ const methodMap = {
mouseLocation() {
clickChange.mouseLocation = !clickChange.mouseLocation
new YJ.Global.MouseCoordinate(window.earth, clickChange.mouseLocation)
// if (clickChange.mouseLocation) {
// window.addEventListener('keydown', handleKeyDown)
// } else {
// window.removeEventListener('keydown', handleKeyDown)
// }
},
//聚合标注
annotationAggregation() {
@ -329,7 +361,7 @@ const methodMap = {
// window.multiViewportMode = false;
})
} else {
let doms:any = document.querySelectorAll('.cesium-widget')
let doms: any = document.querySelectorAll('.cesium-widget')
let leftWidth = doms[0].offsetWidth
let rightWidth = doms[1].offsetWidth
combineBase64Images(res2, leftWidth, res, rightWidth)
@ -356,16 +388,16 @@ const methodMap = {
videoRecord() {
clickChange.videoRecord = !clickChange.videoRecord
let time:any = 3
let time: any = 3
$changeComponentShow('#secondMenu', false)
if (clickChange.videoRecord) {
// document.addEventListener("keydown", onKeyDown);
let loading:any = openLoading(time, {
let loading: any = openLoading(time, {
background: 'rgba(0,0,0,0)',
fullscreen: false,
customClass: 'timer'
})
let timer:any = ''
let timer: any = ''
const p = document.createElement('p')
p.style.color = '#fff'
p.innerHTML = '再次点击录制结束'
@ -386,13 +418,14 @@ const methodMap = {
// document.removeEventListener("keydown", onKeyDown);
}
},
//
//模型压平
pressModel() {
// if (window.checkAuthIsValid) {
let selectedNode = window.treeObj.getSelectedNodes()[0]
if (selectedNode) {
let isTileset = ['bim', 'tileset'].includes(selectedNode.sourceType)
if (!isTileset) {
console.log('aaaaaa')
ElMessage({
message: '请在图层指挥舱选中对应模型进行操作',
type: 'warning'
@ -424,7 +457,7 @@ const methodMap = {
height: flat.height
}
let id = new YJ.Tools().randomString()
let paramsData:any = {
let paramsData: any = {
params: detailOption,
id,
sourceName: '压平面',
@ -435,10 +468,10 @@ const methodMap = {
}
TreeApi.addOtherSource(paramsData)
paramsData.isShow = true;
paramsData.params = JSON.stringify(paramsData.params);
(window as any).pressModelMap.set(id + '_' + selectedNode.id, paramsData)
(window as any).pressModelEntities.set(id, flat)
paramsData.isShow = true
paramsData.params = JSON.stringify(paramsData.params)
;(window as any).pressModelMap.set(id + '_' + selectedNode.id, paramsData)
;(window as any).pressModelEntities.set(id, flat)
cusAddNodes(window.treeObj, paramsData.parentId, [paramsData])
// //鼠标右键点击事件
flat.onRightClick = () => {}
@ -448,7 +481,11 @@ const methodMap = {
}
})
} else {
// this.$message.warning('请在图层指挥舱选中对应模型进行操作!')
console.log('bbbbb')
ElMessage({
message: '请在图层指挥舱选中对应模型进行操作',
type: 'warning'
})
}
// } else {
// this.$message({
@ -515,7 +552,7 @@ const methodMap = {
eventBus.emit('ProjectionConvertDialog')
},
//GDB导入
gdbImport() { },
gdbImport() {},
//圆形统计
circleStatistics() {
// if (window.checkAuthIsValid) {

View File

@ -46,7 +46,7 @@
</div>
</div>
</el-tab-pane>
<el-tab-pane label="度分格式" name="second">
<el-tab-pane label="度分格式" name="second">
<span class="custom-divider"></span>
<div class="div-item">
<div class="row">
@ -78,7 +78,7 @@
</div>
</div>
</el-tab-pane>
<el-tab-pane label="度分格式" name="third">
<el-tab-pane label="度分格式" name="third">
<span class="custom-divider"></span>
<div class="div-item">
<div class="row">
@ -117,8 +117,8 @@
</el-tabs>
</template>
<template #footer>
<!-- <button @click="draw">确定</button> -->
<button @click="close">关闭</button>
<button @click="draw">保存</button>
<button @click="close">取消</button>
</template>
</Dialog>
</template>
@ -127,6 +127,8 @@
import { ref, reactive } from 'vue'
import { inject } from 'vue'
import Dialog from '@/components/dialog/baseDialog.vue'
import { addMapSource } from '../../../common/addMapSource'
import { initMapData } from '@/common/initMapData'
const baseDialog: any = ref(null)
const eventBus: any = inject('bus')
@ -141,14 +143,15 @@ var latMin = ref(null)
var lngSec = ref(null)
var latSec = ref(null)
var id = ref(null)
eventBus.on('coorLocationDialog', () => {
id.value = new YJ.Tools().randomString()
baseDialog.value?.open()
})
// @ts-ignore (define in dts)
const handleClick = (tab: TabsPaneContext, event: Event) => {
console.log(tab, event)
longitude.value = null
latitude.value = null
lngMin.value = null
@ -163,13 +166,21 @@ const closeCallBack = (e) => {
latMin.value = null
lngSec.value = null
latSec.value = null
activeName.value = 'first'
}
const flyto = (e) => {
const turnToPosition = async () => {
let position
switch (activeName.value) {
case 'first':
new YJ.Global.flyTo(window.earth, {
position: { lng: longitude.value, lat: latitude.value, alt: 100 }
})
var point = await new YJ.Tools().sampleHeightMostDetailed(
[{ lng: longitude.value, lat: latitude.value, alt: 0 }],
window.earth
)
position = {
lng: longitude.value,
lat: latitude.value,
alt: point[0].height < 0 ? 0 : point[0].height
}
break
case 'second':
// @ts-ignore (define in dts)
@ -181,10 +192,16 @@ const flyto = (e) => {
// @ts-ignore (define in dts)
lat = latitude.value < 0 ? -lat : lat
var position = { lng, lat, alt: 100 }
new YJ.Global.flyTo(window.earth, {
position: position
})
var point2 = await new YJ.Tools().sampleHeightMostDetailed(
[{ lng, lat, alt: 0 }],
window.earth
)
position = {
lng: lng,
lat: lat,
alt: point2[0].height < 0 ? 0 : point2[0].height
}
break
case 'third':
var lng =
@ -199,14 +216,97 @@ const flyto = (e) => {
// @ts-ignore (define in dts)
lat = latitude.value < 0 ? -lat : lat
var position = { lng, lat, alt: 100 }
new YJ.Global.flyTo(window.earth, {
position: position
})
var point3 = await new YJ.Tools().sampleHeightMostDetailed(
[{ lng, lat, alt: 0 }],
window.earth
)
position = {
lng: lng,
lat: lat,
alt: point3[0].height < 0 ? 0 : point3[0].height
}
break
}
return position
}
const draw = (e) => {
const flyto = async (e) => {
let position = await turnToPosition()
new YJ.Global.flyTo(window.earth, {
position: { lng: position.lng, lat: position.lat, alt: position.alt + 100 }
})
let name = '点标注'
let params = {
type: 'point',
id: id.value,
sourceName: name,
opt: {
id: id.value,
name: name,
position: position
}
}
if (!window.earth.entityMap.get(id.value)) {
await initMapData('point', params)
}
// switch (activeName.value) {
// case 'first':
// new YJ.Global.flyTo(window.earth, {
// position: { lng: longitude.value, lat: latitude.value, alt: 100 }
// })
// break
// case 'second':
// // @ts-ignore (define in dts)
// var lng = Math.abs(longitude.value) + Math.abs(lngMin.value) / 60
// // @ts-ignore (define in dts)
// var lat = Math.abs(latitude.value) + Math.abs(latMin.value) / 60
// // @ts-ignore (define in dts)
// lng = longitude.value < 0 ? -lng : lng
// // @ts-ignore (define in dts)
// lat = latitude.value < 0 ? -lat : lat
// var position = { lng, lat, alt: 100 }
// new YJ.Global.flyTo(window.earth, {
// position: position
// })
// break
// case 'third':
// var lng =
// // @ts-ignore (define in dts)
// Math.abs(longitude.value) + Math.abs(lngMin.value) / 60 + Math.abs(lngSec.value) / 3600
// var lat =
// // @ts-ignore (define in dts)
// Math.abs(latitude.value) + Math.abs(latMin.value) / 60 + Math.abs(latSec.value) / 3600
// // @ts-ignore (define in dts)
// lng = longitude.value < 0 ? -lng : lng
// // @ts-ignore (define in dts)
// lat = latitude.value < 0 ? -lat : lat
// var position = { lng, lat, alt: 100 }
// new YJ.Global.flyTo(window.earth, {
// position: position
// })
// break
// }
}
const draw = async (e) => {
let position = await turnToPosition()
if (!position) {
return
}
let name = '点标注'
await addMapSource({
type: 'point',
id: id.value,
sourceName: name,
opt: {
id: id.value,
name: name,
position: position
}
})
baseDialog.value?.close()
}
const close = (e) => {

View File

@ -1,4 +1,4 @@
<!-- <template>
<template>
<Dialog
ref="baseDialog"
class="fly-roam"
@ -131,7 +131,7 @@ eventBus.on('flyRoamDialog', () => {
baseDialog.value?.open()
setTimeout(() => {
flyRoam = YJ.Global.FlyRoam.open(window.earth, { repeat: Infinity })
}, 0)
}, 100)
})
const clangeViewPointHeight = () => {}
@ -154,4 +154,4 @@ const close = (e) => {
}
</script>
<style scoped lang="scss"></style> -->
<style scoped lang="scss"></style>

View File

@ -5,30 +5,129 @@
title="路径规划"
left="180px"
top="100px"
width="527px"
:closeCallback="closeCallBack"
>
<template #content>
<div class="row" style="align-items: flex-start">
<div class="col start-col">
<button class="crossPoint">
<svg-icon name="add" :size="16" color="rgba(255, 255, 255, 1)"></svg-icon> 途径点
<button
class="crossPoint"
@mouseenter="svgHover[0] = true"
@mouseleave="svgHover[0] = false"
>
<svg-icon
name="add"
:size="12"
:color="svgHover[0] ? 'rgba(0, 255, 255, 1)' : 'rgba(255, 255, 255, 1)'"
></svg-icon>
途径点
</button>
<button style="margin-left: 10px">
<svg-icon name="add" :size="16" color="rgba(255, 255, 255, 1)"></svg-icon>避让点
<button
class="crossPoint"
@mouseenter="svgHover[1] = true"
@mouseleave="svgHover[1] = false"
style="margin-left: 10px"
>
<svg-icon
name="add"
:size="12"
:color="svgHover[1] ? 'rgba(0, 255, 255, 1)' : 'rgba(255, 255, 255, 1)'"
></svg-icon
>避让点
</button>
</div>
</div>
<div class="row" style="align-items: flex-start">
<div class="row">
<p class="lable-left-line">路径规划</p>
</div>
<div class="row">
<div class="col" style="flex: 0 0 50px">
<span class="label">起点</span>
</div>
<div class="col">
<span class="label">经度</span>
<input
class="input"
id="startLng"
type="number"
title=""
min="-180"
max="180"
@model="startLng"
v-model="startLng"
@change="changeStartLng"
@input="inputStartLng"
/>
</div>
<div class="col">
<span class="label">纬度</span>
<input
class="input"
id="startLat"
type="number"
title=""
min="-90"
max="90"
@model="startLat"
v-model="startLat"
@change="changeStartLat"
@input="inputStartLat"
/>
</div>
<div class="col" style="flex: 0 0 80px">
<button class="end-pick-btn" @click="pickStartPos" style="margin-left: 10px">拾取</button>
</div>
</div>
<div class="row">
<div class="col" style="flex: 0 0 50px">
<span class="label">终点</span>
<input class="input" type="number" title="" min="-180" max="180" @model="endLng" />
<input class="input" type="number" title="" min="-90" max="90" @model="endLat" />
</div>
<div class="col">
<span class="label">经度</span>
<input
class="input"
id="endLng"
type="number"
title=""
min="-180"
max="180"
@model="endLng"
v-model="endLng"
@change="changeEndLng"
@input="inputEndLng"
/>
</div>
<div class="col">
<span class="label">纬度</span>
<input
class="input"
id="endLat"
type="number"
title=""
min="-180"
max="180"
@model="endLat"
v-model="endLat"
@change="changeEndLat"
@input="inputEndLat"
/>
</div>
<div class="col" style="flex: 0 0 80px">
<button class="end-pick-btn" @click="pickEndPos" style="margin-left: 10px">拾取</button>
</div>
</div>
<span class="custom-divider"></span>
</template>
<template #footer>
<button @click="draw">绘制</button>
<button id="routeQuery" @clik="routeQuery">
<svg class="icon-query"><use xlink:href="#yj-icon-query"></use></svg>查询
</button>
<button id="clearRoute" @click="clearRoute">
<svg class="icon-route"><use xlink:href="#yj-icon-route"></use></svg>清除路线
</button>
<button @click="close">取消</button>
</template>
</Dialog>
</template>
@ -37,6 +136,7 @@
import { ref, reactive } from 'vue'
import { inject } from 'vue'
import Dialog from '@/components/dialog/baseDialog.vue'
import { RouteApi } from '@/api/route/index.ts'
const baseDialog: any = ref(null)
const eventBus: any = inject('bus')
@ -48,29 +148,148 @@ var endLng: any = ref(null)
var endLat: any = ref(null)
var routePlanning: any = reactive([])
var svgHover: any = reactive([false, false])
eventBus.on('routePlanningDialog', () => {
baseDialog.value?.open()
setTimeout(() => {
//加载路网数据
let host = 'http://192.168.110.25:8848'
routePlanning = new YJ.Obj.RoutePlanning(window.earth, {
gps: false,
host
})
routePlanning.Dialog.queryCallBack = async (v) => {
console.log(v, 'vvvvvvvvv')
// await queryRoute(params, (response) => {
// if (response) {
// routePlanning.createRoute(response.list[0].positions)
// }
// })
let res = await RouteApi.queryRoute({
startLng: startLng.value,
startLat: startLat.value,
endLng: endLng.value,
endLat: endLat.value,
waypoints: []
})
routePlanning.createRoute(res.data.pathPoints)
console.log(res, 'routLIst')
}
}, 100)
})
const closeCallBack = (e) => {}
function pickStartPos() {}
function pickEndPos() {}
//加载路网数据
const draw = (e) => {}
const addRoute = async (fileId) => {
let res = await RouteApi.loadRoute({ fileId })
console.log(res, 'res')
}
const getList = async () => {
let list = await RouteApi.getRouteList()
if (list.data.length > 0) {
let file = list.data[list.data.length - 1]
addRoute(file.id)
}
console.log(list, 'list')
}
const closeCallBack = (e) => {
startLng.value = null
startLat.value = null
endLng.value = null
endLat.value = null
}
const routeQuery = async (e) => {
console.log('aaaaa')
let res = await RouteApi.queryRoute({
startLng: startLng.value,
startLat: startLat.value,
endLng: endLng.value,
endLat: endLat.value,
waypoints: []
})
console.log(res, 'res')
}
const clearRoute = (e) => {}
const pickStartPos = () => {
routePlanning.pickStartPos((position) => {
console.log(position, 'position')
startLng.value = position.lng
startLat.value = position.lat
})
}
const pickEndPos = () => {
routePlanning.pickEndPos((position) => {
endLng.value = position.lng
endLat.value = position.lat
})
}
const close = (e) => {
baseDialog.value?.close()
}
const changeStartLng = () => {
routePlanning.startLng = startLng.value
}
const inputStartLng = () => {
let dom: any = document.getElementById('startLng')
if (startLng.value < dom.min * 1) {
startLng.value = dom.min * 1
} else if (startLng.value > dom.max * 1) {
startLng.value = dom.max * 1
}
}
const changeStartLat = () => {
routePlanning.startLat = startLat.value
}
const inputStartLat = () => {
let dom: any = document.getElementById('startLat')
if (startLat.value < dom.min * 1) {
startLat.value = dom.min * 1
} else if (startLat.value > dom.max * 1) {
startLat.value = dom.max * 1
}
}
const changeEndLng = () => {
routePlanning.endLng = endLng.value
}
const inputEndLng = () => {
let dom: any = document.getElementById('endLng')
if (endLng.value < dom.min * 1) {
endLng.value = dom.min * 1
} else if (endLng.value > dom.max * 1) {
endLng.value = dom.max * 1
}
}
const changeEndLat = () => {
routePlanning.endLat = endLat.value
}
const inputEndLat = () => {
let dom: any = document.getElementById('endLat')
if (endLat.value < dom.min * 1) {
endLat.value = dom.min * 1
} else if (endLat.value > dom.max * 1) {
endLat.value = dom.max * 1
}
}
</script>
<style scoped lang="scss">
::v-deep .RoutePlanning > .content {
width: 460px;
#routeQuery {
position: absolute;
left: 10px;
display: flex;
}
::v-deep .RoutePlanning > .content > div > .row .col {
margin: 0 10px;
#clearRoute {
position: absolute;
left: 95px;
display: flex;
}
::v-deep .RoutePlanning > .content .row .label {
flex: auto;
}
.crossPoint:hover {
color: rgba(var(--color-sdk-base-rgb), 1);
.YJ-custom-base-dialog > .content .row > .col {
margin: 0 5px !important;
}
.crossPoint:hover {
color: rgba(var(--color-sdk-base-rgb), 1);

View File

@ -0,0 +1,171 @@
<template>
<Dialog
ref="baseDialog"
class="RoutePlanning"
title="路径规划"
left="180px"
top="100px"
width="527px"
:closeCallback="closeCallBack"
>
<template #content>
<div class="row" style="align-items: flex-start">
<div class="col start-col">
<button
class="crossPoint"
@mouseenter="svgHover[0] = true"
@mouseleave="svgHover[0] = false"
>
<svg-icon
name="add"
:size="12"
:color="svgHover[0] ? 'rgba(0, 255, 255, 1)' : 'rgba(255, 255, 255, 1)'"
></svg-icon>
途径点
</button>
<button
class="crossPoint"
@mouseenter="svgHover[1] = true"
@mouseleave="svgHover[1] = false"
style="margin-left: 10px"
>
<svg-icon
name="add"
:size="12"
:color="svgHover[1] ? 'rgba(0, 255, 255, 1)' : 'rgba(255, 255, 255, 1)'"
></svg-icon
>避让点
</button>
</div>
</div>
<div class="row">
<p class="lable-left-line">路径规划</p>
</div>
<div class="row">
<div class="col" style="flex: 0 0 50px">
<span class="label">起点</span>
</div>
<div class="col">
<span class="label">经度</span>
<input class="input" type="number" title="" min="-180" max="180" @model="endLng" />
</div>
<div class="col">
<span class="label">纬度</span>
<input class="input" type="number" title="" min="-180" max="180" @model="endLng" />
</div>
<div class="col" style="flex: 0 0 80px">
<button class="end-pick-btn" @click="pickEndPos" style="margin-left: 10px">拾取</button>
</div>
</div>
<!-- 途径点 -->
<div class="row" v-for="(item, index) in positionList.waypoints" :key="index">
<div class="col" style="flex: 0 0 50px">
<span class="label">途径点</span>
</div>
<div class="col">
<span class="label">经度</span>
<input
class="input"
type="number"
title=""
min="-180"
max="180"
@model="endLng"
v-model="item.lng"
/>
</div>
<div class="col">
<span class="label">纬度</span>
<input
class="input"
type="number"
title=""
min="-180"
max="180"
@model="endLng"
v-model="item.lat"
/>
</div>
<div class="col" style="flex: 0 0 80px">
<button class="end-pick-btn" @click="pickEndPos" style="margin-left: 10px">拾取</button>
</div>
</div>
<div class="row">
<div class="col" style="flex: 0 0 50px">
<span class="label">终点</span>
</div>
<div class="col">
<span class="label">经度</span>
<input class="input" type="number" title="" min="-180" max="180" @model="endLng" />
</div>
<div class="col">
<span class="label">纬度</span>
<input class="input" type="number" title="" min="-180" max="180" @model="endLng" />
</div>
<div class="col" style="flex: 0 0 80px">
<button class="end-pick-btn" @click="pickEndPos" style="margin-left: 10px">拾取</button>
</div>
</div>
</template>
<template #footer>
<button @click="draw">绘制</button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue'
import { inject } from 'vue'
import Dialog from '@/components/dialog/baseDialog.vue'
const baseDialog: any = ref(null)
const eventBus: any = inject('bus')
var positionList: any = reactive([
{
startlng: 0,
startlat: 0,
endlng: 0,
endlat: 0,
waypoints: [
{
lat: 0,
lng: 0
}
]
}
])
//属性
var startLng: any = ref(null)
var startLat: any = ref(null)
var endLng: any = ref(null)
var endLat: any = ref(null)
var svgHover: any = reactive([false, false])
eventBus.on('routePlanningDialog', () => {
baseDialog.value?.open()
})
const closeCallBack = (e) => {}
function pickStartPos() {}
function pickEndPos() {}
const draw = (e) => {}
</script>
<style scoped lang="scss">
// ::v-deep .RoutePlanning > .content > div > .row .col {
// margin: 0 10px;
// }
// ::v-deep .RoutePlanning > .content .row .label {
// flex: auto;
// }
.YJ-custom-base-dialog > .content .row > .col {
margin: 0 5px !important;
}
.crossPoint:hover {
color: rgba(var(--color-sdk-base-rgb), 1);
}
</style>

View File

@ -10,27 +10,33 @@
<firstMenu class="absolute zIndex9" ref="firstMenuRef"></firstMenu>
<!--底部菜单-->
<bottomMenu class="absolute zIndex9" ref="bottomMenuRef"></bottomMenu>
<input type="file" id="fileInputlink" style="display: none" multiple accept=".jpeg,.png,.jpg,.mp4,.pdf"
@input="uploadFile" />
<input
type="file"
id="fileInputlink"
style="display: none"
multiple
accept=".jpeg,.png,.jpg,.mp4,.pdf"
@input="uploadFile"
/>
<!-- 多点视线分析 -->
<Visibility ref="visibility"></Visibility>
<CircleViewShed ref="CircleViewShed"></CircleViewShed>
<Submerge ref="Submerge"></Submerge>
<Profile ref="Profile"></Profile>
<ViewShed ref="ViewShed"></ViewShed>
<CutFill ref="CutFill"></CutFill>
<Contour ref="Contour"></Contour>
<RoutePlanning ref="RoutePlanning"></RoutePlanning>
<Graffiti ref="Graffiti"></Graffiti>
<!-- <FlyRoam ref="FlyRoam"></FlyRoam> -->
<CoorLocation ref="CoorLocation"></CoorLocation>
<ScreenShot ref="ScreenShot"></ScreenShot>
<TerrainExcavation ref="TerrainExcavation"></TerrainExcavation>
<ProjConvert ref="ProjConvert"></ProjConvert>
<ProjectionConvert ref="ProjectionConvert"></ProjectionConvert>
<GoodsSearchCircle ref="GoodsSearchCircle"></GoodsSearchCircle>
<GoodsSearchPolgon ref="GoodsSearchPolgon"></GoodsSearchPolgon>
<CircleViewShed ref="circleViewShed"></CircleViewShed>
<Submerge ref="submerge"></Submerge>
<Profile ref="profile"></Profile>
<ViewShed ref="viewShed"></ViewShed>
<CutFill ref="cutFill"></CutFill>
<Contour ref="contour"></Contour>
<RoutePlanning ref="routePlanning"></RoutePlanning>
<Graffiti ref="graffiti"></Graffiti>
<FlyRoam ref="flyRoam"></FlyRoam>
<CoorLocation ref="coorLocation"></CoorLocation>
<ScreenShot ref="screenShot"></ScreenShot>
<TerrainExcavation ref="terrainExcavation"></TerrainExcavation>
<ProjConvert ref="projConvert"></ProjConvert>
<ProjectionConvert ref="projectionConvert"></ProjectionConvert>
<GoodsSearchCircle ref="goodsSearchCircle"></GoodsSearchCircle>
<GoodsSearchPolgon ref="goodsSearchPolgon"></GoodsSearchPolgon>
</template>
<script setup lang="ts">
@ -87,7 +93,7 @@ let addStandTextRef = ref()
let tree = ref()
eventBus.on('openDialog', async (sourceType: any, id: any) => {
console.log(sourceType, id)
if(dynamicComponentRef.value && dynamicComponentRef.value.close) {
if (dynamicComponentRef.value && dynamicComponentRef.value.close) {
dynamicComponentRef.value.close()
}
switch (sourceType) {
@ -202,6 +208,11 @@ eventBus.on('destroyComponent', () => {
const createEarth = async () => {
window.earth = await new YJ.YJEarth('earthContainer')
tree.value.initTreeCallBack()
let options = JSON.parse(localStorage.getItem('defaultView'))
YJ.Global.setDefaultView(window.earth, options)
setTimeout(() => {
new YJ.Tools(window.earth).flyHome()
}, 1000)
// YJ.Global.setDefaultView(window.earth, {
// destination: { lng: 100, lat: 30, alt: 10 },
// orientation: {

View File

@ -4,6 +4,7 @@ import { throttle } from '@/utils/index'
import { ElMessage, ElMessageBox } from 'element-plus'
import { LoginApi } from '@/api/login'
import { useUserStore } from '@/store/modules/user'
import { AuthApi } from '@/api/setting/auth'
// const { ipcRenderer } = require('electron')
export const useLogin = () => {
const showContent = ref(false) // 控制视频显示
@ -72,7 +73,7 @@ export const useLogin = () => {
const res = await LoginApi.login(loginForm.value)
console.log(res);
if ([0,200].includes(res.code) ) {
if ([0, 200].includes(res.code)) {
checkboxVModel.value = true
localStorage.setItem(res.data.header, res.data.token)
localStorage.setItem(
@ -85,6 +86,7 @@ export const useLogin = () => {
)
ElMessage.success('登录成功')
router.push({ path: '/home' })
getAuthInfo()
// ipcRenderer.send('renderNode')
}
} catch (error) {
@ -105,6 +107,27 @@ export const useLogin = () => {
}
})
}
//获取授权信息
const getAuthInfo = async () => {
const res = await AuthApi.showAuth()
if (typeof res.data === 'object') {
let time = res.data.expireTime
getStatus(time)
}
}
const getStatus = (time) => {
const timestamp = new Date(time).getTime()
const currentTimestamp = Date.now()
if (timestamp > currentTimestamp) {
window.checkAuthIsValid = true
} else {
window.checkAuthIsValid = false
}
}
// 播放第一个视频
// 这里可以添加一些逻辑来处理视频播放
const playFirstVideo = () => {