Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
J
JINRUN-PERPOSITION
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
xinzhedeai
JINRUN-PERPOSITION
Commits
3e2b8acf
Commit
3e2b8acf
authored
Nov 21, 2025
by
xinzhedeai
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add:编辑围栏 定位页
parent
cde8d155
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
980 additions
and
544 deletions
+980
-544
index.js
src/router/index.js
+39
-26
index-dw.vue
src/views/index-dw.vue
+586
-0
index-wl.vue
src/views/index-wl.vue
+351
-12
index.vue
src/views/index.vue
+4
-506
No files found.
src/router/index.js
View file @
3e2b8acf
...
...
@@ -74,6 +74,19 @@ export const constantRoutes = [
meta
:
{
title
:
'
首页
'
,
icon
:
'
dashboard
'
,
affix
:
true
}
}
]
},
{
path
:
'
/dw
'
,
component
:
Layout
,
redirect
:
'
noredirect
'
,
children
:
[
{
path
:
'
index
'
,
component
:
()
=>
import
(
'
@/views/index-dw
'
),
name
:
'
Index
'
,
meta
:
{
title
:
'
首页2-dw
'
,
icon
:
'
dashboard
'
,
affix
:
true
}
}
]
},
// {
// path: '/zz',
...
...
@@ -88,32 +101,32 @@ export const constantRoutes = [
// }
// ]
// },
{
path
:
'
/guiji
'
,
component
:
Layout
,
redirect
:
'
noredirect
'
,
children
:
[
{
path
:
'
index
'
,
component
:
()
=>
import
(
'
@/views/index-guiji
'
),
name
:
'
Index
'
,
meta
:
{
title
:
'
首页2-gj
'
,
icon
:
'
dashboard
'
,
affix
:
true
}
}
]
},
{
path
:
'
/wl
'
,
component
:
Layout
,
redirect
:
'
noredirect
'
,
children
:
[
{
path
:
'
screen
'
,
component
:
()
=>
import
(
'
@/views/index-wl
'
),
name
:
'
Screen
'
,
meta
:
{
title
:
'
首页-WL
'
,
icon
:
'
dashboard
'
,
affix
:
true
}
}
]
},
//
{
//
path: '/guiji',
//
component: Layout,
//
redirect: 'noredirect',
//
children: [
//
{
//
path: 'index',
//
component: () => import('@/views/index-guiji'),
//
name: 'Index',
//
meta: { title: '首页2-gj', icon: 'dashboard', affix: true }
//
}
//
]
//
},
//
{
//
path: '/wl',
//
component: Layout,
//
redirect: 'noredirect',
//
children: [
//
{
//
path: 'screen',
//
component: () => import('@/views/index-wl'),
//
name: 'Screen',
//
meta: { title: '首页-WL', icon: 'dashboard', affix: true }
//
}
//
]
//
},
{
path
:
'
/user
'
,
component
:
Layout
,
...
...
src/views/index-dw.vue
0 → 100644
View file @
3e2b8acf
<
template
>
<div
class=
"app-container home"
>
<!-- Cesium地图容器 -->
<div
id=
"cesiumContainer"
class=
"cesium-container"
></div>
</div>
</
template
>
<
script
>
import
{
getTokenApi
}
from
"
@/api/token
"
;
import
{
localStg
}
from
"
@/utils/storage
"
;
export
default
{
name
:
"
Index
"
,
data
()
{
return
{
// 版本号
version
:
"
3.8.9
"
,
// Cesium查看器实例
viewer
:
null
,
tileset
:
null
,
personnelList
:
[
{
longitude
:
121.70710830038986
,
latitude
:
36.853636402927986
,
height
:
100
,
name
:
"
张三
"
,
status
:
"
online
"
,
// 在线
avatar
:
"
/static/images/avatars/zhangsan.png
"
,
// 头像
},
{
longitude
:
121.70810830038986
,
latitude
:
36.854636402927986
,
height
:
100
,
name
:
"
李四
"
,
status
:
"
offline
"
,
// 离线
avatar
:
"
/static/images/avatars/lisi.png
"
,
// 头像
},
// 其他人员数据...
],
intervaler
:
null
,
bgEntities
:
{},
// 所有的key都对应一个实体对象。而人员的实体对应的key不是数字。
};
},
mounted
()
{
// 组件挂载后初始化地图
this
.
initCesium
();
// 监听窗口大小变化
window
.
addEventListener
(
"
resize
"
,
this
.
handleResize
);
},
beforeMount
()
{
localStg
.
set
(
"
token
"
,
222233
);
if
(
localStg
.
get
(
"
token
"
))
{
return
;
}
// 组件挂载前获取token
getTokenApi
().
then
((
res
)
=>
{
console
.
log
(
"
token
"
,
res
);
localStg
.
set
(
"
token
"
,
res
.
data
.
data
);
});
},
beforeDestroy
()
{
// 清理事件监听
window
.
removeEventListener
(
"
resize
"
,
this
.
handleResize
);
// 清理地图资源
if
(
this
.
viewer
)
{
this
.
viewer
.
destroy
();
this
.
viewer
=
null
;
}
// 清理点击事件处理器
if
(
this
.
clickHandler
)
{
this
.
clickHandler
.
destroy
();
this
.
clickHandler
=
null
;
}
// 组件销毁前清理地图资源
if
(
this
.
viewer
)
{
this
.
viewer
.
destroy
();
this
.
viewer
=
null
;
}
// 清理定时器
if
(
this
.
intervaler
)
{
clearInterval
(
this
.
intervaler
);
}
// 清空实体引用
this
.
bgEntities
=
{};
},
methods
:
{
// 新增:清除实体
clearEntities
()
{
if
(
this
.
viewer
&&
this
.
bgEntities
)
{
for
(
let
key
in
this
.
bgEntities
)
{
this
.
viewer
.
entities
.
remove
(
this
.
bgEntities
[
key
]);
delete
this
.
bgEntities
[
key
];
}
}
},
/**
* 初始化Cesium地图
*/
async
initCesium
()
{
Cesium
.
Ion
.
defaultAccessToken
=
"
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI0ZDAxZGFhYy02MjJlLTRiNzktODNhZi00N2VjZGY0NTk4YmIiLCJpZCI6Mjc0NDAxLCJpYXQiOjE3NjMzNDYwNTR9.ZQW2DZ4KaMGbHuwrtIbyI6EdSSvgMJUHmmD74eZW7PQ
"
;
try
{
// 创建Cesium Viewer实例
this
.
viewer
=
new
Cesium
.
Viewer
(
"
cesiumContainer
"
,
{
// 设置地图提供者,这里使用默认的Bing Maps
imageryProvider
:
new
Cesium
.
BingMapsImageryProvider
({
url
:
"
https://dev.virtualearth.net
"
,
key
:
"
AgcbDCAOb9zMfquaT4Z-MdHfx--9wUNrLRiiS7rIElFx8f-4lLulxZ0QnhqX5Lm6
"
,
mapStyle
:
Cesium
.
BingMapsStyle
.
AERIAL
,
}),
// 配置是否显示各种控件
animation
:
false
,
// 动画控件
baseLayerPicker
:
true
,
// 底图选择器
fullscreenButton
:
false
,
// 全屏按钮
geocoder
:
false
,
// 地址搜索
homeButton
:
false
,
// 主页按钮
infoBox
:
false
,
// 信息框
sceneModePicker
:
false
,
// 场景模式选择器
selectionIndicator
:
false
,
// 选择指示器
timeline
:
false
,
// 时间线
navigationHelpButton
:
false
,
// 导航帮助按钮
navigationInstructionsInitiallyVisible
:
false
,
// 设置初始视图位置(中国区域)
center
:
Cesium
.
Cartesian3
.
fromDegrees
(
104.06
,
30.67
,
10000000
),
});
this
.
viewer
.
scene
.
camera
.
setView
({
// 视角-环翠
duration
:
1
,
destination
:
{
x
:
-
2739843.563038797
,
y
:
4357442.794747324
,
z
:
3880768.3292693933
,
},
orientation
:
{
heading
:
6.037000745578596
,
pitch
:
-
1.2499586064720978
,
roll
:
0.000005306352659495417
,
},
});
// 隐藏Cesium logo
this
.
viewer
.
_cesiumWidget
.
_creditContainer
.
style
.
display
=
"
none
"
;
const
VUE_APP_GIS
=
"
http://192.168.2.11:8080/Apps/assets/media/gaoquyingji
"
;
try
{
const
tileset
=
await
Cesium
.
Cesium3DTileset
.
fromUrl
(
VUE_APP_GIS
+
"
/tiles/01_guanwei/tileset.json
"
);
this
.
viewer
.
scene
.
primitives
.
add
(
tileset
);
console
.
log
(
"
倾斜摄影模型加载成功tileset
"
,
tileset
);
if
(
tileset
)
{
this
.
tileset
=
tileset
;
this
.
locateToTileset
();
// 添加鼠标点击事件监听器,用于控制人员信息label显示
this
.
addEntityClickHandler
();
}
}
catch
(
error
)
{
console
.
error
(
`加载倾斜摄影模型失败:
${
error
}
`
);
}
console
.
log
(
"
Cesium地图初始化成功
"
);
}
catch
(
error
)
{
console
.
error
(
"
Cesium地图初始化失败:
"
,
error
);
}
},
/**
* 获取倾斜摄影模型的经纬度并将摄像机视角转向模型上方
*/
locateToTileset
()
{
if
(
!
this
.
tileset
||
!
this
.
viewer
)
{
console
.
error
(
"
模型或视图未准备就绪
"
);
return
;
}
try
{
// 获取模型的边界球
const
boundingSphere
=
this
.
tileset
.
boundingSphere
;
if
(
!
boundingSphere
)
{
console
.
error
(
"
无法获取模型边界
"
);
return
;
}
// 获取模型中心点的笛卡尔坐标
const
center
=
boundingSphere
.
center
;
// 将笛卡尔坐标转换为经纬度坐标
const
cartographic
=
Cesium
.
Cartographic
.
fromCartesian
(
center
);
const
longitude
=
Cesium
.
Math
.
toDegrees
(
cartographic
.
longitude
);
const
latitude
=
Cesium
.
Math
.
toDegrees
(
cartographic
.
latitude
);
const
height
=
cartographic
.
height
;
console
.
log
(
"
倾斜摄影模型中心点经纬度:
"
,
{
longitude
:
longitude
,
latitude
:
latitude
,
height
:
height
,
});
// 计算合适的观察距离 - 基于模型半径的倍数
const
distance
=
boundingSphere
.
radius
*
2.5
;
// 可以根据需要调整倍数
// 设置相机位置在模型上方
const
cameraPosition
=
Cesium
.
Cartesian3
.
fromRadians
(
cartographic
.
longitude
,
cartographic
.
latitude
,
height
+
distance
// 相机高度为模型最高点加上观察距离
);
// 计算相机看向模型中心的方向
const
heading
=
Cesium
.
Math
.
toRadians
(
0
);
// 方向角
const
pitch
=
Cesium
.
Math
.
toRadians
(
-
90
);
// 俯仰角 - 负数表示向下看
const
roll
=
Cesium
.
Math
.
toRadians
(
0
);
// 翻滚角
// 使用flyTo方法平滑过渡到目标位置
this
.
viewer
.
camera
.
flyTo
({
destination
:
cameraPosition
,
orientation
:
{
heading
:
heading
,
pitch
:
pitch
,
roll
:
roll
,
},
duration
:
2
,
// 过渡时间2秒
complete
:
()
=>
{
console
.
log
(
"
相机已成功定位到模型上方
"
);
// this.createPersonModel(); // 定位后创建人员模型
// 根据当前选择的类型创建相应的模型
this
.
createPersonModel
();
// 定位后创建人员模型
},
});
}
catch
(
error
)
{
console
.
error
(
"
定位到模型上方失败:
"
,
error
);
}
},
personCardList
(
fn
)
{
// 将笛卡尔坐标转换为经纬度坐标
const
cartographic
=
Cesium
.
Cartographic
.
fromCartesian
({
x
:
-
2686273.730145489
,
y
:
4293961.185794622
,
z
:
3863430.5618300107
,
});
const
baseLongitude
=
Cesium
.
Math
.
toDegrees
(
cartographic
.
longitude
);
const
baseLatitude
=
Cesium
.
Math
.
toDegrees
(
cartographic
.
latitude
);
const
baseHeight
=
cartographic
.
height
+
1
;
console
.
log
(
"
人员经纬度基准点:
"
,
{
longitude
:
baseLongitude
,
latitude
:
baseLatitude
,
height
:
baseHeight
,
});
// 清除现有的人员列表
this
.
personnelList
=
[];
// 生成10个不同的经纬度坐标
const
maxOffset
=
0.00005
;
for
(
let
index
=
0
;
index
<
10
;
index
++
)
{
// 生成随机偏移量
const
lngOffset
=
(
Math
.
random
()
-
0.5
)
*
2
*
maxOffset
;
const
latOffset
=
(
Math
.
random
()
-
0.5
)
*
2
*
maxOffset
;
this
.
personnelList
.
push
({
lng
:
baseLongitude
+
lngOffset
,
lat
:
baseLatitude
+
latOffset
,
height
:
baseHeight
,
perName
:
"
张三
"
+
index
,
status
:
"
online
"
,
// 在线
avatar
:
"
/static/images/avatars/zhangsan.png
"
,
// 头像
});
}
fn
(
this
.
personnelList
);
},
// 修改:更新点击事件处理器,支持车辆显示
addEntityClickHandler
()
{
// 创建鼠标事件处理器
this
.
clickHandler
=
new
Cesium
.
ScreenSpaceEventHandler
(
this
.
viewer
.
canvas
);
// 监听鼠标左键点击事件
this
.
clickHandler
.
setInputAction
((
click
)
=>
{
// 检测点击位置的实体
const
pickedObject
=
this
.
viewer
.
scene
.
pick
(
click
.
position
);
// 修复条件判断:检查是否有info属性
if
(
Cesium
.
defined
(
pickedObject
)
&&
pickedObject
.
id
&&
pickedObject
.
id
.
info
)
{
// 获取点击的实体
const
entity
=
pickedObject
.
id
;
const
entityInfo
=
entity
.
info
;
// 如果已有详细信息label,则移除它
if
(
entity
.
detailLabel
)
{
this
.
viewer
.
entities
.
remove
(
entity
.
detailLabel
);
delete
entity
.
detailLabel
;
return
;
}
console
.
log
(
"
点击实体了
"
,
entityInfo
);
// 根据实体类型显示不同的信息
let
labelText
=
""
;
// 人员信息
labelText
=
`
${
entityInfo
.
perName
}
\n状态:
${
entityInfo
.
status
===
"
online
"
?
"
在线
"
:
"
离线
"
}
\n高度:
${
entityInfo
.
height
.
toFixed
(
2
)}
m`
;
// 创建详细信息label
const
detailLabel
=
this
.
viewer
.
entities
.
add
({
position
:
entity
.
position
.
getValue
(),
label
:
{
text
:
labelText
,
font
:
"
14px 微软雅黑
"
,
backgroundColor
:
Cesium
.
Color
.
fromCssColorString
(
"
#173349
"
),
showBackground
:
true
,
fillColor
:
Cesium
.
Color
.
WHITE
,
pixelOffset
:
new
Cesium
.
Cartesian2
(
0
,
-
60
),
eyeOffset
:
new
Cesium
.
Cartesian3
(
0
,
0
,
-
10
),
horizontalOrigin
:
Cesium
.
HorizontalOrigin
.
CENTER
,
verticalOrigin
:
Cesium
.
VerticalOrigin
.
TOP
,
scaleByDistance
:
new
Cesium
.
NearFarScalar
(
1000
,
1
,
500000
,
0.5
),
disableDepthTestDistance
:
Number
.
POSITIVE_INFINITY
,
// 确保始终显示在最前面
},
});
// 将详细信息label关联到实体,便于后续管理
entity
.
detailLabel
=
detailLabel
;
}
},
Cesium
.
ScreenSpaceEventType
.
LEFT_CLICK
);
},
// 处理窗口大小变化
handleResize
()
{
// 重新调整Cesium视图大小
if
(
this
.
viewer
)
{
this
.
viewer
.
resize
();
}
// 重新绘制图表
const
chartContainer
=
document
.
getElementById
(
"
trendChart
"
);
if
(
chartContainer
&&
chartContainer
.
firstChild
)
{
chartContainer
.
removeChild
(
chartContainer
.
firstChild
);
this
.
drawTrendChart
();
}
},
// 1. 提取通用实体创建函数
createEntity
(
item
,
type
)
{
const
isPerson
=
type
===
"
person
"
;
const
idField
=
isPerson
?
"
perName
"
:
"
vehicleName
"
;
const
labelColor
=
isPerson
?
Cesium
.
Color
.
YELLOW
:
Cesium
.
Color
.
CYAN
;
const
iconPath
=
isPerson
?
"
/poi-marker-default.png
"
:
"
/poi-marker-vehicle.png
"
;
let
lng
=
Number
(
item
.
lng
);
let
lat
=
Number
(
item
.
lat
);
let
height
=
Number
(
item
.
height
);
let
position
=
Cesium
.
Cartesian3
.
fromDegrees
(
lng
,
lat
,
height
);
console
.
log
(
item
[
idField
],
position
);
// 创建实体
let
entity
=
this
.
viewer
.
entities
.
add
({
position
:
position
,
label
:
{
text
:
item
[
idField
],
font
:
"
16px
"
,
backgroundColor
:
Cesium
.
Color
.
fromCssColorString
(
"
#173349
"
),
showBackground
:
true
,
fillColor
:
labelColor
,
depthTestAgainstTerrain
:
false
,
pixelOffset
:
new
Cesium
.
Cartesian2
(
0
,
-
35
),
disableDepthTestDistance
:
Number
.
POSITIVE_INFINITY
,
// 确保label始终显示在最前面
heightReference
:
Cesium
.
HeightReference
.
CLAMP_TO_3D_TILE
,
// 与billboard保持一致
verticalOrigin
:
Cesium
.
VerticalOrigin
.
TOP
,
// 确保正确的垂直对齐
horizontalOrigin
:
Cesium
.
HorizontalOrigin
.
CENTER
,
// 确保正确的水平对齐
eyeOffset
:
new
Cesium
.
Cartesian3
(
0
,
0
,
0
),
// 调整眼睛偏移量
scaleByDistance
:
new
Cesium
.
NearFarScalar
(
1000
,
1
,
500000
,
0.5
),
// 控制不同距离下的缩放比例
},
billboard
:
{
image
:
iconPath
,
scale
:
0.5
,
heightReference
:
Cesium
.
HeightReference
.
CLAMP_TO_3D_TILE
,
},
description
:
`<div><h4>
${
item
[
idField
]}${
item
.
status
}
</h4></div>`
,
fixedFrame
:
Cesium
.
Transforms
.
eastNorthUpToFixedFrame
(
position
),
});
entity
.
info
=
item
;
entity
.
type
=
type
;
this
.
bgEntities
[
item
[
idField
]]
=
entity
;
return
entity
;
},
// 2. 提取实体更新函数
updateEntity
(
entity
,
item
)
{
let
position
=
Cesium
.
Cartesian3
.
fromDegrees
(
item
.
lng
,
item
.
lat
,
item
.
height
);
entity
.
position
.
setValue
(
position
);
entity
.
fixedFrame
=
Cesium
.
Transforms
.
eastNorthUpToFixedFrame
(
position
);
},
// 3. 提取批量创建实体的函数
createEntities
(
entityList
,
type
)
{
const
isPerson
=
type
===
"
person
"
;
const
idField
=
isPerson
?
"
perName
"
:
"
vehicleName
"
;
for
(
let
item
of
entityList
)
{
this
.
createEntity
(
item
,
type
);
}
},
// 4. 提取批量更新实体的函数(增量更新模式)
updateEntities
(
entityList
,
type
)
{
const
isPerson
=
type
===
"
person
"
;
const
idField
=
isPerson
?
"
perName
"
:
"
vehicleName
"
;
for
(
let
item
of
entityList
)
{
let
entity
=
this
.
bgEntities
[
item
[
idField
]];
if
(
entity
&&
entity
.
type
===
type
)
{
// 更新现有实体
this
.
updateEntity
(
entity
,
item
);
}
else
{
// 创建新实体
this
.
createEntity
(
item
,
type
);
}
}
},
// 5. 提取定时器逻辑为可重用函数
setupEntityUpdateInterval
(
type
,
dataGenerator
,
interval
=
10000
)
{
// 清除现有定时器
if
(
this
.
intervaler
)
{
clearInterval
(
this
.
intervaler
);
this
.
intervaler
=
null
;
}
// 设置新的定时器
this
.
intervaler
=
setInterval
(()
=>
{
console
.
log
(
`开始获取实时
${
type
===
"
person
"
?
"
人员
"
:
"
车辆
"
}
数据`
);
// 生成或获取最新数据
if
(
typeof
dataGenerator
===
"
function
"
)
{
dataGenerator
();
}
const
entityList
=
type
===
"
person
"
?
this
.
personnelList
:
this
.
vehicleList
;
// 更新实体(这里可以选择清除重建或增量更新)
// 方案1:清除所有实体后重建
this
.
clearEntities
();
this
.
createEntities
(
entityList
,
type
);
// 方案2:增量更新(推荐,性能更好)
// this.updateEntities(entityList, type);
},
interval
);
},
// 修改后的createPersonModel方法
createPersonModel
()
{
// 清除现有定时器
if
(
this
.
intervaler
)
{
clearInterval
(
this
.
intervaler
);
this
.
intervaler
=
null
;
}
// 清除现有实体
this
.
clearEntities
();
// 立即生成并显示人员实体
console
.
log
(
"
立即创建人员实体
"
);
this
.
personCardList
((
list
)
=>
{
console
.
log
(
"
人员数据
"
,
this
.
personnelList
);
this
.
createEntities
(
this
.
personnelList
,
"
person
"
);
});
// 设置定时刷新
this
.
setupEntityUpdateInterval
(
"
person
"
,
()
=>
{
this
.
personCardList
(()
=>
{
console
.
log
(
"
人员数据
"
,
this
.
personnelList
);
});
});
},
},
};
</
script
>
<
style
scoped
lang=
"scss"
>
.home
{
width
:
100%
;
height
:
100vh
;
position
:
relative
;
overflow
:
hidden
;
blockquote
{
padding
:
10px
20px
;
margin
:
0
0
20px
;
font-size
:
17
.5px
;
border-left
:
5px
solid
#eee
;
}
hr
{
margin-top
:
20px
;
margin-bottom
:
20px
;
border
:
0
;
border-top
:
1px
solid
#eee
;
}
.col-item
{
margin-bottom
:
20px
;
}
ul
{
padding
:
0
;
margin
:
0
;
}
font-family
:
"open sans"
,
"Helvetica Neue"
,
Helvetica
,
Arial
,
sans-serif
;
font-size
:
13px
;
color
:
#676a6c
;
overflow-x
:
hidden
;
ul
{
list-style-type
:
none
;
}
h4
{
margin-top
:
0px
;
}
h2
{
margin-top
:
10px
;
font-size
:
26px
;
font-weight
:
100
;
}
p
{
margin-top
:
10px
;
b
{
font-weight
:
700
;
}
}
.update-log
{
ol
{
display
:
block
;
list-style-type
:
decimal
;
margin-block-start
:
1em
;
margin-block-end
:
1em
;
margin-inline-start
:
0
;
margin-inline-end
:
0
;
padding-inline-start
:
40px
;
}
}
// Cesium容器样式
.cesium-container
{
// width: 100vw;
// height: 100vh;
width
:
87vw
;
height
:
87vh
;
position
:
absolute
;
top
:
0
;
left
:
0
;
z-index
:
1
;
}
}
</
style
>
\ No newline at end of file
src/views/index-wl.vue
View file @
3e2b8acf
...
...
@@ -39,17 +39,36 @@
</div>
<div
class=
"fence-controls"
>
<button
@
click=
"startCreatingFence"
:disabled=
"isCreatingFence"
>
<button
@
click=
"startCreatingFence"
:disabled=
"isCreatingFence || isEditingFence"
>
创建围栏
</button>
<button
@
click=
"editSelectedFence"
:disabled=
"!selectedFence"
>
编辑围栏
<button
@
click=
"editSelectedFence"
:disabled=
"!selectedFence || isCreatingFence || isEditingFence"
:class=
"
{ editing: isEditingFence }"
>
{{
isEditingFence
?
"
编辑中
"
:
"
编辑围栏
"
}}
</button>
<button
@
click=
"deleteSelectedFence"
:disabled=
"!selectedFence"
>
<button
@
click=
"deleteSelectedFence"
:disabled=
"!selectedFence || isCreatingFence || isEditingFence"
>
删除围栏
</button>
<button
@
click=
"stopCreatingFence"
:disabled=
"!isCreatingFence"
>
取消创建
<button
@
click=
"
isCreatingFence
? stopCreatingFence
: isEditingFence
? completeEditingFence
: null
"
:disabled=
"!isCreatingFence && !isEditingFence"
>
{{
isCreatingFence
?
"
取消创建
"
:
"
完成编辑
"
}}
</button>
</div>
...
...
@@ -122,6 +141,15 @@ export default {
drawingEntity
:
null
,
// 绘制中的实体
fenceEntities
:
{},
// 围栏实体映射
// 电子围栏编辑相关
isEditingFence
:
false
,
// 是否正在编辑围栏
editingFence
:
null
,
// 当前编辑的围栏
vertexEntities
:
[],
// 顶点实体集合
isDraggingVertex
:
false
,
// 是否正在拖拽顶点
draggedVertexIndex
:
-
1
,
// 当前拖拽的顶点索引
temporaryPointEntities
:
null
,
// 临时点实体
originalRightClickHandler
:
null
,
// 原始右键点击处理器
// 告警相关
alarms
:
[],
// 告警列表
};
...
...
@@ -152,6 +180,8 @@ export default {
if
(
this
.
boundaryCheckInterval
)
{
clearInterval
(
this
.
boundaryCheckInterval
);
}
// 清理编辑状态相关资源
this
.
stopEditingFence
();
},
computed
:
{
// 获取当前类型的围栏列表
...
...
@@ -162,6 +192,294 @@ export default {
},
},
methods
:
{
// 修改编辑围栏方法
editSelectedFence
()
{
if
(
!
this
.
selectedFence
||
this
.
isCreatingFence
)
return
;
this
.
startEditingFence
(
this
.
selectedFence
);
},
// 开始编辑围栏
startEditingFence
(
fence
)
{
if
(
!
this
.
viewer
||
this
.
isCreatingFence
)
{
console
.
error
(
"
Cesium viewer未初始化或正在创建围栏
"
);
return
;
}
// 设置编辑状态
this
.
isEditingFence
=
true
;
this
.
editingFence
=
fence
;
// 清除之前可能存在的顶点
this
.
clearVertexEntities
();
console
.
log
(
"
显示围栏顶点
"
);
// 显示围栏顶点
this
.
showFenceVertices
(
fence
);
console
.
log
(
"
添加编辑模式事件监听
"
);
// 添加鼠标事件监听
this
.
addEditModeEventListeners
();
// 显示提示信息
alert
(
"
围栏编辑模式已开启,可拖拽黄色顶点改变围栏形状,右键完成编辑
"
);
},
// 显示围栏顶点
showFenceVertices
(
fence
)
{
if
(
!
this
.
viewer
||
!
fence
||
!
fence
.
points
||
fence
.
points
.
length
===
0
)
{
console
.
error
(
"
无法显示围栏顶点:参数无效
"
);
return
;
}
console
.
log
(
"
创建顶点实体,共
"
,
fence
.
points
.
length
,
"
个顶点
"
);
// 创建顶点实体
fence
.
points
.
forEach
((
point
,
index
)
=>
{
try
{
const
vertexEntity
=
this
.
viewer
.
entities
.
add
({
position
:
Cesium
.
Cartesian3
.
fromDegrees
(
point
.
lng
,
point
.
lat
,
10
),
point
:
{
pixelSize
:
12
,
// 增大顶点大小,更容易点击
color
:
Cesium
.
Color
.
YELLOW
,
outlineColor
:
Cesium
.
Color
.
BLACK
,
outlineWidth
:
2
,
heightReference
:
Cesium
.
HeightReference
.
CLAMP_TO_3D_TILE
,
disableDepthTestDistance
:
Number
.
POSITIVE_INFINITY
,
// 确保显示在最前面
},
// 为顶点添加ID用于识别
properties
:
{
vertexIndex
:
index
,
isFenceVertex
:
true
,
},
});
this
.
vertexEntities
.
push
(
vertexEntity
);
console
.
log
(
"
创建顶点实体
"
,
index
,
"
成功
"
);
}
catch
(
error
)
{
console
.
error
(
"
创建顶点实体失败:
"
,
error
);
}
});
},
// 清除顶点实体
clearVertexEntities
()
{
if
(
this
.
viewer
&&
this
.
vertexEntities
&&
this
.
vertexEntities
.
length
>
0
)
{
console
.
log
(
"
清除顶点实体
"
);
this
.
vertexEntities
.
forEach
((
entity
)
=>
{
try
{
this
.
viewer
.
entities
.
remove
(
entity
);
}
catch
(
error
)
{
console
.
error
(
"
移除顶点实体失败:
"
,
error
);
}
});
this
.
vertexEntities
=
[];
}
},
// 添加编辑模式事件监听
addEditModeEventListeners
()
{
if
(
!
this
.
viewer
)
{
console
.
error
(
"
Cesium viewer未初始化
"
);
return
;
}
console
.
log
(
"
移除现有事件监听器
"
);
// 移除现有的事件监听器,避免冲突
try
{
this
.
viewer
.
screenSpaceEventHandler
.
removeInputAction
(
Cesium
.
ScreenSpaceEventType
.
LEFT_DOWN
);
this
.
viewer
.
screenSpaceEventHandler
.
removeInputAction
(
Cesium
.
ScreenSpaceEventType
.
MOUSE_MOVE
);
this
.
viewer
.
screenSpaceEventHandler
.
removeInputAction
(
Cesium
.
ScreenSpaceEventType
.
LEFT_UP
);
this
.
viewer
.
screenSpaceEventHandler
.
removeInputAction
(
Cesium
.
ScreenSpaceEventType
.
RIGHT_CLICK
);
}
catch
(
error
)
{
console
.
log
(
"
移除事件监听器时出错:
"
,
error
);
}
console
.
log
(
"
添加左键按下事件
"
);
// 添加左键按下事件用于开始拖拽
this
.
viewer
.
screenSpaceEventHandler
.
setInputAction
((
event
)
=>
{
this
.
handleVertexDragStart
(
event
);
},
Cesium
.
ScreenSpaceEventType
.
LEFT_DOWN
);
console
.
log
(
"
添加鼠标移动事件
"
);
// 添加鼠标移动事件用于拖拽中
this
.
viewer
.
screenSpaceEventHandler
.
setInputAction
((
event
)
=>
{
this
.
handleVertexDragging
(
event
);
},
Cesium
.
ScreenSpaceEventType
.
MOUSE_MOVE
);
console
.
log
(
"
添加左键释放事件
"
);
// 添加左键释放事件用于结束拖拽
this
.
viewer
.
screenSpaceEventHandler
.
setInputAction
((
event
)
=>
{
this
.
handleVertexDragEnd
(
event
);
},
Cesium
.
ScreenSpaceEventType
.
LEFT_UP
);
console
.
log
(
"
添加右键点击事件
"
);
// 添加右键点击事件用于完成编辑
this
.
viewer
.
screenSpaceEventHandler
.
setInputAction
((
event
)
=>
{
this
.
completeEditingFence
();
},
Cesium
.
ScreenSpaceEventType
.
RIGHT_CLICK
);
},
// 处理顶点拖拽开始
handleVertexDragStart
(
event
)
{
console
.
log
(
"
开始拖拽顶点
"
);
const
pickedObject
=
this
.
viewer
.
scene
.
pick
(
event
.
position
);
// 检查是否点击了顶点
if
(
pickedObject
&&
pickedObject
.
id
&&
pickedObject
.
id
.
properties
&&
pickedObject
.
id
.
properties
.
isFenceVertex
&&
pickedObject
.
id
.
properties
.
vertexIndex
!==
undefined
)
{
this
.
isDraggingVertex
=
true
;
this
.
draggedVertexIndex
=
pickedObject
.
id
.
properties
.
vertexIndex
;
// 改变拖拽中顶点的样式
pickedObject
.
id
.
point
.
color
=
Cesium
.
Color
.
RED
;
console
.
log
(
"
开始拖拽顶点
"
,
this
.
draggedVertexIndex
);
}
},
// 处理顶点拖拽中
handleVertexDragging
(
event
)
{
if
(
!
this
.
isDraggingVertex
||
this
.
draggedVertexIndex
<
0
||
!
this
.
editingFence
)
{
return
;
}
const
ray
=
this
.
viewer
.
camera
.
getPickRay
(
event
.
endPosition
);
let
intersection
;
// 首先尝试从3D模型上拾取点
if
(
this
.
tileset
)
{
intersection
=
this
.
viewer
.
scene
.
pickFromRay
(
ray
,
[
this
.
tileset
]);
}
// 如果没有从模型上拾取到点,则从地球上拾取
if
(
!
intersection
||
!
intersection
.
position
)
{
intersection
=
this
.
viewer
.
scene
.
globe
.
pick
(
ray
,
this
.
viewer
.
scene
);
}
if
(
intersection
)
{
const
position
=
intersection
.
position
||
intersection
;
const
cartographic
=
Cesium
.
Cartographic
.
fromCartesian
(
position
);
const
longitude
=
Cesium
.
Math
.
toDegrees
(
cartographic
.
longitude
);
const
latitude
=
Cesium
.
Math
.
toDegrees
(
cartographic
.
latitude
);
// 更新围栏点坐标
this
.
editingFence
.
points
[
this
.
draggedVertexIndex
]
=
{
lng
:
longitude
,
lat
:
latitude
,
};
// 更新顶点实体位置
if
(
this
.
vertexEntities
[
this
.
draggedVertexIndex
])
{
this
.
vertexEntities
[
this
.
draggedVertexIndex
].
position
=
Cesium
.
Cartesian3
.
fromDegrees
(
longitude
,
latitude
,
10
);
}
// 重新渲染围栏
this
.
renderFence
(
this
.
editingFence
);
}
},
// 处理顶点拖拽结束
handleVertexDragEnd
(
event
)
{
if
(
this
.
isDraggingVertex
&&
this
.
draggedVertexIndex
>=
0
&&
this
.
vertexEntities
[
this
.
draggedVertexIndex
]
)
{
// 恢复顶点样式
this
.
vertexEntities
[
this
.
draggedVertexIndex
].
point
.
color
=
Cesium
.
Color
.
YELLOW
;
console
.
log
(
"
结束拖拽顶点
"
,
this
.
draggedVertexIndex
);
}
this
.
isDraggingVertex
=
false
;
this
.
draggedVertexIndex
=
-
1
;
},
// 完成围栏编辑
completeEditingFence
()
{
if
(
!
this
.
isEditingFence
||
!
this
.
editingFence
)
{
return
;
}
console
.
log
(
"
完成围栏编辑
"
);
// 移除顶点显示
this
.
clearVertexEntities
();
// 重置编辑状态
this
.
isEditingFence
=
false
;
this
.
editingFence
=
null
;
this
.
isDraggingVertex
=
false
;
this
.
draggedVertexIndex
=
-
1
;
// 移除编辑模式的事件监听
this
.
removeEditModeEventListeners
();
// 重新渲染所有围栏
this
.
renderAllFences
();
alert
(
"
围栏编辑已完成
"
);
},
// 移除编辑模式事件监听
removeEditModeEventListeners
()
{
if
(
!
this
.
viewer
)
{
return
;
}
try
{
console
.
log
(
"
移除编辑模式事件监听
"
);
// 移除编辑模式添加的事件
this
.
viewer
.
screenSpaceEventHandler
.
removeInputAction
(
Cesium
.
ScreenSpaceEventType
.
LEFT_DOWN
);
this
.
viewer
.
screenSpaceEventHandler
.
removeInputAction
(
Cesium
.
ScreenSpaceEventType
.
MOUSE_MOVE
);
this
.
viewer
.
screenSpaceEventHandler
.
removeInputAction
(
Cesium
.
ScreenSpaceEventType
.
LEFT_UP
);
this
.
viewer
.
screenSpaceEventHandler
.
removeInputAction
(
Cesium
.
ScreenSpaceEventType
.
RIGHT_CLICK
);
}
catch
(
error
)
{
console
.
log
(
"
移除编辑事件监听时出错:
"
,
error
);
}
},
// 停止编辑围栏
stopEditingFence
()
{
if
(
this
.
isEditingFence
)
{
console
.
log
(
"
停止编辑围栏
"
);
this
.
completeEditingFence
();
}
},
// 新增:清除实体
clearEntities
()
{
if
(
this
.
viewer
&&
this
.
bgEntities
)
{
...
...
@@ -775,8 +1093,14 @@ export default {
},
// 停止创建电子围栏
stopCreatingFence
()
{
console
.
log
(
"
停止创建围栏
"
);
this
.
isCreatingFence
=
false
;
// 确保同时停止编辑状态
this
.
stopEditingFence
();
// ... 现有代码 ...
// 移除临时绘制的围栏
if
(
this
.
drawingEntity
&&
this
.
viewer
)
{
this
.
viewer
.
entities
.
remove
(
this
.
drawingEntity
);
...
...
@@ -793,7 +1117,6 @@ export default {
// 移除事件监听
if
(
this
.
viewer
)
{
// 只移除我们添加的事件处理器
try
{
this
.
viewer
.
screenSpaceEventHandler
.
removeInputAction
(
Cesium
.
ScreenSpaceEventType
.
LEFT_CLICK
...
...
@@ -812,6 +1135,12 @@ export default {
// 选择围栏
selectFence
(
fence
)
{
console
.
log
(
"
选择围栏:
"
,
fence
.
name
);
// 停止当前编辑
if
(
this
.
isEditingFence
)
{
this
.
stopEditingFence
();
}
this
.
selectedFence
=
fence
;
// 高亮显示选中的围栏
...
...
@@ -820,12 +1149,13 @@ export default {
// 编辑选中的围栏
editSelectedFence
()
{
// 这里可以实现围栏编辑功能,简化版暂时只允许重命名
const
newName
=
prompt
(
"
请输入新的围栏名称:
"
,
this
.
selectedFence
.
name
);
if
(
newName
)
{
this
.
selectedFence
.
name
=
newName
;
this
.
renderAllFences
();
if
(
!
this
.
selectedFence
||
this
.
isCreatingFence
)
{
console
.
log
(
"
无法编辑围栏:未选中围栏或正在创建围栏
"
);
return
;
}
console
.
log
(
"
开始编辑围栏:
"
,
this
.
selectedFence
.
name
);
this
.
startEditingFence
(
this
.
selectedFence
);
},
// 删除选中的围栏
...
...
@@ -1188,6 +1518,15 @@ export default {
cursor
:
not
-
allowed
;
}
}
// 添加编辑中的按钮样式
button
.editing
{
background
:
#ff6600
!
important
;
&
:hover
{
background
:
#ff8833
!
important
;
}
}
}
.fence-list
{
...
...
src/views/index.vue
View file @
3e2b8acf
<
template
>
<div
class=
"app-container home"
>
<!-- Cesium地图容器 -->
<div
id=
"cesiumContainer"
class=
"cesium-container"
></div>
</div>
<div
class=
"app-container home"
>
首页
</div>
</
template
>
<
script
>
import
{
getTokenApi
}
from
"
@/api/token
"
;
import
{
localStg
}
from
"
@/utils/storage
"
;
export
default
{
name
:
"
Index
"
,
data
()
{
return
{
// 版本号
version
:
"
3.8.9
"
,
// Cesium查看器实例
viewer
:
null
,
tileset
:
null
,
personnelList
:
[
{
longitude
:
121.70710830038986
,
latitude
:
36.853636402927986
,
height
:
100
,
name
:
"
张三
"
,
status
:
"
online
"
,
// 在线
avatar
:
"
/static/images/avatars/zhangsan.png
"
,
// 头像
},
{
longitude
:
121.70810830038986
,
latitude
:
36.854636402927986
,
height
:
100
,
name
:
"
李四
"
,
status
:
"
offline
"
,
// 离线
avatar
:
"
/static/images/avatars/lisi.png
"
,
// 头像
},
// 其他人员数据...
],
intervaler
:
null
,
bgEntities
:
{},
// 所有的key都对应一个实体对象。而人员的实体对应的key不是数字。
};
},
mounted
()
{
// 组件挂载后初始化地图
this
.
initCesium
();
// 监听窗口大小变化
window
.
addEventListener
(
"
resize
"
,
this
.
handleResize
);
},
beforeMount
()
{
localStg
.
set
(
"
token
"
,
222233
);
if
(
localStg
.
get
(
"
token
"
))
{
return
;
}
// 组件挂载前获取token
getTokenApi
().
then
((
res
)
=>
{
console
.
log
(
"
token
"
,
res
);
localStg
.
set
(
"
token
"
,
res
.
data
.
data
);
});
},
beforeDestroy
()
{
// 清理事件监听
window
.
removeEventListener
(
"
resize
"
,
this
.
handleResize
);
// 清理地图资源
if
(
this
.
viewer
)
{
this
.
viewer
.
destroy
();
this
.
viewer
=
null
;
}
// 清理点击事件处理器
if
(
this
.
clickHandler
)
{
this
.
clickHandler
.
destroy
();
this
.
clickHandler
=
null
;
}
// 组件销毁前清理地图资源
if
(
this
.
viewer
)
{
this
.
viewer
.
destroy
();
this
.
viewer
=
null
;
}
// 清理定时器
if
(
this
.
intervaler
)
{
clearInterval
(
this
.
intervaler
);
}
// 清空实体引用
this
.
bgEntities
=
{};
},
methods
:
{
// 新增:清除实体
clearEntities
()
{
if
(
this
.
viewer
&&
this
.
bgEntities
)
{
for
(
let
key
in
this
.
bgEntities
)
{
this
.
viewer
.
entities
.
remove
(
this
.
bgEntities
[
key
]);
delete
this
.
bgEntities
[
key
];
}
}
},
/**
* 初始化Cesium地图
*/
async
initCesium
()
{
Cesium
.
Ion
.
defaultAccessToken
=
"
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI0ZDAxZGFhYy02MjJlLTRiNzktODNhZi00N2VjZGY0NTk4YmIiLCJpZCI6Mjc0NDAxLCJpYXQiOjE3NjMzNDYwNTR9.ZQW2DZ4KaMGbHuwrtIbyI6EdSSvgMJUHmmD74eZW7PQ
"
;
try
{
// 创建Cesium Viewer实例
this
.
viewer
=
new
Cesium
.
Viewer
(
"
cesiumContainer
"
,
{
// 设置地图提供者,这里使用默认的Bing Maps
imageryProvider
:
new
Cesium
.
BingMapsImageryProvider
({
url
:
"
https://dev.virtualearth.net
"
,
key
:
"
AgcbDCAOb9zMfquaT4Z-MdHfx--9wUNrLRiiS7rIElFx8f-4lLulxZ0QnhqX5Lm6
"
,
mapStyle
:
Cesium
.
BingMapsStyle
.
AERIAL
,
}),
// 配置是否显示各种控件
animation
:
false
,
// 动画控件
baseLayerPicker
:
true
,
// 底图选择器
fullscreenButton
:
false
,
// 全屏按钮
geocoder
:
false
,
// 地址搜索
homeButton
:
false
,
// 主页按钮
infoBox
:
false
,
// 信息框
sceneModePicker
:
false
,
// 场景模式选择器
selectionIndicator
:
false
,
// 选择指示器
timeline
:
false
,
// 时间线
navigationHelpButton
:
false
,
// 导航帮助按钮
navigationInstructionsInitiallyVisible
:
false
,
// 设置初始视图位置(中国区域)
center
:
Cesium
.
Cartesian3
.
fromDegrees
(
104.06
,
30.67
,
10000000
),
});
this
.
viewer
.
scene
.
camera
.
setView
({
// 视角-环翠
duration
:
1
,
destination
:
{
x
:
-
2739843.563038797
,
y
:
4357442.794747324
,
z
:
3880768.3292693933
,
},
orientation
:
{
heading
:
6.037000745578596
,
pitch
:
-
1.2499586064720978
,
roll
:
0.000005306352659495417
,
},
});
// 隐藏Cesium logo
this
.
viewer
.
_cesiumWidget
.
_creditContainer
.
style
.
display
=
"
none
"
;
const
VUE_APP_GIS
=
"
http://192.168.2.11:8080/Apps/assets/media/gaoquyingji
"
;
try
{
const
tileset
=
await
Cesium
.
Cesium3DTileset
.
fromUrl
(
VUE_APP_GIS
+
"
/tiles/01_guanwei/tileset.json
"
);
this
.
viewer
.
scene
.
primitives
.
add
(
tileset
);
console
.
log
(
"
倾斜摄影模型加载成功tileset
"
,
tileset
);
if
(
tileset
)
{
this
.
tileset
=
tileset
;
this
.
locateToTileset
();
// 添加鼠标点击事件监听器,用于控制人员信息label显示
this
.
addEntityClickHandler
();
}
}
catch
(
error
)
{
console
.
error
(
`加载倾斜摄影模型失败:
${
error
}
`
);
}
console
.
log
(
"
Cesium地图初始化成功
"
);
}
catch
(
error
)
{
console
.
error
(
"
Cesium地图初始化失败:
"
,
error
);
}
},
/**
* 获取倾斜摄影模型的经纬度并将摄像机视角转向模型上方
*/
locateToTileset
()
{
if
(
!
this
.
tileset
||
!
this
.
viewer
)
{
console
.
error
(
"
模型或视图未准备就绪
"
);
return
;
}
try
{
// 获取模型的边界球
const
boundingSphere
=
this
.
tileset
.
boundingSphere
;
if
(
!
boundingSphere
)
{
console
.
error
(
"
无法获取模型边界
"
);
return
;
}
// 获取模型中心点的笛卡尔坐标
const
center
=
boundingSphere
.
center
;
// 将笛卡尔坐标转换为经纬度坐标
const
cartographic
=
Cesium
.
Cartographic
.
fromCartesian
(
center
);
const
longitude
=
Cesium
.
Math
.
toDegrees
(
cartographic
.
longitude
);
const
latitude
=
Cesium
.
Math
.
toDegrees
(
cartographic
.
latitude
);
const
height
=
cartographic
.
height
;
console
.
log
(
"
倾斜摄影模型中心点经纬度:
"
,
{
longitude
:
longitude
,
latitude
:
latitude
,
height
:
height
,
});
// 计算合适的观察距离 - 基于模型半径的倍数
const
distance
=
boundingSphere
.
radius
*
2.5
;
// 可以根据需要调整倍数
// 设置相机位置在模型上方
const
cameraPosition
=
Cesium
.
Cartesian3
.
fromRadians
(
cartographic
.
longitude
,
cartographic
.
latitude
,
height
+
distance
// 相机高度为模型最高点加上观察距离
);
// 计算相机看向模型中心的方向
const
heading
=
Cesium
.
Math
.
toRadians
(
0
);
// 方向角
const
pitch
=
Cesium
.
Math
.
toRadians
(
-
90
);
// 俯仰角 - 负数表示向下看
const
roll
=
Cesium
.
Math
.
toRadians
(
0
);
// 翻滚角
// 使用flyTo方法平滑过渡到目标位置
this
.
viewer
.
camera
.
flyTo
({
destination
:
cameraPosition
,
orientation
:
{
heading
:
heading
,
pitch
:
pitch
,
roll
:
roll
,
},
duration
:
2
,
// 过渡时间2秒
complete
:
()
=>
{
console
.
log
(
"
相机已成功定位到模型上方
"
);
// this.createPersonModel(); // 定位后创建人员模型
// 根据当前选择的类型创建相应的模型
this
.
createPersonModel
();
// 定位后创建人员模型
},
});
}
catch
(
error
)
{
console
.
error
(
"
定位到模型上方失败:
"
,
error
);
}
},
personCardList
(
fn
)
{
// 将笛卡尔坐标转换为经纬度坐标
const
cartographic
=
Cesium
.
Cartographic
.
fromCartesian
({
x
:
-
2686273.730145489
,
y
:
4293961.185794622
,
z
:
3863430.5618300107
,
});
const
baseLongitude
=
Cesium
.
Math
.
toDegrees
(
cartographic
.
longitude
);
const
baseLatitude
=
Cesium
.
Math
.
toDegrees
(
cartographic
.
latitude
);
const
baseHeight
=
cartographic
.
height
+
1
;
console
.
log
(
"
人员经纬度基准点:
"
,
{
longitude
:
baseLongitude
,
latitude
:
baseLatitude
,
height
:
baseHeight
,
});
// 清除现有的人员列表
this
.
personnelList
=
[];
// 生成10个不同的经纬度坐标
const
maxOffset
=
0.00005
;
for
(
let
index
=
0
;
index
<
10
;
index
++
)
{
// 生成随机偏移量
const
lngOffset
=
(
Math
.
random
()
-
0.5
)
*
2
*
maxOffset
;
const
latOffset
=
(
Math
.
random
()
-
0.5
)
*
2
*
maxOffset
;
this
.
personnelList
.
push
({
lng
:
baseLongitude
+
lngOffset
,
lat
:
baseLatitude
+
latOffset
,
height
:
baseHeight
,
perName
:
"
张三
"
+
index
,
status
:
"
online
"
,
// 在线
avatar
:
"
/static/images/avatars/zhangsan.png
"
,
// 头像
});
}
fn
(
this
.
personnelList
);
},
// 修改:更新点击事件处理器,支持车辆显示
addEntityClickHandler
()
{
// 创建鼠标事件处理器
this
.
clickHandler
=
new
Cesium
.
ScreenSpaceEventHandler
(
this
.
viewer
.
canvas
);
// 监听鼠标左键点击事件
this
.
clickHandler
.
setInputAction
((
click
)
=>
{
// 检测点击位置的实体
const
pickedObject
=
this
.
viewer
.
scene
.
pick
(
click
.
position
);
// 修复条件判断:检查是否有info属性
if
(
Cesium
.
defined
(
pickedObject
)
&&
pickedObject
.
id
&&
pickedObject
.
id
.
info
)
{
// 获取点击的实体
const
entity
=
pickedObject
.
id
;
const
entityInfo
=
entity
.
info
;
// 如果已有详细信息label,则移除它
if
(
entity
.
detailLabel
)
{
this
.
viewer
.
entities
.
remove
(
entity
.
detailLabel
);
delete
entity
.
detailLabel
;
return
;
}
console
.
log
(
"
点击实体了
"
,
entityInfo
);
// 根据实体类型显示不同的信息
let
labelText
=
""
;
// 人员信息
labelText
=
`
${
entityInfo
.
perName
}
\n状态:
${
entityInfo
.
status
===
"
online
"
?
"
在线
"
:
"
离线
"
}
\n高度:
${
entityInfo
.
height
.
toFixed
(
2
)}
m`
;
// 创建详细信息label
const
detailLabel
=
this
.
viewer
.
entities
.
add
({
position
:
entity
.
position
.
getValue
(),
label
:
{
text
:
labelText
,
font
:
"
14px 微软雅黑
"
,
backgroundColor
:
Cesium
.
Color
.
fromCssColorString
(
"
#173349
"
),
showBackground
:
true
,
fillColor
:
Cesium
.
Color
.
WHITE
,
pixelOffset
:
new
Cesium
.
Cartesian2
(
0
,
-
60
),
eyeOffset
:
new
Cesium
.
Cartesian3
(
0
,
0
,
-
10
),
horizontalOrigin
:
Cesium
.
HorizontalOrigin
.
CENTER
,
verticalOrigin
:
Cesium
.
VerticalOrigin
.
TOP
,
scaleByDistance
:
new
Cesium
.
NearFarScalar
(
1000
,
1
,
500000
,
0.5
),
disableDepthTestDistance
:
Number
.
POSITIVE_INFINITY
,
// 确保始终显示在最前面
},
});
// 将详细信息label关联到实体,便于后续管理
entity
.
detailLabel
=
detailLabel
;
}
},
Cesium
.
ScreenSpaceEventType
.
LEFT_CLICK
);
},
// 处理窗口大小变化
handleResize
()
{
// 重新调整Cesium视图大小
if
(
this
.
viewer
)
{
this
.
viewer
.
resize
();
}
// 重新绘制图表
const
chartContainer
=
document
.
getElementById
(
"
trendChart
"
);
if
(
chartContainer
&&
chartContainer
.
firstChild
)
{
chartContainer
.
removeChild
(
chartContainer
.
firstChild
);
this
.
drawTrendChart
();
}
},
// 1. 提取通用实体创建函数
createEntity
(
item
,
type
)
{
const
isPerson
=
type
===
"
person
"
;
const
idField
=
isPerson
?
"
perName
"
:
"
vehicleName
"
;
const
labelColor
=
isPerson
?
Cesium
.
Color
.
YELLOW
:
Cesium
.
Color
.
CYAN
;
const
iconPath
=
isPerson
?
"
/poi-marker-default.png
"
:
"
/poi-marker-vehicle.png
"
;
let
lng
=
Number
(
item
.
lng
);
let
lat
=
Number
(
item
.
lat
);
let
height
=
Number
(
item
.
height
);
let
position
=
Cesium
.
Cartesian3
.
fromDegrees
(
lng
,
lat
,
height
);
console
.
log
(
item
[
idField
],
position
);
// 创建实体
let
entity
=
this
.
viewer
.
entities
.
add
({
position
:
position
,
label
:
{
text
:
item
[
idField
],
font
:
"
16px
"
,
backgroundColor
:
Cesium
.
Color
.
fromCssColorString
(
"
#173349
"
),
showBackground
:
true
,
fillColor
:
labelColor
,
depthTestAgainstTerrain
:
false
,
pixelOffset
:
new
Cesium
.
Cartesian2
(
0
,
-
35
),
disableDepthTestDistance
:
Number
.
POSITIVE_INFINITY
,
// 确保label始终显示在最前面
heightReference
:
Cesium
.
HeightReference
.
CLAMP_TO_3D_TILE
,
// 与billboard保持一致
verticalOrigin
:
Cesium
.
VerticalOrigin
.
TOP
,
// 确保正确的垂直对齐
horizontalOrigin
:
Cesium
.
HorizontalOrigin
.
CENTER
,
// 确保正确的水平对齐
eyeOffset
:
new
Cesium
.
Cartesian3
(
0
,
0
,
0
),
// 调整眼睛偏移量
scaleByDistance
:
new
Cesium
.
NearFarScalar
(
1000
,
1
,
500000
,
0.5
),
// 控制不同距离下的缩放比例
},
billboard
:
{
image
:
iconPath
,
scale
:
0.5
,
heightReference
:
Cesium
.
HeightReference
.
CLAMP_TO_3D_TILE
,
},
description
:
`<div><h4>
${
item
[
idField
]}${
item
.
status
}
</h4></div>`
,
fixedFrame
:
Cesium
.
Transforms
.
eastNorthUpToFixedFrame
(
position
),
});
entity
.
info
=
item
;
entity
.
type
=
type
;
this
.
bgEntities
[
item
[
idField
]]
=
entity
;
return
entity
;
},
// 2. 提取实体更新函数
updateEntity
(
entity
,
item
)
{
let
position
=
Cesium
.
Cartesian3
.
fromDegrees
(
item
.
lng
,
item
.
lat
,
item
.
height
);
entity
.
position
.
setValue
(
position
);
entity
.
fixedFrame
=
Cesium
.
Transforms
.
eastNorthUpToFixedFrame
(
position
);
},
// 3. 提取批量创建实体的函数
createEntities
(
entityList
,
type
)
{
const
isPerson
=
type
===
"
person
"
;
const
idField
=
isPerson
?
"
perName
"
:
"
vehicleName
"
;
for
(
let
item
of
entityList
)
{
this
.
createEntity
(
item
,
type
);
}
},
// 4. 提取批量更新实体的函数(增量更新模式)
updateEntities
(
entityList
,
type
)
{
const
isPerson
=
type
===
"
person
"
;
const
idField
=
isPerson
?
"
perName
"
:
"
vehicleName
"
;
for
(
let
item
of
entityList
)
{
let
entity
=
this
.
bgEntities
[
item
[
idField
]];
if
(
entity
&&
entity
.
type
===
type
)
{
// 更新现有实体
this
.
updateEntity
(
entity
,
item
);
}
else
{
// 创建新实体
this
.
createEntity
(
item
,
type
);
}
}
},
// 5. 提取定时器逻辑为可重用函数
setupEntityUpdateInterval
(
type
,
dataGenerator
,
interval
=
10000
)
{
// 清除现有定时器
if
(
this
.
intervaler
)
{
clearInterval
(
this
.
intervaler
);
this
.
intervaler
=
null
;
}
// 设置新的定时器
this
.
intervaler
=
setInterval
(()
=>
{
console
.
log
(
`开始获取实时
${
type
===
"
person
"
?
"
人员
"
:
"
车辆
"
}
数据`
);
// 生成或获取最新数据
if
(
typeof
dataGenerator
===
"
function
"
)
{
dataGenerator
();
}
const
entityList
=
type
===
"
person
"
?
this
.
personnelList
:
this
.
vehicleList
;
// 更新实体(这里可以选择清除重建或增量更新)
// 方案1:清除所有实体后重建
this
.
clearEntities
();
this
.
createEntities
(
entityList
,
type
);
// 方案2:增量更新(推荐,性能更好)
// this.updateEntities(entityList, type);
},
interval
);
},
// 修改后的createPersonModel方法
createPersonModel
()
{
// 清除现有定时器
if
(
this
.
intervaler
)
{
clearInterval
(
this
.
intervaler
);
this
.
intervaler
=
null
;
}
// 清除现有实体
this
.
clearEntities
();
// 立即生成并显示人员实体
console
.
log
(
"
立即创建人员实体
"
);
this
.
personCardList
((
list
)
=>
{
console
.
log
(
"
人员数据
"
,
this
.
personnelList
);
this
.
createEntities
(
this
.
personnelList
,
"
person
"
);
});
// 设置定时刷新
this
.
setupEntityUpdateInterval
(
"
person
"
,
()
=>
{
this
.
personCardList
(()
=>
{
console
.
log
(
"
人员数据
"
,
this
.
personnelList
);
});
});
goTarget
(
href
)
{
window
.
open
(
href
,
"
_blank
"
);
},
},
};
...
...
@@ -506,11 +21,6 @@ export default {
<
style
scoped
lang=
"scss"
>
.home
{
width
:
100%
;
height
:
100vh
;
position
:
relative
;
overflow
:
hidden
;
blockquote
{
padding
:
10px
20px
;
margin
:
0
0
20px
;
...
...
@@ -570,17 +80,5 @@ export default {
padding-inline-start
:
40px
;
}
}
// Cesium容器样式
.cesium-container
{
// width: 100vw;
// height: 100vh;
width
:
87vw
;
height
:
87vh
;
position
:
absolute
;
top
:
0
;
left
:
0
;
z-index
:
1
;
}
}
</
style
>
\ No newline at end of file
</
style
>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment