Merge branch 'main' of http://121.37.111.42:3000/ThbTech/gis-bi into main
This commit is contained in:
commit
296a1e9585
@ -4,13 +4,13 @@ export default {
|
|||||||
'/api/f': {
|
'/api/f': {
|
||||||
target: 'http://192.168.1.58:8100',
|
target: 'http://192.168.1.58:8100',
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
rewrite: path => path.replace(/^\/api\/f/, '')
|
rewrite: path => path.replace(/^\/api\/f/, 'de2api')
|
||||||
},
|
},
|
||||||
// 使用 proxy 实例
|
// 使用 proxy 实例
|
||||||
'/api': {
|
'/api': {
|
||||||
target: 'http://192.168.1.58:8100',
|
target: 'http://192.168.1.58:8100',
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
rewrite: path => path.replace(/^\/api/, '')
|
rewrite: path => path.replace(/^\/api/, 'de2api')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
port: 8080
|
port: 8080
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@antv/g2plot": "^2.4.29",
|
"@antv/g2plot": "^2.4.29",
|
||||||
"@antv/l7": "^2.22.0",
|
"@antv/l7": "^2.22.0",
|
||||||
|
"@antv/l7-three": "^2.22.5",
|
||||||
"@antv/l7plot": "^0.5.5",
|
"@antv/l7plot": "^0.5.5",
|
||||||
"@antv/s2": "^1.49.0",
|
"@antv/s2": "^1.49.0",
|
||||||
"@codemirror/lang-sql": "^6.4.0",
|
"@codemirror/lang-sql": "^6.4.0",
|
||||||
@ -26,6 +27,7 @@
|
|||||||
"@npkg/tinymce-plugins": "^0.0.7",
|
"@npkg/tinymce-plugins": "^0.0.7",
|
||||||
"@tinymce/tinymce-vue": "^5.1.0",
|
"@tinymce/tinymce-vue": "^5.1.0",
|
||||||
"@turf/centroid": "^7.0.0",
|
"@turf/centroid": "^7.0.0",
|
||||||
|
"@types/three": "^0.160.0",
|
||||||
"@videojs-player/vue": "^1.0.0",
|
"@videojs-player/vue": "^1.0.0",
|
||||||
"@vue/compiler-sfc": "^3.5.15",
|
"@vue/compiler-sfc": "^3.5.15",
|
||||||
"@vueuse/core": "^9.13.0",
|
"@vueuse/core": "^9.13.0",
|
||||||
@ -59,6 +61,7 @@
|
|||||||
"qs": "^6.11.0",
|
"qs": "^6.11.0",
|
||||||
"screenfull": "^6.0.2",
|
"screenfull": "^6.0.2",
|
||||||
"snowflake-id": "^1.1.0",
|
"snowflake-id": "^1.1.0",
|
||||||
|
"three": "^0.160.0",
|
||||||
"tinymce": "^5.8.2",
|
"tinymce": "^5.8.2",
|
||||||
"vant": "^4.8.3",
|
"vant": "^4.8.3",
|
||||||
"video.js": "^7.21.6",
|
"video.js": "^7.21.6",
|
||||||
|
BIN
core/core-frontend/public/static/3DModel/Camera.glb
Normal file
BIN
core/core-frontend/public/static/3DModel/Camera.glb
Normal file
Binary file not shown.
BIN
core/core-frontend/public/static/3DModel/Camera1.glb
Normal file
BIN
core/core-frontend/public/static/3DModel/Camera1.glb
Normal file
Binary file not shown.
BIN
core/core-frontend/public/static/3DModel/Camera2.glb
Normal file
BIN
core/core-frontend/public/static/3DModel/Camera2.glb
Normal file
Binary file not shown.
BIN
core/core-frontend/public/static/3DModel/Camera3.glb
Normal file
BIN
core/core-frontend/public/static/3DModel/Camera3.glb
Normal file
Binary file not shown.
BIN
core/core-frontend/public/static/3DModel/DevicePoint.glb
Normal file
BIN
core/core-frontend/public/static/3DModel/DevicePoint.glb
Normal file
Binary file not shown.
BIN
core/core-frontend/public/static/3DModel/PointCloud.glb
Normal file
BIN
core/core-frontend/public/static/3DModel/PointCloud.glb
Normal file
Binary file not shown.
BIN
core/core-frontend/public/static/3DModel/Q.glb
Normal file
BIN
core/core-frontend/public/static/3DModel/Q.glb
Normal file
Binary file not shown.
BIN
core/core-frontend/public/static/3DModel/UAV.glb
Normal file
BIN
core/core-frontend/public/static/3DModel/UAV.glb
Normal file
Binary file not shown.
BIN
core/core-frontend/public/static/3DModel/UV.glb
Normal file
BIN
core/core-frontend/public/static/3DModel/UV.glb
Normal file
Binary file not shown.
14
core/core-frontend/public/static/3DModel/XiaoSanJiao.mtl
Normal file
14
core/core-frontend/public/static/3DModel/XiaoSanJiao.mtl
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
# 3ds Max Wavefront OBJ Exporter v0.97b - (c)2007 guruware
|
||||||
|
# 创建的文件:23.12.2020 17:11:48
|
||||||
|
|
||||||
|
newmtl 02___Default
|
||||||
|
Ns 10.0000
|
||||||
|
Ni 1.5000
|
||||||
|
d 0.3000
|
||||||
|
Tr 0.7000
|
||||||
|
Tf 0.3000 0.3000 0.3000
|
||||||
|
illum 2
|
||||||
|
Ka 0.5961 0.4196 0.0745
|
||||||
|
Kd 0.5961 0.4196 0.0745
|
||||||
|
Ks 0.5400 0.5400 0.5400
|
||||||
|
Ke 0.0000 0.0000 0.0000
|
86
core/core-frontend/public/static/3DModel/XiaoSanJiao.obj
Normal file
86
core/core-frontend/public/static/3DModel/XiaoSanJiao.obj
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
# 3ds Max Wavefront OBJ Exporter v0.97b - (c)2007 guruware
|
||||||
|
# ´´½¨µÄÎļþ:23.12.2020 17:11:48
|
||||||
|
|
||||||
|
mtllib XiaoSanJiao.mtl
|
||||||
|
|
||||||
|
#
|
||||||
|
# object Cone001
|
||||||
|
#
|
||||||
|
|
||||||
|
v 0.1414 0.4000 -0.1411
|
||||||
|
v 0.1414 0.4000 0.1418
|
||||||
|
v 0.0943 0.2667 0.0946
|
||||||
|
v 0.0943 0.2667 -0.0939
|
||||||
|
v -0.1414 0.4000 0.1418
|
||||||
|
v -0.0943 0.2667 0.0946
|
||||||
|
v -0.1414 0.4000 -0.1411
|
||||||
|
v -0.0943 0.2667 -0.0939
|
||||||
|
v 0.0471 0.1333 0.0475
|
||||||
|
v 0.0471 0.1333 -0.0468
|
||||||
|
v -0.0471 0.1333 0.0475
|
||||||
|
v -0.0471 0.1333 -0.0468
|
||||||
|
v 0.0000 0.0000 0.0004
|
||||||
|
# 13 vertices
|
||||||
|
|
||||||
|
vn 0.9428 -0.3333 -0.0000
|
||||||
|
vn 0.9428 -0.3333 0.0000
|
||||||
|
vn -0.0000 -0.3333 0.9428
|
||||||
|
vn -0.9428 -0.3333 -0.0000
|
||||||
|
vn -0.0000 -0.3333 -0.9428
|
||||||
|
vn 0.7071 0.0000 -0.7071
|
||||||
|
vn 0.0000 1.0000 0.0000
|
||||||
|
# 7 vertex normals
|
||||||
|
|
||||||
|
vt 0.7500 0.0000 1.0000
|
||||||
|
vt 1.0000 0.0000 1.0000
|
||||||
|
vt 1.0000 0.3333 0.6667
|
||||||
|
vt 0.7500 0.3333 0.6667
|
||||||
|
vt 0.0000 0.0000 1.0000
|
||||||
|
vt 0.2500 0.0000 1.0000
|
||||||
|
vt 0.2500 0.3333 0.6667
|
||||||
|
vt 0.0000 0.3333 0.6667
|
||||||
|
vt 0.5000 0.0000 1.0000
|
||||||
|
vt 0.5000 0.3333 0.6667
|
||||||
|
vt 1.0000 0.6667 0.3333
|
||||||
|
vt 0.7500 0.6667 0.3333
|
||||||
|
vt 0.2500 0.6667 0.3333
|
||||||
|
vt 0.0000 0.6667 0.3333
|
||||||
|
vt 0.5000 0.6667 0.3333
|
||||||
|
vt 0.5000 1.0000 0.0000
|
||||||
|
vt 0.5000 0.0000 -0.2500
|
||||||
|
vt 0.0000 0.5000 -0.2500
|
||||||
|
vt 0.5000 1.0000 -0.2500
|
||||||
|
vt 1.0000 0.5000 -0.2500
|
||||||
|
# 20 texture coords
|
||||||
|
|
||||||
|
g Cone001
|
||||||
|
usemtl 02___Default
|
||||||
|
s 1
|
||||||
|
f 1/1/1 2/2/2 3/3/2 4/4/1
|
||||||
|
s 2
|
||||||
|
f 2/5/3 5/6/3 6/7/3 3/8/3
|
||||||
|
s 1
|
||||||
|
f 5/6/4 7/9/4 8/10/4 6/7/4
|
||||||
|
s 2
|
||||||
|
f 7/9/5 1/1/5 4/4/5 8/10/5
|
||||||
|
s 1
|
||||||
|
f 4/4/1 3/3/2 9/11/1 10/12/1
|
||||||
|
s 2
|
||||||
|
f 3/8/3 6/7/3 11/13/3 9/14/3
|
||||||
|
s 1
|
||||||
|
f 6/7/4 8/10/4 12/15/4 11/13/4
|
||||||
|
s 2
|
||||||
|
f 8/10/5 4/4/5 10/12/5 12/15/5
|
||||||
|
s 1
|
||||||
|
f 10/12/1 9/11/1 13/16/1 13/16/6
|
||||||
|
s 2
|
||||||
|
f 9/14/3 11/13/3 13/16/3 13/16/6
|
||||||
|
s 1
|
||||||
|
f 11/13/4 12/15/4 13/16/4 13/16/6
|
||||||
|
s 2
|
||||||
|
f 12/15/5 10/12/5 13/16/5 13/16/6
|
||||||
|
s 4
|
||||||
|
f 5/17/7 2/18/7 1/19/7 7/20/7
|
||||||
|
f 13/16/6 13/16/6 13/16/6 13/16/6
|
||||||
|
# 14 polygons
|
||||||
|
|
BIN
core/core-frontend/public/static/3DModel/range.glb
Normal file
BIN
core/core-frontend/public/static/3DModel/range.glb
Normal file
Binary file not shown.
BIN
core/core-frontend/public/static/3DModel/scene.glb
Normal file
BIN
core/core-frontend/public/static/3DModel/scene.glb
Normal file
Binary file not shown.
1995
core/core-frontend/public/static/css/iconfont.css
Normal file
1995
core/core-frontend/public/static/css/iconfont.css
Normal file
File diff suppressed because it is too large
Load Diff
BIN
core/core-frontend/public/static/css/iconfont.woff2
Normal file
BIN
core/core-frontend/public/static/css/iconfont.woff2
Normal file
Binary file not shown.
8222
core/core-frontend/public/static/js/ZLMRTCClient.js
Normal file
8222
core/core-frontend/public/static/js/ZLMRTCClient.js
Normal file
File diff suppressed because it is too large
Load Diff
1
core/core-frontend/public/static/js/ZLMRTCClient.js.map
Normal file
1
core/core-frontend/public/static/js/ZLMRTCClient.js.map
Normal file
File diff suppressed because one or more lines are too long
1
core/core-frontend/public/static/js/decoder.js
Normal file
1
core/core-frontend/public/static/js/decoder.js
Normal file
File diff suppressed because one or more lines are too long
BIN
core/core-frontend/public/static/js/decoder.wasm
Normal file
BIN
core/core-frontend/public/static/js/decoder.wasm
Normal file
Binary file not shown.
34
core/core-frontend/public/static/js/draco_decoder.js
Normal file
34
core/core-frontend/public/static/js/draco_decoder.js
Normal file
File diff suppressed because one or more lines are too long
BIN
core/core-frontend/public/static/js/draco_decoder.wasm
Normal file
BIN
core/core-frontend/public/static/js/draco_decoder.wasm
Normal file
Binary file not shown.
1
core/core-frontend/public/static/js/jessibuca.js
Normal file
1
core/core-frontend/public/static/js/jessibuca.js
Normal file
File diff suppressed because one or more lines are too long
BIN
core/core-frontend/public/static/logo/favicon.ico
Normal file
BIN
core/core-frontend/public/static/logo/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
@ -34,6 +34,9 @@ import { GaodeMap } from '@antv/l7-maps';
|
|||||||
import * as THREE from 'three';
|
import * as THREE from 'three';
|
||||||
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
|
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
|
||||||
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js' // 控制器
|
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js' // 控制器
|
||||||
|
import { ThreeLayer, ThreeRender } from '@antv/l7-three';
|
||||||
|
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
const dvMainStore = dvMainStoreWithOut()
|
const dvMainStore = dvMainStoreWithOut()
|
||||||
const { nowPanelTrackInfo, nowPanelJumpInfo, mobileInPc, embeddedCallBack, inMobile } =
|
const { nowPanelTrackInfo, nowPanelJumpInfo, mobileInPc, embeddedCallBack, inMobile } =
|
||||||
@ -122,11 +125,8 @@ const state = reactive({
|
|||||||
let chartData = shallowRef<Partial<Chart['data']>>({
|
let chartData = shallowRef<Partial<Chart['data']>>({
|
||||||
fields: []
|
fields: []
|
||||||
})
|
})
|
||||||
// 添加普通变量存储Three.js对象
|
|
||||||
let threeScene: THREE.Scene | null = null;
|
|
||||||
let threeRenderer: THREE.WebGLRenderer | null = null;
|
|
||||||
let threeCamera: THREE.PerspectiveCamera | null = null;
|
|
||||||
let model: THREE.Object3D | null = null;
|
|
||||||
const containerId = 'container-' + showPosition.value + '-' + view.value.id + '-' + suffixId.value
|
const containerId = 'container-' + showPosition.value + '-' + view.value.id + '-' + suffixId.value
|
||||||
const viewTrack = ref(null)
|
const viewTrack = ref(null)
|
||||||
|
|
||||||
@ -200,7 +200,7 @@ const calcData = async (view, callback) => {
|
|||||||
isError.value = false
|
isError.value = false
|
||||||
const v = JSON.parse(JSON.stringify(view))
|
const v = JSON.parse(JSON.stringify(view))
|
||||||
getData(v)
|
getData(v)
|
||||||
.then(async res => {
|
.then(async (res: any) => {
|
||||||
if (res.code && res.code !== 0) {
|
if (res.code && res.code !== 0) {
|
||||||
isError.value = true
|
isError.value = true
|
||||||
errMsg.value = res.msg
|
errMsg.value = res.msg
|
||||||
@ -279,7 +279,7 @@ const renderChart = async (view, callback?) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
let myChart = null
|
let myChart = null
|
||||||
let g2Timer: number
|
let g2Timer: any
|
||||||
const renderG2Plot = async (chart, chartView: G2PlotChartView<any, any>) => {
|
const renderG2Plot = async (chart, chartView: G2PlotChartView<any, any>) => {
|
||||||
g2Timer && clearTimeout(g2Timer)
|
g2Timer && clearTimeout(g2Timer)
|
||||||
g2Timer = setTimeout(async () => {
|
g2Timer = setTimeout(async () => {
|
||||||
@ -308,7 +308,7 @@ const country = ref('')
|
|||||||
const appStore = useAppStoreWithOut()
|
const appStore = useAppStoreWithOut()
|
||||||
const chartContainer = ref<HTMLElement>(null)
|
const chartContainer = ref<HTMLElement>(null)
|
||||||
let scope
|
let scope
|
||||||
let mapTimer: number
|
let mapTimer: any
|
||||||
const renderL7Plot = async (chart: ChartObj, chartView: L7PlotChartView<any, any>, callback) => {
|
const renderL7Plot = async (chart: ChartObj, chartView: L7PlotChartView<any, any>, callback) => {
|
||||||
const map = parseJson(chart.customAttr).map
|
const map = parseJson(chart.customAttr).map
|
||||||
let areaId = map.id
|
let areaId = map.id
|
||||||
@ -387,6 +387,7 @@ class SatelliteControl extends Control {
|
|||||||
let mapL7Timer: any
|
let mapL7Timer: any
|
||||||
let scaleControl: Scale | null = null // 存储比例尺实例
|
let scaleControl: Scale | null = null // 存储比例尺实例
|
||||||
let fullscreenControl
|
let fullscreenControl
|
||||||
|
let content = null
|
||||||
let satelliteControlInstance = null; // 用于存储卫星控件实例
|
let satelliteControlInstance = null; // 用于存储卫星控件实例
|
||||||
const renderL7 = async (chart: ChartObj, chartView: L7ChartView<any, any>, callback) => {
|
const renderL7 = async (chart: ChartObj, chartView: L7ChartView<any, any>, callback) => {
|
||||||
mapL7Timer && clearTimeout(mapL7Timer);
|
mapL7Timer && clearTimeout(mapL7Timer);
|
||||||
@ -424,12 +425,190 @@ const renderL7 = async (chart: ChartObj, chartView: L7ChartView<any, any>, callb
|
|||||||
myChart.getScene()?.addControl(satelliteControlInstance);
|
myChart.getScene()?.addControl(satelliteControlInstance);
|
||||||
}
|
}
|
||||||
// ====== 修复完成 ======
|
// ====== 修复完成 ======
|
||||||
|
threel7()
|
||||||
myChart?.render();
|
myChart?.render();
|
||||||
callback?.();
|
callback?.();
|
||||||
emit('resetLoading');
|
emit('resetLoading');
|
||||||
}, 500);
|
}, 500);
|
||||||
};
|
};
|
||||||
|
//三维模型集成
|
||||||
|
let threeJSLayerRef:any = null
|
||||||
|
const threel7 = () => {
|
||||||
|
// ====== 三维模型集成 ======
|
||||||
|
const scene = myChart.getScene(); // 获取场景
|
||||||
|
scene.registerRenderService(ThreeRender);
|
||||||
|
threeJSLayerRef = new ThreeLayer({
|
||||||
|
enableMultiPassRenderer: false,
|
||||||
|
onAddMeshes: (threeScene: any, layer: any) => {
|
||||||
|
// 添加相机初始化代码
|
||||||
|
const camera = new THREE.PerspectiveCamera(
|
||||||
|
75,
|
||||||
|
scene.width / scene.height,
|
||||||
|
0.1,
|
||||||
|
1000000000
|
||||||
|
);
|
||||||
|
camera.position.set(0, 0, 10000000);
|
||||||
|
threeScene.add(camera);
|
||||||
|
layer.camera = camera; // 关键:将相机绑定到图层
|
||||||
|
threeScene.add(new THREE.AmbientLight(0xffffff));
|
||||||
|
const sunlight: any = new THREE.DirectionalLight(0xffffff, 0.25);
|
||||||
|
sunlight.position.set(0, 80000000, 100000000);
|
||||||
|
sunlight.matrixWorldNeedsUpdate = true;
|
||||||
|
threeScene.add(sunlight);
|
||||||
|
// 使用 Three.js glTFLoader 加载模型
|
||||||
|
const manager: any = new THREE.LoadingManager()
|
||||||
|
manager.setURLModifier((url: any, path: any) => {
|
||||||
|
return (path || '') + url
|
||||||
|
})
|
||||||
|
const loader = new GLTFLoader(manager);
|
||||||
|
const dracoLoader = new DRACOLoader();
|
||||||
|
dracoLoader.setDecoderPath('./static/js/');
|
||||||
|
dracoLoader.setDecoderConfig({ type: 'js' });
|
||||||
|
loader.setDRACOLoader(dracoLoader);
|
||||||
|
loader.load(
|
||||||
|
`./static/3DModel/scene.glb`,
|
||||||
|
(gltf) => {
|
||||||
|
// debugger
|
||||||
|
const gltfScene: any = gltf.scene
|
||||||
|
// setDouble(gltfScene);
|
||||||
|
content = gltfScene
|
||||||
|
layer.adjustMeshToMap(gltfScene);
|
||||||
|
// gltfScene.scale.set(1000, 1000, 1000)
|
||||||
|
layer.setMeshScale(gltfScene, 10, 10, 10);
|
||||||
|
layer.setObjectLngLat(gltfScene, [116.397428, 39.91923], 0);
|
||||||
|
// 添加环境光
|
||||||
|
threeScene.add(new THREE.AmbientLight(0xffffff, 0.3));
|
||||||
|
// 动态调整 UV Mapping
|
||||||
|
gltfScene.traverse((node) => {
|
||||||
|
if (node.isMesh) {
|
||||||
|
const material = node.material;
|
||||||
|
if (material.map) {
|
||||||
|
const uv = node.geometry.attributes.uv;
|
||||||
|
for (let i = 0; i < uv.count; i++) {
|
||||||
|
uv.setX(i, /* 新的 U 值 */);
|
||||||
|
uv.setY(i, /* 新的 V 值 */);
|
||||||
|
}
|
||||||
|
uv.needsUpdate = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 调整材质属性
|
||||||
|
gltfScene.traverse((node) => {
|
||||||
|
if (node.isMesh) {
|
||||||
|
const material = node.material;
|
||||||
|
if (material.map) {
|
||||||
|
material.map.repeat.set(1, 1);
|
||||||
|
material.map.offset.set(0, 0);
|
||||||
|
material.map.wrapS = THREE.ClampToEdgeWrapping;
|
||||||
|
material.map.wrapT = THREE.ClampToEdgeWrapping;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// 添加方向光
|
||||||
|
const sunlight = new THREE.DirectionalLight(0xffffff, 0.4);
|
||||||
|
sunlight.position.set(50, 100, 50);
|
||||||
|
sunlight.target.position.set(0, 0, 0);
|
||||||
|
sunlight.matrixWorldNeedsUpdate = true;
|
||||||
|
threeScene.add(sunlight);
|
||||||
|
|
||||||
|
// 添加点光源
|
||||||
|
const pointLight = new THREE.PointLight(0xffffff, 0.6, 1000);
|
||||||
|
pointLight.position.set(10, 15, -5);
|
||||||
|
threeScene.add(pointLight);
|
||||||
|
|
||||||
|
// 添加聚光灯
|
||||||
|
const spotLight = new THREE.SpotLight(0xffffff, 0.8);
|
||||||
|
spotLight.position.set(10, 25, 15);
|
||||||
|
spotLight.angle = Math.PI / 4;
|
||||||
|
threeScene.add(spotLight);
|
||||||
|
// 添加模型点击事件监听
|
||||||
|
scene.on('click', handleModelClick);
|
||||||
|
// 向场景中添加模型
|
||||||
|
threeScene.add(gltfScene);
|
||||||
|
// // 重绘图层
|
||||||
|
layer.render();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
}).animate(true);
|
||||||
|
scene.addLayer(threeJSLayerRef);
|
||||||
|
|
||||||
|
// ====== 三维模型集成完成 ======
|
||||||
|
}
|
||||||
|
// 模型点击事件处理函数
|
||||||
|
const handleModelClick = (e: any) => {
|
||||||
|
// debugger
|
||||||
|
// 添加安全校验
|
||||||
|
if (!threeJSLayerRef || !threeJSLayerRef.camera) {
|
||||||
|
console.warn('Camera not initialized');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. 获取正确的鼠标坐标
|
||||||
|
const point = e.containerPoint || { x: e.originEvent.x, y: e.originEvent.y }; // 兼容不同事件结构
|
||||||
|
const scene = myChart.getScene();
|
||||||
|
const container = scene.getContainer();
|
||||||
|
const width = container.clientWidth;
|
||||||
|
const height = container.clientHeight;
|
||||||
|
// 2. 计算归一化设备坐标
|
||||||
|
const mouse = new THREE.Vector2();
|
||||||
|
mouse.x = (point.x / width) * 2 - 1;
|
||||||
|
mouse.y = -(point.y / height) * 2 + 1;
|
||||||
|
|
||||||
|
// 3. 优化射线检测
|
||||||
|
const raycaster = new THREE.Raycaster();
|
||||||
|
raycaster.setFromCamera(mouse, threeJSLayerRef.camera);
|
||||||
|
|
||||||
|
// 4. 检测所有可交互对象(包括嵌套结构)
|
||||||
|
const allObjects = [];
|
||||||
|
content.traverse(child => {
|
||||||
|
if (child.isMesh && child.visible) {
|
||||||
|
allObjects.push(child);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const intersects = raycaster.intersectObjects(allObjects);
|
||||||
|
|
||||||
|
// 5. 处理点击结果
|
||||||
|
if (intersects.length > 0) {
|
||||||
|
const closest = intersects[0];
|
||||||
|
console.log('模型被点击:', closest.object);
|
||||||
|
|
||||||
|
// 6. 添加业务逻辑(示例:高亮选中对象)
|
||||||
|
highlightSelectedObject(closest.object);
|
||||||
|
} else {
|
||||||
|
// 点击空白区域处理
|
||||||
|
clearSelection();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 高亮选中对象
|
||||||
|
const highlightSelectedObject = (object) => {
|
||||||
|
// 保存原始材质
|
||||||
|
if (!object.userData.originalMaterial) {
|
||||||
|
object.userData.originalMaterial = object.material;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 应用高亮材质
|
||||||
|
object.material = new THREE.MeshBasicMaterial({
|
||||||
|
color: 0xff0000,
|
||||||
|
transparent: true,
|
||||||
|
opacity: 0.7
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 清除选中状态
|
||||||
|
const clearSelection = () => {
|
||||||
|
content.traverse(child => {
|
||||||
|
if (child.userData.originalMaterial) {
|
||||||
|
child.material = child.userData.originalMaterial;
|
||||||
|
delete child.userData.originalMaterial;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
const pointClickTrans = () => {
|
const pointClickTrans = () => {
|
||||||
if (embeddedCallBack.value === 'yes') {
|
if (embeddedCallBack.value === 'yes') {
|
||||||
trackClick('pointClick')
|
trackClick('pointClick')
|
||||||
@ -736,140 +915,11 @@ defineExpose({
|
|||||||
clearLinkage
|
clearLinkage
|
||||||
})
|
})
|
||||||
|
|
||||||
//三维 three.js 实现方法
|
|
||||||
// 新增方法 - 初始化 Three.js
|
|
||||||
const initThree = (container: HTMLElement) => {
|
|
||||||
// 创建场景
|
|
||||||
threeScene = new THREE.Scene();
|
|
||||||
|
|
||||||
// 创建相机
|
|
||||||
threeCamera = new THREE.PerspectiveCamera(
|
|
||||||
75,
|
|
||||||
container.clientWidth / container.clientHeight,
|
|
||||||
0.1,
|
|
||||||
1000
|
|
||||||
);
|
|
||||||
threeCamera.position.z = 5;
|
|
||||||
|
|
||||||
// 创建渲染器
|
|
||||||
threeRenderer = new THREE.WebGLRenderer({ alpha: true, antialias: true });
|
|
||||||
threeRenderer.setSize(container.clientWidth, container.clientHeight);
|
|
||||||
// 设置关键样式
|
|
||||||
threeRenderer.domElement.style.position = 'absolute';
|
|
||||||
threeRenderer.domElement.style.top = '0';
|
|
||||||
threeRenderer.domElement.style.left = '0';
|
|
||||||
threeRenderer.domElement.style.zIndex = '1'; // 确保在地图之上
|
|
||||||
container.appendChild(threeRenderer.domElement);
|
|
||||||
|
|
||||||
|
|
||||||
// 添加光源
|
|
||||||
const ambientLight = new THREE.AmbientLight(0xffffff, 0.6);
|
|
||||||
threeScene.add(ambientLight);
|
|
||||||
|
|
||||||
const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8);
|
|
||||||
directionalLight.position.set(10, 10, 10);
|
|
||||||
threeScene.add(directionalLight);
|
|
||||||
};
|
|
||||||
// 新增方法 - 加载模型
|
|
||||||
const loadModel = (filePath: string) => {
|
|
||||||
const loader = new GLTFLoader();
|
|
||||||
const dracoLoader = new DRACOLoader()
|
|
||||||
dracoLoader.setDecoderPath('./static/js/')
|
|
||||||
dracoLoader.setDecoderConfig({ type: 'js' })
|
|
||||||
loader.setDRACOLoader(dracoLoader)
|
|
||||||
|
|
||||||
// 确保地图场景存在
|
|
||||||
if (!myChart?.getScene()) {
|
|
||||||
console.warn('地图场景尚未初始化,延迟加载模型');
|
|
||||||
// 延迟重试
|
|
||||||
setTimeout(() => loadModel(filePath), 500);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const scene = myChart.getScene();
|
|
||||||
|
|
||||||
// 检查场景是否已加载
|
|
||||||
if (scene.loaded) {
|
|
||||||
// 场景已加载,直接加载模型
|
|
||||||
loadModelInternal(loader, filePath);
|
|
||||||
} else {
|
|
||||||
// 添加一次性事件监听器
|
|
||||||
const loadedHandler = () => {
|
|
||||||
scene.off('loaded', loadedHandler); // 移除监听器
|
|
||||||
loadModelInternal(loader, filePath);
|
|
||||||
};
|
|
||||||
scene.on('loaded', loadedHandler);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 内部加载方法
|
|
||||||
const loadModelInternal = (loader, filePath) => {
|
|
||||||
loader.load(
|
|
||||||
filePath,
|
|
||||||
(gltf) => {
|
|
||||||
console.log('Model loaded successfully:', gltf);
|
|
||||||
model = gltf.scene;
|
|
||||||
threeScene?.add(model);
|
|
||||||
// animate();
|
|
||||||
placeModelByLngLat(116.3974, 39.9093); // 直接调用放置方法
|
|
||||||
},
|
|
||||||
(progress) => {
|
|
||||||
console.log('Loading progress:', progress);
|
|
||||||
},
|
|
||||||
(error) => {
|
|
||||||
console.error('模型加载失败:', error);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
// 新增方法 - 根据经纬度放置模型
|
|
||||||
const placeModelByLngLat = (lng: number, lat: number) => {
|
|
||||||
if (!model || !myChart?.getScene()) {
|
|
||||||
console.warn('模型或地图场景未初始化');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const scene = myChart.getScene();
|
|
||||||
console.log('地图场景状态:', scene);
|
|
||||||
|
|
||||||
try {
|
|
||||||
const containerPoint = scene.lngLatToContainer([lng, lat]);
|
|
||||||
console.log('容器坐标:', containerPoint);
|
|
||||||
|
|
||||||
const container = document.getElementById(containerId);
|
|
||||||
if (!container) {
|
|
||||||
console.error('容器元素未找到');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 转换为Three.js的标准化设备坐标
|
|
||||||
const x = (containerPoint.x / container.clientWidth) * 2 - 1;
|
|
||||||
const y = -(containerPoint.y / container.clientHeight) * 2 + 1;
|
|
||||||
|
|
||||||
console.log('Three.js坐标:', { x, y });
|
|
||||||
|
|
||||||
// 更新模型位置
|
|
||||||
model.position.set(x * 5, y * 5, 0);
|
|
||||||
|
|
||||||
// 确保相机看向模型
|
|
||||||
if (threeCamera) {
|
|
||||||
threeCamera.lookAt(model.position);
|
|
||||||
console.log('相机已调整朝向模型');
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.error('坐标转换错误:', e);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// 动画循环
|
|
||||||
const animate = () => {
|
|
||||||
requestAnimationFrame(animate);
|
|
||||||
if (threeRenderer && threeScene && threeCamera) {
|
|
||||||
threeRenderer.render(threeScene, threeCamera);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let resizeObserver
|
let resizeObserver
|
||||||
const TOLERANCE = 0.01
|
const TOLERANCE = 0.01
|
||||||
const RESIZE_MONITOR_CHARTS = ['map', 'bubble-map', 'flow-map', 'heat-map']
|
const RESIZE_MONITOR_CHARTS = ['map', 'bubble-map', 'flow-map', 'heat-map']
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
console.log('Three.js实际版本:', THREE.REVISION);
|
||||||
const containerDom = document.getElementById(containerId)
|
const containerDom = document.getElementById(containerId)
|
||||||
const { offsetWidth, offsetHeight } = containerDom
|
const { offsetWidth, offsetHeight } = containerDom
|
||||||
const preSize = [offsetWidth, offsetHeight]
|
const preSize = [offsetWidth, offsetHeight]
|
||||||
@ -893,14 +943,7 @@ onMounted(() => {
|
|||||||
useEmitt({ name: 'l7-prepare-picture', callback: preparePicture })
|
useEmitt({ name: 'l7-prepare-picture', callback: preparePicture })
|
||||||
useEmitt({ name: 'l7-unprepare-picture', callback: unPreparePicture })
|
useEmitt({ name: 'l7-unprepare-picture', callback: unPreparePicture })
|
||||||
// 初始化 Three.js
|
// 初始化 Three.js
|
||||||
// const container = document.getElementById(containerId);
|
|
||||||
// if (container) {
|
|
||||||
// initThree(container);
|
|
||||||
// // 加载模型(替换为实际路径)
|
|
||||||
// // loadModel(`./static/3DModel/Camera1.glb`);
|
|
||||||
// // loadModel('static/3DModel/scene.glb');
|
|
||||||
|
|
||||||
// }
|
|
||||||
})
|
})
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
try {
|
try {
|
||||||
@ -909,9 +952,7 @@ onBeforeUnmount(() => {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn(e)
|
console.warn(e)
|
||||||
}
|
}
|
||||||
if (threeRenderer) {
|
|
||||||
threeRenderer.dispose();
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -953,16 +994,19 @@ onBeforeUnmount(() => {
|
|||||||
fill: #fff !important;
|
fill: #fff !important;
|
||||||
color: #fff !important;
|
color: #fff !important;
|
||||||
}
|
}
|
||||||
:deep(.l7-control-zoom){
|
|
||||||
position:fixed !important;
|
:deep(.l7-control-zoom) {
|
||||||
|
position: fixed !important;
|
||||||
right: 0px;
|
right: 0px;
|
||||||
bottom: 65px;
|
bottom: 65px;
|
||||||
}
|
}
|
||||||
:deep(.l7-control-button){
|
|
||||||
position:fixed !important;
|
:deep(.l7-control-button) {
|
||||||
|
position: fixed !important;
|
||||||
right: 0px;
|
right: 0px;
|
||||||
bottom: 35px;
|
bottom: 35px;
|
||||||
}
|
}
|
||||||
|
|
||||||
// :deep(.l7-button-control){
|
// :deep(.l7-button-control){
|
||||||
// position:fixed;
|
// position:fixed;
|
||||||
// right: 0px;
|
// right: 0px;
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user