我基于“添加 3D 模型”示例编写了一些代码,以便在地图上仅绘制水平面,并使用
setTerrain
添加地形图层。我的目的是在海拔高度绘制半透明图层,并让它们与山脉相交,有点类似于等高线。
我在海拔 0 处创建了一个 1 公里宽的正方形。海拔 0 是可见地图区域中心地形的高度。当我拖动地图并释放鼠标时,高度 0 会重置为中心地形的新高度 0,从而使飞机改变其相对高度:
为了更好地说明问题,夸大了海拔。
如何指定飞机的高度(以米为单位)并在拖动地图时将其固定在该高度?我想我需要获取中心地形的高度,然后从平面的 z 位置添加/减去它,但是如何在自定义图层的渲染函数中执行此操作?
就像你说的,一个简单的解决方案是获取屏幕中心地形的高度和模型的高度,然后减去它们。这可以像这样实现:
render(gl, matrix) {
const modelOrigin = new LngLat(11.53, 47.67); // just an example
const modelElevation = map.terrain ? map.terrain.getElevationForLngLatZoom(modelOrigin, map.getZoom()) : 0;
const modelOriginMercator = mlg.MercatorCoordinate.fromLngLat(modelOrigin, 0);
// calculating the difference between center-elevation and model-elevation
const terrainCenterElevation = map.transform.elevation;
const deltaMetersZ = modelElevation - terrainCenterElevation;
const mercatorPerMeter = modelOriginMercator.meterInMercatorCoordinateUnits();
const deltaMercatorZ = deltaMetersZ * mercatorPerMeter;
const modelTransform = {
translateX: modelOriginMercator.x,
translateY: modelOriginMercator.y,
translateZ: modelOriginMercator.z + deltaMercatorZ,
rotateX: Math.PI / 2,
rotateY: 0,
rotateZ: 0,
scale: modelOriginMercator.meterInMercatorCoordinateUnits()
};
const rotationX = new Matrix4().makeRotationAxis(new Vector3(1, 0, 0), modelTransform.rotateX);
const rotationY = new Matrix4().makeRotationAxis(new Vector3(1, 0, 0), modelTransform.rotateY);
const rotationZ = new Matrix4().makeRotationAxis(new Vector3(0, 0, 1), modelTransform.rotateZ);
const m = new Matrix4().fromArray(matrix);
const l = new Matrix4()
.makeTranslation(modelTransform.translateX, modelTransform.translateY, modelTransform.translateZ)
.scale(new Vector3(modelTransform.scale, modelTransform.scale, modelTransform.scale))
.multiply(rotationX).multiply(rotationY).multiply(rotationZ);
const cameraProjectionMatrix = m.multiply(l);
// @ts-ignore
this.camera.projectionMatrix = cameraProjectionMatrix;
// @ts-ignore
this.renderer.resetState();
// @ts-ignore
this.renderer.render(this.scene, this.camera);
map.triggerRepaint();
}
mlg.MercatorCoordinate.fromLngLat(modelOrigin, 0)
获取模型高度时,我们不需要提供实际的模型高度,只需传递 0
deltaMercatorZ
正在添加到模型的 z 轴翻译中关于 transform.ts 中的 maplibre 命名法的一些注释:
elevation
[米]:center
center
[lng, lat]:屏幕中心在世界中的位置centerPoint
[像素]:屏幕中心在屏幕上的位置altitude
[m]:相机相对于海平面的高度我认为可能有一个更优雅的解决方案,但这可能暂时可以完成工作!