可视化运行效果(水质污染扩散)
实现运行效果
术语
Mesh网格数据解析
Mesh(网格)在不同领域有不同的应用和定义。在计算机网络中,Mesh网络指的是一种无中心的网状结构,每个节点都与其他节点相连。而在3D计算机图形学中,Mesh是一个由许多小而简单的三角形构成的3D模型。
Mesh网格的应用场景
- 三维建模:Mesh用于创建三维模型,提供网格、曲面及多边形建模技术。
- 游戏开发:构建游戏角色、场景和特效。
- 计算机辅助设计(CAD):建立几何模型,提供建模工具和技术。
- 数值分析:用于数值分析、有限元模拟和计算流体动力学等计算应用程序。
- 医学领域:生成三维重建的解剖结构。
- 建筑设计:建立建筑外观、结构和平面图。
- 制造业:模拟非线性、动态和多物理场景下的部件行为。
- 流体力学:用于数值模拟和计算流体力学。
- 结构力学:用于有限元分析和结构优化。
- 计算机动画:用于人物建模、环境建模和特效制作。
- 环境工程:水污染扩散模拟,水质模拟预测。
Cesium中的Mesh网格可视化
Cesium是一个强大的三维地理空间可视化平台,它支持对Mesh网格数据的解析和可视化。通过Cesium,可以将Mesh网格数据转化为可视化的三角网格模型,实现以下功能:
- 数据解析:解析各种格式的Mesh网格数据。
- 三角网格生成:将网格数据转换为三角网格,用于可视化。
- 动态渲染:根据视角和光照条件动态渲染三角网格。
- 交互操作:支持用户与三角网格模型的交互操作,如旋转、缩放和探索。
实现步骤
- 数据准备:收集并准备Mesh网格数据。
- 数据导入:将Mesh数据导入Cesium平台。
- 网格解析:解析网格数据,提取网格结构和属性。
- 三角网格构建:根据解析结果构建三角网格模型。
- 可视化设置:设置光照、材质和其他视觉效果参数。
- 用户交互:实现用户与三角网格模型的交互功能。
通过上述步骤,可以在Cesium中实现Mesh网格数据的解析及可视化,为用户提供直观、动态的三维网格模型展示。
解析接口关键代码编写
//http://localhost:8085/ReadMesh/getMeshDataFiltered?FileName=A.mesh
@RequestMapping(value = "/getMeshDataFiltered",method = RequestMethod.GET)
public @ResponseBody Map getMeshDataFiltered(String FileName) {
//! 获取传入的参数,存在传入的文件名,则替换默认的文件名
String defaultfilename = "A.mesh";
String filename = FileName;
if (!filename.isEmpty()){
defaultfilename = filename;
}
String Meshpath = defaultfilename;
String fileTyle = Meshpath.substring(Meshpath.lastIndexOf("."),Meshpath.length());
Map map = new HashMap();
if (fileTyle.equals(".mesh")){
map = GenDataFromMesh(Meshpath);
}
if (fileTyle.equals(".msh")){
map = GenDataFromMsh(Meshpath);
}
return map;
}
前端可视化关键代码编写
primitiveTriangle:{
isRLayerPanel: true,
primitives:[],
url: '/static/data/trangles.json',
dataPath: '',
dataIdField: 'code',
options:{
id:'primitiveTriangle',
name:'三角格网',
type:'triangles',
isShow: false
},
location: {
"destination":{"x":-2194142.1719457568,"y":4477352.104342483,"z":3981503.0453665117},
"orientation":{"heading":6.283185231778362,"pitch":-0.6090220537393618,"roll":7.622047348831984e-8},
duration: 2
},
entityType:'primitive'
}
<template>
<div class="container">
<div id="cesiumContainer1" style="height: 85%">
<div id="tooltippop" class="ol-popup-tip" style="display:none; z-index:120; height:30px;">
<div id="tooltip-title"></div>
<div id="tooltip-content"></div>
</div>
<div id="gisToolPopoup">
<GisTool :zjnCesium="zjnCesium" @setLayerVisible="setLayerVisible" @zoomToC="zoomToC"></GisTool>
</div>
<div id="layersPanel">
<layerPanel :layersInfo="layersInfo" @setLayerVisible="setLayerVisible" @zoomToC="zoomToC"></layerPanel>
</div>
</div>
<popHover :popHoverInfo="popHoverInfo" :popHoverScreenPoint="popHoverScreenPoint" :popHoverVisible="popHoverVisible"></popHover>
<popClick :popAspect="popAspect" :popClickScreenPoint="popClickScreenPoint" :popClickVisible="popClickVisible" :popClickTitleInfo="popClickTitleInfo" :popClickContentInfo="popClickContentInfo"></popClick>
<div class="CoordinateLabel">
<p><label id="lon"></label></p>
<p><label id="lat"></label></p>
<p><label id="cdem"></label></p>
<p><label id="cvInfo"></label></p>
</div>
<div>
<input value="获取当前视图" type="button" style="height: 50px;width:100px" @click="getCv()">
</div>
</div>
</template>
<script>
// import { Viewer,createWorldTerrain,Cesium3DTileset,WebMapTileServiceImageryProvider,ImageryLayer,Cartesian3,HeadingPitchRange,Math} from 'cesium/Cesium'
import 'cesium/Widgets/widgets.css'
import './renderStyle/index.css'
import GisTool from "./gisTool"
import ZJNCesium from './ZJNCesium.js'
import layerPanel from './widgets/layerPanel/index'
import popHover from './widgets/popHover/index'
import popClick from './widgets/popClick/index'
import {layersInfo} from './store/LayersInfo'
import {LayersRenderSet} from './renderSet/LayersRenderSet'
import {LayersRenderLabelSet} from './renderSet/LayersRenderLabelSet'
import {layerMsgClick} from "./layerMsg/LayerMsgClick";
import {
CommonDrawEntities,
CommonDrawEntitiesByLayerID,
CommonDrawWallEntities,
CommonDrawPolylineEntities,
setLayerVisible,
CommonDrawPolygonEntities,
CommonDrawPointEntitiesByUrl,
CommonDrawWallEntitiesByUrl,
CommonDrawPolylineEntitiesByUrl,
CommonDrawPolygonEntitiesByUrl,
CommonDrawCorridorEntitiesByUrl,
CommonDrawByGeojson,
CommonDrawPolylineVolumeEntitiesByUrl,
CommonDrawWindyEntitiesByUrl,
CommonDrawHeatmapByUrl,
CommonDrawPrimitiveEntitiesByUrl,
CommonCreateMeshGrid,CommonCreateMeshTriangle
} from './MapCommon'
import {carDatas} from "../../common/api/carRoad"
import {linedata,polygondata} from "./data/pointlinepolygon"
import {TransferSimUtil} from "./utils/TransferSimUtil"
var zjnCesium;
export default {
name: "earth",
components: {
layerPanel,
GisTool,
popHover,
popClick
},
data() {
return {
zjnCesium: null,
popHoverScreenPoint: {x: null, y: null},
popHoverInfo: '',
popHoverVisible: false,
popClickScreenPoint: {x: null, y: null},
popAspect:{cWidth: 600, cHeight: 400},
popClickPoint: null,
popClickTitleInfo: '',
popClickContentInfo: '',
popClickVisible: false,
transferSimUtil: null,
buttondaohe:"道合",
layersInfo:layersInfo,
modelList:{
daohe:{x: -2412207.790025016,y: 4418038.146476992,z: 3904021.2752170297},
daoheOrientation:{
heading : 0,
pitch : -0.3,
roll : 0
},
caike:{x: -2399848.645912107,y: 4425276.703809752,z: 3903524.9361700616},
caikeOrientation:{
heading : 0,
pitch : -0.3,
roll : 0
},
dairuike:{x: -2398945.254669891,y: 4426231.6794353435,z: 3903000.9872286734},
dairuikeOrientation:{
heading : 0,
pitch : -0.3,
roll : 0
},
guangyue:{x: -2410663.34105633, y: 4417042.059943647, z: 3905962.3976926757},
guangyueOrientation:{heading: 3.282430123199906,pitch: -0.20432213919653686,roll: 7.223571873993251e-7}
},
};
},
methods:{
setPosition:function (key){
zjnCesium.viewer.camera.flyTo({
destination : this.modelList[key],
orientation : this.modelList[key+'Orientation'],
duration: 2
});
},
getCv:function (){
let cp=zjnCesium.getCurrentViewPosition();
document.getElementById('cvInfo').innerText=JSON.stringify(cp);
// this.transferSimUtil.RemoveTrack()
// this.setViewType(1)
},
MousemoveCallback(data,layerId,c){
// debugger
if (layersInfo[layerId] && layersInfo[layerId].floatLabelInfo) {
this.popHoverScreenPoint.x = c.x + layersInfo[layerId].floatLabelInfo.offsetX
this.popHoverScreenPoint.y = c.y + layersInfo[layerId].floatLabelInfo.offsetY
this.popHoverInfo = data[layersInfo[layerId].floatLabelInfo.floatLabelField]
this.popHoverVisible = true
} else {
this.popHoverVisible = false
}
},
MouseclickCallback(data,layerId){
if (layersInfo[layerId].CustomPopupTemplate) {
this.popClickTitleInfo = data[layersInfo[layerId].CustomPopupTemplate.titleField]
this.popClickContentInfo = layersInfo[layerId].CustomPopupTemplate.content
let attrs = Object.keys(data)
for (let i = 0; i < attrs.length; i++) {
this.popClickContentInfo = this.popClickContentInfo.replaceAll('{' + attrs[i] + '}', data[attrs[i]])
}
this.popAspect.cWidth = layersInfo[layerId].CustomPopupTemplate.width
this.popAspect.cHeight = layersInfo[layerId].CustomPopupTemplate.height
this.popClickVisible = true
}
if(layerMsgClick[layerId] !== undefined){
for(var i = 0; i < layerMsgClick[layerId].length; i++){
var mcmd = layerMsgClick[layerId][i].method+'(';
for(var j = 0; j < layerMsgClick[layerId][i].params.length; j++){
mcmd += layerMsgClick[layerId][i].params[j];
if(j < layerMsgClick[layerId][i].params.length - 1){
mcmd += ',';
}
}
mcmd += ')';
eval(mcmd);
}
}
},
setLayerVisible(layerId, visible){
setLayerVisible(layersInfo,layerId,visible)
var testdata = [
[115.66560745239256,
34.41760191899927],
[115.67530632019043,
34.41795594404557],
[115.685133934021,
34.4180621512672],
[115.69406032562254,
34.4180621512672],
[115.69509029388428,
34.41700007298082],
[115.69547653198244,
34.416079594221465],
[115.69607734680174,
34.414769664672725],
[115.69620609283447,
34.41186650444182],
[115.69624900817871,
34.41048569775086],
[115.69612026214601,
34.40917568058836],
[115.69067001342772,
34.409211086727375],
[115.69071292877196,
34.402412833257614]
]
// this.transferSimUtil.SimulateTansfer(testdata)
},
zoomToC(location){
zjnCesium.viewer.camera.flyTo(location);
},
testClick(re,layerId){
debugger
},
setViewType(viewType){
//0二维,1三维
zjnCesium.setViewType(viewType)
},
// setLayerOpacity (layerId, opacity) {
// // getLayerByCode(this.smap, layerId).setOpacity(opacity)
// }
},
mounted() {
zjnCesium = new ZJNCesium("cesiumContainer1");
this.zjnCesium = zjnCesium
zjnCesium.initMap()
for (let key in layersInfo){
if(layersInfo[key].entityType == 'rectangle'){
CommonDrawEntitiesByLayerID(zjnCesium,layersInfo,key)
}else if((layersInfo[key].entityType == 'point' || layersInfo[key].entityType == 'billboard' || layersInfo[key].entityType == 'ellipse' || layersInfo[key].entityType == 'cylinder' || layersInfo[key].entityType == 'box' || layersInfo[key].entityType == 'ellipsoid') && layersInfo[key].url != undefined && layersInfo[key].url != ""){
CommonDrawPointEntitiesByUrl(zjnCesium,layersInfo,LayersRenderSet,LayersRenderLabelSet,key)
}
else if(layersInfo[key].entityType == 'heatmap'){
CommonDrawHeatmapByUrl(zjnCesium,layersInfo,key)
}
else if((layersInfo[key].entityType == 'wall') && layersInfo[key].url != undefined && layersInfo[key].url != ""){
CommonDrawWallEntitiesByUrl(zjnCesium,layersInfo,LayersRenderSet,LayersRenderLabelSet,key)
}
else if((layersInfo[key].entityType == 'line') && layersInfo[key].url != undefined && layersInfo[key].url != ""){
CommonDrawPolylineEntitiesByUrl(zjnCesium,layersInfo,LayersRenderSet,LayersRenderLabelSet,key)
}
else if((layersInfo[key].entityType == 'corridor') && layersInfo[key].url != undefined && layersInfo[key].url != ""){
CommonDrawCorridorEntitiesByUrl(zjnCesium,layersInfo,LayersRenderSet,LayersRenderLabelSet,key)
}
else if((layersInfo[key].entityType == 'polylineVolume') && layersInfo[key].url != undefined && layersInfo[key].url != ""){
CommonDrawPolylineVolumeEntitiesByUrl(zjnCesium,layersInfo,LayersRenderSet,LayersRenderLabelSet,key)
}
else if((layersInfo[key].entityType == 'polygon') && layersInfo[key].url != undefined && layersInfo[key].url != ""){
CommonDrawPolygonEntitiesByUrl(zjnCesium,layersInfo,LayersRenderSet,LayersRenderLabelSet,key)
}
else if((layersInfo[key].entityType == 'primitive') && layersInfo[key].url != undefined && layersInfo[key].url != ""){
CommonDrawPrimitiveEntitiesByUrl(zjnCesium,layersInfo,LayersRenderSet,LayersRenderLabelSet,key)
}
else if((layersInfo[key].entityType == 'windy') && layersInfo[key].url != undefined && layersInfo[key].url != ""){
CommonDrawWindyEntitiesByUrl(zjnCesium,layersInfo,key)
}
else if(layersInfo[key].entityType == 'glb'){
zjnCesium.CommonCreateGlbEntityModel(layersInfo[key])
}
else if(layersInfo[key].entityType == 'geojson'){
CommonDrawByGeojson(zjnCesium,layersInfo,LayersRenderSet,LayersRenderLabelSet,key)
}
else{
zjnCesium.commonAddProviderLayer(layersInfo,key)
}
}
// CommonCreateMeshTriangle(undefined,zjnCesium,layersInfo,'')
// CommonCreateMeshGrid(zjnCesium,layersInfo,'')
// CommonCreateMesh(undefined,zjnCesium,layersInfo,'')
// CommonDrawEntities(outputData,zjnCesium,layersInfo,LayersRenderSet,LayersRenderLabelSet,'outPutPoint','lng','lat','outPutId')
// // setLayerVisible(layersInfo,'outPutPoint',false)
// CommonDrawWallEntities(roadData,zjnCesium,layersInfo,LayersRenderSet,LayersRenderLabelSet,'roadWall','positions','minimumHeights','code')
// CommonDrawPolylineEntities(linedata,zjnCesium,layersInfo,LayersRenderSet,LayersRenderLabelSet,'rline','positions','code')
// CommonDrawPolygonEntities(polygondata,zjnCesium,layersInfo,LayersRenderSet,LayersRenderLabelSet,'rpolygon','positions','code')
// carDatas().then((res)=>{
// // CommonDrawWallEntities(res.data,zjnCesium,layersInfo,LayersRenderSet,LayersRenderLabelSet,'roadWall','positions','minimumHeights','code')
// })
// setLayerVisible(layersInfo,'roadwall',false)
// zjnCesium.createGltfEntityModel('/static/model/bingdundun.glb','gltf','xmf',115.650964712670241,34.44454369992611,{heading: 90, pitch: 0, roll: 0})
//绑定鼠标移动,点击等事件
zjnCesium.bindMousemoveDefault(this.MousemoveCallback);
zjnCesium.bindLonLatOnMouseMove("lon", "lat", "cdem");
//地图点击
zjnCesium.bindClickDefault(this.MouseclickCallback);
//设置初始视野
zjnCesium.Home();
this.transferSimUtil = new TransferSimUtil(zjnCesium)
}
};
</script>
<style>
#layersPanel{
position: absolute;
top: 50px;
right: 300px;
z-index: 999;
}
#gisToolPopoup{
position: absolute;
top: 50px;
left: 20px;
z-index: 999;
}
</style>
如果对恁有帮助,请点赞打赏支持,多谢!