# 自定义矢量和材质
适用于场景:
想要同步显示其他矢量,比如加载线时在线的某一个地方加载一个点对象;
目前的矢量类型没有想要的效果、材质等
如何自定义:
可使用注册矢量数据类GraphicUtil - register (opens new window)去自定矢量;
使用注册自定义的材质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);
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
# 有没有工具类辅助矢量加载
GraphicUtil (opens new window) - 矢量数据 相关静态方法
MaterialUtil (opens new window) - 矢量数据 材质
PointUtil (opens new window) - 单个坐标或位置矩阵相关的处理 静态方法
PolyUtil (opens new window) - 多个点 或 线面数据 相关处理 静态方法
LngLatPoint (opens new window) - 坐标点类(含经度、纬度、高度)
LngLatArray (opens new window) - 坐标数组处理类
PointTrans (opens new window) - 坐标点的转换 相关静态方法。 提供了 cesium 内部不同坐标系之间的坐标转换、提供了国内偏移坐标系与标准坐标的转换。
# 大数据相关
大数据适合一次性加载的数据,效率较大于 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
}
2
3
4
5
6
# 贴地面、贴地矩形之类的贴地对象,移动视角会闪烁或有碎面在对面
cesium 本身存在问题;可设置参数 logarithmicDepthBuffer 为 false,具体用法可参考示例代码和 Map 的 api
# 矢量放大的时候不圆滑
使用 granularity 参数
granularity: Cesium.Math.RADIANS_PER_DEGREE / 10;
# 矢量改变坐标的时候,怎么让其不闪烁
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],
]);
2
3
4
5
6
7
# 矢量的边框宽度无法设置
问题原因:window 电脑的宽度永远是 1,是 webgl 的一个因素造成的
除了二维矩形、圆、多边形 外,其他宽度只能是 1
# 矢量在指定时间内显示
- 查看对应矢量的 api,是否存在availability参数,存在则可直接使用该参数;
- 使用属性机制控制,可参考开发教程 - 基础知识点 - Property 属性机制或者属性机制示例 (opens new window)
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))
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);
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);
});
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 矢量内置的附加矢量,初始化不加载,后续无法加载
例如 modelEntity 矢量,内置的这些附加矢量;
涉及效率问题,初始化没有的话,后续是不会在创建的了;
可根据自身需求进行下列选择:
设置 circle:{show:false,...(其他设置)},后续使用 setOptions 修改 show 参数控制显隐即可;
自行创建另外的矢量,可做更多个性化操作
# 矢量的附加 label 对象,怎么使用矢量内的属性
将 label 中的参数显示成矢量内的属性,比如 name、项目名称等,可使用 text: "{name}";
如果发现没有生效,则需要确定下矢量内是否有该参数,若不清楚可以使用 popup:"all" 显示矢量内的额外参数;
没有参数的话,写上即可;
# 矢量的 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,
},
};
},
},
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 行政区突出显示边界图片拉升
这种图片拉升的问题:
一般是因为 开始地图的范围 比 行政区的边界要大,凸显 行政区是哪个就用哪个行政区的地图,超出边界就会出现这种错误
可以考虑加个单张图片做底图,cesium 如果底图不是全球的局部区域就出现这种效果
# 如何把运动中的两个卫星连接到一起,且卫星根数只能用 tle 吗?可否用六根数格式?
解决方案:
目前只能 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);
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 中。