• [转]cesium很全的入门教程翻译官网和加入自己理解


    快速入门教程基本涵盖了大多数的CesiumJS API概念,主要用于Cesium基本入门,对Cesium有全面基本的了解和使用

    一、概述
    本教程会一步一步教会你做一个项目,主要介绍如下内容:

    配置1个Cesium viewer
    加载各种数据集
    创建几何和设置样式
    加载3D Tiles
    控制相机
    添加鼠标交互
    学完后你将会创建如下项目。

    二、前期准备
    下载 workshop code
    在vscode中打开cesium-workshop 目录.
    Run npm install.安装需要的依赖
    Run npm start.服务会使用node.js启动,主要根据服务中的server.js配置文件启动,也可以直接使用其他服务器启动,不需要 server.js
    2.1 workshop code目录结构
    Source/ : js业务逻辑和一些数据.
    ThirdParty/ : 可以引用其他类库,如 CesiumJS library.
    LICENSE.md : Terms of use for this application.
    index.html : 主页.
    server.js : 服务会使用node.js启动,主要根据服务中的server.js配置文件启动.
    因此,我们主要使用index.html和app.js两个文件进行本项目的编写工作,如果你下载了workshop code工程,可以看到里面的代码是写好的,我们主要需要学会每行代码的意义和使用方法。
    该项目完整的演示效果:演示地址
    2.2 从index.html开始
    引入cesium类库,在源码中运行npm run build会将所有的源码创建快捷索引到一个ceiusm.js文件中,该文件只是对所有源码创建了快捷入口方式,不同于npm run release,可以使用该文件进行源码调试 创建一个App.js逻辑文件或者index.js,来初始化三维地球,里面就是写var viewer = new Cesium.Viewer('cesiumContainer');初始化等功能
    导入cesium样式文件,@import url(ThirdParty/Cesium/Widgets/widgets.css);
    让我们正式开始吧!

    三、创建一个地球视窗

    var viewer = new Cesium.Viewer('cesiumContainer',option);

    Viewer是一个综合,包含中心的地球globe,周围的控件widget,如果只需要一个地球的话,使用可以cesiumwidget()来初始化,viewer的内部源码就是使用了cesiumwidget()创建地球,并创建一些div来生成widget控件

    1、Geocoder : 地名地址搜索,地点搜索默认使用bing地图. Uses Bing Maps data by default.
    2、HomeButton : 主页视图,可覆盖该方法,自定义主页视图.
    3、SceneModePicker : 不解释。Switches between 3D, 2D and Columbus View (CV) modes.
    4、BaseLayerPicker : 不解释。Chooses the imagery and terrain to display on the globe.
    5、NavigationHelpButton :帮助信息,没啥用。 Displays the default camera controls.
    6、Animation : 一般去掉。Controls the play speed for view animation.
    7、CreditsDisplay : 使用代码可以去掉版权信息:viewer._cesiumWidget._creditContainer.style.display=“none”;
    8、Timeline : 不显示一般。Indicates current time and allows users to jump to a specific time using the scrubber.
    9、FullscreenButton : Makes the Viewer fullscreen.

    var viewer = new Cesium.Viewer('cesiumContainer', {
        scene3DOnly: true,
        selectionIndicator: false,
        baseLayerPicker: false
    });

    四、Cesium ion
    Cesium的数据服务器,功能很强大,但是国内一般不用

    4.1 添加影像地图Adding Imagery
    支持的 Imagery Formats:
    WMS
    TMS
    WMTS (with time dynamic imagery)
    ArcGIS
    Bing Maps
    Google Earth
    Mapbox
    Open Street Map
    Cesium提供了不同的接口加载上述几种类型的服务,但都是使用ImageryProvider来加载,可通过该链接查看所有接口类型many different providers
    示例如下:

    // 去掉默认底图bing   Remove default base layer
    viewer.imageryLayers.remove(viewer.imageryLayers.get(0));
    
    // Add Sentinel-2 imagery
    viewer.imageryLayers.addImageryProvider(new Cesium.IonImageryProvider({ assetId : 3954 }));

    通过以上示例可以知道,默认的Cesium会加载一个底图,是bingMap底图,网络不太好,一般要先去掉这个默认的,加载我们自己的。

    五、添加地形服务Adding Terrain

    示例代码如下:

    // Load Cesium World Terrain
    viewer.terrainProvider = Cesium.createWorldTerrain({
        requestWaterMask : true, // required for water effects
        requestVertexNormals : true // required for terrain lighting
    });
    // Enable depth testing so things behind the terrain disappear.
    viewer.scene.globe.depthTestAgainstTerrain = true;

    equestVertexNormals是地形光照效果,需要打开场景光源支持,depthTestAgainstTerrain是地形遮挡效果开关,打开后地形会遮挡看不到的区域

    六、配置Scene
    重点标注:影像和地形都是加载scene中的globe对象上的,但是其他的entiy和3dtiles等,是加载在scene上的,和globe是同级别的,关闭globe,entiy等也会显示

    6.1 场景中的坐标概念简介:
    Cartesian3 : 世界坐标系,坐标原点在globe球心的一个坐标系,坐标值是以米为单位,所以Cartesian3的坐标值大多是地球的半径那么大的数值。a 3D Cartesian coordinate – when used as a position it is relative to the center of the globe in meters using the Earth fixed-frame (ECEF)

    Cartographic : WGS84-就是经纬度坐标系,地球的经纬度值,单位是度,如118°。a position defined by longitude, latitude (in radians) and height from the WGS84 ellipsoid surface

    局部坐标系:啥叫局部坐标系呢?很简单,就是你自己在地球上找个经纬度点,把他当原点,形成一个坐标系。
    看代码:

    // Get the transform from local east-north-up at cartographic (0.0, 0.0) to Earth's fixed frame.
    var center = Cesium.Cartesian3.fromDegrees(118.0, 30.0);
    var transform = Cesium.Transforms.eastNorthUpToFixedFrame(center);

    我们把坐标原点移动到了118.0, 30.0这个地方,x轴指向东,y轴指向北,还有northEastDownToFixedFrame等不同的方向坐标轴

    • HeadingPitchRoll : HPR地球视角上下左右偏移调整,参考博客相机中的HeadingPitchRoll

    • Quaternion : 行话为四元数,其实就是使一个物体围绕指定的轴旋转多少角度。和旋转方法,旋转矩阵是同步改变的。(A 3D rotation represented as 4D coordinates.)

    6.2 相机控制(Camera Control)

    viewer.scene.Camera ,就是单纯的实现视角的各种移动缩放等

    Camera.setView(options) : 直接定位到一个视角,没动画set camera at specific position and orientation immediately
    Camera.zoomIn(amount) : 缩放多少米move camera forward along the view vector
    Camera.zoomOut(amount) : 缩放多少米move camera backwards along the view vector
    Camera.flyTo(options) : 最常用,有动画过程create an animated camera flight from the current camera position to a new position
    Camera.lookAt(target, offset) : 定位到一个点,并以这个点为中心锁定orient and position the camera to look at target point with given offset
    Camera.move(direction, amount) : 平移一定距离move the camera in any direction
    Camera.rotate(axis, angle) : 旋转rotate the camera about any axis
    示例:

    // Create an initial camera view
    var initialPosition = new Cesium.Cartesian3.fromDegrees(-73.998114468289017509, 40.674512895646692812, 2631.082799425431);
    var initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees(7.1077496389876024807, -31.987223091598949054, 0.025883251314954971306);
    var homeCameraView = {
        destination : initialPosition,
        orientation : {
            heading : initialOrientation.heading,
            pitch : initialOrientation.pitch,
            roll : initialOrientation.roll
        }
    };
    // Set the initial view
    viewer.scene.camera.setView(homeCameraView);

    可以修改cesium默认的主页按钮定位位置

    // Add some camera flight animation options
    homeCameraView.duration = 2.0;//飞行用时
    homeCameraView.maximumHeight = 2000;//飞行过程中最大高度
    homeCameraView.pitchAdjustHeight = 2000;
    homeCameraView.endTransform = Cesium.Matrix4.IDENTITY;
    // Override the default home button覆盖home默认事件
    viewer.homeButton.viewModel.command.beforeExecute.addEventListener(function (e) {
        e.cancel = true;
        viewer.scene.camera.flyTo(homeCameraView);
    });

    坐标系转换:参考

    6.3 Clock Control

    这个在沿着路线飞行漫游的时候能用到,暂时不会,后期补充,举个使用列子吧在这。

    // Set up clock and timeline.
    viewer.clock.shouldAnimate = true; // make the animation play when the viewer starts
    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; // sets a speedup
    viewer.clock.clockStep = Cesium.ClockStep.SYSTEM_CLOCK_MULTIPLIER; // tick computation mode
    viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP; // loop at the end
    viewer.timeline.zoomTo(viewer.clock.startTime, viewer.clock.stopTime); // set visible range

    七、加载Entities
    Entities相较于Primitive接口更加简单直观,是对Primitive封装
    常见的Entities:

    Polygon
    Polyline
    Billboard
    Label
    可以使用viewer.entities.add()方法直接添加entity到一个默认的dataSource里面,DataSource是添加各种entity的集合,默认有一个defaultDataSource,viewer.entities.add()如果不知道加载到哪个DataSource里面,就会被默认加载到defaultDataSource里。
    DataSource有一下几类:
    CustomDataSource-就是最常见的添加Entity类型的

    var dataSource = new Cesium.CustomDataSource('myData');
    
    var entity = dataSource.entities.add({
       position : Cesium.Cartesian3.fromDegrees(1, 2, 0),
       billboard : {
           image : 'image.png'
       }
    });
    
    viewer.dataSources.add(dataSource);
    • CzmlDataSource-加载czml文件格式的数据
    • GeoJsonDataSource-加载geojson格式的数据
    var viewer = new Cesium.Viewer('cesiumContainer');
    viewer.dataSources.add(Cesium.GeoJsonDataSource.load('../../SampleData/ne_10m_us_states.topojson', {
      stroke: Cesium.Color.HOTPINK,
      fill: Cesium.Color.PINK,
      strokeWidth: 3,
      markerSymbol: '?'
    }));
    • KmlDataSource-加载kml格式的数据
    var kmlOptions = {
        camera : viewer.scene.camera,
        canvas : viewer.scene.canvas,
        clampToGround : true
    };
    // Load geocache points of interest from a KML file
    // Data from : http://catalog.opendata.city/dataset/pediacities-nyc-neighborhoods/resource/91778048-3c58-449c-a3f9-365ed203e914
    var geocachePromise = Cesium.KmlDataSource.load('./Source/SampleData/sampleGeocacheLocations.kml', kmlOptions);
    
    // Add geocache billboard entities to scene and style them
    geocachePromise.then(function(dataSource) {
        // Add the new data as entities to the viewer
        viewer.dataSources.add(dataSource);
    
            // Get the array of entities
        var geocacheEntities = dataSource.entities.values;
    
        for (var i = 0; i < geocacheEntities.length; i++) {
            var entity = geocacheEntities[i];
            // Add geocache billboard entities to scene and style them
    
            if (Cesium.defined(entity.billboard)) {
                // 贴地形Adjust the vertical origin so pins sit on terrain
                entity.billboard.verticalOrigin = Cesium.VerticalOrigin.BOTTOM;
                // 去掉自带的标注,不显示那么乱--Disable the labels to reduce clutter
                entity.label = undefined;
                // 按照缩放距离显示Add distance display condition
                entity.billboard.distanceDisplayCondition = new Cesium.DistanceDisplayCondition(10.0, 20000.0);
    
                   // Compute longitude and latitude in degrees
                var cartographicPosition = Cesium.Cartographic.fromCartesian(entity.position.getValue(Cesium.JulianDate.now()));
                var longitude = Cesium.Math.toDegrees(cartographicPosition.longitude);
                var latitude = Cesium.Math.toDegrees(cartographicPosition.latitude);
                // Modify description
                // Modify description
                var description = '<table class="cesium-infoBox-defaultTable cesium-infoBox-defaultTable-lighter"><tbody>' +
                    '<tr><th>' + "Longitude" + '</th><td>' + longitude.toFixed(5) + '</td></tr>' +
                    '<tr><th>' + "Latitude" + '</th><td>' + latitude.toFixed(5) + '</td></tr>' +
                    '</tbody></table>';
                entity.description = description;
                // entity styling code here
    
                // Set the polygon material to a random, translucent color.
                entity.polygon.material = Cesium.Color.fromRandom({
                    red : 0.1,
                    maximumGreen : 0.5,
                    minimumBlue : 0.5,
                    alpha : 0.6
                });
    
                // 面贴地或者贴3dties---Tells the polygon to color the terrain. ClassificationType.CESIUM_3D_TILE will color the 3D tileset, and ClassificationType.BOTH will color both the 3d tiles and terrain (BOTH is the default)
                entity.polygon.classificationType = Cesium.ClassificationType.TERRAIN;
    
                // entity styling code here
    
                // Generate Polygon position
                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;
                // Generate labels
                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
                };
    // Add computed orientation based on sampled positions根据位置自动调整朝向
                entity.orientation = new Cesium.VelocityOrientationProperty(entity.position);
                // Smooth path interpolation路径插值,就是在两点直接移动过程中,使物体的移动平滑
    drone.position.setInterpolationOptions({
        interpolationDegree : 3,
        interpolationAlgorithm : Cesium.HermitePolynomialApproximation
    });
                
            }
        }
    });

    代码说明

    1. clampToGround意思是添加的entity到dem上,而不是wgs84的球面
    2. load加载数据都是异步加载的,所以会返回一个Promise—Promise是ES6解决ajax循环请求问题的。
    3. entity.description是修改这个默认弹框信息:

    entity.polygon.classificationType = Cesium.ClassificationType.TERRAIN;可以把面贴地,或者贴3dtiles表面
    Cesium.BoundingSphere.fromPoints(polyPositions).center;计算几何中心
    Property Types Demo动态效果实现用到了cesium中的property属性功能
    根据position自动计算entity的方向。VelocityOrientationProperty
    setInterpolationOptions就是使用插值算法,使模型在两点直接移动过程中,在两点之间进行插值,使移动更平滑
    property介绍–参考vtxf博客
    比如一个entity中很多值都是属性property类型new Cesium.Entity({position:PositionProperty,orientation:property}),这个属性值是Cesium提供的一种机制,让某个property比如positioon可以随时间自动发生变化,自动赋予不同的数值(位置)。这也就是property的作用了。

    // 创建盒子
    var blueBox = viewer.entities.add({
        name : 'Blue box',
        position: Cesium.Cartesian3.fromDegrees(-114.0, 40.0, 300000.0),
        box : {
            dimensions : new Cesium.Cartesian3(400000.0, 300000.0, 500000.0),
            material : Cesium.Color.BLUE,
            outline: true,
        }
    });
    
        var property = new Cesium.SampledProperty(Cesium.Cartesian3);
    
        property.addSample(Cesium.JulianDate.fromIso8601('2019-01-01T00:00:00.00Z'), 
            new Cesium.Cartesian3(400000.0, 300000.0, 200000.0));
        
        property.addSample(Cesium.JulianDate.fromIso8601('2019-01-03T00:00:00.00Z'), 
            new Cesium.Cartesian3(400000.0, 300000.0, 700000.0));
    
        blueBox.box.dimensions = property;

    以上代码的意思就是在两个不同的时间点分别赋予不同的位置,用SampledProperty包装成一个property,最后赋给blueBox.box.dimensions。

    由此可见,Property最大的特点是和时间相互关联,在不同的时间可以动态地返回不同的属性值。而Entity则可以感知这些Property的变化,在不同的时间驱动物体进行动态展示。

    Cesium宣称自己是数据驱动和time-dynamic visualization,这些可都是仰仗Property系统来实现的。

    通俗讲就是比如position属性不只是能赋值一个固定的坐标,还能赋值一个有时间和位置组成的数组对象。
    属性的作用是可以实现漫游飞行功能:
    漫游飞行实现Interpolation

    八、3D Tiles
    简介
    开源介绍
    格式介绍
    The 3D Tiles Inspector
    各类示例

    加载3dtiles

    // Load the NYC buildings tileset
    var city = viewer.scene.primitives.add(new Cesium.Cesium3DTileset({ url: Cesium.IonResource.fromAssetId(75343) }))

    添加样式

    cesium专门提供了3D Tiles styling language

    var defaultStyle = new Cesium.Cesium3DTileStyle({
        color : "color('white')",
        show : true
    });
    //按照条件
    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)"]
            ]
        }
    });

    九、鼠标点击交互事件Interactivity

    鼠标事件主要有左键,右键,滚轮键盘,鼠标移动事件,使用ScreenSpaceEventHandler来获取相应的事件

    //鼠标移动事件捕捉
    var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
    handler.setInputAction(function(movement) {}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

    鼠标事件主要用于捕捉选择场景中添加的各种数据,选择到数据后,便可以对数据进行各种展示处理操作,选择场景中的数据的方式主要使用pick()函数,目前有一下几类:

    Scene.pick : 选择一个图元。returns an object containing the primitive at the given window position.
    Scene.drillPick : returns a list of objects containing all the primitives at the given window position.
    Globe.pick : returns the intersection point of a given ray with the terrain.
    高亮示例,移动高亮,移除恢复:

    // If the mouse is over a point of interest, change the entity billboard scale and color
    var previousPickedEntity = undefined;
    handler.setInputAction(function(movement) {
        var pickedPrimitive = viewer.scene.pick(movement.endPosition);
    
        //获取鼠标的经纬度位置
        var cartesian = viewer.camera.pickEllipsoid(movement.endPosition, scene.globe.ellipsoid);
        if (cartesian) {
            var cartographic = Cesium.Cartographic.fromCartesian(cartesian);
            var longitudeString = Cesium.Math.toDegrees(cartographic.longitude).toFixed(2);
            var latitudeString = Cesium.Math.toDegrees(cartographic.latitude).toFixed(2);
    
            entity.position = cartesian;
            
        }
    
        var pickedEntity = (Cesium.defined(pickedPrimitive)) ? pickedPrimitive.id : undefined;
        // Unhighlight the previously picked entity
        if (Cesium.defined(previousPickedEntity)) {
            previousPickedEntity.billboard.scale = 1.0;
            previousPickedEntity.billboard.color = Cesium.Color.WHITE;
        }
        // Highlight the currently picked entity
        if (Cesium.defined(pickedEntity) && Cesium.defined(pickedEntity.billboard)) {
            pickedEntity.billboard.scale = 2.0;
            pickedEntity.billboard.color = Cesium.Color.ORANGERED;
            previousPickedEntity = pickedEntity;
        }
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

    可以使用camera.pickEllipsoid来获取鼠标移动过程中的位置信息:

     //获取鼠标的经纬度位置
        var cartesian = viewer.camera.pickEllipsoid(movement.endPosition, scene.globe.ellipsoid);
        if (cartesian) {
            var cartographic = Cesium.Cartographic.fromCartesian(cartesian);
            var longitudeString = Cesium.Math.toDegrees(cartographic.longitude).toFixed(2);
            var latitudeString = Cesium.Math.toDegrees(cartographic.latitude).toFixed(2);
    
            entity.position = cartesian;
            
        }

    高亮选择的3dtiles边缘示例

    3D Tiles Feature Picking Demo

    十、Camera Modes

    viewer.trackedEntity可以让视角一直跟着某个entity走,漫游模式。

    // Create a follow camera by tracking the drone entity
    function setViewMode() {
        if (droneModeElement.checked) {
            viewer.trackedEntity = drone;
        } else {
            viewer.trackedEntity = undefined;
            viewer.scene.camera.flyTo(homeCameraView);
        }
    }

    十一、参考资料

    西部世界Cesium资料大全
    Cesium学习系列汇总

    原文链接:cesium很全的入门教程-翻译官网和加入自己理解

  • 相关阅读:
    Linq 中的Select事例
    C#关于事件的几个好例子
    C#运用实例.读取csv里面的词条,对每一个词条抓取百度百科相关资料,然后存取到数据库
    cookie 和 session 基本使用 以及 封装
    javascript 兼容各个浏览器的事件
    jquery选择器从认识到使用初级篇
    作业八—Alpha阶段项目总结
    第十四次
    第十三次
    十二次
  • 原文地址:https://www.cnblogs.com/rainbow70626/p/16019280.html
Copyright © 2020-2023  润新知