作为一个刚开始学习 mapvthree 的小白,今天要学习数据源系统了!听说这个系统可以把各种格式的数据加载到地图上,还能让数据可视化!想想就实用!
第一次听说数据源系统
今天在文档里看到了"数据源"这个词,一开始我还以为是数据库,结果查了一下才知道,原来这是用来存储和加载地理数据的系统!
文档说数据源系统可以:
- 存储带坐标信息的数据
- 支持多种数据格式(GeoJSON、JSON、CSV)
- 与可视化组件配合使用
- 动态添加、删除、修改数据
我的理解:简单说就是"数据仓库",把地理数据存起来,然后给可视化组件用!
第一步:理解数据源的基本概念
作为一个初学者,我习惯先理解基本概念。文档说 DataSource 是数据源类,用于存储一组带坐标信息的数据。
我的发现:数据源通常与可视化组件配合使用:
js
// 创建可视化组件
const point = engine.add(new mapvthree.SimplePoint());
// 创建数据源
const dataSource = new mapvthree.DataSource();
// 将数据源赋值给可视化组件
point.dataSource = dataSource;
我的理解:数据源存储数据,可视化组件负责渲染,两者配合才能显示数据!
DataItem:数据的最小单元
文档说 DataItem 是数据的最小单元,用于存储单条数据的信息。
js
// 创建一个点数据
const dataItem = new mapvthree.DataItem([116.404, 39.915, 10]);
// 添加到数据源
dataSource.add(dataItem);
我的理解:
DataItem是单条数据DataSource是数据集合- 一个数据源可以包含多个
DataItem
第二步:使用 GeoJSON 数据源
看到基本概念后,我想:怎么加载实际的数据?
文档说可以用 GeoJSONDataSource 来加载 GeoJSON 格式的数据!
js
import * as mapvthree from '@baidumap/mapv-three';
const container = document.getElementById('container');
const engine = new mapvthree.Engine(container, {
map: {
center: [116.404, 39.915],
range: 2000,
},
});
// 创建点图层
const point = engine.add(new mapvthree.SimplePoint({
size: 15,
}));
// 从 URL 加载 GeoJSON 数据
const dataSource = await mapvthree.GeoJSONDataSource.fromURL('data/geojson/points.geojson');
point.dataSource = dataSource;
我的发现 :fromURL 是异步方法,需要用 await 等待数据加载完成!
我的理解:
fromURL:从 URL 加载数据fromGeoJSON:直接传入 GeoJSON 对象
我的尝试:
js
// 方式 1:从 URL 加载
const dataSource1 = await mapvthree.GeoJSONDataSource.fromURL('data/geojson/points.geojson');
// 方式 2:直接传入 GeoJSON 对象
const geojson = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [116.404, 39.915],
},
properties: {},
},
],
};
const dataSource2 = mapvthree.GeoJSONDataSource.fromGeoJSON(geojson);
我的发现:两种方式都可以,根据数据来源选择合适的方式!
第三步:使用 JSON 数据源
看到 GeoJSON 后,我想:如果数据是 JSON 格式怎么办?
文档说可以用 JSONDataSource 来加载 JSON 格式的数据!
js
// 从 URL 加载 JSON 数据
const dataSource = await mapvthree.JSONDataSource.fromURL('data/json/points.json');
point.dataSource = dataSource;
我的理解:JSON 数据源需要满足特定格式:
- 有坐标字段(默认是
coordinates,可通过coordinatesKey指定) - 坐标数据满足 WKT 格式要求
我的尝试:
js
// JSON 数据格式示例
const jsonData = [{
coordinates: 'POINT(116.404 39.915)',
name: '北京',
}, {
coordinates: 'POINT(121.473 31.230)',
name: '上海',
}];
const dataSource = mapvthree.JSONDataSource.fromJSON(jsonData);
point.dataSource = dataSource;
我的发现:JSON 数据源支持 WKT 格式的坐标!
自定义坐标解析
如果坐标不是 WKT 格式,可以自定义解析函数:
js
const dataSource = mapvthree.JSONDataSource.fromJSON([{
position: [116.404, 39.915],
color: 0xff0000,
}, {
position: '121.473, 31.230',
color: 0x00ff00,
}], {
coordinatesKey: 'position', // 指定坐标字段
parseCoordinates: function({position}) {
// 自定义解析函数
if (Array.isArray(position)) {
return position;
} else {
return position.split(',').map(v => parseFloat(v));
}
},
});
我的发现:可以自定义解析函数,处理各种格式的坐标数据!
第四步:使用 CSV 数据源
看到 JSON 后,我想:如果数据是 CSV 格式怎么办?
文档说可以用 CSVDataSource 来加载 CSV 格式的数据!
js
// 从 URL 加载 CSV 数据
const dataSource = await mapvthree.CSVDataSource.fromURL('data/csv/points.csv');
point.dataSource = dataSource;
我的理解:CSV 数据源也需要满足特定格式:
- 有坐标列(默认是
coordinates,可通过coordinatesKey指定) - 坐标数据满足 WKT 格式要求
我的发现:CSV 数据源和 JSON 数据源的格式要求类似,都支持 WKT 格式!
第五步:定义数据属性
看到可以加载数据后,我想:能不能根据数据的不同属性显示不同的样式?
文档说可以用 defineAttribute 来定义数据属性!
js
// 加载数据
const dataSource = await mapvthree.GeoJSONDataSource.fromURL('data/geojson/points.geojson');
// 定义颜色属性
dataSource.defineAttribute('color', 'color');
// 定义大小属性
dataSource.defineAttribute('size', 'size');
我的理解 :defineAttribute 可以将数据中的字段映射到可视化属性!
我的尝试:
js
// 创建支持颜色和大小的点图层
const point = engine.add(new mapvthree.SimplePoint({
vertexColors: true, // 开启颜色属性
vertexSizes: true, // 开启大小属性
}));
// 加载数据并定义属性
const dataSource = await mapvthree.GeoJSONDataSource.fromURL('data/geojson/points.geojson');
dataSource.defineAttribute('color', 'color');
dataSource.defineAttribute('size', 'size');
point.dataSource = dataSource;
我的发现 :需要在可视化组件中开启对应的属性标志(如 vertexColors),才能使用数据属性!
使用回调函数定义属性
文档说可以用回调函数来动态计算属性值:
js
// 使用回调函数定义颜色
dataSource.defineAttribute('color', properties => {
// 根据数据动态计算颜色
return properties.count > 100 ? 0xff0000 : 0x00ff00;
});
// 使用回调函数定义大小
dataSource.defineAttribute('size', properties => {
return properties.count * 2;
});
我的发现:回调函数可以灵活地根据数据计算属性值!
第六步:动态修改数据
看到可以加载数据后,我想:能不能动态添加、删除、修改数据?
文档说数据源提供了 add、remove、setData 等方法来修改数据!
js
// 添加数据
const newItem = new mapvthree.DataItem([116.404, 39.915]);
dataSource.add(newItem);
// 删除数据
dataSource.remove(itemId);
// 更新整个数据源
dataSource.setData(newGeoJSONData);
// 修改单个数据的属性
dataSource.setAttributeValues(itemId, {
color: 0xff0000,
size: 20,
});
// 修改单个数据的坐标
dataSource.setCoordinates(itemId, [116.414, 39.925]);
我的发现:可以动态地添加、删除、修改数据,非常灵活!
我的尝试:
js
// 点击地图添加点
engine.map.addEventListener('click', e => {
if (!e.target) {
const newItem = new mapvthree.DataItem(e.point);
dataSource.add(newItem);
}
});
// 点击点删除
point.addEventListener('rightclick', e => {
dataSource.remove(e.entity.value.id);
});
// 点击点修改颜色
point.addEventListener('click', e => {
dataSource.setAttributeValues(e.entity.value.id, {
color: 0xffffff * Math.random(),
});
});
我的发现:结合事件系统,可以实现交互式的数据编辑!
第七步:创建自定义数据源
看到可以加载各种格式的数据后,我想:能不能手动创建数据源?
文档说可以直接使用 DataSource 构造函数创建数据源!
js
// 创建数据源
const dataSource = new mapvthree.DataSource({
attributes: {
color: p => p.color || 0xffff00,
size: p => p.size || 10,
},
});
// 创建数据项
const item1 = new mapvthree.DataItem([116.404, 39.915], {
color: 0xff0000,
size: 20,
});
const item2 = new mapvthree.DataItem([121.473, 31.230], {
color: 0x00ff00,
size: 15,
});
// 添加数据项
dataSource.add(item1);
dataSource.add(item2);
// 绑定到可视化组件
point.dataSource = dataSource;
我的发现:可以手动创建数据源和数据项,适合动态生成数据的场景!
创建不同类型的几何数据
文档说 DataItem 可以表示不同类型的几何图形:
js
// 点数据
const pointItem = new mapvthree.DataItem([116.404, 39.915]);
// 线数据
const lineItem = new mapvthree.DataItem({
geometry: {
type: 'LineString',
coordinates: [[116.404, 39.915], [121.473, 31.230]],
},
});
// 面数据
const polygonItem = new mapvthree.DataItem({
geometry: {
type: 'Polygon',
coordinates: [[[116.404, 39.915], [116.414, 39.915], [116.414, 39.925], [116.404, 39.925], [116.404, 39.915]]],
},
});
我的发现:可以创建点、线、面等不同类型的几何数据!
第八步:设置数据投影
看到可以创建数据后,我想:如果数据的坐标系统不同怎么办?
文档说可以通过 crs 属性来设置数据的投影信息!
js
// 创建使用投影坐标的数据项
const item = new mapvthree.DataItem({
geometry: {
type: 'Point',
coordinates: [12960000, 4850000, 0], // 投影坐标
},
}, {
crs: 'EPSG:3857', // 指定投影
});
我的理解:引擎会自动将数据从源投影转换到目标投影!
我的发现:这样就能处理不同坐标系统的数据了!
第九步:完整示例
我想写一个完整的示例,把学到的都用上:
js
import * as mapvthree from '@baidumap/mapv-three';
const container = document.getElementById('container');
const engine = new mapvthree.Engine(container, {
map: {
center: [116.404, 39.915],
range: 2000,
},
rendering: {
enableAnimationLoop: true,
},
});
// 创建支持颜色和大小的点图层
const point = engine.add(new mapvthree.SimplePoint({
size: 15,
vertexColors: true,
vertexSizes: true,
}));
// 从 URL 加载 GeoJSON 数据
const dataSource = await mapvthree.GeoJSONDataSource.fromURL('data/geojson/points.geojson');
// 定义属性
dataSource.defineAttribute('color', properties => {
return properties.count > 100 ? 0xff0000 : 0x00ff00;
});
dataSource.defineAttribute('size', properties => {
return properties.count * 2;
});
// 绑定数据源
point.dataSource = dataSource;
// 点击地图添加点
engine.map.addEventListener('click', e => {
if (!e.target) {
const newItem = new mapvthree.DataItem(e.point, {
count: Math.random() * 200,
});
dataSource.add(newItem);
}
});
// 点击点修改颜色
point.addEventListener('click', e => {
dataSource.setAttributeValues(e.entity.value.id, {
count: Math.random() * 200,
});
});
我的感受:写一个完整的示例,把学到的都用上,感觉很有成就感!
第十步:踩过的坑
作为一个初学者,我踩了不少坑,记录下来避免再犯:
坑 1:数据源不显示
原因:数据源加载是异步的,在数据加载完成前就绑定了。
解决 :确保使用 await 等待数据加载完成后再绑定。
坑 2:属性不生效
原因:没有在可视化组件中开启对应的属性标志。
解决 :需要在组件中开启对应的属性标志,如 vertexColors、vertexSizes。
坑 3:坐标格式错误
原因:坐标格式不符合要求,或者坐标字段名不对。
解决:
- 确保坐标格式正确(WKT 格式或数组格式)
- 使用
coordinatesKey指定坐标字段名
坑 4:JSON/CSV 数据解析失败
原因:坐标数据不是 WKT 格式,且没有自定义解析函数。
解决 :使用 parseCoordinates 自定义解析函数。
坑 5:数据更新不生效
原因:使用了错误的方法更新数据。
解决:
- 更新整个数据源:使用
setData - 添加/删除数据:使用
add/remove - 修改属性:使用
setAttributeValues - 修改坐标:使用
setCoordinates
我的学习总结
经过这一天的学习,我掌握了:
- 数据源的作用:存储带坐标信息的数据,与可视化组件配合使用
- DataItem:数据的最小单元,可以表示点、线、面等几何图形
- GeoJSON 数据源 :最常用的数据格式,支持
fromURL和fromGeoJSON - JSON 数据源:支持 WKT 格式坐标,可以自定义解析函数
- CSV 数据源:支持 WKT 格式坐标,格式要求与 JSON 类似
- 定义属性 :通过
defineAttribute将数据字段映射到可视化属性 - 动态修改 :通过
add、remove、setData等方法动态修改数据 - 数据投影 :通过
crs属性设置数据投影,引擎自动转换
我的感受:数据源系统真的很强大!虽然功能很多,但是用起来其实不难。关键是要理解数据源和可视化组件的关系,然后根据数据格式选择合适的加载方式!
下一步计划:
- 学习更多数据源的配置选项
- 尝试处理复杂的数据格式
- 做一个完整的数据可视化项目
学习笔记就到这里啦!作为一个初学者,我觉得数据源系统虽然功能很多,但是用起来其实不难。关键是要理解数据源和可视化组件的关系,然后根据数据格式选择合适的加载方式!希望我的笔记能帮到其他初学者!大家一起加油!