矢量数据 是用经度、纬度、高度坐标来表示地图图形或地理实体位置的数据,一般是通过记录坐标的方式来尽可能将地理实体的空间位置表现的准确无误,常见的矢量数据有:点、线、面、体等格式。
1. 矢量数据对象
平台对 Cesium 矢量数据和平台自身扩展开发的矢量对象都做了梳理及统一对外接口的封装,这样使用更加简单易用、对开发人员更友好、开发效率高。
平台的所有矢量数据类都继承于BaseGraphic 类,矢量数据类均在mars3d.graphic.*
命名空间下面。矢量数据清单请访问GraphicType 类
下面我们演示创建一个矢量数据对象 ,并调用 layer.addGraphic 添加到图层上。
//创建矢量数据图层
let graphicLayer = new mars3d.layer.GraphicLayer();
map.addLayer(graphicLayer);
//加载数据到矢量图层
let graphic = new mars3d.graphic.LabelEntity({
position: new mars3d.LngLatPoint(116.1, 31.0, 1000),
style: {
text: 'Mars3D三维可视化平台',
font_size: 25,
color: '#003da6'
}
});
graphicLayer.addGraphic(graphic);
//创建矢量数据图层
let graphicLayer = new mars3d.layer.GraphicLayer();
map.addLayer(graphicLayer);
//加载数据到矢量图层
let graphic = new mars3d.graphic.LabelEntity({
position: new mars3d.LngLatPoint(116.1, 31.0, 1000),
style: {
text: 'Mars3D三维可视化平台',
font_size: 25,
color: '#003da6'
}
});
graphicLayer.addGraphic(graphic);
矢量数据 由 坐标、样式、属性 3 部分组成构成
构成 | mars3d 属性名 | 说明 |
---|---|---|
坐标 | position 或 positions | 地理位置,如经度、纬度、高度(三维 GIS 中) 构成 |
样式 | style | 表现形式,如图标图片、线条样式、填充色、文字样式等 |
属性 | attr | 除经纬度信息之外的关联信息,如名称、地址、电话、面积、长度、备注等 |
可以通过图层的graphicLayer.addGraphic(graphic)
和 graphicLayer.removeGraphic(graphic)
方法来控制矢量数据的加载和删除。
在矢量数据本身也有graphic.addTo (graphicLayer)
和graphic.remove ()
2 个方法支持添加或移除矢量数据。
2. 矢量数据的类别
目前平台内的矢量数据分为四大类:
类型 | 性能 | 数据量极限 | 功能/特点 | 动态坐标位置 | 功能示例 |
---|---|---|---|---|---|
Entity | 低 | <1 千 | 支持动态属性,控制方便 | 支持 | PolygonEntity 示例 |
Primitive | 中 | <1 万 | 性能比较好 | 点对象支持 | PolygonPrimitive 示例 |
CombinePrimitive | 高 | <几十万 | 多个数据合并渲染,性能最佳 | 不支持 | PolygonCombine 示例 |
DIV | 低 | <100 | 基于 DOM ,可以写 CSS3 效果 | 支持 | DivGraphic 示例 |
在使用优先级上,推荐按下面顺序:Combine > Primitive > Entity ,DIV 主要看你需求选择,不支持太多数据
2.1 Entity 矢量对象
Entity API 的主要目的是定义一组高级对象,它们把可视化和信息存储到统一的数据结果中,这个对象叫 Entity。 它让我们更加关注我们的数据展示而不是底层的可视化机制。它提供了很方便的创建复杂的与静态数据相匹配的随时间变化的可视化效果。Entity 内部也是使用了 Primitive,它的实现细节,我们无需关心, Entity 暴露一些一致性的、容易去学习和使用的接口。
Entity 矢量对象特点:
- (1)性能略低、适合少量数据
- (2)支持 Property 属性机制
- (3)支持 Draw 标绘和编辑
- (4)针对 Billboard、Label、Point 对象提供聚合功能。
目前 Entity 常用类型包括:
更多请参考 矢量数据类型
2.2 Primitive 矢量对象
Primitive API 的主要目的是为了完成(可视化)任务的最少的抽象需求。它很强大又很灵活,要求我们以一个图形开发者的方式去思考,并且使用了一些图形学术语。它是为了最高效最灵活的实现可视化效果,忽略了 API 的一致性。他们每种都有自己的独特的性能提升方式,也需要遵守不同的优化原则。
Primitive 方式更接近渲染引擎底层,需要理解 Primitive API 参数时需要您已有 WebGL 知识储备,建议先学习下《WebGL 编程指南》,Primitive 由两个部分组成:
- 几何形状(Geometry):定义了 Primitive 的结构,例如三角形、线条、点等
- 外观(Appearance ):定义 Primitive 的着色(Sharding),包括 GLSL(OpenGL 着色语言)顶点着色器和片段着色器(vertex and fragment shaders),以及渲染状态(render state)
使用 Primitive 具有以下优势:
- (1)性能:尤其是绘制大量静态图元(比如整个美国的邮政编码区域多边形),使用几何体可以把他们组合成一个单一的几何体,这样会减少 cpu 的开销,并且充分利用 GPU 的能力。组合几何体可以在 web worker 中完成,不会影响用户界面的响应。
- (2)灵活性:图元由几何体和外观构成。不过他们可以单独修改。新建的几何体可以兼容多种不同的外观,反之亦然。
- (3)底层访问:外观提供了近乎最底层的渲染访问,但是又不需要直接担心渲染 Renderer 的细节技术 。外观使下面的技术简单了很多:编写完整的顶点和片段着色器 GLSL 代码、使用用户自定义的渲染状态。
同时,具有以下劣势:
- (1)使用几何体和外观需要写更多的代码,并且需要对图形知识有深刻的理解。Entity 是应用层的抽象;而几何体和外观更像是一个传统 3D 引擎的级别。
- (2)对于静态数据,几何体合并非常有效,但是对于动态数据不适合。
目前 Primitive 常用以下类型:
目前 Primitive 的大数据集合 (合并渲染) 类型:
类型名 | 说明 | 对应的矢量数据类 | 坐标参数 | style 样式参数 |
---|---|---|---|---|
modelC | 批量 gltf 模型 | mars3d.graphic.ModelCombine | instances 数组 | 参数清单 |
polylineC | 批量线 | mars3d.graphic.PolylineCombine | instances 数组 | 参数清单 |
polygonC | 批量面 | mars3d.graphic.PolygonCombine | instances 数组 | 参数清单 |
更多请参考 矢量数据类型
2.3 DIV 矢量对象
这类实际不是真正的矢量数据对象,由 Div 构成的 DOM 对象在页面中展示,在与地图位置进行联动。
类型名 | 说明 | 对应的矢量数据类 | 坐标参数 | style 样式参数 |
---|---|---|---|---|
div | DIV 点 | mars3d.graphic.DivGraphic | position 单个坐标 | style 参数清单 |
divLightPoint | 动画的扩散 div 点 | mars3d.graphic.DivLightPoint | position 单个坐标 | style 参数清单 |
divUpLabel | 竖立的文本 DIV 点 | mars3d.graphic.DivUpLabel | position 单个坐标 | style 参数清单 |
divBoderLabel | 动态边框文本 DIV 点 | mars3d.graphic.DivBoderLabel | position 单个坐标 | style 参数清单 |
2.4 其他 矢量对象
除了上面介绍的 3 类,还有一些其他如如粒子、视频融合 等对象,具体可以参考功能示例 和 矢量数据类型清单来了解和学习。
3. 矢量数据的控制
前面我们讲到了平台对所有矢量数据 做了统一风格的对外接口的封装,都继承于BaseGraphic 类,这样使用更加简单易用、对开发人员更友好、开发效率高。并且参数属性和方法均一致。
3.1 矢量数据的事件
矢量数据均支持事件的绑定、解绑、触发等统一的事件机制,例如:
graphic.on(mars3d.EventType.click, function (event) {
console.log('您单击了矢量对象', event);
});
graphic.on(mars3d.EventType.click, function (event) {
console.log('您单击了矢量对象', event);
});
3.2 矢量数据的 Popup、Tooltip 等控件
graphic 矢量数据对象上可以操作的常用方法控件相关操作方法有:
//Popup相关
graphic.hasPopup(); //是否存在Popup绑定
graphic.bindPopup(content, options); //绑定鼠标单击对象后的弹窗。
graphic.unbindPopup(); //解除绑定的鼠标单击对象后的弹窗。
graphic.openPopup(position); //打开Popup弹窗
graphic.closePopup(); //关闭弹窗
//Tooltip相关
graphic.hasTooltip(); //是否存在Tooltip绑定
graphic.bindTooltip(content, options); //绑定鼠标移入对象后的弹窗。
graphic.unbindTooltip(); //解除绑定的鼠标移入对象后的弹窗。
graphic.openTooltip(position); //打开Tooltip弹窗
graphic.closeTooltip(); //关闭Tooltip弹窗
//SmallTooltip相关
graphic.openSmallTooltip(position, message); //显示小提示窗,一般用于鼠标操作的提示。
graphic.closeSmallTooltip(); //关闭小提示窗
//右键菜单相关
graphic.hasContextMenu(); //是否有绑定的右键菜单
graphic.getContextMenu(); //获取绑定的右键菜单数组
graphic.bindContextMenu(content, options); //绑定地图的默认右键菜单
graphic.unbindContextMenu(); //解除绑定的右键菜单
graphic.openContextMenu(position, options); //打开右键菜单
graphic.closeContextMenu(); //关闭右键菜单
//Popup相关
graphic.hasPopup(); //是否存在Popup绑定
graphic.bindPopup(content, options); //绑定鼠标单击对象后的弹窗。
graphic.unbindPopup(); //解除绑定的鼠标单击对象后的弹窗。
graphic.openPopup(position); //打开Popup弹窗
graphic.closePopup(); //关闭弹窗
//Tooltip相关
graphic.hasTooltip(); //是否存在Tooltip绑定
graphic.bindTooltip(content, options); //绑定鼠标移入对象后的弹窗。
graphic.unbindTooltip(); //解除绑定的鼠标移入对象后的弹窗。
graphic.openTooltip(position); //打开Tooltip弹窗
graphic.closeTooltip(); //关闭Tooltip弹窗
//SmallTooltip相关
graphic.openSmallTooltip(position, message); //显示小提示窗,一般用于鼠标操作的提示。
graphic.closeSmallTooltip(); //关闭小提示窗
//右键菜单相关
graphic.hasContextMenu(); //是否有绑定的右键菜单
graphic.getContextMenu(); //获取绑定的右键菜单数组
graphic.bindContextMenu(content, options); //绑定地图的默认右键菜单
graphic.unbindContextMenu(); //解除绑定的右键菜单
graphic.openContextMenu(position, options); //打开右键菜单
graphic.closeContextMenu(); //关闭右键菜单
3.3 矢量数据的鼠标交互高亮样式
在大部分矢量数据的 style 属性中支持highlight
参数,该参数支持的值与本身的 style 是一致的,用于定义鼠标单击或移入后高亮显示的样式。
let graphic = new mars3d.graphic.PolygonEntity({
positions: [
[117.183593, 31.856606, 32.1],
[117.213155, 31.854726, 28.6],
[117.186741, 31.845103, 45.5]
],
style: {
color: '#00ff00',
opacity: 0.5,
//高亮时的样式
highlight: {
type: mars3d.EventType.click, //默认为鼠标移入,也可以加该参数后单击高亮
opacity: 0.9
}
}
});
graphicLayer.addGraphic(graphic);
let graphic = new mars3d.graphic.PolygonEntity({
positions: [
[117.183593, 31.856606, 32.1],
[117.213155, 31.854726, 28.6],
[117.186741, 31.845103, 45.5]
],
style: {
color: '#00ff00',
opacity: 0.5,
//高亮时的样式
highlight: {
type: mars3d.EventType.click, //默认为鼠标移入,也可以加该参数后单击高亮
opacity: 0.9
}
}
});
graphicLayer.addGraphic(graphic);
并且矢量数据中也有openHighlight 方法、closeHighlight 方法来外部调用按指定样式高亮对象和取消高亮对象。