最近有这样一个需求,在Cesium的遥感底图中,水系不是很明显,需要再Cesium中,用蓝色的多边形将水系覆盖住,让水系变得明显一点。就是类似下图中的效果,在网上找了半天,都说的不是很清楚。找了一个以前做过的同学请教了一下,在这里记录一下,希望能帮助到有需要的童鞋。
其实这个实现的原理很简单,就是在Cesium中,绘制多边形。核心代码如下:
var viewer=new Cesium.Viewer('cesiumContainer');
//河道关键点数组
var River1Point =[
115.5985634205044,32.43079913513041,
115.5985704898825,32.43076382867626,
115.5986098946194,32.43075670644404,
115.5986511920998,32.43073818875409,
115.5986996374219,32.43071993834909,
115.5987716706982,32.43070870799402,
115.5988434106588,32.43068161650099,
115.5989474182998,32.43063064362859,
115.5990091340221,32.43061110564393
];
//河道1多边形
var polygon1 = new Cesium.PolygonGeometry({
polygonHierarchy : new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArray(River1Point)),
extrudedHeight:0,
height:0,
vertexFormat : Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT
});
var River1=new Cesium.Primitive({
geometryInstances : new Cesium.GeometryInstance({
geometry :polygon1
}),
appearance : new Cesium.EllipsoidSurfaceAppearance({
aboveGround : true
}),
show : true
});
var River1_Material =new Cesium.Material({
fabric : {
type : 'Water',
uniforms : {
normalMap:'image/waterNormals.jpg',
frequency: 100.0,
animationSpeed: 0.01,
amplitude: 10.0
}
}
});
var scene = viewer.scene;
River1.appearance.material = River1_Material;
scene.primitives.add(River1); //添加到场景
//设置照相机位置与朝向、设置home的默认值
var initialPosition = new Cesium.Cartesian3.fromDegrees(115.5985634205044,32.43079913513041,1000);
var initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees(0,-30,0);//(朝向,俯 仰,绕视线轴旋转)
var homeCameraView = {
destination : initialPosition,
orientation : {
heading : initialOrientation.heading,
pitch : initialOrientation.pitch,
roll : initialOrientation.roll
}
};
// Set the initial view
viewer.scene.camera.setView(homeCameraView);
viewer.homeButton.viewModel.command.beforeExecute.addEventListener(function (e) {
e.cancel = true;
viewer.scene.camera.flyTo(homeCameraView);
});
上面的代码主要做了两件事,第一件就是通过scene.primitives.add(River1)这句代码将绘制的河流水系的多边形添加到Cesium中进行显示,第二件事是,将一打开网页初始的位置,设置到河流多边形的第一个点,这样一打开网页就能看到我们所绘制的河流,而不是整个地球。需要注意以下几件事:
1、River1Point中的点就是你所需要绘制的河流多边形的一系列坐标点,这些坐标点的坐标系应该是WGS84坐标系。如果有shapefile,可以通过shapefile属性导出,如果没有,可以在Google earth桌面版上去绘制河流的边界多边形,将绘制的多边形导出成KML格式,再用记事本打开,就能找到坐标点了。具体方法可以百度。
2、var polygon1 = new Cesium.PolygonGeometry这句代码中,有两个属性需要注意,extrudedHeight这个属性表示的是水体的厚度,你设置为1,那那个水体就是1米什的水。height这个属性,设置的是水体的高度。我这里设置为1,表示水面试紧贴遥感图像的,设置的高了,水体就可以悬浮在空中。这个可以根据需要自己设置。
3、River1_Material这个变量设置了多边形的材质,Cesium有很多自带的材质,这里用了水的材质,其中 normalMap:这个值设置材质的图片的路径,就是下图这个图片,可以在我这里保存,也可以在Cesium的安装包下搜索waterNormal。图片路径是相对路径,自己注意就好。
好了,就是这么简单。希望能帮助到你。