| title | Source |
|---|---|
| order | 0 |
source 地理数据处理模块,主要包含数据解析(parser)和数据处理(transforms)。
const source = new Source(data, option);- data
- option
- cluster boolean 是否聚合
- clusterOptions 聚合配置项
- parser 数据解析配置
- transforms 数据处理配置
本次渐进式重构(阶段 0–6)保证对外 API 完全向后兼容,旧写法无需改动即可继续工作:
new Source(data, cfg)与new Source(data)写法保持不变(cfg与registry均可选)。cluster: true配置静默走新ClusterManager直调路径,无任何 warning。ISourceCFG旧字段(cluster/clusterOptions/parser/transforms/autoRender)全部保留。- 事件
'update' { type: 'inited' | 'update' }行为不变;新增'error'事件仅用于显式 surfacing 失败(无监听即静默)。
新增的 Source.create / createSource / source.ready / source.stats() / source.dataVersion 为可选的更优路径,旧代码可按需逐步迁移,非强制。
transforms配置项中{ type: 'cluster' }已弃用(运行时会 warn 一次,但仍可工作)。聚合请改用顶层cluster: true配置项,详见下方 cluster。
不同 parser 类型对应不同 data 类型
- 瓦片图层 data 为 url 模板,支持 TMS、WMS、WMTS 数据服务
- 非瓦片图层 data 为数据对象
source 通过 option 来描述或处理数据, 其中主要包括 parser 和 transforms。
parser 可以将不同类型的空间数据处理成统一数据格式。空间数据分为矢量数据、栅格数据和瓦片服务三大类:
type IParserType =
| 'csv'
| 'json'
| 'geojson'
| 'image'
| 'raster'
| 'rasterTile'
| 'mvt'
| 'geojsonvt';
interface IParser {
type: IParserType;
x?: string;
y?: string;
x1?: string;
y1?: string;
coordinates?: string;
geometry?: string;
[key: string]: any;
}geojson 为默认数据格式,可以不设置 parser 参数
layer.source(data);transforms 处理的是标准化后的数据,可进行数据转换、数据统计、网格布局、数据聚合等数据操作,处理完后返回的也是标准数据。标准化后的数据结构包括 coordinates 地理坐标字段,以及其他属性字段。
[
{
"coordinates": [[]], // 地理坐标字段
"_id": "122", // 标准化之后新增字段
"name": "test",
"value": 1
// ....
}
]目前 grid、hexagon 两种热力图支持使用数据处理方法 transforms 配置项
- type 数据处理类型
- transforms cfg 数据处理配置项
生成方格网布局,根据数据字段统计,主要在网格热力图中使用
- type: 'grid'
- size: 网格半径
- field: 数据统计字段
- method: 聚合方法,有 count、max、min、sum、mean 5 个统计维度
layer.source(data, {
transforms: [
{
type: 'grid',
size: 15000,
field: 'v',
method: 'sum',
},
],
});生成六边形网格布局,根据数据字段统计
- type: 'hexagon'
- size: 网格半径
- field: 数据统计字段
- method: 聚合方法,有 count、max、min、sum、mean 5 个统计维度
数据连接,业务中跟多情况是地理数据和业务数据分开的两套数据,我们可与通过 join 方法将地理数据和业务数据进行关联。
配置项
- type: join
- sourceField: 需要连接的业务数据字段名称
- data: 需要连接的数据源,仅支持 json 格式
- targetField: 关联的地理数据字段名称
// geoData 是地理数据
const geoData = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
properties: {
city: '北京',
},
geometry: {},
},
],
};
// customData 属性数据或者业务数据
const customData = [
{
name: '北京',
value: 13,
},
{
name: '天津',
value: 20,
},
];
// 通过 join 方法我们就可以将两个数据连接到一起
layer
.source(geoData, {
transforms: [
{
type: 'join',
sourceField: 'name', //customData 对应字段名
targetField: 'city', // geoData 对应字段名,绑定到的地理数据
data: customData,
},
],
})
.color('value'); // 可以采用 customData 的 value 字段进行数据到颜色的映射对数据进行映射转换,可对每一个数据元素进行处理并返回新的数据元素。
配置项
- type: 'map'
- callback:
(feature: any) => any对每条数据进行处理的回调函数
layer.source(data, {
transforms: [
{
type: 'map',
callback: (feature) => {
feature.value = feature.value * 2;
return feature;
},
},
],
});对数据进行过滤,仅保留满足条件的数据元素。
配置项
- type: 'filter'
- callback:
(feature: any) => boolean过滤条件回调函数,返回true时保留该条数据
layer.source(data, {
transforms: [
{
type: 'filter',
callback: (feature) => {
return feature.value > 10; // 仅保留 value 大于 10 的数据
},
},
],
});- cluster:
boolean
cluster 表示是否对数据进行聚合操作, 目前只有点图层支持。
推荐使用
cluster: true顶层配置项开启聚合。transforms: [{ type: 'cluster' }]已弃用(会破坏source.data语义并 warn),仅为向后兼容保留。
- radius: 聚合半径 number default 40
- minZoom: 最小聚合缩放等级 number default 0
- maxZoom: 最大聚合缩放等级 number default 16
更新 source 数据,会触发图层重新渲染。
data数据,同 source 初始化参数options配置项,同 source 初始化参数
const source = new Source(data, { parser: { type: 'json', x: 'lng', y: 'lat' } });
// 更新数据
source.setData(newData);根据 featureID 获取 feature 要素。
idfeatureId,L7 内部编码的唯一要素 ID
const source = layer.getSource();
const feature = source.getFeatureById(1);根据属性的 key、value 获取要素 L7 编码 featureId,确保该属性的 value 是唯一值,如存在多个返回第一个。
field属性字段value对应的值
const source = layer.getSource();
const featureId = source.getFeatureId('name', '张三');根据 ID 更新 source 的属性数据,会触发重新渲染。
idfeatureId,L7 内部编码的唯一要素 IDproperties需要更新属性数据,进行 merge 操作
const source = layer.getSource();
layer.on('click', (e) => {
source.updateFeaturePropertiesById(e.featureId, {
name: Math.random() * 10,
});
});聚合图使用,获取指定缩放等级下的聚合数据。
zoom缩放等级
const clusters = source.getClusters(scene.getZoom());聚合图使用,获取聚合节点的原始数据。
id聚合节点的 cluster_id
layer.on('click', (e) => {
console.log(source.getClustersLeaves(e.feature.cluster_id));
});更新聚合数据,在地图缩放后需要调用以刷新聚合结果。
zoom当前缩放等级
scene.on('zoomchange', () => {
source.updateClusterData(scene.getZoom());
});获取 source 的初始化配置项。
const cfg = source.getSourceCfg();获取当前 source 使用的数据解析器类型。
const parserType = source.getParserType(); // 如 'geojson', 'json', 'csv', 'mvt' 等销毁 source,释放相关资源。
source.destroy();Source.create 是异步工厂方法,内部 await source 初始化(parse + cluster 初始化 + transforms)完成后返回。相比 new Source(data, cfg) 的 fire-and-forget 初始化,create 返回的实例 data 已就绪,可直接读取,消除 source.data 可能为 undefined 的竞态。
data数据,同 source 初始化参数cfg配置项,同 source 初始化参数- 返回
Promise<Source>
const source = await Source.create(data, { parser: { type: 'json', x: 'lng', y: 'lat' } });
// 此时 source.data 已解析完成,无 undefined 竞态createSource 与 new Source 行为等价的同步工厂函数,返回 source 实例(初始化仍为 fire-and-forget)。第三个可选参数 registry 可注入自定义 ParserRegistry 实例,按需子集注册 parser / transform 或做测试隔离。
data数据,同 source 初始化参数cfg配置项,同 source 初始化参数registry(可选)自定义 parser / transform 注册表,默认使用内置defaultRegistry
import { createSource } from '@antv/l7-source';
const source = createSource(data, { parser: { type: 'geojson' } });source.ready 是一个 Promise<void>,resolve 时 source 初始化完成(inited === true 且数据已解析)。可在消费侧 await source.ready 消除 source.data 竞态。
const source = new Source(data);
await source.ready;
// source.data 已就绪返回 source 当前数据的只读快照,便于调试与大小监控。不影响 source 内部状态。
返回 ISourceStats 对象:
rows: number已解析数据行数(data.dataArray.length)bbox: BBox数据范围[minLng, minLat, maxLng, maxLat]parserType: string当前解析器类型(如'geojson'、'mvt')tileCount: number已加载瓦片数(非瓦片源或未触发视口更新时为0)isTile: boolean是否为瓦片数据源cluster: boolean是否开启聚合dataVersion: number数据 generation(见下)
const stats = source.stats();
console.log(stats.rows, stats.parserType, stats.tileCount);dataVersion 是单调递增的数据 generation 计数器,每次「数据可能变化」的操作 +1:
setData(全量数据替换)后+1updateFeaturePropertiesById(原地属性变更)后+1updateClusterData(zoom 驱动的聚合视图重算,原始数据未变)不 bump- 构造期首次解析为 generation
0
可用于判断数据是否已变化、避免重复处理。
const v1 = source.dataVersion;
source.setData(newData);
const v2 = source.dataVersion; // v2 === v1 + 1如果数据发生改变,可以需要更新数据。
可以通过调用 layer 的 setData 方法实现数据的更新。
具体见 Layer
layer.setData(data);栅格数据类型
Source 继承自 EventEmitter,支持 on/off/once/emit 等事件方法。
数据更新事件,在以下情况触发:
- source 初始化完成后(
type: 'inited') - 调用
setData或updateFeaturePropertiesById后(type: 'update')
const source = layer.getSource();
source.on('update', (e) => {
if (e.type === 'inited') {
console.log('source 初始化完成');
} else if (e.type === 'update') {
console.log('source 数据已更新');
}
});数据初始化或更新失败事件。当 setData 触发的 re-parse / cluster 初始化 / transform 执行失败时触发,payload 为错误对象。使用 setData 时建议监听 error 事件以感知失败(旧版本失败会静默 hang,现为显式 surfacing)。
const source = layer.getSource();
source.on('error', (err) => {
console.error('source 数据更新失败', err);
});
source.setData(newData);注:
new Source(data, cfg)构造期 init 失败仍为 fire-and-forget(未捕获 rejection,保留旧行为)。若需感知构造期失败,使用await Source.create(...)或await source.ready(失败时 reject)。