mirror of https://gitee.com/antv-l7/antv-l7
feat: 补全高德地图 2.0 的模型加载能力,增加模型的经纬度移动能力
This commit is contained in:
parent
1a161121ff
commit
3da2676b0e
|
@ -275,6 +275,12 @@ export default class AMapService
|
|||
};
|
||||
}
|
||||
|
||||
public lngLatToCoord(lnglat: [number, number]): any {
|
||||
// @ts-ignore
|
||||
let { x, y } = this.map.lngLatToGeodeticCoord(lnglat)
|
||||
return [x, -y]
|
||||
}
|
||||
|
||||
public lngLatToMercator(
|
||||
lnglat: [number, number],
|
||||
altitude: number,
|
||||
|
|
|
@ -370,7 +370,10 @@ export default class AMapService
|
|||
scale: [number, number, number] = [1, 1, 1],
|
||||
origin: IMercator = { x: 0, y: 0, z: 0 },
|
||||
): number[] {
|
||||
const flat = this.viewport.projectFlat(lnglat);
|
||||
|
||||
// const flat = this.viewport.projectFlat(lnglat);
|
||||
// @ts-ignore
|
||||
const flat = this.map.customCoords.lngLatToCoord(lnglat)
|
||||
// @ts-ignore
|
||||
const modelMatrix = mat4.create();
|
||||
|
||||
|
@ -379,6 +382,7 @@ export default class AMapService
|
|||
modelMatrix,
|
||||
vec3.fromValues(flat[0], flat[1], altitude),
|
||||
);
|
||||
|
||||
mat4.scale(
|
||||
modelMatrix,
|
||||
modelMatrix,
|
||||
|
|
|
@ -236,6 +236,18 @@ export default class MapboxService
|
|||
public lngLatToContainer(lnglat: [number, number]): IPoint {
|
||||
return this.map.project(lnglat);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将经纬度转成墨卡托坐标
|
||||
* @param lnglat
|
||||
* @returns
|
||||
*/
|
||||
public lngLatToCoord(lnglat: [number, number]) {
|
||||
// @ts-ignore
|
||||
let { x, y } = this.lngLatToMercator(lnglat, 0);
|
||||
return [x, y] as [number, number];
|
||||
}
|
||||
|
||||
public lngLatToMercator(
|
||||
lnglat: [number, number],
|
||||
altitude: number,
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
import { ILayer } from '@antv/l7';
|
||||
import {
|
||||
AnimationMixer,
|
||||
Matrix4,
|
||||
Object3D
|
||||
} from 'three';
|
||||
|
||||
export type ILngLat = [number, number]
|
||||
|
||||
export interface IThreeJSLayer extends ILayer {
|
||||
// 获取对应地图的经纬度模型矩阵
|
||||
getModelMatrix(
|
||||
lnglat: ILngLat,
|
||||
altitude: number,
|
||||
rotation: [number, number, number],
|
||||
scale: [number, number, number],
|
||||
): Matrix4;
|
||||
|
||||
// 获取对应地图的经纬度平移矩阵
|
||||
getTranslateMatrix(lnglat: ILngLat, altitude?: number): Matrix4;
|
||||
|
||||
// 设置模型对应地图在经纬度和高度方向的平移
|
||||
setObjectLngLat(object: Object3D, lnglat: ILngLat, altitude?: number): void;
|
||||
|
||||
// 根据经纬度设置模型对应地图的平移
|
||||
setObjectLngLat(object: Object3D, lnglat: ILngLat, altitude?: number): void;
|
||||
|
||||
// 返回物体在场景中的经纬度
|
||||
getObjectLngLat(object: Object3D): ILngLat;
|
||||
|
||||
// 增加加载模型的动画混合器
|
||||
addAnimateMixer(mixer: AnimationMixer): void;
|
||||
}
|
|
@ -7,21 +7,14 @@ import {
|
|||
PerspectiveCamera,
|
||||
Scene,
|
||||
WebGLRenderer,
|
||||
Object3D
|
||||
} from 'three';
|
||||
import {
|
||||
IThreeRenderService,
|
||||
ThreeRenderServiceType,
|
||||
} from './threeRenderService';
|
||||
import { IThreeJSLayer, ILngLat } from './IThreeJSLayer'
|
||||
const DEG2RAD = Math.PI / 180;
|
||||
interface IThreeJSLayer extends ILayer {
|
||||
getModelMatrix(
|
||||
lnglat: [number, number],
|
||||
altitude: number,
|
||||
rotation: [number, number, number],
|
||||
scale: [number, number, number],
|
||||
): Matrix4;
|
||||
addAnimateMixer(mixer: AnimationMixer): void;
|
||||
}
|
||||
export default class ThreeJSLayer
|
||||
extends BaseLayer<{
|
||||
onAddMeshes: (threeScene: Scene, layer: ThreeJSLayer) => void;
|
||||
|
@ -36,10 +29,9 @@ export default class ThreeJSLayer
|
|||
// 地图中点墨卡托坐标
|
||||
private center: IMercator;
|
||||
|
||||
// 初始状态相机变换矩阵
|
||||
|
||||
/**
|
||||
* 根据模型
|
||||
* 根据数据计算对应地图的模型矩阵 不同地图主要是点位偏移不同
|
||||
*/
|
||||
public getModelMatrix(
|
||||
lnglat: [number, number],
|
||||
|
@ -58,7 +50,53 @@ export default class ThreeJSLayer
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取平移矩阵
|
||||
* @param lnglat
|
||||
* @param altitude
|
||||
* @returns
|
||||
*/
|
||||
public getTranslateMatrix( lnglat: ILngLat, altitude: number = 0,) {
|
||||
return this.getModelMatrix( lnglat, altitude, [0, 0, 0], [1, 1, 1] )
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前物体往经纬度和高度方向的移动
|
||||
* @param object
|
||||
* @param lnglat
|
||||
* @param altitude
|
||||
*/
|
||||
public applyObjectLngLat(object: Object3D, lnglat: ILngLat, altitude = 0) {
|
||||
let positionMatrix = this.getTranslateMatrix(lnglat, altitude)
|
||||
object.applyMatrix4(positionMatrix)
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置物体当前的经纬度和高度
|
||||
* @param object
|
||||
* @param lnglat
|
||||
* @param altitude
|
||||
*/
|
||||
public setObjectLngLat(object: Object3D, lnglat: ILngLat, altitude = 0) {
|
||||
// @ts-ignore
|
||||
let [x, y] = this.mapService?.lngLatToCoord(lnglat)
|
||||
// @ts-ignore
|
||||
// console.log(this.mapService?.lngLatToCoord(lnglat))
|
||||
// if(x && y) {
|
||||
// console.log('------')
|
||||
object.position.set(x, y, altitude)
|
||||
// }
|
||||
}
|
||||
|
||||
public getObjectLngLat(object: Object3D) {
|
||||
// let coord = [object.position.x, object.position.y];
|
||||
// // @ts-ignore
|
||||
// return this.mapService.coordToLngLat(coord);
|
||||
return [0,0] as ILngLat
|
||||
}
|
||||
|
||||
public buildModels() {
|
||||
// @ts-ignore
|
||||
this.threeRenderService = this.getContainer().get<IThreeRenderService>(
|
||||
ThreeRenderServiceType,
|
||||
);
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
import ThreeLayer from './core/baseLayer';
|
||||
import ThreeRender from './core/threeRender';
|
||||
export { ThreeLayer, ThreeRender };
|
||||
import { IThreeJSLayer, ILngLat } from './core/IThreeJSLayer';
|
||||
import {
|
||||
|
||||
Object3D
|
||||
} from 'three';
|
||||
export { ThreeLayer, ThreeRender, IThreeJSLayer, ILngLat, Object3D };
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Scene } from '@antv/l7';
|
||||
import { GaodeMap, GaodeMapV2, Mapbox } from '@antv/l7-maps';
|
||||
import { ThreeLayer, ThreeRender } from '@antv/l7-three';
|
||||
import { ThreeLayer, ThreeRender, ILngLat, Object3D } from '@antv/l7-three';
|
||||
import * as React from 'react';
|
||||
// import { DirectionalLight, Scene as ThreeScene } from 'three';
|
||||
import * as THREE from 'three';
|
||||
|
@ -27,7 +27,7 @@ export default class GlTFThreeJSDemo extends React.Component {
|
|||
center: [111.4453125, 32.84267363195431],
|
||||
pitch: 45,
|
||||
rotation: 30,
|
||||
zoom: 15,
|
||||
zoom: 13,
|
||||
}),
|
||||
});
|
||||
this.scene = scene;
|
||||
|
@ -37,10 +37,21 @@ export default class GlTFThreeJSDemo extends React.Component {
|
|||
enableMultiPassRenderer: false,
|
||||
onAddMeshes: (threeScene: THREE.Scene, layer: ThreeLayer) => {
|
||||
threeScene.add(new THREE.AmbientLight(0xffffff));
|
||||
|
||||
const sunlight = new THREE.DirectionalLight(0xffffff, 0.25);
|
||||
sunlight.position.set(0, 80000000, 100000000);
|
||||
sunlight.matrixWorldNeedsUpdate = true;
|
||||
threeScene.add(sunlight);
|
||||
|
||||
// threeScene.applyMatrix4(
|
||||
// layer.getModelMatrix(
|
||||
// [111.4453125, 32.84267363195431], // 经纬度坐标
|
||||
// 0, // 高度,单位米/
|
||||
// [Math.PI / 2, -Math.PI, 0], // 沿 XYZ 轴旋转角度
|
||||
// [100, 100, 100], // 沿 XYZ 轴缩放比例
|
||||
// ),
|
||||
// )
|
||||
|
||||
// 使用 Three.js glTFLoader 加载模型
|
||||
const loader = new GLTFLoader();
|
||||
loader.load(
|
||||
|
@ -52,37 +63,22 @@ export default class GlTFThreeJSDemo extends React.Component {
|
|||
// 'https://gw.alipayobjects.com/os/antvdemo/assets/gltf/man/CesiumMan.gltf',
|
||||
'https://gw.alipayobjects.com/os/bmw-prod/3ca0a546-92d8-4ba0-a89c-017c218d5bea.gltf',
|
||||
(gltf) => {
|
||||
// console.log(gltf)
|
||||
const gltfScene = gltf.scene;
|
||||
// gltfScene.rotation.set(90, 90, 0)
|
||||
const model: Object3D = gltf.scene;
|
||||
|
||||
layer.getSource().data.dataArray.forEach(({ coordinates }) => {
|
||||
const gltfScene = gltf.scene;
|
||||
|
||||
gltfScene.scale.set(10, 10, 10);
|
||||
// gltfScene.applyMatrix4(
|
||||
// // 生成模型矩阵
|
||||
// layer.getModelMatrix(
|
||||
// [coordinates[0], coordinates[1]], // 经纬度坐标
|
||||
// 0, // 高度,单位米/
|
||||
// [Math.PI / 2, -Math.PI, 0], // 沿 XYZ 轴旋转角度
|
||||
// [100, 100, 100], // 沿 XYZ 轴缩放比例
|
||||
// ),
|
||||
// );
|
||||
|
||||
// gltfScene.applyMatrix4(
|
||||
// // 生成模型矩阵
|
||||
// layer.getModelMatrix(
|
||||
// // [coordinates[0], coordinates[1]], // 经纬度坐标
|
||||
// [0, 0], // 经纬度坐标
|
||||
// 0, // 高度,单位米/
|
||||
// [Math.PI / 2, -Math.PI, 0], // 沿 XYZ 轴旋转角度
|
||||
// [10000, 10000, 10000], // 沿 XYZ 轴缩放比例
|
||||
// ),
|
||||
// );
|
||||
model.applyMatrix4(
|
||||
// 生成模型矩阵
|
||||
layer.getModelMatrix(
|
||||
[coordinates[0], coordinates[1]], // 经纬度坐标
|
||||
0, // 高度,单位米/
|
||||
[Math.PI / 2, -Math.PI, 0], // 沿 XYZ 轴旋转角度
|
||||
[100, 100, 100], // 沿 XYZ 轴缩放比例
|
||||
),
|
||||
);
|
||||
|
||||
const animations = gltf.animations;
|
||||
if (animations && animations.length) {
|
||||
const mixer = new THREE.AnimationMixer(gltfScene);
|
||||
const mixer = new THREE.AnimationMixer(model);
|
||||
// @ts-ignore
|
||||
// for (let i = 0; i < 1; i++) {
|
||||
const animation = animations[2];
|
||||
|
@ -97,11 +93,27 @@ export default class GlTFThreeJSDemo extends React.Component {
|
|||
layer.addAnimateMixer(mixer);
|
||||
}
|
||||
|
||||
// 向场景中添加模型
|
||||
// threeScene.add(gltfScene);
|
||||
});
|
||||
// 向场景中添加模型
|
||||
threeScene.add(model);
|
||||
|
||||
let lnglat = [121.107, 30.267069] as [number, number]
|
||||
let altitude = 0
|
||||
let center = scene.getCenter()
|
||||
// layer.setObjectLngLat(model, lnglat, altitude)
|
||||
// console.log()
|
||||
// layer.setObjectLngLat(model, [center.lng + 0.05, center.lat] as ILngLat, 0)
|
||||
// layer.setObjectLngLat(model, [center.lng + 0.05, center.lat] as ILngLat, 0)
|
||||
|
||||
layer.setObjectLngLat(model, [center.lng + 0.05, center.lat] as ILngLat, 0)
|
||||
|
||||
let t = 0
|
||||
setInterval(() => {
|
||||
t += 0.01
|
||||
layer.setObjectLngLat(model, [center.lng, center.lat + Math.sin(t) * 0.1] as ILngLat, 0)
|
||||
// layer.setObjectLngLat(model, [center.lng + 0.2, center.lat], 0)
|
||||
}, 16)
|
||||
|
||||
threeScene.add(gltfScene);
|
||||
// 重绘图层
|
||||
layer.render();
|
||||
},
|
||||
|
@ -117,6 +129,7 @@ export default class GlTFThreeJSDemo extends React.Component {
|
|||
geometry: {
|
||||
type: 'Point',
|
||||
coordinates: [111.4453125, 32.84267363195431],
|
||||
// coordinates: [121.107, 30.267069], // 该坐标点在钱塘江入海口附近
|
||||
},
|
||||
},
|
||||
],
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Scene } from '@antv/l7';
|
||||
import { GaodeMap, Mapbox } from '@antv/l7-maps';
|
||||
import { ThreeLayer, ThreeRender } from '@antv/l7-three';
|
||||
import { ThreeLayer, ThreeRender, ILngLat } from '@antv/l7-three';
|
||||
import * as React from 'react';
|
||||
// import { DirectionalLight, Scene as ThreeScene } from 'three';
|
||||
import * as THREE from 'three';
|
||||
|
@ -41,6 +41,16 @@ export default class GlTFThreeJSDemo extends React.Component {
|
|||
sunlight.position.set(0, 80000000, 100000000);
|
||||
sunlight.matrixWorldNeedsUpdate = true;
|
||||
threeScene.add(sunlight);
|
||||
|
||||
|
||||
// threeScene.applyMatrix4(
|
||||
// layer.getModelMatrix(
|
||||
// [111.4453125, 32.84267363195431], // 经纬度坐标
|
||||
// 0, // 高度,单位米/
|
||||
// [Math.PI / 2, -Math.PI, 0], // 沿 XYZ 轴旋转角度
|
||||
// [1, 1, 1], // 沿 XYZ 轴缩放比例
|
||||
// ),
|
||||
// )
|
||||
// 使用 Three.js glTFLoader 加载模型
|
||||
const loader = new GLTFLoader();
|
||||
loader.load(
|
||||
|
@ -61,7 +71,7 @@ export default class GlTFThreeJSDemo extends React.Component {
|
|||
[coordinates[0], coordinates[1]], // 经纬度坐标
|
||||
0, // 高度,单位米/
|
||||
[Math.PI / 2, -Math.PI, 0], // 沿 XYZ 轴旋转角度
|
||||
[100, 100, 100], // 沿 XYZ 轴缩放比例
|
||||
[1000, 1000, 1000], // 沿 XYZ 轴缩放比例
|
||||
),
|
||||
);
|
||||
const animations = gltf.animations;
|
||||
|
@ -80,6 +90,18 @@ export default class GlTFThreeJSDemo extends React.Component {
|
|||
// }
|
||||
layer.addAnimateMixer(mixer);
|
||||
}
|
||||
// console.log(gltfScene.position)
|
||||
let center = scene.getCenter()
|
||||
console.log(center)
|
||||
console.log(layer.getObjectLngLat(gltfScene))
|
||||
// layer.setObjectLngLat(gltfScene, [center.lng + 0.05, center.lat] as ILngLat, 0)
|
||||
// layer.setObjectLngLat(gltfScene, [center.lng, center.lat] as ILngLat, 0)
|
||||
let t = 0
|
||||
setInterval(() => {
|
||||
t += 0.01
|
||||
layer.setObjectLngLat(gltfScene, [center.lng, center.lat + Math.sin(t) * 0.1] as ILngLat, 0)
|
||||
// layer.setObjectLngLat(model, [center.lng + 0.2, center.lat], 0)
|
||||
}, 16)
|
||||
|
||||
// 向场景中添加模型
|
||||
threeScene.add(gltfScene);
|
||||
|
@ -98,7 +120,7 @@ export default class GlTFThreeJSDemo extends React.Component {
|
|||
properties: {},
|
||||
geometry: {
|
||||
type: 'Point',
|
||||
coordinates: [111.4453125, 32.84267363195431],
|
||||
coordinates: [111.4453125, 32.84267363195431]
|
||||
},
|
||||
},
|
||||
],
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { PolygonLayer, Scene } from '@antv/l7';
|
||||
import { GaodeMap, Mapbox } from '@antv/l7-maps';
|
||||
import { ThreeLayer, ThreeRender } from '@antv/l7-three';
|
||||
import { ThreeLayer, ThreeRender, ILngLat } from '@antv/l7-three';
|
||||
import * as React from 'react';
|
||||
// import { DirectionalLight, Scene as ThreeScene } from 'three';
|
||||
import * as THREE from 'three';
|
||||
|
@ -73,8 +73,9 @@ export default class GlTFThreeJSDemo extends React.Component {
|
|||
// 'https://gw.alipayobjects.com/os/bmw-prod/3ca0a546-92d8-4ba0-a89c-017c218d5bea.gltf',
|
||||
(gltf) => {
|
||||
// 根据 GeoJSON 数据放置模型
|
||||
const gltfScene = gltf.scene.clone();
|
||||
layer.getSource().data.dataArray.forEach(({ coordinates }) => {
|
||||
const gltfScene = gltf.scene.clone();
|
||||
|
||||
gltfScene.applyMatrix4(
|
||||
// 生成模型矩阵
|
||||
layer.getModelMatrix(
|
||||
|
@ -105,6 +106,20 @@ export default class GlTFThreeJSDemo extends React.Component {
|
|||
// 向场景中添加模型
|
||||
threeScene.add(gltfScene);
|
||||
});
|
||||
|
||||
let center = scene.getCenter()
|
||||
console.log(center)
|
||||
console.log(layer.getObjectLngLat(gltfScene))
|
||||
// layer.setObjectLngLat(gltfScene, [center.lng + 0.05, center.lat] as ILngLat, 0)
|
||||
|
||||
// let t = 0
|
||||
// setInterval(() => {
|
||||
// t += 0.01
|
||||
// layer.setObjectLngLat(gltfScene, [center.lng, center.lat + Math.sin(t) * 0.1] as ILngLat, 0)
|
||||
// // layer.setObjectLngLat(model, [center.lng + 0.2, center.lat], 0)
|
||||
// }, 16)
|
||||
|
||||
|
||||
// 重绘图层
|
||||
layer.render();
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue