Skip to content

Commit

Permalink
feat: 新增文本图层配置控件
Browse files Browse the repository at this point in the history
  • Loading branch information
heiyexing committed Dec 15, 2023
1 parent 2a382e1 commit b3a998d
Show file tree
Hide file tree
Showing 17 changed files with 200 additions and 76 deletions.
3 changes: 2 additions & 1 deletion docs/docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ title: API
| mapControl | 控件显隐 | [MapControlProps](#mapcontrolprops) | `-` |
| toolbar | 头部组件显隐 | [ToolbarProps](#toolbarprops) | `-` |
| tabItems | 侧面版标签页选项卡内容 | [TabItemType](https://ant-design.antgroup.com/components/tabs-cn#tabitemtype) | `-` |
| showIndex | 是否展示元素序号 | `boolean` | `false` |
| showTextLayer | 是否展示元素文本 | `boolean` | `false` |
| textLayerFields | 展示元素文本的字段,不选则展示元素序号 | `string[] | undefined` | `undefined` |
| wasmPath | sam 组件的 wasm 路径 | `string` | `\` |

#### `tabItems`
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@antv/l7-editor",
"version": "1.1.8",
"version": "1.1.9",
"description": "Geographic data editing tool based on L7",
"files": [
"lib",
Expand Down
25 changes: 2 additions & 23 deletions src/components/app-header/btn/setting-btn.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,8 @@ import { useGlobal } from '../../../recoil';

export const SettingBtn = () => {
const [isModalOpen, setIsModalOpen] = useState(false);
const {
popupTrigger,
setPopupTrigger,
autoFitBounds,
setAutoFitBounds,
showIndex,
setShowIndex
} = useGlobal();
const { popupTrigger, setPopupTrigger, autoFitBounds, setAutoFitBounds } =
useGlobal();
const { t } = useTranslation();
const [form] = Form.useForm();

Expand Down Expand Up @@ -55,14 +49,12 @@ export const SettingBtn = () => {
initialValues={{
popupTrigger,
autoFitBounds,
showIndex,
}}
style={{ textAlign: 'right' }}
onFinish={(e) => {
setIsModalOpen(false);
setPopupTrigger(e.popupTrigger);
setAutoFitBounds(e.autoFitBounds);
setShowIndex(e.showIndex)
}}
>
<Form.Item
Expand All @@ -86,19 +78,6 @@ export const SettingBtn = () => {
>
<Switch />
</Form.Item>
<Form.Item
name="showIndex"
label={t('btn.setting_btn.shiFouZhanShiYuan')}
>
<Radio.Group>
<Radio.Button value={true}>
{t('btn.setting_btn.kaiQi')}
</Radio.Button>
<Radio.Button value={false}>
{t('btn.setting_btn.guanBi')}
</Radio.Button>
</Radio.Group>
</Form.Item>
</Form>
</Modal>
</>
Expand Down
4 changes: 3 additions & 1 deletion src/components/layer-list/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@ import { FeatureKey, LayerId, LayerZIndex } from '../../constants';
import { useFilterFeatures } from '../../hooks';
import { useFeature, useGlobal } from '../../recoil';
import { getPointImage } from '../../utils/change-image-color';
import { EditorTextLayer } from '../text-layer';

export const LayerList: React.FC = () => {
const scene = useScene();
const [isMounted, setIsMounted] = useState(false);
const { layerColor, coordConvert, baseMap } = useGlobal();
const { layerColor, coordConvert, baseMap, showTextLayer } = useGlobal();
const { transformCoord } = useFeature();
const { features: newFeatures } = useFilterFeatures();
const [features, setFeatures] = useState<Feature[]>([]);
Expand Down Expand Up @@ -111,6 +112,7 @@ export const LayerList: React.FC = () => {
state={{ active: { color: activeColor } }}
zIndex={LayerZIndex}
/>
{showTextLayer && <EditorTextLayer />}
</>
) : null;
};
4 changes: 3 additions & 1 deletion src/components/map-control-group/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import MapThemeControl from './map-theme-control';
import { OfficialLayerControl } from './official-layer-control';
import { SamControl } from './sam-control';
import useStyles from './styles';
import { TextLayerControl } from './text-layer-control';

type MapControlGroupProps = {
mapControl?: MapControlProps;
Expand Down Expand Up @@ -70,7 +71,7 @@ export const MapControlGroup: React.FC<MapControlGroupProps> = ({
{isControlGroupState.drawControl && <DrawControl />}
{isControlGroupState.clearControl && <ClearControl />}
{isControlGroupState.zoomControl && (
<ZoomControl className={styles.zoom} showZoom />
<ZoomControl className={styles.zoom} showZoom position="rightbottom" />
)}
{isControlGroupState.mapAdministrativeControl && (
<MapAdministrativeControl />
Expand All @@ -96,6 +97,7 @@ export const MapControlGroup: React.FC<MapControlGroupProps> = ({
/>
)}
{layerType.includes(OfficeLayerEnum.GoogleSatellite) && <SamControl />}
<TextLayerControl />
</>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const useStyle = () => {
`,
hideOfficeLayerBtn: css`
height: 127px;
width: 20px;
width: 28px;
display: flex;
align-items: center;
justify-content: center;
Expand Down
73 changes: 73 additions & 0 deletions src/components/map-control-group/text-layer-control/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { CustomControl } from '@antv/larkmap';
import { Form, Popover, Select, Switch, Tooltip } from 'antd';
import React, { useState } from 'react';
import { useFeature, useGlobal } from '../../../recoil';
import { IconFont } from '../../iconfont';
import useStyles from '../styles';

export type TextLayerControlProps = {};

export const TextLayerControl: React.FC = () => {
const styles = useStyles();
const {
showTextLayer,
setShowTextLayer,
textLayerFields,
setTextLayerFields,
} = useGlobal();
const { features } = useFeature();
const [fields, setFields] = useState<string[]>([]);

const refreshFields = () => {
const newFieldSet = new Set<string>();
features.forEach((feature) => {
const properties = feature.properties;
if (properties) {
Object.keys(properties).forEach((key) => {
newFieldSet.add(key);
});
}
});
setFields(Array.from(newFieldSet));
};

return (
<CustomControl position="bottomleft">
<Popover
title="文本标注图层配置"
overlayStyle={{ width: 300 }}
content={
<Form size="small">
<Form.Item label="是否展示图层">
<Switch value={showTextLayer} onChange={setShowTextLayer} />
</Form.Item>

<Form.Item label="展示字段">
<Select
value={textLayerFields}
onChange={setTextLayerFields}
placeholder="不选则默认展示元素序号"
mode="multiple"
options={fields.map((item) => {
return { label: item, value: item };
})}
/>
</Form.Item>
</Form>
}
trigger="click"
onOpenChange={(visible) => {
if (visible) {
refreshFields();
}
}}
>
<Tooltip placement="left" overlay="文本图层配置">
<button className={styles.L7EditorControl} id="text-layer-control">
<IconFont type="icon-wenbenkuang" />
</button>
</Tooltip>
</Popover>
</CustomControl>
);
};
86 changes: 59 additions & 27 deletions src/components/text-layer/index.tsx
Original file line number Diff line number Diff line change
@@ -1,60 +1,92 @@
import type { TextLayerProps } from '@antv/larkmap';
import { TextLayer } from '@antv/larkmap';
import type { Feature, LineString } from '@turf/turf';
import { center } from '@turf/turf';
import { cloneDeep } from 'lodash-es';
import React, { useMemo } from 'react';
import { FeatureKey } from '../../constants';
import { useFilterFeatures } from '../../hooks';
import { useFeature, useGlobal } from '../../recoil';
import { centerOfLine } from '../../utils';

export const EditorTextLayer = () => {
const { transformCoord } = useFeature();
const { features: newFeatures } = useFilterFeatures();
const { layerColor } = useGlobal();
const { layerColor, textLayerFields } = useGlobal();

const layerOptions: Omit<TextLayerProps, 'source'> = useMemo(() => {
const textOptions: Omit<TextLayerProps, 'source'> = useMemo(() => {
return {
zIndex: 101,
field: 'name',
field: 'text',
style: {
fill: `${layerColor}`,
opacity: 1,
fontSize: 18,
fontSize: 16,
stroke: '#fff',
strokeWidth: 2,
textAllowOverlap: true,
padding: [10, 10] as [number, number],
textOffset: [0, -18],
},
};
}, [layerColor]);

const pointTextOptions: Omit<TextLayerProps, 'source'> = useMemo(() => {
const newLayerOptions = cloneDeep(textOptions);
newLayerOptions.style!.textOffset = [0, -20];
return newLayerOptions;
}, [textOptions]);

const sourceData = useMemo(() => {
const transformData = transformCoord(newFeatures).map((item) => {
return {
data: center(item),
//@ts-ignore
featureIndex: item.properties?.[FeatureKey.Index],
};
});
const data = transformData.map((item) => {
const data = transformCoord(newFeatures).map((item) => {
// @ts-ignore
const featureIndex = item.properties?.[FeatureKey.Index];
const [x, y] = (() => {
if (item.geometry.type === 'LineString') {
return centerOfLine(item as Feature<LineString>).geometry.coordinates;
}
if (item.geometry.type === 'Point') {
return item.geometry.coordinates;
} else {
return center(item).geometry.coordinates;
}
})();

let text = `${featureIndex + 1}`;

if (textLayerFields?.length) {
text = textLayerFields
.map((field) => {
return String(item.properties?.[field] ?? '');
})
.join(' ');
}

return {
//@ts-ignore
x: item.data.geometry.coordinates[0],
//@ts-ignore
y: item.data.geometry.coordinates[1],
name: `${item.featureIndex + 1}`,
x,
y,
text,
type: item.geometry.type,
};
});
return data;
}, [transformCoord, newFeatures]);
}, [transformCoord, newFeatures, textLayerFields]);

return (
<TextLayer
{...layerOptions}
source={{
data: sourceData,
parser: { type: 'json', x: 'x', y: 'y' },
}}
/>
<>
<TextLayer
{...textOptions}
source={{
data: sourceData.filter((item) => item.type !== 'Point'),
parser: { type: 'json', x: 'x', y: 'y' },
}}
/>
<TextLayer
{...pointTextOptions}
source={{
data: sourceData.filter((item) => item.type === 'Point'),
parser: { type: 'json', x: 'x', y: 'y' },
}}
/>
</>
);
};
2 changes: 1 addition & 1 deletion src/constants/iconfont.js

Large diffs are not rendered by default.

10 changes: 4 additions & 6 deletions src/constants/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
export const RightPanelWidthRange = [20, 80];




export enum LocalStorageKey {
RightPanelWidth = 'RightPanelWidth',
MapOptions = 'MapOptions',
Expand All @@ -18,11 +15,12 @@ export enum LocalStorageKey {
Convert = 'Convert',
theme = 'theme',
cityHistory = 'cityHistory',
showIndex = 'showIndex',
showTextLayer = 'showTextLayer',
textLayerFields = 'textLayerFields',
locale = 'locale',
firstOpening = 'firstOpening',
wasmPath = "wasmPath",
customTiles = "customTiles"
wasmPath = 'wasmPath',
customTiles = 'customTiles',
}

export enum LayerId {
Expand Down
4 changes: 1 addition & 3 deletions src/pages/components/editor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import {
MapControlGroup,
ResizePanel,
} from '../../components';
import { EditorTextLayer } from '../../components/text-layer';
import { LocalStorageKey } from '../../constants';
import { LangList } from '../../locales';
import { useFeature, useGlobal } from '../../recoil';
Expand All @@ -26,7 +25,7 @@ type EditorProps = L7EditorProps;
export const Editor: React.FC<EditorProps> = (props) => {
const { onFeatureChange } = props;
const { i18n, t } = useTranslation();
const { theme, mapOptions, setMapOptions, showIndex, locale } = useGlobal();
const { theme, mapOptions, setMapOptions, locale } = useGlobal();
const styles = useStyle();
const { saveEditorText, bboxAutoFit, scene } = useFeature();

Expand Down Expand Up @@ -99,7 +98,6 @@ export const Editor: React.FC<EditorProps> = (props) => {
left={
<AppMap>
<MapControlGroup mapControl={props.mapControl} />
{showIndex && <EditorTextLayer />}
<LayerList />
<LayerPopup />
<LayerContextmenuPopup />
Expand Down
4 changes: 4 additions & 0 deletions src/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import {
officialLayersState,
popupTriggerState,
rightWidthState,
showTextLayerState,
textLayerFieldsState,
themeState,
wasmPathState,
} from '../recoil/atomState';
Expand Down Expand Up @@ -47,6 +49,8 @@ export const L7Editor = (props: L7EditorProps) => {
set(convertState, props?.coordConvert ?? 'GCJ02');
set(localeState, props?.locale ?? 'zh-CN');
set(wasmPathState, props?.wasmPath ?? '/');
set(showTextLayerState, props?.showTextLayer ?? false);
set(textLayerFieldsState, props?.textLayerFields ?? undefined);
};
}, [props]);

Expand Down
Loading

0 comments on commit b3a998d

Please sign in to comment.