左边是使用gltf模型 右边是3dTiles
gltf模型清晰但是加载速度缓慢(可以使用indexedDb前端缓存 进行优化 安装插件idb-js 本文未做该方法实现 请各位看官自行摸索);
3dTiles模型加载速度快 但是略模糊;
看个人需求进行选择;
gltf文件转换为3dTiles文件:可通过Stories | Cesium ion进行转换
/*
* 说明: 加载3d模型
*/
import * as Cesium from "cesium/Cesium.js";
import {applyWaterMaterial} from "./WaterMaterialHelper/WaterMaterialHelper.mini.js"
export const initLoadModel = (
function() {
var viewer;
var dataSource;
var primitives = []; //模型水域集合
function constructInitLoadModel(option) { //传入viewer
viewer = option.viewer;
viewer.scene.moon.show = false;
viewer.scene.sun.show = false;
// dataSource = handleDataSources()
handleModelLoad()
}
//加载所有模型
function handleModelLoad() {
setInitView() // 设置初始化视角
// 处理加载渔港
loadDtyg()
loadSz()
}
/**
* 加载动态水域部分
* @param name
* @returns {null}
*/
function handleDataSources() {
}
// 设置初始化视角
function setInitView(viewLon, viewLat, viewHeight, viewHeading, viewPitch, viewRoll) {
viewer.camera.setView({
// {x: -2920698.527415139, y: 4829685.984492454, z: 2961366.1046909913} 1.4957989195393306 -0.40170036471106374 0.0030000140388031227
// z 越小 越向上移动
// destination: Cesium.Cartesian3.fromDegrees(121.1633233, 27.8545, 700),
destination: new Cesium.Cartesian3(-2920698.527415139, 4829685.984492454, 2961366.1046909913),
// destination: Cesium.Cartesian3.fromDegrees(121.1635, 27.8442451, 330),
orientation: {
// 越小越向下移动
heading: 1.4957989195393306, // 航向角
pitch: -0.40170036471106374,// 俯仰角
roll: 0.0030000140388031227 //滚转角
}
});
}
// 处理加载渔港模型及水域部分
function loadDtyg() {
var position = Cesium.Cartesian3.fromDegrees(121.17500877, 27.8450605, -3);
// heading:绕负z轴的旋转 pitch:绕负y轴的旋转,roll:绕正x轴的
let headingPitchRoll = new Cesium.HeadingPitchRoll(Cesium.Math.toRadians(parseFloat(90)), Cesium.Math.toRadians(parseFloat(0)), Cesium.Math.toRadians(parseFloat(0)));
// var modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(position);
let modelMatrix = Cesium.Transforms.headingPitchRollToFixedFrame(position, headingPitchRoll, Cesium.Ellipsoid.WGS84, Cesium.Transforms.eastNorthUpToFixedFrame, new Cesium.Matrix4());
// 方法一 gltf加载较慢 但是特别清晰
// var terrain = viewer.scene.primitives.add(Cesium.Model.fromGltf({
// modelMatrix: modelMatrix,
// url: '/dx1/dtyg.gltf',
// scale: 1.0,
// allowPicking: false,
// }));
// terrain.readyPromise.then(function (terrain) {
// terrain.activeAnimations.addAll();
// })
// console.log(terrain, 'terrain')
// 方法二: 3d模型加载速度快 但是没有gltf清晰
// (越大越向上偏移,越大越像左边偏移,‘’)
var position1 = Cesium.Cartesian3.fromDegrees(121.17574905, 27.8438080, -3);
// heading:绕负z轴的旋转 pitch:绕负y轴的旋转,roll:绕正x轴的
let headingPitchRoll1 = new Cesium.HeadingPitchRoll(Cesium.Math.toRadians(parseFloat(0)), Cesium.Math.toRadians(parseFloat(0)), Cesium.Math.toRadians(parseFloat(0)));
let modelMatrix1 = Cesium.Transforms.headingPitchRollToFixedFrame(position1, headingPitchRoll1, Cesium.Ellipsoid.WGS84, Cesium.Transforms.eastNorthUpToFixedFrame, new Cesium.Matrix4());
var tileset = new Cesium.Cesium3DTileset({
url: 'tileset.json',
skipLevelOfDetail: true,
//控制切片视角显示的数量,可调整性能
maximumScreenSpaceError: 2,
maximumNumberOfLoadedTiles: 100000,
baseScreenSpaceError: 1024,
maximumScreenSpaceError: 256, // 数值加大,能让最终成像变模糊
skipScreenSpaceErrorFactor: 16,
skipLevels: 1,
immediatelyLoadDesiredLevelOfDetail: false,
loadSiblings: true, // 如果为true则不会在已加载完模型后,自动从中心开始超清化模型
cullWithChildrenBounds: true,
cullRequestsWhileMoving: true,
cullRequestsWhileMovingMultiplier: 10, // 值越小越能够更快的剔除
preloadWhenHidden: true,
preferLeaves: true,
maximumMemoryUsage: 128, // 内存分配变小有利于倾斜摄影数据回收,提升性能体验
progressiveResolutionHeightFraction: 0.5, // 数值偏于0能够让初始加载变得模糊
dynamicScreenSpaceErrorDensity: 0.5, // 数值加大,能让周边加载变快
dynamicScreenSpaceErrorFactor: 1, // 不知道起了什么作用没,反正放着吧先
dynamicScreenSpaceError: true, // 根据测试,有了这个后,会在真正的全屏加载完之后才清晰化房屋
})
tileset.readyPromise.then(function (tileset) {
tileset.modelMatrix = modelMatrix1
console.log(viewer.scene.primitives, '.scene.primitives.')
});
viewer.scene.primitives.add(tileset);
var polygon = new Cesium.PolygonGeometry({
polygonHierarchy: new Cesium.PolygonHierarchy(
Cesium.Cartesian3.fromDegreesArray([
121.170687, 27.846771, 121.170079, 27.847184, 121.169493, 27.847253, 121.168774, 27.846997, 121.168188, 27.846398, 121.168034, 27.845887, 121.168078, 27.845671, 121.168012, 27.845307, 121.167978, 27.844943, 121.167967, 27.844717, 121.168269, 27.844337, 121.168844, 27.843993, 121.169618, 27.843511, 121.170016, 27.843266, 121.171994, 27.840711, 121.173828, 27.840711, 121.174325, 27.840456, 121.174270, 27.840201, 121.174922, 27.839494, 121.175783, 27.839590, 121.175861, 27.839119, 121.176159, 27.838049, 121.179516, 27.836979, 121.181802, 27.838284, 121.183846, 27.839806, 121.182807, 27.841641, 121.180707, 27.842191, 121.179945, 27.843783, 121.178805, 27.844384, 121.177401, 27.845043, 121.176981, 27.845436, 121.177401, 27.846065, 121.178706, 27.846488, 121.179502, 27.846645, 121.179701, 27.847490, 121.179259, 27.848286, 121.178772, 27.848394, 121.177434, 27.848089, 121.173077, 27.846310, 121.172026, 27.847165, 121.170876, 27.846802
])
),
});
var instance = new Cesium.GeometryInstance({
geometry: polygon,
});
var waterScene = viewer.scene;
applyWaterMaterial(instance, waterScene);
}
//创建数据区域
function createDataSource(info) {
const dataSource = new Cesium.CustomDataSource(info.type);
viewer.dataSources.add(dataSource);
return dataSource
}
//加载水质监测点
function loadSz() {
dataSource = createDataSource('sz')
console.log(dataSource, 'dataSource')
let data = [
{
id: "402889865f1327d7015f1333454a0000",
pointNum: "1",
savetime: "2017-10-13 08:47:28",
status: "1",
updatetime: "2017-10-13 08:47:28",
waterRules: '[{"el":"N","min":"1","max":"9"}]',
x: "121.172448",
y: "27.844544",
},
{
id: "402889865f1327d7015f1335cdb40001",
pointNum: "2",
savetime: "2017-10-13 08:50:14",
status: "1",
updatetime: "2017-10-13 08:50:14",
waterRules: '[{"el":"P","min":"1","max":"19"}]',
x: "121.175197",
y: "27.843448",
},
]
let water = viewer.entities.add(new Cesium.Entity({
id: data[0].id,
name: "监测点:" + data[0].pointNum,
position: Cesium.Cartesian3.fromDegrees(121.1682304181, 27.84638921, 1.7),
model: {
url: 'water/sz.gltf',
scale: 1
},
selname: "water_" + data[0].pointNum
}));
return water;
}
function loadShipBoat(ds2) {
let shipBoat = dataSource.entities.add(new Cesium.Entity({
type: "",
name: ds2[i].shipcn,
mmsi: ds2[i].shipmmsi,
ship: "1",
id: ds2[i].c,
shipid: ds2[i].a,
time: ds2[i].o,
lon: ds2[i].e,
lat: ds2[i].f,
termtype: types[ds2[i].b],
termno: ds2[i].c,
position: position,
orientation: orientation,
model: {
// 根据渔船长度展示不同渔船模型
uri: ds2[i].long > 40 ? "ship/boat3.gltf" : (ds2[i].long > 30 ? "/ship/boat2.gltf" : "/ship/boat.gltf"),
scale: 1,
silhouetteColor: Cesium.Color.fromAlpha(ship_color, parseFloat(0.8)),
silhouetteSize: ship_opacity
},
description: '<table class="cesium-infoBox-defaultTable"><tbody>' +
'<tr><th>渔船中文名</th><td>' + ds2[i].shipcn + '</td></tr>' +
'<tr><th>渔船所有人</th><td>' + ds2[i].shipOwner + '</td></tr>' +
'<tr><th>mmsi</th><td>' + ds2[i].shipmmsi + '</td></tr>' +
'<tr><th>船东</th><td>' + ds2[i].shipOwner + '</td></tr>' +
'<tr><th>联系电话</th><td>' + ds2[i].tel + '</td></tr>' +
'<tr><th>船舶类型</th><td>' + ds2[i].shiptype + '</td></tr>' +
'<tr><th>作业类型</th><td>' + ds2[i].worktype + '</td></tr>' +
'<tr><th>作业方式</th><td>' + ds2[i].workmode + '</td></tr>' +
'<tr><th>发动机功率</th><td>' + ds2[i].power + '</td></tr>' +
'<tr><th>船只长度(米)</th><td>' + ds2[i].long + '</td></tr>' +
'<tr><th>船只宽度(米)</th><td>' + ds2[i].width + '</td></tr>' +
'<tr><th>船深(米)</th><td>' + ds2[i].depth + '</td></tr>' +
'<tr><th>总吨位(吨)</th><td>' + ds2[i].tonnage + '</td></tr>' +
'<tr><th>船首朝向(正北角1/10 度)</th><td>' + ds2[i].j + '</td></tr>' +
'<tr><th>记录时间</th><td>' + dateFormat(new Date(ds2[i].o * 1000), 'yyyy-MM-dd hh:mm') + '</td></tr>' +
'<tr><th>终端号码</th><td>' + ds2[i].c + '</td></tr>' +
'<tr><th>终端类型</th><td>' + types[ds2[i].b] + '</td></tr>' +
'<tr><th>渔船经度(1/10000000度)</th><td>' + ds2[i].e + '</td></tr>' +
'<tr><th>渔船纬度(1/10000000度)</th><td>' + ds2[i].f + '</td></tr>' +
'</tbody></table>'
}));
return shipBoat;
}
return constructInitLoadModel;
})()