cesium------常用笔记

// 打开深度检测,那么在地形以下的对象不可见
viewer.scene.globe.depthTestAgainstTerrain = true;


//createWorldTerrain辅助函数去创建 Cesium全球地形 . 
viewer.terrainProvider = Cesium.createWorldTerrain({
    requestWaterMask : true,    //告知Cesium去请求额外的水面数据
    requestVertexNormals : true    //告知Cesium去请求额外的光照数据
  });


 viewer.scene   // 这个类控制了我们的viewer中所有的图形元素

 // 开启全球光照
viewer.scene.globe.enableLighting = true;

在初始化视图之前,先学下基本的cesium 类型:

Cartesian3 : 三维笛卡尔(直角)坐标 – 当用来表示位置的时候,这个坐标指在地固坐标系(Earth fixed-frame (ECEF))下,相对地球中心的坐标位置,单位是米。
Cartographic :使用经纬度(弧度)和高度(WGS84地球高程)描述的三维坐标 。
HeadingPitchRoll :在ENU(East-North-Up)坐标系中,相对坐标轴的旋转(弧度)。Heading 相对负z轴(垂直向下). Pitch 相对负y轴. Roll相对正x轴.
Quaternion :使用四维坐标描述的三维旋转。
这是在Cesium的scene中摆放对象的基本类型,Cesium提供了一系列的方便的转换函数。具体请查看cesium文档。


Camera 是 viewer.scene的一个属性,用来控制当前可见范围。
一些最常用的方法:

Camera.setView(options) : 立即设置相机位置和朝向。
Camera.zoomIn(amount) : 沿着相机方向移动相机。
Camera.zoomOut(amount) : 沿着相机方向远离
Camera.flyTo(options) : 创建从一个位置到另一个位置的相机飞行动画。
Camera.lookAt(target, offset) : 依据目标偏移来设置相机位置和朝向。
Camera.move(direction, amount) : 沿着direction方向移动相机。
Camera.rotate(axis, angle) : 绕着任意轴旋转相机。
 Cartesian3表示位置,
 HeadingPitchRoll表示朝向。
 Cesium使用 JulianDate 描述某个时刻。

下面是一些关于scene中时间的配置选项:
// 设置时钟和时间线
viewer.clock.shouldAnimate = true; // 当viewer开启后,启动动画
viewer.clock.startTime = Cesium.JulianDate.fromIso8601("2017-07-11T16:00:00Z");
viewer.clock.stopTime = Cesium.JulianDate.fromIso8601("2017-07-11T16:20:00Z");
viewer.clock.currentTime = Cesium.JulianDate.fromIso8601("2017-07-11T16:00:00Z");
viewer.clock.multiplier = 2; // 设置加速倍率
viewer.clock.clockStep = Cesium.ClockStep.SYSTEM_CLOCK_MULTIPLIER; // tick computation mode(还没理解具体含义)
viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP; // 循环播放
viewer.timeline.zoomTo(viewer.clock.startTime, viewer.clock.stopTime); // 设置时间的可见范围


Cesium支持流行的矢量格式GeoJson和KML,同时也支持自定义格式 CZML。无论最初是什么格式,所有的空间矢量数据在Cesium里都是使用Entity 相关API去展示的, Entity是一种对几何图形做空间和时间展示的数据对象。sandcastle 里提供了很多简单的entity。

//使用 KmlDataSource.load(optinos) 来从KML文件中读取点位数据。
var kmlOptions = {
    camera : viewer.scene.camera,
    canvas : viewer.scene.canvas,
    clampToGround : true     //控制数据是否贴地
};
// 从这个KML的url里加载POI点位  : http://catalog.opendata.city/dataset/pediacities-nyc-neighborhoods/resource/91778048-3c58-449c-a3f9-365ed203e914
var geocachePromise = Cesium.KmlDataSource.load('./Source/SampleData/sampleGeocacheLocations.kml', kmlOptions);


geocachePromise.then(function(dataSource) {
  // 把所有entities添加到viewer中显示
    viewer.dataSources.add(dataSource);

    // 获得entity列表
    var geocacheEntities = dataSource.entities.values;
    for (var i = 0; i < geocacheEntities.length; i++) {
        var entity = geocacheEntities[i];
        if (Cesium.defined(entity.billboard)) {
            // 对这个entity设置样式
        }
    }
});
if (Cesium.defined(entity.billboard)) {
            // 调整垂直方向的原点,保证图标里的针尖对着地表位置 
            entity.billboard.verticalOrigin = Cesium.VerticalOrigin.BOTTOM;
            // 去掉文字的显示
            entity.label = undefined;
            // 设置可见距离
            entity.billboard.distanceDisplayCondition = new Cesium.DistanceDisplayCondition(10.0, 20000.0);    //控制只显示和相机一定距离内的点.
        }

// 设置样式代码,entity.properties来存储GeoJson的属性。
// 把properties里的neighborhood设置到name
entity.name = entity.properties.neighborhood


// 为了避免所有多边形颜色都相同,可以使用一个随机颜色 Color去设置每个多边形的 ColorMaterialProperty属性。
// 设置一个随机半透明颜色
entity.polygon.material = Cesium.Color.fromRandom({
    red : 0.1,
    maximumGreen : 0.5,
    minimumBlue : 0.5,
    alpha : 0.6
});
// 设置这个属性让多边形贴地,ClassificationType.CESIUM_3D_TILE 是贴模型,ClassificationType.BOTH是贴模型和贴地
entity.polygon.classificationType = Cesium.ClassificationType.TERRAIN;

// 获取多边形的positions列表 并计算它的中心点
var polyPositions = entity.polygon.hierarchy.getValue(Cesium.JulianDate.now()).positions;
var polyCenter = Cesium.BoundingSphere.fromPoints(polyPositions).center;
polyCenter = Cesium.Ellipsoid.WGS84.scaleToGeodeticSurface(polyCenter);
entity.position = polyCenter;
// 生成文字标注
entity.label = {
    text : entity.name,
    showBackground : true,
    scale : 0.6,
    horizontalOrigin : Cesium.HorizontalOrigin.CENTER,
    verticalOrigin : Cesium.VerticalOrigin.BOTTOM,
    distanceDisplayCondition : new Cesium.DistanceDisplayCondition(10.0, 8000.0),
    disableDepthTestDistance : 100.0   //  确保这个标注不会被其他对象盖住
};


// 基于无人机轨迹的位置点,自动计算朝向
drone.orientation = new Cesium.VelocityOrientationProperty(drone.position);

//为了飞行路径更平滑,可以如下修改配置 :
// 光滑的路径插值
drone.position.setInterpolationOptions({
    interpolationDegree : 3,
    interpolationAlgorithm : Cesium.HermitePolynomialApproximation
});


//  3D Tiles,它是一个流式载入海量各种类型得空间三维数据的开放协议,使用一种类似Cesium的地形和影像数据切片技术,3d tiles格式使原先那些不可能做可视化交互的大模型数据能够展示出来,包括建筑物数据、CAD(或者BIM)模型,点云,倾斜模型。


//使用 Cesium3DTileset 类添加整个纽约的真实建筑物模型,改进了可视化效果的真实性。
// 加载纽约建筑物模型
var city = viewer.scene.primitives.add(new Cesium.Cesium3DTileset({ url: Cesium.IonResource.fromAssetId(3839) }))


// 调整3dtile模型的高度,让他刚好放在地表
//把数据当前的包围球转为Cartographic,就能计算出模型现在相对于地面的偏移,然后增加这个偏移值,然后重设modelMatrix:
var heightOffset = -32;
city.readyPromise.then(function(tileset) {
    // Position tileset
    var boundingSphere = tileset.boundingSphere;
    var cartographic = Cesium.Cartographic.fromCartesian(boundingSphere.center);   
    var surface = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, 0.0);
    var offset = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, heightOffset);
    var translation = Cesium.Cartesian3.subtract(offset, surface, new Cesium.Cartesian3());
    tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation)//通过 modelMatrix,我们可以调整这个数据的位置。
});


// 根据Cesium3DTileFeature模型属性去修改某一部分甚至某一栋建筑物的颜色(RGB和透明度)
var defaultStyle = new Cesium.Cesium3DTileStyle({
    color : "color('white', 0.3)",  //0.3为设置建筑物半透明状
    show : true
});
city.style = defaultStyle;   //这个样式只是简单的让纽约的所有建筑都可见。把它设置到 city.style就可以看到可视化效果。

下面是一个依据建筑高度去着色的示例:
var heightStyle = new Cesium.Cesium3DTileStyle({
    color : {
        conditions : [
            ["${height} >= 300", "rgba(45, 0, 75, 0.5)"],
            ["${height} >= 200", "rgb(102, 71, 151)"],
            ["${height} >= 100", "rgb(170, 162, 204)"],
            ["${height} >= 50", "rgb(224, 226, 238)"],
            ["${height} >= 25", "rgb(252, 230, 200)"],
            ["${height} >= 10", "rgb(248, 176, 87)"],
            ["${height} >= 5", "rgb(198, 106, 11)"],
            ["true", "rgb(127, 59, 8)"]
        ]
    }
});


// 为了在这些样式之间切换,增加代码去监听HTML的输入框变化:
var tileStyle = document.getElementById('tileStyle');
function set3DTileStyle() {
    var selectedStyle = tileStyle.options[tileStyle.selectedIndex].value;
    if (selectedStyle === 'none') {
        city.style = defaultStyle;
    } else if (selectedStyle === 'height') {
        city.style = heightStyle;
    } else if (selectedStyle === 'transparent') {
        city.style = transparentStyle;
    }
}
tileStyle.addEventListener('change', set3DTileStyle);


// 拾取技术(picking),它能够根据一个屏幕上的像素位置返回三维场景中的对象信息。
有好几种拾取:
Scene.pick : 返回窗口坐标对应的图元的第一个对象。
Scene.drillPick :返回窗口坐标对应的所有对象列表。
Globe.pick : 返回一条射线和地形的相交位置点。


因为我们想实现鼠标滑过的高亮效果,首先需要创建一个鼠标事件处理器。 ScreenSpaceEventHandler是可以处理一系列的用户输入事件的处理器. ScreenSpaceEventHandler.setInputAction()``](/Cesium/Build/Documentation/ScreenSpaceEventHandler.html#setInputAction) 监听某类型的用户输入事件 -- [ScreenSpaceEventType`用户输入事件类型,做为一个参数传递过去。这里我们设置一个回调函数来接受鼠标移动事件:
var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
handler.setInputAction(function(movement) {}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

// 我们使用一个变量来存储上次的高亮图标,当鼠标不在它上面的时候,恢复它原来的样式。

 这是包含高亮和不高亮完整功能的代码:
var previousPickedEntity = undefined;
handler.setInputAction(function(movement) {
    var pickedPrimitive = viewer.scene.pick(movement.endPosition);
    var pickedEntity = (Cesium.defined(pickedPrimitive)) ? pickedPrimitive.id : undefined;
    // 取消上一个高亮对象的高亮效果
    if (Cesium.defined(previousPickedEntity)) {
        previousPickedEntity.billboard.scale = 1.0;
        previousPickedEntity.billboard.color = Cesium.Color.WHITE;
    }
    // 当前entity高亮
    if (Cesium.defined(pickedEntity) && Cesium.defined(pickedEntity.billboard)) {
        pickedEntity.billboard.scale = 2.0;
        pickedEntity.billboard.color = Cesium.Color.ORANGERED;
        previousPickedEntity = pickedEntity;
    }


 //这是相机模式代码:

function setViewMode() {
    if (droneModeElement.checked) {
        viewer.trackedEntity = drone;    // 相机也能和目标之间保持一个固定的偏移距离
    } else {
        viewer.trackedEntity = undefined;    // 切换到自由模式
        viewer.scene.camera.flyTo(homeCameraView);   //返回到初始位置。
    }
}


// 只需要把这个函数绑定到HTML元素的change事件上。当我们双击entity的时候,就会自动进行跟随模式。
var freeModeElement = document.getElementById('freeMode');
var droneModeElement = document.getElementById('droneMode'); 
function setViewMode() {
    if (droneModeElement.checked) {
        viewer.trackedEntity = drone;
    } else {
        viewer.trackedEntity = undefined;
        viewer.scene.camera.flyTo(homeCameraView);
    }
}
freeModeElement.addEventListener('change', setCameraMode); 
droneModeElement.addEventListener('change', setCameraMode);

//如果用户通过点击跟踪无人机,添加一些处理去自动更新UI界面:
viewer.trackedEntityChanged.addEventListener(function() {
    if (viewer.trackedEntity === drone) {
        freeModeElement.checked = false;
        droneModeElement.checked = true;
    }
});


// 通过设置EntityCollection的 show 属性来控制。只需要设置一次neighborhoods.show属性即可控制所有entity的可见性。

var neighborhoodsElement =  document.getElementById('neighborhoods');

neighborhoodsElement.addEventListener('change', function (e) {
    neighborhoods.show = e.target.checked;
});


// 因为3D Tiles数据可能不是瞬间载入,可以添加一个载入指示器,当所有切片都载入后隐藏。
// 当城市数据初始化完成后,移除加载指示器
var loadingIndicator = document.getElementById('loadingIndicator');
loadingIndicator.style.display = 'block';
city.readyPromise.then(function () {
    loadingIndicator.style.display = 'none';
});

你可能感兴趣的:(gis方向,cesium)