Skip to content

Commit

Permalink
feat: 区域复合图层标注指定坐标 (#260)
Browse files Browse the repository at this point in the history
Co-authored-by: wb-yzg904416@antgroup.com <wb-yzg904416@antgroup.com>
Co-authored-by: yunji <yunji.me@outlook.com>
  • Loading branch information
3 people authored Jan 3, 2023
1 parent f22e77a commit d482ef0
Show file tree
Hide file tree
Showing 8 changed files with 385 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { IParserCfg } from '@antv/l7';
import { ChoroplethLayerOptions, LabelPosition } from './types';
import { SourceOptions } from '../../types/attr';
import { ISource } from '../../types/common';
import { isBoolean, isUndefined } from '@antv/util';
import { getLabelLayerOptions as getLabelOptions } from '../common/label-layer';

/**
* 是否开启自定义标注图层坐标字段
*/
export const isLabelPosition = (
position?: LabelPosition
): position is Pick<IParserCfg, 'x' | 'y' | 'coordinates' | 'geometry'> => {
if (isUndefined(position) || isBoolean(position)) return false;

if (
isUndefined(position['coordinates']) &&
(isUndefined(position['x']) || isUndefined(position['y'])) &&
isUndefined(position['geometry'])
) {
return false;
}

return true;
};

/**
* 开启自定义标注图层坐标字段,解析标注图层 source
*/
export const parserLabeSourceData = (
source: ISource,
labelOptions: ChoroplethLayerOptions['label']
): ISource | SourceOptions => {
const position = labelOptions?.position;
if (!isLabelPosition(position)) {
return source;
}

// TODO: type 为 json 有效,为 geojson 会自动计算中心点,指定坐标字段无效
const type = source.parser.type;
const transforms = source.transforms;
const originData = source['originData'];
const sourceOptions = { data: originData, transforms };

if (position['coordinates']) {
const coordinates = position['coordinates'];
sourceOptions['parser'] = { type, coordinates };
} else if (position['x'] && position['y']) {
const x = position['x'];
const y = position['y'];
sourceOptions['parser'] = { type, x, y };
} else if (position['geometry']) {
const geometry = position['geometry'];
sourceOptions['parser'] = { type, geometry };
}

return sourceOptions;
};

/**
* 获取标注图层配置项
*/
export const getLabelLayerOptions = (options: ChoroplethLayerOptions, source: ISource) => {
return {
...getLabelOptions<ChoroplethLayerOptions>(options),
source: parserLabeSourceData(source, options.label),
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import { ChoroplethLayerOptions, ChoroplethLayerSourceOptions } from './types';
import { ICoreLayer, ISource, MouseEvent } from '../../types';
import { EMPTY_GEOJSON_SOURCE } from '../common/constants';
import { DEFAULT_OPTIONS, DEFAULT_STATE } from './constants';
import { getLabelLayerOptions } from '../common/label-layer';
import { isGestureMultiSelect } from '../common/multi-select';
import { getLabelLayerOptions, isLabelPosition, parserLabeSourceData } from './helper';

export class ChoroplethLayer extends CompositeLayer<ChoroplethLayerOptions> {
/**
Expand Down Expand Up @@ -131,9 +131,8 @@ export class ChoroplethLayer extends CompositeLayer<ChoroplethLayerOptions> {

// 标注图层
const labelLayer = new TextLayer({
...getLabelLayerOptions<ChoroplethLayerOptions>(this.options),
...getLabelLayerOptions(this.options, source),
id: 'labelLayer',
source,
});

const subLayers = [fillLayer, strokeLayer, highlightStrokeLayer, selectFillLayer, selectStrokeLayer, labelLayer];
Expand Down Expand Up @@ -283,6 +282,12 @@ export class ChoroplethLayer extends CompositeLayer<ChoroplethLayerOptions> {
} else {
const { data, ...option } = source;
this.source.setData(data, option);

// 自定义标注图层 position 时,source 不是共享的 Source 实例
if (isLabelPosition(this.options.label?.position)) {
const labelSource = parserLabeSourceData(this.source, this.options.label);
this.labelLayer.changeData(labelSource);
}
}

this.highlightStrokeLayer.changeData(EMPTY_GEOJSON_SOURCE);
Expand Down Expand Up @@ -436,7 +441,7 @@ export class ChoroplethLayer extends CompositeLayer<ChoroplethLayerOptions> {
this.selectStrokeLayer.update(this.getSelectStrokeLayerOptions(), false);

// 标注图层
this.labelLayer.update(getLabelLayerOptions<ChoroplethLayerOptions>(this.options), false);
this.labelLayer.update(getLabelLayerOptions(this.options, this.source), false);

// 重置高亮/选中状态
if (this.options.visible) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { IParserCfg } from '@antv/l7';
import { PolygonLayerOptions } from '../../core-layers/polygon-layer/types';
import { CompositeLayerOptions } from '../../core/composite-layer';
import { ISourceCFG, ISource } from '../../types';
Expand All @@ -22,6 +23,11 @@ export type ChoroplethLayerActiveOptions = {
lineOpacity?: number;
};

/**
* 文本标注点位,默认不需要设置,点位为几何中心点。
*/
export type LabelPosition = Pick<IParserCfg, 'x' | 'y' | 'coordinates' | 'geometry'> | false;

export interface ChoroplethLayerOptions extends CompositeLayerOptions {
/**
* 数据配置
Expand Down Expand Up @@ -65,7 +71,16 @@ export interface ChoroplethLayerOptions extends CompositeLayerOptions {
/**
* 文本标注
*/
label?: LabelOptions;
label?: LabelOptions & {
/**
* 文本标注点位,默认不需要设置,点位为几何中心点。
* 指定经纬度字段时: { x: string, y: string };
* 指定数组坐标字段时: { coordinates: string };
* 指定 geometry 字段时: { geometry: string };
* @default false
*/
position?: LabelPosition;
};
/**
* 交互反馈
*/
Expand Down
17 changes: 16 additions & 1 deletion packages/composite-layers/src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Source } from '@antv/l7';
import { deepMix, isEqual } from '@antv/util';

export * from './keypress';
Expand All @@ -8,7 +9,16 @@ export * from './keypress';
export const deepMergeLayerOptions = <O extends { source: any }>(options: Partial<O>, srcOptions: Partial<O>): O => {
const { source, ...restOptions } = options;
const { source: srcSource, ...restSrcOptions } = srcOptions;
const target = { ...deepMix(restOptions, restSrcOptions), source: { ...source, ...srcSource } };
const target = { ...deepMix(restOptions, restSrcOptions) };

// source 是实例的情况
if ((srcSource as any) instanceof Source) {
target.source = srcSource;
} else if ((source as any) instanceof Source) {
target.source = source;
} else {
target.source = { ...source, ...srcSource };
}

return target;
};
Expand All @@ -17,6 +27,11 @@ export const deepMergeLayerOptions = <O extends { source: any }>(options: Partia
* 判断 source 数据是否发生改变
*/
export const isSourceChanged = <S extends { data: any } = { data: any }>(source: S, currentSource: S) => {
// source 是实例的情况
if (source instanceof Source && currentSource instanceof Source) {
return source !== currentSource;
}

const { data, ...restOptions } = source;
const { data: currentData, ...restCurrentOptions } = currentSource;
const changed = data !== currentData || !isEqual(restOptions, restCurrentOptions);
Expand Down
2 changes: 1 addition & 1 deletion packages/l7plot/src/core/map/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -658,7 +658,7 @@ export abstract class Map<O extends MapOptions> extends EventEmitter {
/**
* 导出地图图片
*/
public exportPng(type?: 'png' | 'jpg'): string {
public exportPng(type?: 'png' | 'jpg'): Promise<string> {
return this.scene.exportPng(type);
}

Expand Down
Loading

0 comments on commit d482ef0

Please sign in to comment.