From 1039ec3e0a5813cc6a035a6a443a009b19c0ac17 Mon Sep 17 00:00:00 2001 From: "@thinkinggis" Date: Tue, 22 Feb 2022 12:00:51 +0800 Subject: [PATCH] Feat layer legend (#977) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: add cluster demo * fix(baselayer): 聚合图共用source 时数据不更新问题 layer 增加cluster zoom 标识符' * fix(source): lint error * fix: 聚合图缩放等级范围设置 * fix: demo * fix: demo lint * fix(layer): getlengenditem * feat: 新增source属性更新 * docs: 更新source文档 * fix: lint error * fix: 文档目录顺序 --- docs/api/source/source.zh.md | 55 ++++++- gatsby-config.js | 16 +- packages/component/src/css/l7.css | 2 +- .../src/services/source/ISourceService.ts | 4 + packages/source/src/source.ts | 29 +++- stories/Source/Map.stories.tsx | 2 + stories/Source/components/updateproperty.tsx | 144 ++++++++++++++++++ 7 files changed, 233 insertions(+), 19 deletions(-) create mode 100644 stories/Source/components/updateproperty.tsx diff --git a/docs/api/source/source.zh.md b/docs/api/source/source.zh.md index 8522c9398f..cde5880c77 100644 --- a/docs/api/source/source.zh.md +++ b/docs/api/source/source.zh.md @@ -83,21 +83,62 @@ layer.on('click', (e) => { }); ``` -### 方法 +#### setData -#### getClustersLeaves(cluster_id) +更新 source 数据 -聚合图使用,获取聚合节点的原始数据 +##### 参数 -参数: -id 聚合节点的 cluster_id +- data 数据同 source 初始化参数 +- option 配置项同 source 初始化参数 -```javascript +#### getFeatureById + +根据 featurID 获取 feature 要素 + +##### 参数 + +- id featureId,L7 内部编码的唯一要素 ID + +```tsx +const source = layer.getSource(); +source.getFeatureById(1); +``` + +#### updateFeaturePropertiesById + +根据 ID 更新 source 的属性数据,会触发从新渲染 + +##### 参数 + +- id featureId,L7 内部编码的唯一要素 ID +- Properties 需要更新属性数据,merge 操作 + +```tsx +const source = layer.getSource(); layer.on('click', (e) => { - console.log(source.getClustersLeaves(e.feature.cluster_id)); + source.updateFeaturePropertiesById(e.featureId, { + name: Math.random() * 10, + }); }); ``` +#### getFeatureId + +根据属性的 key、value 获取要素 L7 编码 featureId,确保该属性的 value 是唯一值,如存在多个返回第一个。 + +##### 参数 + +- key: 属性字段 +- value: 对应的值 + +```tsx +const source = layer.getSource(); +source.getFeatureId('name', '张三'); +``` + +### 数据类型 + #### JSON [JSON 数据格式解析](./json) diff --git a/gatsby-config.js b/gatsby-config.js index af80fe97e5..883ebb32b4 100644 --- a/gatsby-config.js +++ b/gatsby-config.js @@ -133,6 +133,14 @@ module.exports = { }, order: 2, }, + { + slug: 'api/source', + title: { + zh: '数据 Source', + en: 'Source', + }, + order: 2, + }, { slug: 'api/point_layer', title: { @@ -221,14 +229,6 @@ module.exports = { }, order: 9, }, - { - slug: 'api/source', - title: { - zh: '数据 Source', - en: 'Source', - }, - order: 10, - }, { slug: 'api/district', title: { diff --git a/packages/component/src/css/l7.css b/packages/component/src/css/l7.css index 2d8655ed77..b7e09ea077 100644 --- a/packages/component/src/css/l7.css +++ b/packages/component/src/css/l7.css @@ -366,7 +366,7 @@ .l7-control-container .l7-control-attribution { background: #fff; - background: rgba(255, 255, 255, 0.7); + background: rgba(59, 58, 58, 0.7); margin: 0; } .l7-control-attribution, diff --git a/packages/core/src/services/source/ISourceService.ts b/packages/core/src/services/source/ISourceService.ts index 74ecc54ec0..fa015e7a7d 100644 --- a/packages/core/src/services/source/ISourceService.ts +++ b/packages/core/src/services/source/ISourceService.ts @@ -67,6 +67,10 @@ export interface ISource { getFeatureId(field: string, value: any): number | undefined; getClusters(zoom: number): any; getClustersLeaves(id: number): any; + updateFeaturePropertiesById( + id: number, + properties: Record, + ): void; } export interface IRasterCfg { extent: [number, number, number, number]; diff --git a/packages/source/src/source.ts b/packages/source/src/source.ts index 95b186c1a1..b16aa3ba0e 100644 --- a/packages/source/src/source.ts +++ b/packages/source/src/source.ts @@ -60,6 +60,8 @@ export default class Source extends EventEmitter implements ISource { // 是否有效范围 private invalidExtent: boolean = false; + private dataArrayChanged: boolean = false; + // 原始数据 private originData: any; private rawData: any; @@ -86,8 +88,8 @@ export default class Source extends EventEmitter implements ISource { } public setData(data: any, options?: ISourceCFG) { - this.rawData = data; this.originData = data; + this.dataArrayChanged = false; this.initCfg(options); this.init(); this.emit('update'); @@ -145,7 +147,9 @@ export default class Source extends EventEmitter implements ISource { ? this.originData.features[id] : 'null'; const newFeature = cloneDeep(feature); - if (this.transforms.length !== 0) { + + if (this.transforms.length !== 0 || this.dataArrayChanged) { + // 如果数据进行了transforms 属性会发生改变 或者数据dataArray发生更新 const item = this.data.dataArray.find((dataItem: IParseDataItem) => { return dataItem._id === id; }); @@ -157,9 +161,28 @@ export default class Source extends EventEmitter implements ISource { } } + public updateFeaturePropertiesById( + id: number, + properties: Record, + ) { + this.data.dataArray = this.data.dataArray.map( + (dataItem: IParseDataItem) => { + if (dataItem._id === id) { + return { + ...dataItem, + ...properties, + }; + } + return dataItem; + }, + ); + this.dataArrayChanged = true; + this.emit('update'); + } + public getFeatureId(field: string, value: any): number | undefined { const feature = this.data.dataArray.find((dataItem: IParseDataItem) => { - return dataItem[field] === name; + return dataItem[field] === value; }); return feature?._id; } diff --git a/stories/Source/Map.stories.tsx b/stories/Source/Map.stories.tsx index dbc836addc..06fefdfbd6 100644 --- a/stories/Source/Map.stories.tsx +++ b/stories/Source/Map.stories.tsx @@ -6,6 +6,7 @@ import MultiLine from './components/multiLine'; import MultiPolygon from './components/multiPolygon'; import UpdatePolygon from './components/ReuseSource'; import ReuseSource from './components/ReuseSource'; +import UpdateProperty from './components/updateproperty' // @ts-ignore import notes from './Map.md'; // @ts-ignore @@ -14,5 +15,6 @@ storiesOf('数据', module) .add('updatePolygon', () => , {}) .add('MultiLine', () => , {}) .add('HolePolygon', () => , {}) + .add('更新属性', () => , {}) .add('折线', () => , {}) .add('复用 Source', () => , {}); diff --git a/stories/Source/components/updateproperty.tsx b/stories/Source/components/updateproperty.tsx new file mode 100644 index 0000000000..b81c4958b7 --- /dev/null +++ b/stories/Source/components/updateproperty.tsx @@ -0,0 +1,144 @@ +import { PointLayer, PolygonLayer, Scene, Source } from '@antv/l7'; +import { GaodeMap, Mapbox } from '@antv/l7-maps'; +import * as React from 'react'; + +function convertRGB2Hex(rgb: number[]) { + return ( + '#' + rgb.map((r) => ('0' + Math.floor(r).toString(16)).slice(-2)).join('') + ); +} + +export default class MultiPolygon extends React.Component { + private gui: dat.GUI; + private $stats: Node; + private scene: Scene; + + public componentWillUnmount() { + this.scene.destroy(); + } + + public async componentDidMount() { + const scene = new Scene({ + id: 'map', + map: new GaodeMap({ + pitch: 0, + style: 'dark', + center: [-44.40673828125, -18.375379094031825], + zoom: 12, + }), + }); + const data = { + type: 'FeatureCollection', + features: [ + { + type: 'Feature', + properties: { name: 'test1' }, + geometry: { + type: 'MultiPolygon', + coordinates: [ + [ + [ + [110.5224609375, 32.731840896865684], + [113.0712890625, 32.731840896865684], + [113.0712890625, 34.56085936708384], + [110.5224609375, 34.56085936708384], + [110.5224609375, 32.731840896865684], + ], + [ + [111.26953125, 33.52307880890422], + [111.26953125, 34.03445260967645], + [112.03857421875, 34.03445260967645], + [112.03857421875, 33.52307880890422], + [111.26953125, 33.52307880890422], + ], + ], + [ + [ + [115.04882812499999, 34.379712580462204], + [114.9609375, 33.46810795527896], + [115.8837890625, 33.50475906922609], + [115.86181640625001, 34.379712580462204], + [115.04882812499999, 34.379712580462204], + ], + ], + ], + }, + }, + { + type: 'Feature', + properties: { name: 'test2' }, + geometry: { + type: 'Polygon', + coordinates: [ + [ + [113.8623046875, 30.031055426540206], + [116.3232421875, 30.031055426540206], + [116.3232421875, 31.090574094954192], + [113.8623046875, 31.090574094954192], + [113.8623046875, 30.031055426540206], + ], + [ + [117.26806640625, 32.13840869677249], + [118.36669921875, 32.13840869677249], + [118.36669921875, 32.47269502206151], + [117.26806640625, 32.47269502206151], + [117.26806640625, 32.13840869677249], + ], + ], + }, + }, + ], + }; + // console.log(data.features[5]); + // data.features = data.features.slice(6); + const source = new Source(data); + const layer = new PolygonLayer({ + autoFit: true, + }) + .source(source) + .shape('fill') + .color('name', ['#fc8d59', '#ffffbf', '#99d594']) + .style({ + opacity: 1.0, + }); + + const layerText = new PointLayer({ + autoFit: false, + }) + .source(source) + .shape('name', 'text') + .size(10) + .color('#fff') + .style({ + opacity: 1.0, + }); + scene.addLayer(layer); + scene.addLayer(layerText); + + layer.on('click', (e) => { + console.log(e.feature.properties); + const source = layer.getSource(); + + source.updateFeaturePropertiesById(e.featureId, { + name: Math.random() * 10, + }); + console.log(source.data.dataArray); + }); + this.scene = scene; + } + + public render() { + return ( +
+ ); + } +}