0、数据输入为类似Geojson的压缩文件和纹理图片,基于DrawCommand命令绘制;
1、自定义建筑几何,包括顶点、法线、纹理等;
2、自定义纹理贴图,包括按建筑高度贴图、按距离贴图,mipmap多级纹理;
3、自定义批处理表和ID纹理,支持单个显示控制和鼠标交互。
效果
部分代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>北京建筑</title>
<script src="./js/config.js"></script>
<script src="./scripts/vue.min.js"></script>
<link rel="stylesheet" href="./css/common.css" />
<script type="text/javascript" src="../anov-gis-sdk/index.js"></script>
<link rel="stylesheet" href="../anov-gis-sdk/index.css" />
<script type="text/javascript" src="./scripts/element.index.js"></script>
<link rel="stylesheet" href="./scripts/element.index.css">
<!-- <script src="https://cdn.jsdelivr.net/npm/pbf"></script> -->
</head>
<body>
<div id="global"></div>
<script type="module">
import CustomPrimitive from './html/performance/CustomPrimitive.js';
import CustomTexture from './html/performance/CustomTexture.js';
import CustomWallGeometry from './html/performance/CustomWallGeometry.js';
import { showLoading, hideLoading, setText } from './html/performance/loadingUtil.js';
new Vue({
el: "#global",
template: `<div id="cesiumContainer"></div>`,
mounted() {
this.init3D();
this.addTestPrimitive();
setTimeout(() => {
showLoading();
this.creatWall();
}, 1000);
setTimeout(() => {
console.log('viewer.scene.frameState.commandList', viewer.scene.frameState.commandList);
}, 5000);
},
methods: {
init3D() {
window.viewer = new ANOVGIS.Viewer("cesiumContainer", {
contextOptions: {
id: "cesiumCanvas",
webgl: {
preserveDrawingBuffer: false,
},
showRenderLoopErrors: true,
},
geocoderType: ANOVGIS.GeocoderType.TIANDITU,
vrButton: false,
baseLayerPicker: true,
fullscreenButton: true,
homeButton: true,
sceneModePicker: true,
navigationHelpButton: true,
copyRight: false,
showMapInfo: true,
drillPick: false,
});
top.viewer = window.viewer;
viewer.setOptions({
enableFxaa: true,
});
viewer.nativeObjCesium.shadowMap.maximumDistance = 1300;
let time = 0;
setInterval(() => {
// 改变时间设置光照效果
let date = new Date().getTime() + time
let utc = Cesium.JulianDate.fromDate(new Date(date))
//北京时间
viewer.nativeObjCesium.clockViewModel.currentTime = Cesium.JulianDate.addHours(utc, 8, new Cesium.JulianDate())
time = time + 5000 * 60
}, 100)
},
locate() {
ANOVGIS.LocateUtil.flyToPosition(viewer, '116.4244631,39.8453427', 0, -35, 5000, 2, null);
},
creatWall() {
this.addBuildingWallsToViwer(0, datasArr);
},
async addBuildingWallsToViwer(indexB, arr) {
// 模拟异步操作
},
getFile(path, callback) {
return fetch(path, {
responseType: 'arraybuffer'
}).then(res => {
return res.arrayBuffer();
}).then(data => {
let geojson = geobuf.decode(new Pbf(data))
callback(geojson);
})
},
addWallPrimitive(buildingMaterial) {
const buildsArr = buildingMaterial.buildingdatas;
const customWallGeometry = new CustomWallGeometry({
buildsArr,
textureWidth: buildingMaterial.textureWidth
});
const geometryCombined = customWallGeometry.createGeometry(buildsArr);
const attributeLocations = {
position3DHigh: 0,
position3DLow: 1,
normal: 2,
st: 3
};
let texture;
const customTexture = new CustomTexture();
customTexture.getMipmapTexture(viewer.scene.context, '../modelData/building/' + buildingMaterial.material[0], (t) => {
texture = t;
});
const customPrimitive = new CustomPrimitive({
geometry: geometryCombined,
attributeLocations: attributeLocations,
receiveShadows: true,
castShadows: true,
})
return viewer.scene.primitives.add(customPrimitive);
},
addBuildTops(buildingMaterial) {
const buildsArr = buildingMaterial.buildingdatas;
const topsInstancesArr = [];
for (let index = 0; index < buildsArr.length; index++) {
const element = buildsArr[index];
const positionsCartesian3 = element.positions;
const buildingHeight = element.height;
const topInstance = new Cesium.GeometryInstance({
geometry: Cesium.PolygonGeometry.createGeometry(new Cesium.PolygonGeometry({
polygonHierarchy: new Cesium.PolygonHierarchy(
positionsCartesian3
),
height: buildingHeight
}))
});
topsInstancesArr.push(topInstance);
}
const geometryCombined = Cesium.GeometryPipeline.combineInstances(topsInstancesArr)[0];
const attributeLocations = {
position3DHigh: 0,
position3DLow: 1,
normal: 2,
st: 3
};
let texture;
const customTexture = new CustomTexture();
customTexture.getMipmapTexture(viewer.scene.context, '../modelData/building/' + buildingMaterial.topMaterial[0], (t) => {
texture = t;
})
const topsPrimitive = new CustomPrimitive({
geometry: geometryCombined,
attributeLocations: attributeLocations,
receiveShadows: true,
castShadows: false,
uniformMap: {
myImage: () => {
if (Cesium.defined(texture)) {
return texture;
} else {
return viewer.scene.context.defaultTexture;
}
}
},
})
return viewer.scene.primitives.add(topsPrimitive);
},
}
})
</script>
</body>
</html>