写点什么

JSAPIThree 数据源系统学习笔记:让数据在地图上可视化

作者:map_3d_vis
  • 2025-12-02
    北京
  • 本文字数:5632 字

    阅读完需:约 18 分钟

作为一个刚开始学习 mapvthree 的小白,今天要学习数据源系统了!听说这个系统可以把各种格式的数据加载到地图上,还能让数据可视化!想想就实用!

第一次听说数据源系统

今天在文档里看到了"数据源"这个词,一开始我还以为是数据库,结果查了一下才知道,原来这是用来存储和加载地理数据的系统!


文档说数据源系统可以:


  • 存储带坐标信息的数据

  • 支持多种数据格式(GeoJSON、JSON、CSV)

  • 与可视化组件配合使用

  • 动态添加、删除、修改数据


我的理解:简单说就是"数据仓库",把地理数据存起来,然后给可视化组件用!

第一步:理解数据源的基本概念

作为一个初学者,我习惯先理解基本概念。文档说 DataSource 是数据源类,用于存储一组带坐标信息的数据。


我的发现:数据源通常与可视化组件配合使用:


// 创建可视化组件const point = engine.add(new mapvthree.SimplePoint());
// 创建数据源const dataSource = new mapvthree.DataSource();
// 将数据源赋值给可视化组件point.dataSource = dataSource;
复制代码


我的理解:数据源存储数据,可视化组件负责渲染,两者配合才能显示数据!

DataItem:数据的最小单元

文档说 DataItem 是数据的最小单元,用于存储单条数据的信息。


// 创建一个点数据const dataItem = new mapvthree.DataItem([116.404, 39.915, 10]);
// 添加到数据源dataSource.add(dataItem);
复制代码


我的理解


  • DataItem 是单条数据

  • DataSource 是数据集合

  • 一个数据源可以包含多个 DataItem

第二步:使用 GeoJSON 数据源

看到基本概念后,我想:怎么加载实际的数据?


文档说可以用 GeoJSONDataSource 来加载 GeoJSON 格式的数据!


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 对象


我的尝试


// 方式 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 格式的数据!


// 从 URL 加载 JSON 数据const dataSource = await mapvthree.JSONDataSource.fromURL('data/json/points.json');point.dataSource = dataSource;
复制代码


我的理解:JSON 数据源需要满足特定格式:


  1. 有坐标字段(默认是 coordinates,可通过 coordinatesKey 指定)

  2. 坐标数据满足 WKT 格式要求


我的尝试


// 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 格式,可以自定义解析函数:


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 格式的数据!


// 从 URL 加载 CSV 数据const dataSource = await mapvthree.CSVDataSource.fromURL('data/csv/points.csv');point.dataSource = dataSource;
复制代码


我的理解:CSV 数据源也需要满足特定格式:


  1. 有坐标列(默认是 coordinates,可通过 coordinatesKey 指定)

  2. 坐标数据满足 WKT 格式要求


我的发现:CSV 数据源和 JSON 数据源的格式要求类似,都支持 WKT 格式!

第五步:定义数据属性

看到可以加载数据后,我想:能不能根据数据的不同属性显示不同的样式?


文档说可以用 defineAttribute 来定义数据属性!


// 加载数据const dataSource = await mapvthree.GeoJSONDataSource.fromURL('data/geojson/points.geojson');
// 定义颜色属性dataSource.defineAttribute('color', 'color');
// 定义大小属性dataSource.defineAttribute('size', 'size');
复制代码


我的理解defineAttribute 可以将数据中的字段映射到可视化属性!


我的尝试


// 创建支持颜色和大小的点图层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),才能使用数据属性!

使用回调函数定义属性

文档说可以用回调函数来动态计算属性值:


// 使用回调函数定义颜色dataSource.defineAttribute('color', properties => {    // 根据数据动态计算颜色    return properties.count > 100 ? 0xff0000 : 0x00ff00;});
// 使用回调函数定义大小dataSource.defineAttribute('size', properties => { return properties.count * 2;});
复制代码


我的发现:回调函数可以灵活地根据数据计算属性值!

第六步:动态修改数据

看到可以加载数据后,我想:能不能动态添加、删除、修改数据?


文档说数据源提供了 addremovesetData 等方法来修改数据!


// 添加数据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]);
复制代码


我的发现:可以动态地添加、删除、修改数据,非常灵活!


我的尝试


// 点击地图添加点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 构造函数创建数据源!


// 创建数据源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 可以表示不同类型的几何图形:


// 点数据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 属性来设置数据的投影信息!


// 创建使用投影坐标的数据项const item = new mapvthree.DataItem({    geometry: {        type: 'Point',        coordinates: [12960000, 4850000, 0], // 投影坐标    },}, {    crs: 'EPSG:3857', // 指定投影});
复制代码


我的理解:引擎会自动将数据从源投影转换到目标投影!


我的发现:这样就能处理不同坐标系统的数据了!

第九步:完整示例

我想写一个完整的示例,把学到的都用上:


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:属性不生效

原因:没有在可视化组件中开启对应的属性标志。


解决:需要在组件中开启对应的属性标志,如 vertexColorsvertexSizes

坑 3:坐标格式错误

原因:坐标格式不符合要求,或者坐标字段名不对。


解决


  1. 确保坐标格式正确(WKT 格式或数组格式)

  2. 使用 coordinatesKey 指定坐标字段名

坑 4:JSON/CSV 数据解析失败

原因:坐标数据不是 WKT 格式,且没有自定义解析函数。


解决:使用 parseCoordinates 自定义解析函数。

坑 5:数据更新不生效

原因:使用了错误的方法更新数据。


解决


  • 更新整个数据源:使用 setData

  • 添加/删除数据:使用 add/remove

  • 修改属性:使用 setAttributeValues

  • 修改坐标:使用 setCoordinates

我的学习总结

经过这一天的学习,我掌握了:


  1. 数据源的作用:存储带坐标信息的数据,与可视化组件配合使用

  2. DataItem:数据的最小单元,可以表示点、线、面等几何图形

  3. GeoJSON 数据源:最常用的数据格式,支持 fromURLfromGeoJSON

  4. JSON 数据源:支持 WKT 格式坐标,可以自定义解析函数

  5. CSV 数据源:支持 WKT 格式坐标,格式要求与 JSON 类似

  6. 定义属性:通过 defineAttribute 将数据字段映射到可视化属性

  7. 动态修改:通过 addremovesetData 等方法动态修改数据

  8. 数据投影:通过 crs 属性设置数据投影,引擎自动转换


我的感受:数据源系统真的很强大!虽然功能很多,但是用起来其实不难。关键是要理解数据源和可视化组件的关系,然后根据数据格式选择合适的加载方式!


下一步计划


  1. 学习更多数据源的配置选项

  2. 尝试处理复杂的数据格式

  3. 做一个完整的数据可视化项目




学习笔记就到这里啦!作为一个初学者,我觉得数据源系统虽然功能很多,但是用起来其实不难。关键是要理解数据源和可视化组件的关系,然后根据数据格式选择合适的加载方式!希望我的笔记能帮到其他初学者!大家一起加油!

用户头像

map_3d_vis

关注

还未添加个人签名 2025-11-17 加入

还未添加个人简介

评论

发布
暂无评论
JSAPIThree 数据源系统学习笔记:让数据在地图上可视化_csv_map_3d_vis_InfoQ写作社区