当mapbox的底图设置好了,我们便可以在此基础之上建立各个资源了。 这次我先分享三个资源的添加,也是我们最经常使用的三个方法。
添加png格式的图片
function addPNG() {
map.addSource('radar', {
'type': 'image',
'url': "http://localhost:82/model/p1.png",
'coordinates': [
[108.942413 - 0.01, 34.260424 + 0.01],
[108.942413 + 0.01, 34.260424 + 0.01],
[108.942413 + 0.01, 34.260424 - 0.01],
[108.942413 - 0.01, 34.260424 - 0.01]
]
});
map.addLayer({
'id': 'radar-layer',
'type': 'raster',
'source': 'radar',
'paint': {
'raster-fade-duration': 0
}
});
map.getSource('source-id').setData(data);
}
我还是把它们放到了函数中,便于调取。
url是我的图片的地址;
coordinates 是我的图片的四个顶点的经纬度,这样设置会让图片不随着我们地图的缩放而跟着变化;
map.addSource主要是跟图片有关的,选择图片的格式,位置,路径等,而map.addLayer和地图有关,可以选择图片的id等等,而这部分一般是不会变化的。
创建3D模型
function create3DModel() {
// 模型的原点经纬度坐标
const modelOrigin = [108.942413, 34.260424];
// 模型的海拔高度
const modelAltitude = 0;
// 模型的旋转角度(绕X、Y、Z轴的旋转)
const modelRotate = [Math.PI / 2, 0, 0];
// 将模型的原点经纬度坐标转换为墨卡托坐标
const modelAsMercatorCoordinate = mapboxgl.MercatorCoordinate.fromLngLat(
modelOrigin,
modelAltitude
);
// 构建模型的变换信息
const modelTransform = {
translateX: modelAsMercatorCoordinate.x,
translateY: modelAsMercatorCoordinate.y,
translateZ: modelAsMercatorCoordinate.z,
rotateX: modelRotate[0],
rotateY: modelRotate[1],
rotateZ: modelRotate[2],
scale: modelAsMercatorCoordinate.meterInMercatorCoordinateUnits()
};
// 引入THREE.js库
const THREE = window.THREE;
// 创建自定义图层对象
const customLayer = {
id: '3d-model',
type: 'custom',
renderingMode: '3d',
onAdd: function (map, gl) {
this.camera = new THREE.Camera();
this.scene = new THREE.Scene();
// 创建定向光源1
const directionalLight = new THREE.DirectionalLight(0xffffff);
directionalLight.position.set(0, -70, 100).normalize();
this.scene.add(directionalLight);
// 创建定向光源2
const directionalLight2 = new THREE.DirectionalLight(0xffffff);
directionalLight2.position.set(0, 70, 100).normalize();
this.scene.add(directionalLight2);
// 使用GLTFLoader加载模型
const loader = new THREE.GLTFLoader();
loader.load(
'http://localhost:82/model/zhangzhou.gltf', // 请替换为您本地GLTF模型的路径
(gltf) => {
this.scene.add(gltf.scene);
}
);
this.map = map;
// 创建WebGLRenderer
this.renderer = new THREE.WebGLRenderer({
canvas: map.getCanvas(),
context: gl,
antialias: true
});
this.renderer.autoClear = false;
},
render: function (gl, matrix) {
// 创建X、Y、Z轴的旋转矩阵
const rotationX = new THREE.Matrix4().makeRotationAxis(
new THREE.Vector3(1, 0, 0),
modelTransform.rotateX
);
const rotationY = new THREE.Matrix4().makeRotationAxis(
new THREE.Vector3(0, 1, 0),
modelTransform.rotateY
);
const rotationZ = new THREE.Matrix4().makeRotationAxis(
new THREE.Vector3(0, 0, 1),
modelTransform.rotateZ
);
// 构建模型的变换矩阵
const m = new THREE.Matrix4().fromArray(matrix);
const l = new THREE.Matrix4()
.makeTranslation(
modelTransform.translateX,
modelTransform.translateY,
modelTransform.translateZ
)
.scale(
new THREE.Vector3(
modelTransform.scale,
-modelTransform.scale,
modelTransform.scale
)
)
.multiply(rotationX)
.multiply(rotationY)
.multiply(rotationZ);
// 设置相机的投影矩阵
this.camera.projectionMatrix = m.multiply(l);
// 清除渲染器状态并进行渲染
this.renderer.resetState();
this.renderer.render(this.scene, this.camera);
// 触发地图重绘
this.map.triggerRepaint();
}
};
// 在地图加载样式后添加自定义图层
map.on('style.load', () => {
map.addLayer(customLayer, 'waterway-label');
});
}
这个代码是添加3D模型,也就是gltf格式的代码,后续我还会出一个加载多个gltf模型的代码。
这个是官方的例子,里面有很多关于gltf模型的属性的篇幅(位置,大小,角度等等),官方例子是没有中文注释的,这些注释是我加进去的,我觉得已经够详细了,就不再过多赘述了。
另外,加载gltf文件还需要对应的three.js的头文件,我到时候会把所以需要的头文件单独放到一个文章里吧,对我来说会方便一点把,烦请自己找一下吧。
加载外部GeoJson资源
function create3DModel() {
// 你的现有 create3DModel 函数代码...
// 加载外部 GeoJSON 数据并显示
function addGeoJson() {
fetch('http://localhost:82/model/xiancopy.json')
.then(response => response.json())
.then(data => {
const sourceId = 'geojson-source';
const layerId = 'geojson-layer';
map.addSource(sourceId, {
type: 'geojson',
data: data
});
map.addLayer({
id: layerId,
type: 'fill-extrusion',
source: sourceId,
paint: {
'fill-extrusion-color': {
property: 'Conc',
stops: [
[1.59e-33, '#ff0000'],
[1.73e+00, '#00ff00'],
[Infinity, '#000000']
]
},
'fill-extrusion-height': ['get', 'Floor'],
'fill-extrusion-opacity': 1
}
});
})
.catch(error => {
console.error('Error fetching GeoJSON:', error);
});
}
// 在地图加载样式后添加自定义图层
map.on('style.load', () => {
map.addLayer(customLayer, 'waterway-label');
// 添加外部 GeoJSON 数据
addGeoJson();
});
}
这是加载geojson格式的代码,这里主要针对的时加载外部geojson文件,就是文件的代码不放到这里,注释我也尽可能标注上了,大家有什么不懂的可以在评论区提问哈
关于geojson文件,是一种特殊的json文件,当然mapbox也可以加载json文件。
这里是我一开始学到的三个加载的资源,后续我还会把更复杂的情况(比如加载多个文件)的代码写下来。