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
7b2b66c8
Commit
7b2b66c8
authored
Nov 19, 2025
by
xinzhedeai
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add:zhuizong page
parent
16c3735b
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
878 additions
and
8 deletions
+878
-8
index.js
src/router/index.js
+21
-8
index-zz.vue
src/views/index-zz.vue
+857
-0
No files found.
src/router/index.js
View file @
7b2b66c8
...
...
@@ -75,32 +75,45 @@ export const constantRoutes = [
}
]
},
{
path
:
'
/
guiji
'
,
{
path
:
'
/
zz
'
,
component
:
Layout
,
redirect
:
'
noredirect
'
,
children
:
[
{
path
:
'
index
'
,
component
:
()
=>
import
(
'
@/views/index-
guiji
'
),
component
:
()
=>
import
(
'
@/views/index-
zz
'
),
name
:
'
Index
'
,
meta
:
{
title
:
'
首页2-zz
'
,
icon
:
'
dashboard
'
,
affix
:
true
}
}
]
},
{
path
:
'
/
dp
'
,
path
:
'
/
guiji
'
,
component
:
Layout
,
redirect
:
'
noredirect
'
,
children
:
[
{
path
:
'
screen
'
,
component
:
()
=>
import
(
'
@/views/index-
dp
'
),
name
:
'
Screen
'
,
meta
:
{
title
:
'
首页
-DP
'
,
icon
:
'
dashboard
'
,
affix
:
true
}
path
:
'
index
'
,
component
:
()
=>
import
(
'
@/views/index-
guiji
'
),
name
:
'
Index
'
,
meta
:
{
title
:
'
首页
2-gj
'
,
icon
:
'
dashboard
'
,
affix
:
true
}
}
]
},
// {
// path: '/dp',
// component: Layout,
// redirect: 'noredirect',
// children: [
// {
// path: 'screen',
// component: () => import('@/views/index-dp'),
// name: 'Screen',
// meta: { title: '首页-DP', icon: 'dashboard', affix: true }
// }
// ]
// },
{
path
:
'
/user
'
,
component
:
Layout
,
...
...
src/views/index-zz.vue
0 → 100644
View file @
7b2b66c8
<
template
>
<div
class=
"app-container home"
>
<!-- Cesium地图容器 -->
<div
id=
"cesiumContainer"
class=
"cesium-container"
></div>
<!-- 人员实时追踪控制面板 -->
<div
class=
"tracking-panel"
>
<div
class=
"panel-header"
>
<h3>
人员实时追踪
</h3>
<select
v-model=
"selectedPerson"
@
change=
"onPersonSelect"
>
<option
value=
""
>
选择人员
</option>
<option
v-for=
"person in personnelList"
:key=
"person.perName"
:value=
"person.perName"
>
{{
person
.
perName
}}
</option>
</select>
</div>
<!-- 时间轴组件 -->
<div
class=
"timeline-container"
>
<div
class=
"time-info"
>
<span>
当前时间:
{{
currentTimeDisplay
}}
</span>
</div>
<input
type=
"range"
v-model.number=
"currentTimeIndex"
:min=
"0"
:max=
"timePoints.length - 1"
@
input=
"onTimelineChange"
class=
"timeline-slider"
/>
<div
class=
"time-labels"
>
<span>
{{
formatTime
(
timePoints
[
0
])
}}
</span>
<span>
{{
formatTime
(
timePoints
[
timePoints
.
length
-
1
])
}}
</span>
</div>
</div>
<!-- 控制面板按钮 -->
<div
class=
"control-buttons"
>
<button
@
click=
"startTracking"
:disabled=
"isTracking"
>
开始追踪
</button>
<button
@
click=
"stopTracking"
:disabled=
"!isTracking"
>
停止追踪
</button>
<button
@
click=
"showFullPath"
>
显示完整轨迹
</button>
<button
@
click=
"clearTrails"
>
清除轨迹
</button>
</div>
</div>
</div>
</
template
>
<
script
>
export
default
{
name
:
"
Index
"
,
data
()
{
return
{
// 版本号
version
:
"
3.8.9
"
,
// Cesium查看器实例
viewer
:
null
,
tileset
:
null
,
personnelList
:
[],
personModelInterval
:
null
,
trackingInterval
:
null
,
bgEntities
:
{},
// 所有的key都对应一个实体对象。而人员的实体对应的key不是数字。
// 轨迹追踪相关数据
selectedPerson
:
""
,
// 选中的人员
timePoints
:
[],
// 时间点数组
currentTimeIndex
:
0
,
// 当前时间索引
personTrajectories
:
{},
// 人员轨迹数据 { 人员名称: [{time, lng, lat, height}] }
trailEntities
:
{},
// 轨迹实体
isTracking
:
false
,
// 是否正在实时追踪
currentTimeDisplay
:
""
,
// 当前显示时间
};
},
mounted
()
{
// 组件挂载后初始化地图
this
.
initCesium
();
// 初始化时间点数据
this
.
initTimePoints
();
},
beforeDestroy
()
{
// 组件销毁前清理地图资源
if
(
this
.
viewer
)
{
this
.
viewer
.
destroy
();
this
.
viewer
=
null
;
}
if
(
this
.
personModelInterval
)
{
clearInterval
(
this
.
personModelInterval
);
}
if
(
this
.
trackingInterval
)
{
clearInterval
(
this
.
trackingInterval
);
}
},
methods
:
{
// 新增:清除实体
clearEntities
()
{
if
(
this
.
viewer
&&
this
.
bgEntities
)
{
for
(
let
key
in
this
.
bgEntities
)
{
this
.
viewer
.
entities
.
remove
(
this
.
bgEntities
[
key
]);
delete
this
.
bgEntities
[
key
];
}
}
},
// 初始化时间点数据(生成过去1小时的时间点,每5分钟一个)
initTimePoints
()
{
const
now
=
new
Date
();
const
points
=
[];
// 生成过去1小时的时间点,每5分钟一个
for
(
let
i
=
60
;
i
>=
0
;
i
-=
5
)
{
const
time
=
new
Date
(
now
.
getTime
()
-
i
*
60
*
1000
);
points
.
push
(
time
);
}
this
.
timePoints
=
points
;
this
.
currentTimeIndex
=
points
.
length
-
1
;
// 默认显示最新时间
this
.
currentTimeDisplay
=
this
.
formatTime
(
points
[
points
.
length
-
1
]);
// 初始化人员轨迹数据
this
.
initPersonTrajectories
();
},
// 初始化人员轨迹数据
initPersonTrajectories
()
{
// 将笛卡尔坐标转换为经纬度坐标作为基准点
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
;
// 为每个人生成轨迹数据
this
.
personnelList
.
forEach
((
person
)
=>
{
const
trajectories
=
[];
let
currentLng
=
baseLongitude
+
(
Math
.
random
()
-
0.5
)
*
0.0001
;
let
currentLat
=
baseLatitude
+
(
Math
.
random
()
-
0.5
)
*
0.0001
;
this
.
timePoints
.
forEach
((
time
)
=>
{
// 生成平滑的移动路径
currentLng
+=
(
Math
.
random
()
-
0.5
)
*
0.00002
;
currentLat
+=
(
Math
.
random
()
-
0.5
)
*
0.00002
;
trajectories
.
push
({
time
,
lng
:
currentLng
,
lat
:
currentLat
,
height
:
baseHeight
,
});
});
this
.
personTrajectories
[
person
.
perName
]
=
trajectories
;
});
},
// 格式化时间显示
formatTime
(
date
=
new
Date
())
{
const
hours
=
date
.
getHours
().
toString
().
padStart
(
2
,
"
0
"
);
const
minutes
=
date
.
getMinutes
().
toString
().
padStart
(
2
,
"
0
"
);
return
`
${
hours
}
:
${
minutes
}
`
;
},
// 人员选择变化处理
onPersonSelect
()
{
this
.
clearTrails
();
if
(
this
.
selectedPerson
)
{
this
.
updatePersonPositionByTimeIndex
(
this
.
currentTimeIndex
);
this
.
showFullPath
();
}
},
// 时间轴变化处理
onTimelineChange
()
{
this
.
currentTimeDisplay
=
this
.
formatTime
(
this
.
timePoints
[
this
.
currentTimeIndex
]
);
this
.
updatePersonPositionByTimeIndex
(
this
.
currentTimeIndex
);
},
// 根据时间索引更新人员位置
updatePersonPositionByTimeIndex
(
index
)
{
if
(
!
this
.
selectedPerson
||
!
this
.
personTrajectories
[
this
.
selectedPerson
]
)
{
return
;
}
const
trajectory
=
this
.
personTrajectories
[
this
.
selectedPerson
][
index
];
if
(
!
trajectory
)
return
;
// 更新人员实体位置
const
personEntity
=
this
.
bgEntities
[
this
.
selectedPerson
];
if
(
personEntity
)
{
const
position
=
Cesium
.
Cartesian3
.
fromDegrees
(
trajectory
.
lng
,
trajectory
.
lat
,
trajectory
.
height
);
personEntity
.
position
.
setValue
(
position
);
// 更新描述信息,包含时间
personEntity
.
description
=
`<div><h4>
${
this
.
selectedPerson
}
</h4><p>时间:
${
this
.
formatTime
(
trajectory
.
time
)}
</p></div>`
;
}
// 移动相机到人员位置
if
(
this
.
isTracking
)
{
this
.
viewer
.
camera
.
flyTo
({
destination
:
Cesium
.
Cartesian3
.
fromDegrees
(
trajectory
.
lng
,
trajectory
.
lat
,
trajectory
.
height
+
100
),
duration
:
0.5
,
});
}
},
// 开始实时追踪
startTracking
()
{
if
(
!
this
.
selectedPerson
)
{
alert
(
"
请先选择要追踪的人员
"
);
return
;
}
this
.
isTracking
=
true
;
this
.
currentTimeIndex
=
this
.
timePoints
.
length
-
1
;
// 设置定时器模拟时间流逝
this
.
trackingInterval
=
setInterval
(()
=>
{
// 模拟新时间点的到来
const
now
=
new
Date
();
this
.
timePoints
.
push
(
now
);
// 为每个人员生成新的位置数据
this
.
personnelList
.
forEach
((
person
)
=>
{
if
(
!
this
.
personTrajectories
[
person
.
perName
])
{
this
.
personTrajectories
[
person
.
perName
]
=
[];
}
const
lastPos
=
this
.
personTrajectories
[
person
.
perName
][
this
.
personTrajectories
[
person
.
perName
].
length
-
1
];
let
newLng
=
lastPos
.
lng
+
(
Math
.
random
()
-
0.5
)
*
0.00002
;
let
newLat
=
lastPos
.
lat
+
(
Math
.
random
()
-
0.5
)
*
0.00002
;
this
.
personTrajectories
[
person
.
perName
].
push
({
time
:
now
,
lng
:
newLng
,
lat
:
newLat
,
height
:
lastPos
.
height
,
});
});
// 更新到最新时间
this
.
currentTimeIndex
=
this
.
timePoints
.
length
-
1
;
this
.
currentTimeDisplay
=
this
.
formatTime
(
now
);
this
.
updatePersonPositionByTimeIndex
(
this
.
currentTimeIndex
);
// 如果选择了当前人员,显示最新轨迹
if
(
this
.
selectedPerson
)
{
this
.
updateTrailDisplay
();
}
},
5000
);
// 每5秒更新一次
},
// 停止实时追踪
stopTracking
()
{
this
.
isTracking
=
false
;
if
(
this
.
trackingInterval
)
{
clearInterval
(
this
.
trackingInterval
);
this
.
trackingInterval
=
null
;
}
},
// 显示完整轨迹
showFullPath
()
{
if
(
!
this
.
selectedPerson
||
!
this
.
personTrajectories
[
this
.
selectedPerson
]
)
{
return
;
}
this
.
clearTrails
();
this
.
updateTrailDisplay
();
},
// 更新轨迹显示
updateTrailDisplay
()
{
const
trajectories
=
this
.
personTrajectories
[
this
.
selectedPerson
];
if
(
!
trajectories
||
trajectories
.
length
<
2
)
return
;
// 创建轨迹点数组
const
positions
=
[];
trajectories
.
forEach
((
point
)
=>
{
positions
.
push
(
Cesium
.
Cartesian3
.
fromDegrees
(
point
.
lng
,
point
.
lat
,
point
.
height
)
);
});
// 创建轨迹线
const
trailEntity
=
this
.
viewer
.
entities
.
add
({
polyline
:
{
positions
:
positions
,
width
:
3
,
material
:
new
Cesium
.
PolylineGlowMaterialProperty
({
glowPower
:
0.5
,
color
:
Cesium
.
Color
.
YELLOW
,
}),
clampToGround
:
false
,
},
});
this
.
trailEntities
[
this
.
selectedPerson
]
=
trailEntity
;
// 添加轨迹点标记
trajectories
.
forEach
((
point
,
index
)
=>
{
// 只显示部分点,避免过多标记影响性能
if
(
index
%
Math
.
ceil
(
trajectories
.
length
/
10
)
===
0
||
index
===
trajectories
.
length
-
1
)
{
const
pointEntity
=
this
.
viewer
.
entities
.
add
({
position
:
Cesium
.
Cartesian3
.
fromDegrees
(
point
.
lng
,
point
.
lat
,
point
.
height
+
5
),
point
:
{
pixelSize
:
5
,
color
:
index
===
trajectories
.
length
-
1
?
Cesium
.
Color
.
RED
:
Cesium
.
Color
.
GREEN
,
outlineColor
:
Cesium
.
Color
.
WHITE
,
outlineWidth
:
2
,
},
description
:
`<div><p>时间:
${
this
.
formatTime
(
point
.
time
)}
</p></div>`
,
});
if
(
!
this
.
trailEntities
[
`
${
this
.
selectedPerson
}
_point_
${
index
}
`
])
{
this
.
trailEntities
[
`
${
this
.
selectedPerson
}
_point_
${
index
}
`
]
=
pointEntity
;
}
}
});
},
// 清除轨迹
clearTrails
()
{
for
(
let
key
in
this
.
trailEntities
)
{
this
.
viewer
.
entities
.
remove
(
this
.
trailEntities
[
key
]);
}
this
.
trailEntities
=
{};
},
// 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
),
},
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
()
{
// 清除现有定时器
if
(
this
.
personModelInterval
)
{
clearInterval
(
this
.
personModelInterval
);
this
.
personModelInterval
=
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
);
});
});
// this.personModelInterval = setInterval(() => {
// console.log("开始获取实时数据");
// if (this.bgEntities) {
// for (let key in this.bgEntities) {
// if (isNaN(parseFloat(key))) {
// // 非数字键名的是人员实体
// this.viewer.entities.remove(this.bgEntities[key]);
// delete this.bgEntities[key];
// }
// }
// }
// // 从API获取最新的人员定位数据
// this.personCardList((list) => {
// console.log("人员数据", this.personnelList);
// // 创建新实体
// for (let item of this.personnelList) {
// 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.perName, position);
// // 创建人员标记
// let entity = this.viewer.entities.add({
// position: position,
// label: {
// text: item.perName,
// font: "16px",
// backgroundColor: Cesium.Color.fromCssColorString("#173349"),
// showBackground: true,
// fillColor: Cesium.Color.YELLOW,
// depthTestAgainstTerrain: false, // 禁用地形深度测试
// pixelOffset: new Cesium.Cartesian2(0, -35),
// },
// billboard: {
// image: "/poi-marker-default.png",
// scale: 0.5,
// },
// description: `
<
div
><
h4
>
$
{
item
.
perName
}
$
{
item
.
status
}
<
/h4></
div
>
`,
// fixedFrame: Cesium.Transforms.eastNorthUpToFixedFrame(position),
// });
// entity.info = item; // 添加 info 属性
// this.bgEntities[item.perName] = entity; // 存储新实体
// }
// // 如果已经选择了人员,更新其位置和轨迹
// if (this.selectedPerson) {
// this.updatePersonPositionByTimeIndex(this.currentTimeIndex);
// }
// });
// }, 10000); // 每10秒刷新一次
},
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", // 头像
});
}
// 初始化轨迹数据(如果尚未初始化)
if (Object.keys(this.personTrajectories).length === 0) {
this.initPersonTrajectories();
}
fn(this.personnelList);
},
/**
* 初始化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();
}
} 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(); // 定位后创建人员模型
},
});
} catch (error) {
console.error("定位到模型上方失败:", error);
}
},
},
};
</
script
>
<
style
scoped
lang=
"scss"
>
.home
{
width
:
100%
;
height
:
100vh
;
position
:
relative
;
overflow
:
hidden
;
font-family
:
"open sans"
,
"Helvetica Neue"
,
Helvetica
,
Arial
,
sans-serif
;
font-size
:
13px
;
color
:
#676a6c
;
overflow-x
:
hidden
;
.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
:
87vw
;
height
:
87vh
;
position
:
absolute
;
top
:
0
;
left
:
0
;
z-index
:
1
;
}
// 追踪控制面板样式
.tracking-panel
{
position
:
absolute
;
bottom
:
20px
;
left
:
50%
;
transform
:
translateX
(
-50%
);
width
:
80%
;
background
:
rgba
(
0
,
0
,
0
,
0
.8
);
border-radius
:
8px
;
padding
:
15px
;
color
:
white
;
z-index
:
100
;
.panel-header
{
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
margin-bottom
:
15px
;
h3
{
margin
:
0
;
font-size
:
18px
;
}
select
{
padding
:
5px
10px
;
border-radius
:
4px
;
border
:
none
;
background
:
#333
;
color
:
white
;
}
}
.timeline-container
{
margin-bottom
:
15px
;
.time-info
{
margin-bottom
:
10px
;
text-align
:
center
;
}
.timeline-slider
{
width
:
100%
;
margin-bottom
:
10px
;
}
.time-labels
{
display
:
flex
;
justify-content
:
space-between
;
font-size
:
12px
;
}
}
.control-buttons
{
display
:
flex
;
justify-content
:
center
;
gap
:
10px
;
button
{
padding
:
8px
16px
;
border-radius
:
4px
;
border
:
none
;
background
:
#173349
;
color
:
white
;
cursor
:
pointer
;
&
:hover:not
(
:disabled
)
{
background
:
#1e4763
;
}
&
:disabled
{
background
:
#555
;
cursor
:
not
-
allowed
;
}
}
}
}
}
</
style
>
\ No newline at end of file
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