SuperMap iClient3D for WebGL 使用说明

前言:

最近由于公司需要用的superMap相关的技术,本人之前也从未接触过这方面的东西,也是从零开始,边做边学。下面简单对本次项目进行一个技术总结,希望对没有经验的人有所帮助。
SuperMap iClient3D for WebGL 官方文档
http://support.supermap.com.cn:8090/webgl/web/index.html

一、Viewer视图

Viewer是Cesium中用于显示3D场景的组件。它提供了创建和控制3D场景所需的所有基本功能,包括加载3D模型、添加图像覆盖物、设置相机位置和方向、处理用户输入等。

在创建Viewer时,可以指定要使用的HTML元素(例如canvas),该元素将用于呈现3D场景。一旦创建了Viewer对象,就可以通过调用其方法来添加实体、图像覆盖物和其他元素,并对相机进行操作。

new Cesium.Viewer(container, options):是用来创建一个新的 Cesium 视图器(Viewer)实例的构造函数。
container:必需,表示视图器容器元素的ID字符串或HTML元素。
options:{
	geocoder: false, // 是否创建右上角的查询按钮(右上第一个)
    homeButton: false, // 是否创建 home 按钮(右上第二个)
    sceneModePicker: false, // 是否创建右上角的切换地图的按钮(右上第三个)
    baseLayerPicker: false, // 是否创建右上角 BaseLayerPicker 小部件(右上第四个)
    navigationHelpButton: false, // 是否创建右上角的导航帮助按钮(右上第五个
    // vrButton: true, // 是否创建右下角的 VR 按钮,默认值为 true
    animation: false, // 是否创建左下角的动画小部件
    fullscreenButton: false, // 是否创建右下角全屏按钮
    timeline: false, // 是否创建最下方的时间线
    infoBox: false, // 点击实体是否展示详情
    selectionIndicator: false, // 点击实体是否显示选中样式
    // 左下方的 Cesium logo 使用 css 删除
    terrainProvider: Cesium.createWorldTerrain(), // 加载地球椭球体
}

二、scene场景

三维场景类,所有3D图形对象的容器(HTML canvas)。它是所有三维图形对象和状态的容器,通常不直接创建场景,而是由Widget隐式创建。

 scene = viewer.scene

常用方法:

// 打开指定图层资源
scene.open(url, sceneName, options)
scene.open(
  url, 必须,服务url 例如 http://{s}/iserver/services/3D-QX20230317-2/rest/realspace
  sceneName, //工作空间中有多个场景,需要指定场景名称;设置为undefined,默认打开第一个
  options: {
   // 用于子域, 例如 ['192.168.2.1:8090', '192.168.2.1:8091']
    subdomains: ['t1','t2'],
    // 是否自动定位到场景, 默认为true
    autoSetView: false
  }
)

三、camera相机

相机类,它由位置、方向和视锥体定义。 视锥体(viewing frustum)由6个(上、下、左、右、近、远)平面限定,每个平面可 由Cartesian4对象表示,其中x,y和z分量定义垂直于平面的单位向量,w分量是平面距原点/相机位置的距离。

camera = viewer.scene.camera;

常用方法:

// 设置相机位置、方向和变换。
1、camera.setView(options) 
camera.setView({
    // 相机在WGS84世界坐标系中的最终位置,或是自顶向下视图中可见的矩形区域。
    destination : new Cesium.Cartesian3(-1590650.7796661195, 5331299.69368041, 3109890.2682378646),
    orientation : {
      // 方位角
      heading : 1.4092244106070817,
      // 俯仰角
      pitch : -0.6060137107123218,
      // 滚动角
      roll : 3.055333763768431e-13
    },
    // 是否将相机最终位置从世界坐标转换为场景坐标,默认值True。
    convert: true
  });
// camera.flyTo(target, options): 使相机飞行到指定的目标位置,并设置相应的动画效果和参数。
2、camera.flyTo({
  // 相机在WGS84世界坐标系中的最终位置,或是自顶向下视图中可见的矩形区域。
  destination: SuperMap3D.Cartesian3.fromDegrees(Number(data.camera.longitude), Number(data.camera.latitude), Number(data.camera.hight)),
  orientation: {
     // 方位角
      heading : 1.4092244106070817,
      // 俯仰角
      pitch : -0.6060137107123218,
      // 滚动角
      roll : 3.055333763768431e-13
  },
  // 动画持续时间
  duration: 5,
  // 飞行结束后的回调
  complete: function () {
   
  }
});
// 监听相机位置
3、 camera.moveEnd.addEventListener 
camera.moveEnd.addEventListener(() => {
   // 世界坐标系
   const result = Cesium.Cartographic.fromCartesian(position)
   // 纬度
   const latitude = Cesium.Math.toDegrees(result.latitude)
   // 经度
   const longitude = Cesium.Math.toDegrees(result.longitude)
 	console.log(camera.position)
 })

用的到一些方法说明

1、在地图上创建点线面
// 点实体
var boxEntity = viewer.entities.add({
    position: position, // 格式为世界坐标的点位置
	point: {
        show: ture, // 点是否可见
        pixelSize: Number, // 点的大小
        color: color, // 点的颜色
        outlineClor: color, // 边框颜色
        outlineWidth: Number, // 轮廓宽度
    },
});
// 线实体
var boxEntity = viewer.entities.add({
    polyline: {
        show: Boolean, // 线是否可见
        positions: positions, // 格式为世界坐标的线位置数组
        width: Number, // 线的宽度
        material: color, // 线的颜色
        clampToGround: Boolean, // 线是否固定在地面
    },
});
// 面实体
var boxEntity = viewer.entities.add({
    polygon: {
        show: Boolean, // 面是否可见
        hierarchy: positions, // 格式为世界坐标的面位置数组
        height: Number, // 面相对于椭球表面的高度
        fill: Boolean, // 面是否有填充
        material: color, // 面的填充颜色
        outline: Boolean, // 面是否有边框
        outlinColor: color, // 边框的颜色
        outlineWidth: Number, // 边框的宽度,无论设置为多少宽度始终只会显示为 1
        perPositionHeight: Boolean, // 面是否使用每个位置的高度
    },
});
2、移除某个绘制实体
  var redBox = viewer.entities.add(boxEntity);
  viewer.entities.remove(redBox )
3、移除全部绘制实体
  viewer.entities.removeAll()
4、更换地图影像
  viewer.imageryLayers.addImageryProvider(new Cesium.SuperMapImageryProvider({
    url: ‘xxxx’
  }));
5、查询所有矢量面数据
function doSqlQuery () {
  let _this = this
  var sqlParameter= {
    // 具体的数据源+数据源列表
   "datasetNames"  : ["G65结构物数据库:结构物库"],
    getFeatureMode  : "SQL",
    queryParameter  : {
      // 查询条件,smId 大于 0 的数据
      attributeFilter : 'SmID > 0'
    }
  };
  var queryData = JSON.stringify(sqlParameter);
  // 要查询的数据服务地址
  axios.post('http://183.64.62.11:9490/iserver/services/data-QX20230317/rest/data/featureResults.rjson?returnContent=true', queryData).then(res => {
    const data = res.data.features
    console.log(data, '所有矢量面详细数据')
  })
}
// 具体可参考官方文档中的 查询/属性查询/SQL查询
6、根据具体的坐标查询矢量面
// 根据倾斜摄影ID查询建筑物
function queryByPoint (queryPoint) {
  var queryObj = {
    "getFeatureMode": "SPATIAL",
    "spatialQueryMode": "INTERSECT",
    // 要查询的数据源
    "datasetNames": ["G65结构物数据库:结构物库"],
    "geometry": {
      id: 0,
      parts: [1],
      points: [queryPoint],
      type: "POINT"
    }
  };
  var queryObjJSON = JSON.stringify(queryObj); // 转化为JSON字符串作为查询参数
  axios.post('http://183.64.62.11:9490/iserver/services/data-QX20230317/rest/data/featureResults.rjson?returnContent=true', queryObjJSON).then(res => {
    if (res.data.features.length) {
      const data = res.data.features[0]
      console.log(data, ''单条矢量数据)
    }
  })
}
// 具体可参考官方文档中的 查询/属性查询/动态单体化
7、监听鼠标左键单击
var handler = new SuperMap3D.ScreenSpaceEventHandler(scene.canvas);
handler.setInputAction(function (e) {
  // 首先移除之前添加标识实体
  viewer.entities.removeById('identify-area');
  // 获取点击位置笛卡尔坐标
  var position = scene.pickPosition(e.position);
  scenePosition = position;
  // 从笛卡尔坐标获取经纬度
  var cartographic = SuperMap3D.Cartographic.fromCartesian(position);
  var longitude = SuperMap3D.Math.toDegrees(cartographic.longitude);
  var latitude = SuperMap3D.Math.toDegrees(cartographic.latitude);

  var queryPoint = { // 查询点对象
      x: longitude,
      y: latitude
  };
 console.log(queryPoint , '当前点击的具体方位坐标')
}, SuperMap3D.ScreenSpaceEventType.LEFT_CLICK);

开发的时候在网上用到的一下技术文献
1、不使用fpf文件实现漫游功能。可参考

https://blog.csdn.net/wo_buzhidao/article/details/102681925

如果使用fpf文件实现漫游,vue项目 注意fpf文件需放在public目录下

var fpfUrl = './SampleData/fpf/niaocao.fpf';  // 注意这里的./指的是public目录下
routes.fromFile(fpfUrl);

2、关于在地图上绘制点线面、经纬度坐标转换、具体的有哪些事件可参考

https://blog.csdn.net/m0_49788155/article/details/126966718

你可能感兴趣的:(3d,webgl)