webgis(cesium)初学者必经之路

lxf2023-05-05 06:24:01
  • 作为一个菜鸟,说实话打出这个标题都有点慌的赶脚,但是确实对于我来说,从事gis开发,从来都是理解大于开发的,必不可少的就是对gis的了解
  • 我最常用的就是像openlayers、leaflet这两个二维地图框架cesium三维地图框架,当然其实本质是没有特别多的区别的,无非就是方法上的一些差异和cesium会涉及到三维上的算法较多,比如土方量、高程这些东西,所以说cesium会复杂一些,对于初学者来说学起来也并不是特别容易。当然如果cesium已经入门了,那么剩下的两个就变得简单了。
  • 下面我们来说一些cesium基础的一些东西:
  1. 底图影像(初始化地图)

webgis(cesium)初学者必经之路

  • 配置好环境之后,初始化地球:
//如需要,可以在前面配置的cesium 的token,不需要的话可以在源码截断自动获取token的方法以防报错
Cesium.Ion.defaultAccessToken = "你的token"
const viewer = new Cesium.Viewer("cesiumContainer");
  • 像右边工具栏打开的这些都是它的一些底图,这些地图在任何框架上加载的方式都大同小异,常见的地图服务有几个,像我经常用的WMS、WMTS,还有WFS、TMS、WCS这些,具体的概念可以自行百度。这里大家在做示例的时候如果不想去调用线上别人已经发布好的一些图层服务,想要自己尝试服务发布的话,像我会用到geoserver去发布,当然学习geoserver也是需要时间成本的,建议先了解,后面可以自行学习。
//cesium加载wms
const imageryLayers = viewer.imageryLayers;
imageryLayers.addImageryProvider(
  new Cesium.WebMapServiceImageryProvider({
    url:
      "https://nationalmap.gov.au/proxy/http://geoserver.nationalmap.nicta.com.au/geotopo_250k/ows",
    layers: "Hydrography:bores",
    parameters: {
      transparent: true,
      format: "image/png",
    },
  })
);

// cesium加载 wmts
const provider = new Cesium.WebMapTileServiceImageryProvider({
  url:
    "https://gibs.earthdata.nasa.gov/wmts/epsg4326/best/MODIS_Terra_CorrectedReflectance_TrueColor/default/{Time}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.jpg",
  layer: "MODIS_Terra_CorrectedReflectance_TrueColor",
  style: "default",
  tileMatrixSetID: "250m",
  maximumLevel: 5,
  format: "image/jpeg",
  clock: viewer.clock,
  credit: "NASA Global Imagery Browse Services for EOSDIS",
});
const imageryLayers = viewer.imageryLayers;
imageryLayers.addImageryProvider(provider);
  • 上面是加载WMS、WMTS的方法,加载的参数会比较多,这个是发布的时候配置的,如果加载在线底图的不知道配置的话,可以在控制台查看它调用的接口请求的一些什么参数。 2.高程(数字高程模型DEM)
// 初始化地图的时候加载高程(也可以在初始化之后加载高程)
const viewer = new Cesium.Viewer("cesiumContainer", {
  terrainProvider: Cesium.createWorldTerrain(), //可以把Cesium.createWorldTerrain()替换成自己发布的地形文件URL
});

webgis(cesium)初学者必经之路

  • 高程就是加载三维地图上的地形,具体的概念也可以自行百度。它只存在在三维地图里面(openlayers、leaflet这些二维地图里不存在高程)如果你想自己发布高程的话,像我会下载tiff格式的,然后推荐用cesium实验室(可以自行百度下载)直接可以在上面处理成cesium支持的散列文件,用nginx在本地代理一下,就可以直接加载了。 3.矢量数据
  • 矢量数据其实就是带有坐标点的不同类型(点线面)的一些平面数据,同样可以在openlayers这些二维地图里面去加载。 webgis(cesium)初学者必经之路
//点
 viewer.entities.add({
    name: "点",
    position: Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883),
    point: {
      show: true, // 默认为true
      color: Cesium.Color.SKYBLUE, // 默认: 白色
      pixelSize: 10, // (尺寸)默认: 1 
      outlineColor: Cesium.Color.YELLOW, // (边框颜色)默认: 黑色
      outlineWidth: 3, // (边框宽度)默认: 0
    },
  });
//线
viewer.entities.add({
    name: "线",
    polyline: {
      positions: Cesium.Cartesian3.fromDegreesArray([-75, 35, -125, 35]),
      width: 5, // 线宽 
      material: Cesium.Color.RED,
      clampToGround: true, //是否贴地 (如果贴地,那么positions里面的高度是无效的)
    },
 });
  //面数据
 viewer.entities.add({
  name: "面",
  polygon: {
    hierarchy: Cesium.Cartesian3.fromDegreesArray([
      -115.0,
      37.0,
      -115.0,
      32.0,
      -107.0,
      33.0,
      -102.0,
      31.0,
      -102.0,
      35.0,
    ]),
    material: Cesium.Color.RED,
  },
});

  • 当然还会有不同格式的数据,比如GeoJson、kml、kmz、shaper等等各类数据,这些数据都可以去转成矢量数据,或者最常用的GeoJson数据加载到地图上 (shaper文件的话,其实不会需要知道它是怎么转的,一般都会交给后端来写,当然如果需要自己写示例的话,shaper文件就是个zip文件,包括有shp、dbf、prj、fix、shx五个文件,我们用的只要有shp、dbf、prj文件就可以加载,怎么加载可以自行百度,这里就不贴出来了)
//加载GeoJson
const dataSource = Cesium.GeoJsonDataSource.load(
  "../SampleData/simplestyles.geojson"
);
viewer.dataSources.add(dataSource);
//加载KML
viewer.dataSources.add(
    Cesium.KmlDataSource.load(
      "../SampleData/kml/eiffel-tower-flyto.kml",
      camera: viewer.scene.camera,
      canvas: viewer.scene.canvas,
    )
 ).then(
 //当然也是可以有回调的 每个加载的方法都会有回调
 //比如监听
    tour = dataSource.kmlTours[0];
    tour.tourStart.addEventListener(function () {
      console.log("Start tour");
    });
 )

4.3D tiles

  • 3D TilesCesium于2016年3月定义的一种三维模型瓦片数据格式,目前已经是OGC标准之一,3D Tiles将海量三维数据以分块分层的形式组织起来,大大减轻了浏览器和GPU的负担。从结构关系上看,3D Tiles归属于Primitive,有很高的数据加载效率。

webgis(cesium)初学者必经之路

  • 这一部分算是复杂一些的内容了,它的配置比较多,往它延伸的拓展也较多,所以先了解基本的加载显示就ok了,至于是用作项目需求还是自己写demo,了解一个写一个记住一个的方式我觉得是最好的(我这种脑子难记全)
  • 粗糙点说,就是会把模型加载到地图上,所以模型的格式必须是cesium所支持的格式。这个可以自行百度,反正我是懒得写一些复杂且深奥的东西。(首先你得有模型,淘宝上就有,然后可以自行百度Cesium 3D Tiles 转换工具)转换完成之后,用nginx代理一下本地的文件 直接填写在下面的url里就行。
const tileset = scene.primitives.add(
  new Cesium.Cesium3DTileset({
    url: Cesium.IonResource.fromAssetId(8564), 
  })
);
tileset.readyPromise
  .then(function (tileset) {
    viewer.zoomTo(
      tileset,
      new Cesium.HeadingPitchRange(
        0.5,
        -0.2,
        tileset.boundingSphere.radius * 4.0
      )
    );
  })
  .catch(function (error) {
    console.log(error);
  });

5.3D Models

  • Cesium 支持 3D模型,包括关键帧动画,蒙皮和单个节点拾取,使用 GlTF(由Khronos Group,WebGL和 COLLADA 联合成立的 Khronos Group 在网络上为 3D模型提供的一种新兴的行业标准格式)支持。 Cesium ion 还提供了将 COLLADA 模型转换为glTF的解决方案,以优化流式传输到 CesiumJS 应用程序中。

webgis(cesium)初学者必经之路

const position = Cesium.Cartesian3.fromDegrees(
    -123.0744619,
    44.0503706,
    height
  );
  const heading = Cesium.Math.toRadians(135);
  const pitch = 0;
  const roll = 0;
  const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
  const orientation = Cesium.Transforms.headingPitchRollQuaternion(
    position,
    hpr
  );

  const entity = viewer.entities.add({
    name: url,
    position: position,
    orientation: orientation,
    model: {
      uri: "../SampleData/models/DracoCompressed/CesiumMilkTruck.gltf",
      minimumPixelSize: 128,
      maximumScale: 20000,
    },
  });
  viewer.trackedEntity = entity;
  • gltf和glb格式是cesium比较常用的模型格式,如果模型不是这两种格式,请百度xx格式转gltf,大部分应该都有答案的。 6.Entities
  • 上面贴出来的哪些点线面的加载方式,仔细看代码的话,每一次添加到地图上,都是viewer.entities.add,entities是一个实体(具体其实可以先了解再去深究),一般常用来进行标绘操作,画点、线、面、矩形,加载3D模型,挖填方的加载,entities算是在项目里面最常见的一个api了,经常会用到它。
//entity方式
    viewer.entities.add({
        rectangle: {
            coordinates: Cesium.Rectangle.fromDegrees(128, 30, 130, 32),
            material: new Cesium.StripeMaterialProperty({
                evenColor: Cesium.Color.YELLOW,
                oddColor: Cesium.Color.GREEN,
                repeat:8
            })
        }
    });
  1. Primitive
  • Primitive是一个我认为更强大的api,它比entities更接近底层的渲染逻辑,它可以通过Geometry和Appearance来实现一些更底层的绘制操作,它接近于webgl又更为好用(你要用的时候,去ceisum的官网看一下关于这个api以及它的一些用法,记忆会更加深刻。)
    //primitive加载
    var instance = new Cesium.GeometryInstance({
        geometry: new Cesium.RectangleGeometry({
            rectangle: Cesium.Rectangle.fromDegrees(128, 30, 130, 32),
            vertexFormat:Cesium.EllipsoidSurfaceAppearance.VERTEXT_FORMAT
        })
    });
    viewer.scene.primitives.add(new Cesium.Primitive({
        geometryInstances: instance,
        appearance: new Cesium.EllipsoidSurfaceAppearance({
            material:Cesium.Material.fromType('Stripe')
        })
    }));
  • Cesium 是一个比较强大也比较稳定的二三维地图框架,它的api有很多,入门不代表结束,仅仅代表你进入了gis的世界,这个世界相当的精彩,加油骚年~~~~