图形开发学院|GraphAnyWhere
第三章:图层类(Layer)
\quad 在上一章中,我们讲到了图层(Layers)是一种用于组织和管理图像内容的办法。可以将不同的图像元素分开,使得它们可以独立地进行绘制、编辑和操作。每个图层都可以包含一个或多个图像对象,这些对象可以是几何对象、文本、图像等。图层可以互相叠加,并且可以通过控制透明度、颜色和大小等属性来创建各种视觉效果。
\quad
本章以 anyGraph
中图层类的设计为例讲述图层在图形中的作用。
1. 类的设计
\quad 面向对象程序设计中的抽象是指从具体事物中抽取其共性的过程。按照这个方法,我们对图层的属性、数据和行为进行分析后,归纳出在图形系统中,图层的特征可分为三类:图层属性、图层数据、图层渲染。图层属性包括图层名称、渲染顺序、可见范围等信息,图层数据包含了该图层中的图形对象集合,图层渲染是指将图形对象集合渲染至画板Canvas中的操作。
\quad
这三个特征可分别对应一个Class,在其封装内部逻辑,这三个类命名分别为Layer类
、LayerSource类
和LayerRenderer类
,这三者的关系如下图所示:
\quad 按照上一章对图形的定义,一个图形包含了多个图层,负责图层的集合管理。集合中每个图层均包含了上述三个类的实例。
类关系图
\quad
按照数据类型差异,图层的数据源可以是几何数据源,可以是位图数据源,也可以是地图瓦片数据源。数据类型的差异会导致在渲染时采用不同的渲染方法,因此图层数据源
和图层渲染
是一种强对应关系,例如图层矢量数据源VectorSource
对应的是图层矢量渲染类VectorRenderer
类,图层瓦片数据源TileSource
对于图层瓦片渲染类TileRenderer
。
\quad 下面这张类图包含了这几个类及其父类。
2. 图层类
类名为:Layer
,源代码位于src
目录。
\quad
图层类 Layer
是图层中这几个类的核心类,提供了图层信息、图层控制、图层样式等方面的功能。
(1) 初始化
constructor(options)
\quad
该类的构造函数接受一个 Object
类型的参数,其值包括:
名称 | 类型 | 说明 |
---|---|---|
name | String | 名称 |
zIndex | int | 图层顺序,zIndex较大的图层显示在较小的图层之上 |
usePixelCoord | Boolean | 是否使用像素作为坐标 |
opacity | float | 透明度,取值范围为 0~1 |
minResolution | float | 图层可见的最小密度 |
maxResolution | float | 图层可见的最大密度 |
visible | Boolean | 图层是否可见 |
style | Object | 图层样式 |
source | Source | 图层数据源 |
下面是创建一个图层的示例:
let layer = new Layer({
source: new VectorSource({
"fileUrl": path + "export_roadcenter.geojson",
"projection": projection,
"format": new GeoJSONFormat()
}),
zIndex: 10025,
name: "道路-路中线",
style: { "color": "#00BFFF", "lineWidth": 2 },
minResolution: 0.880,
maxResolution: 3.240,
visible: true
});
graph.addLayer(layer);
(2) 图层信息
下面列出了几个常用的获取图层信息的方法:
名称 | 说明 |
---|---|
getName() | 名称 |
getZIndex() | 图层顺序 |
isUsePixelCoord() | 是否使用像素作为坐标 |
渲染顺序
\quad
该属性在构造函数中通过 zIndex
属性指定,通过 getZIndex() 可获取图层的渲染顺序。在将图层合成至图形时,先绘制该值较小的图层,然后绘制该值较大的图层。
是否采用像素坐标
\quad
该属性在构造函数中通过 usePixelCoord
属性指定,通过 isUsePixelCoord() 可获取该图层是否采用像素坐标。采用像素坐标时,该图层不会进行矩阵变换,而是直接渲染至Canvas指定位置,这也意味着该图层中的图形位置和大小不会随着图形的缩放和漫游而发生变化。之前多个示例的效果图中都包含了一个带有网格和水印的背景层,就设置了usePixelCoord=true
,因此不管对图形进行怎样的缩放和漫游操作,其背景始终是不变的。
(3) 图层控制
下面列出了几个图层控制的方法:
名称 | 说明 |
---|---|
getVisible() | 是否显示 |
setVisible(visible) | 设置是否显示 |
getMaxResolution() | 获取最大分辨率值 |
setMaxResolution(maxResolution) | 设置渲染该图层的最大分辨率值 |
getMinResolution() | 获取最小分辨率值 |
setMinResolution(minResolution) | 设置渲染该图层的最小分辨率值 |
可见性
\quad
该属性可在构造函数中通过 visible
属性指定 或 通过 setVisible() 设置图层可见性。如果该值为false,则不合成至图形中。
分辨率
\quad
分辨率指的Canvas中像素对应图形的宽度/高度的比值,通过分辨率属性同样可以控制图层的可见性。在构造函数中可指定最小分辨率 minResolution
和 最大分辨率 maxResolution
属性指定。
- 在地图图纸中通常使用 比例尺 来描述地图的精度,比例尺是表示图上一条线段的长度与地面相应线段的实际长度之比。公式为:比例尺=图上距离/实际距离。一般来讲,越是大的比例尺地图,几何精度越高。
- 而在计算中通常使用 分辨率 来描述地图的精度,分辨率指的Canvas中1个像素对应图形的宽度/高度的比值。同样分辨率越大,几何精度越高。
- 在计算机中通常不采用比例尺来描述图形的精度,这是因为“比例尺=图上距离/实际距离",而显示器屏幕的大小是不确定的,同一张图在14寸的显示器上和27寸的显示器上显示全图时,由于分母相同分子不相同,因此其比值是不一样的。
(4) 图层样式
名称 | 说明 |
---|---|
getStyle() | 获取图层渲染样式 |
setStyle(style) | 设置图层渲染样式 |
getOpacity() | 获取图层透明度 (between 0 and 1). |
setOpacity(opacity) | 设置透明度(between 0 and 1) |
\quad
该属性在构造函数中通过 style
属性指定,也可通过 setStyle(style)
方法赋值。样式主要指的是几何对象的颜色、线宽、线型等渲染时的属性,而对于文字而言,样式还包括文本的大小、字型、对齐等属性。
\quad 在渲染图层中的图形对象时,既可以为图层中的每一个图形对象指定样式,也可以为图层指定样式。如果图形对象和图层均指定了样式,则优先使用图形对象的样式。
3 数据源
\quad 图层数据包含了某图层渲染时的图形对象集合,该集合中的所有对象都位于同一个坐标系中。
\quad
该属性在构造函数中通过 source
属性指定,缺省为 VectorDataSource
类型, 图层类 Layer
提供了getSource()
方法可获取该图层对应的数据源对象。
名称 | 说明 |
---|---|
getSource() | 获取图层数据源 |
(1) 矢量数据源
类名为:VectorDataSource
,位于src/source
目录。
\quad 矢量数据源是为矢量图层提供具体的数据来源,包含了在图形上展示几何对象和文本、图像等图形对象集合。
初始化
constructor(options)
\quad
该类的构造函数接受一个 Object
类型的参数,其值包括:
名称 | 类型 | 说明 |
---|---|---|
format | FeatureFormat | 格式化对象 |
fileUrl | String | 数据文件Url |
data | Array | 数据列表 |
projection | Projection | 投影类型对象 |
说明:
format
属性,用于在loadFile()
或loadData()
时解析数据的格式化对象;data
属性,如果指定了该属性,则构造后立即将该数据装载至Source
中,优先级高于fileUrl
属性;fileUrl
属性,如果指定了该属性,则构造后立即下载该数据文件,并装载至Source
中;projection
属性,如果指定了该属性,则从data
或fileUrl
加载数据时,将进行坐标投影变换。
\quad
下面这个示例在构造VectorSource
时,指定了 fileUrl
属性,因此在构造之后,数据将渲染至图形中。
<script type="module">
import { Graph, VectorSource, Layer, debug } from "../../../src/index.js";
// graph对象
let graph = new Graph({
"target": "graphWrapper",
"layers": [
new Layer({
"source": new VectorSource({
"fileUrl": "../../../data/geom.json"
})
})
]
});
// 图形渲染
graph.render();
</script>
属性
名称 | 说明 |
---|---|
dataBuffer | 矢量数据集合 |
imageBuffer | 图像数据集合 |
quadTree | 空间索引对象 |
format | 格式化对象 |
这几个属性中 dataBuffer
、imageBuffer
、quadTree
均属于内部对象。
\quad
format
对象是 FeatureFormat
类的实例,该对象可将外部矢量数据解析为 anyGraph
所使用的内部数据格式, 缺省值为GeometryFormat
。可在构造VectorDataSource
实例时指定 format
属性,或是通过 setFormat(format)
指定 format
属性。
方法
名称 | 说明 |
---|---|
add(geom) | 增加Geomtory对象至数据源中 |
loadFile(fileUrl, success, failure) | 从文件中读取矢量数据 |
loadData(features) | 装载Geomtory数据至数据源中 |
clearData(id) | 清除指定ID数据,如果ID为空则清除数据源中所有数据 |
buildIndex() | 构建四叉树索引 |
getExtentData(extent) | 获取指定范围内的数据 |
getBBox() | 获取数据源中的最大空间范围 |
add2Cache(filePath, imageUid) | 将图片数据加至缓存中 |
getImageFromCache(src) | 从缓存中获取Image对象 |
loadImage(src, callback, callback) | 加载Image对象 |
toData(options = {}) | 以矢量数据格式返回当前数据源中的数据 |
\quad 下面介绍几个常用的方法:
loadFile()
\quad
该方法下载数据文件通过format
对象解析后,加载至 Source
中。
loadFile(fileUrl, success, failure)
\quad
下面这个示例,将从Url中下载数据文件,通过缺省的format
对象解析后装载至VectorSource
中,并进行图形渲染。
<script type="module">
import { Graph, VectorSource, Layer, debug } from "../../../src/index.js";
// 初始化graph对象
let graph = new Graph({
"target": "graphWrapper",
});
// 增加数据层
let layer = graph.addLayer({"name":"数据层"});
layer.getSource().loadFile("../../../data/geom.json");
// 图形渲染
graph.render();
</script>
\quad
该方法从文件中读取矢量数据,该方法通过XMLHttpRequest
从指定的fileUrl
中下载文件,并通过format
对象解析文件中的图形对象。
loadData()
\quad
该方法将矢量数据通过format
对象解析后,加载至 Source
中。
loadData(features)
\quad
下面这个示例,将数据通过缺省的format
对象解析后装载至VectorSource
中,并进行图形渲染。
<script type="module">
import { Graph, Layer, VectorSource, debug, DomUtil } from "../../../src/index.js";
// 初始化graph对象
let graph = new Graph({
"target": "graphWrapper"
});
// 增加数据层
let layer = graph.addLayer({"name":"数据层"});
layer.getSource().loadData([
{ "type": "Polygon", "coords": [[1, 1], [161, 1], [81, 81]], "style": { "fillStyle": 1, "fillColor": "#caff67" } },
{ "type": "Polygon", "coords": [[1, 2], [81, 82], [1, 162]], "style": { "fillStyle": 1, "fillColor": "#67becf" } },
{ "type": "Polygon", "coords": [[162, 1], [162, 81], [122, 121], [122, 41]], "style": { "fillStyle": 1, "fillColor": "#ef3d61" } },
{ "type": "Polygon", "coords": [[121, 42], [121, 122], [81, 82]], "style": { "fillStyle": 1, "fillColor": "#f9f51a" } },
{ "type": "Polygon", "coords": [[82, 82], [122, 122], [82, 162], [42, 122]], "style": { "fillStyle": 1, "fillColor": "#a54c09" } },
{ "type": "Polygon", "coords": [[42, 122], [82, 162], [2, 162]], "style": { "fillStyle": 1, "fillColor": "#fa8ccc" } },
{ "type": "Polygon", "coords": [[162, 82], [162, 162], [82, 162]], "style": { "fillStyle": 1, "fillColor": "#f6ca29" } }
]);
// 图形渲染
graph.render();
</script>
add()
add(geom)
\quad
该方法将一个或多个Geometry
的对象加入数据源中。
buildIndex()
buildIndex()
\quad 该方法将建立空间索引。建立空间索引可以提高检测视点范围内数据的效率,排除视点外的数据,缩短图形的渲染时间,特别适合大数据量的情况。在loadFile()中会自动调用该方法建立空间索引。
toData()
toData(options = {})
\quad
该方法将返回当前数据源中Geometry
对象JSON格式数据,可用于数据持久化。
数据格式
\quad
矢量数据源 VectorDataSource
在装载数据的时候,可以根据 Format
对象装载不同格式的数据,anyGraph1.0可支持的格式包括:
- Geometry对象格式,其Format数据类为
GeometryFormat
类,这也是VectorDataSource
的缺省数据格式。 - GeoJSON格式,一种很常用的地理空间数据交换格式,其Format数据类为
GeoJSONFormat
类。 - SVG格式,可缩放矢量图形(Scalable Vector Graphics)是一种基于XML的矢量图像格式,其Format数据类为
SvgFormat
类。 - CIMG(CIM/G)格式,是国家电网公司发布一种基于CIM的图形交换格式,其Format数据类为
CimgFormat
类。 - AXFG格式,是一种很经典的基于json的图形交换格式,其Format数据类为
AxfgFormat
类。
下面的示例将装载和显示一个SVG格式文件,其源代码如下:
<!DOCTYPE html>
<html>
<head>
<title>SVG</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<script type="module">
import { Graph, VectorSource, Layer, SvgFormat, debug } from "../../src/index.js";
// 数据源
let fileUrl = "../../data/flower.svg";
// graph对象
let graph = new Graph({
"target": "graphWrapper",
"layers": [
new Layer({
"source": new VectorSource({
"dataType": "xml",
"fileUrl": fileUrl,
"format": new SvgFormat()
})
})
]
});
// 显示辅助网格
debug.generateGrid(Object.assign({ "interval": 10, "graph": graph }, graph.getSize()));
</script>
</head>
<body style="overflow: hidden; margin:0px;" oncontextmenu="return false;">
<div id="graphWrapper" style="position:absolute; width:100%; height:100%; border:solid 0px #CCC;"></div>
</body>
</html>
该代码运行后将在浏览器中全屏显示一幅SVG图形,其运行效果如下图:
(2) 图像数据源
略
(3) 瓦片数据源
略
4 图层渲染
图层渲染负责将数据集合中的图形对象渲染至画板Canvas中,图层类 Layer
提供了getRenderer()
方法可获取该图层对应的图层渲染器对象。
名称 | 说明 |
---|---|
getRenderer() | 获取取图层渲染器 |
(1) 矢量数据图层渲染
类名为:VectorRenderer
,位于src/renderer
目录。
\quad
矢量数据图层渲染类负责将图层中 VectorSource
数据渲染至图层的Canvas画布中。
\quad
该类中最重要的属性是 _canvas
,这是一个Canvas对象,是该图层的临时画布,图层中的数据先由 composeBuffer()
方法合成至该临时画布中,然后在合并至图形主画布中。
\quad
该类中最重要的方法是 composeBuffer(frameState)
,该方法由 GraphRenderer
负责调用,将数据合成至Canvas画布,其主要分为三个步骤。
-
根据
frameState
参数中的extent
属性(当前显示范围)从DataSource
查询Geometry对象
数据,如果DataSource
建立了空间索引,该步骤将极大提高数据检索效率; -
对这些
Geometry对象
数据进行坐标变换,将图形坐标转换为Canvas画布中的像素坐标; -
逐个将这些
Geometry对象
数据绘制至Canvas画布中。
\quad
步骤二中的将 Geometry对象
的图形坐标转换为像素坐标功能,由于不同类型的 Geometry对象
其空间属性不相同,因此其转换方法不相同;步骤三中逐个将 Geometry对象
绘制至Canvas画布中也因为不同类型的 Geometry对象
其绘制方法不相同。因此我们根据Geometry
对象类型设计了针对其类型的 Geometry
子类,这些子类均从 Geometry
继承, 在各个子类中实现了将图形坐标转换为像素坐标的 toPixel()
方法和图形绘制 draw()
方法,关于这部分的详细介绍我们将在下一章 “图形基本形状” 中进行讲解。
(2) 图像数据图层渲染
略
(3) 瓦片数据图层渲染
略
\quad “图形系统实战开发-进阶篇 第三章 图层” 的内容讲解到这里就结束了,如果觉得对你有帮助有收获,可以关注我们的官方账号,持续关注更多精彩内容。
相关资料
▶ 系列教程及代码资料:https://GraphAnyWhere.com
▶ 图形系统开发实战课程:进阶篇(上)——前言
▶ 图形系统开发实战课程:进阶篇(上)——1.基础知识
▶ 图形系统开发实战课程:进阶篇(上)——2.图形管理类(Graph)
作者信息
作者 : 图形开发学院
CSDN: https://blog.csdn.net/2301_81340430?type=blog
官网:https://graphanywhere.com