矢量使用时可能遇到的问题

9/18/2024

# 自定义矢量和材质

适用于场景:

  • 想要同步显示其他矢量,比如加载线时在线的某一个地方加载一个点对象;

  • 目前的矢量类型没有想要的效果、材质等

如何自定义:

  1. 可使用注册矢量数据类GraphicUtil - register (opens new window)去自定矢量;

  2. 使用注册自定义的材质MaterialUtil - register (opens new window)去自定材质

可在示例中全局搜索“注册”,查看代码

若是想要集成原生 cesium 的矢量,如有 update 的 primitive 类

钩子函数里取 this.primitiveCollection (是 Cesium.PrimitiveCollection 对象)进行操作你内部的自定义对象就行。

其中 CamberRadarPrimitive 是按 cesium 本身规范定义的对象,也就是你说的有 update 的 Primitive 类。

export class CamberRadar extends BasePointPrimitive {
  _addedHook() {
    this._primitive = this.primitiveCollection.add(
      new CamberRadarPrimitive({
        id: this.id,
        modelMatrix: this.modelMatrix,
      })
    );
  }

  _removedHook(style) {
    if (this._primitive) {
      this.primitiveCollection.remove(this._primitive);
      delete this._primitive;
    }
  }

  _updateStyleHook(style, newStyle) {
    if (
      Cesium.defined("heading") ||
      Cesium.defined("pitch") ||
      Cesium.defined("roll")
    ) {
      this._primitive.modelMatrix = this.modelMatrix;
    }
    style2Primitive(newStyle, this._primitive);
  }
}
mars3d.graphic.CamberRadar = CamberRadar;

// 注册下
mars3d.GraphicUtil.register("camberRadar", CamberRadar, true);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

# 有没有工具类辅助矢量加载

# 大数据相关

  • 大数据适合一次性加载的数据,效率较大于 entity 和 primitive

  • 合并渲染,是一个整体了,无法进行单个的删除、新增或其他修改操作,每次更新都是全部重新渲染。

  • 只支持一个材质且一个颜色。多色时不能合并渲染。例如下面是不会生效的

materialType: mars3d.MaterialType.LineFlow,
materialOptions: {
  image: "//data.mars3d.cn/img/textures/line-arrow-right.png",
  color: Cesium.Color.fromRandom({ alpha: 0.6 }),
  speed: 30
}
1
2
3
4
5
6

# 贴地面、贴地矩形之类的贴地对象,移动视角会闪烁或有碎面在对面

cesium 本身存在问题;可设置参数 logarithmicDepthBuffer 为 false,具体用法可参考示例代码和 Map 的 api

# 矢量放大的时候不圆滑

使用 granularity 参数

granularity: Cesium.Math.RADIANS_PER_DEGREE / 10;
1

# 矢量改变坐标的时候,怎么让其不闪烁

entity 如果想不闪烁,需要将坐标改为属性机制的,可以用 setCallbackPositions 方法赋值

graphic.setCallbackPositions([
  [117.271662, 31.870639, 10],
  [117.290605, 31.871517, 19.47],
  [117.302056, 31.858145, 16.27],
  [117.299439, 31.847545, 14.77],
  [117.267705, 31.8491, 22.11],
]);
1
2
3
4
5
6
7

# 矢量的边框宽度无法设置

问题原因:window 电脑的宽度永远是 1,是 webgl 的一个因素造成的

除了二维矩形、圆、多边形 外,其他宽度只能是 1

# 矢量在指定时间内显示

  1. 查看对应矢量的 api,是否存在availability参数,存在则可直接使用该参数;

image

  1. 使用属性机制控制,可参考开发教程 - 基础知识点 - Property 属性机制或者属性机制示例 (opens new window)

image

   position : property
    // 演示属性机制
   const property = new Cesium.SampledPositionProperty()
   property.addSample(Cesium.JulianDate.fromDate(new Date("2017-08-25 08:00:00")), Cesium.Cartesian3.fromDegrees(117.198461, 31.834956, 40.2))
   property.addSample(Cesium.JulianDate.fromDate(new Date("2017-08-25 08:00:20")), Cesium.Cartesian3.fromDegrees(117.231979, 31.833411, 35.6))
1
2
3
4
5

# 如何在平台加载 GIF 动画

官网有相关示例参考:

http://mars3d.cn/editor-vue.html?id=graphic/entity/billboard

http://mars3d.cn/editor-vue.html?id=graphic/divGraphic/basis

方式 1:

// 绘制台风当前位置 gif 点

const gifGraphic = new mars3d.graphic.DivGraphic({
  position: [endItem.lon, endItem.lat],
  style: {
    html: `<img src="img/icon/typhoon.gif">`,
    horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
    verticalOrigin: Cesium.VerticalOrigin.CENTER,
  },
});
this.typhoonLayer.addGraphic(gifGraphic);
1
2
3
4
5
6
7
8
9

方式 2:

// 利用第 3 方库(libgif.js)加载 gif

function addDemoGraphic12(graphicLayer) {
  const gifImg = document.createElement("img");
  gifImg.setAttribute("rel:animated_src", "img/icon/typhoon.gif");
  gifImg.setAttribute("rel:auto_play", "1"); // 设置自动播放属性

  // eslint-disable-next-line no-undef
  const superGif = new SuperGif({ gif: gifImg });

  superGif.load(function () {
    const graphic = new mars3d.graphic.BillboardEntity({
      position: new mars3d.LngLatPoint(116.3, 30.8, 1000),
      style: {
        image: new Cesium.CallbackProperty(() => {
          // 转成base64,直接加canvas理论上是可以的,这里设置有问题
          return superGif.get_canvas().toDataURL();
        }, false),
        horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
        verticalOrigin: Cesium.VerticalOrigin.CENTER,
      },
      attr: { remark: "示例12" },
    });
    graphicLayer.addGraphic(graphic);
  });
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# 矢量内置的附加矢量,初始化不加载,后续无法加载

例如 modelEntity 矢量,内置的这些附加矢量;

image

涉及效率问题,初始化没有的话,后续是不会在创建的了;

可根据自身需求进行下列选择:

  • 设置 circle:{show:false,...(其他设置)},后续使用 setOptions 修改 show 参数控制显隐即可;

  • 自行创建另外的矢量,可做更多个性化操作

# 矢量的附加 label 对象,怎么使用矢量内的属性

将 label 中的参数显示成矢量内的属性,比如 name、项目名称等,可使用 text: "{name}";

image

如果发现没有生效,则需要确定下矢量内是否有该参数,若不清楚可以使用 popup:"all" 显示矢量内的额外参数;

image

没有参数的话,写上即可;

image

# 矢量的 Text 材质怎么使用矢量内的属性

同 label 参数一样,设置 text:{name}的话不生效;

目前不支持,是材质内的属性,需要 callback 回调,比如

graphicLayer = new mars3d.layer.GeoJsonLayer({
  // ...其他参数
  symbol: {
    styleOptions: {
      color: "#0d3685",
      outlineColor: "#0d3685",
      opacity: 0.8,
    },
    callback: function (attr, styleOpt) {
      return {
        materialType: "Text",
        materialOptions: {
          text: attr.name,
        },
      };
    },
  },
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 行政区突出显示边界图片拉升

image

这种图片拉升的问题:

  1. 一般是因为 开始地图的范围 比 行政区的边界要大,凸显 行政区是哪个就用哪个行政区的地图,超出边界就会出现这种错误

  2. 可以考虑加个单张图片做底图,cesium 如果底图不是全球的局部区域就出现这种效果

# 如何把运动中的两个卫星连接到一起,且卫星根数只能用 tle 吗?可否用六根数格式?

image

解决方案:

image

目前只能 tle,六根数可以转 tle 的,tle 的解释参考

http://mars3d.cn/api/Tle.html

# 矢量图层能使用 datasource,直接赋值使用

1.矢量图层使用 datasource 直接赋值使用

从 kml 中解析得到一些 entity,然后需要进行一些配置和操作,之后再显示到 map 中

graphicLayer.datasource 等价原生 cesium 的 datasource ,可以直接使用,加 entity

# distanceDisplayCondition_near 相关

cesium 本身属性,这个属性的意思是视距,并且线还有线的中心与相机的视距,

下侧工具栏是视高,与视距无关,只有概略的关系。

# 如何修改矢量的位置

graphic.postion = xxxx,修改坐标位置,直接赋值修改

# 矢量如何修改高度,改变 position 的话会闪烁

改变 positions 整个架子都变了是需要重新渲染。可参考下面代码平滑移动高度

let height = 0;
setInterval(() => {
  if (height > 10000 || graphic.isDestroy) {
    return;
  }
  height += 1;
  graphic.offsetHeight = height;
}, 10);
1
2
3
4
5
6
7
8

# mars3d.MaterialType.Image 材质加载或更改时会导致图片闪一下

使用 mars3d.MaterialType.Image2 材质,具体用法可参考示例

# 矢量如何定位?

搜索下 API 文档(关键词:getGraphic ),根据自身需要选择合适的方式;

比如说根据 id 获取;layer.getGraphicById(),拿到对应 id 的矢量数据然后再 flyTo;

如果是 pathEntity.flyToPoint(),目前只能定位到他所在的实时定位。如果想要定位,还得同步时钟。可以外部记录下 path 的所有坐标 map.flyToPositions

# 矢量的文本字体换成扩展后的自定义字体

web 前端 css 的规则一样,可以任意注册字体到 css 中。

最后更新: 11/3/2024, 1:40:29 AM