diff --git a/packages/li-core-assets/src/widgets/LayerSwitchControl/Component.tsx b/packages/li-core-assets/src/widgets/LayerSwitchControl/Component.tsx new file mode 100644 index 00000000..c4e08379 --- /dev/null +++ b/packages/li-core-assets/src/widgets/LayerSwitchControl/Component.tsx @@ -0,0 +1,55 @@ +import { CustomControl, LayerSwitchControl } from '@antv/larkmap'; +import type { ImplementWidgetProps } from '@antv/li-sdk'; +import { useGlobalModel, useScene } from '@antv/li-sdk'; +import { useDebounceEffect } from 'ahooks'; +import React, { useMemo } from 'react'; +import type { Properties } from './registerForm'; +import useStyle from './style'; + +export interface LayerSwitchProps extends Properties, ImplementWidgetProps {} + +const LayerSwitch: React.FC = (props) => { + const { position, layerFilter, isMultiple } = props; + const [scene] = useScene(); + const style = useStyle(); + const [, setGlobalData] = useGlobalModel(); + + const newLayers = useMemo(() => { + return layerFilter + ?.filter(({ visible }) => visible) + ?.map((item) => ({ + layer: item?.id, + name: item?.name, + img: item?.img, + })); + }, [layerFilter, isMultiple, scene]); + + useDebounceEffect(() => { + if (!isMultiple && layerFilter?.length) { + const [firstLayer] = layerFilter; + setGlobalData({ visibleLayer: firstLayer.name, isMultiple }); + } + }, [isMultiple, layerFilter]); + + return ( + + { + if (!isMultiple) { + setGlobalData({ visibleLayer: name, isMultiple }); + // 单选时瓦片图层不会展示,采用zoom最小阀值来更改地图的状态 + // 瓦片图层随zoom展示,在切换时地图状态并没有更改,所以不展示,也许是L7的bug。 + scene?.setZoom(scene.getZoom() + 0.001); + } + }} + /> + + ); +}; + +export default LayerSwitch; diff --git a/packages/li-core-assets/src/widgets/LayerSwitchControl/index.md b/packages/li-core-assets/src/widgets/LayerSwitchControl/index.md new file mode 100644 index 00000000..9e373977 --- /dev/null +++ b/packages/li-core-assets/src/widgets/LayerSwitchControl/index.md @@ -0,0 +1 @@ +## LayerSwitchControl diff --git a/packages/li-core-assets/src/widgets/LayerSwitchControl/index.ts b/packages/li-core-assets/src/widgets/LayerSwitchControl/index.ts new file mode 100644 index 00000000..f95d3a46 --- /dev/null +++ b/packages/li-core-assets/src/widgets/LayerSwitchControl/index.ts @@ -0,0 +1,16 @@ +import { implementWidget } from '@antv/li-sdk'; +import component from './Component'; +import registerForm from './registerForm'; + +export default implementWidget({ + version: 'v0.1', + metadata: { + name: 'LayerSwitch', + displayName: '图层选择器', + description: '用于图层选择', + type: 'Auto', + category: 'MapControl', + }, + component, + registerForm, +}); diff --git a/packages/li-core-assets/src/widgets/LayerSwitchControl/registerForm.ts b/packages/li-core-assets/src/widgets/LayerSwitchControl/registerForm.ts new file mode 100644 index 00000000..cf77bd76 --- /dev/null +++ b/packages/li-core-assets/src/widgets/LayerSwitchControl/registerForm.ts @@ -0,0 +1,161 @@ +import type { PositionName } from '@antv/l7'; +import type { WidgetRegisterForm, WidgetRegisterFormProps } from '@antv/li-sdk'; + +/** + * 属性面板生产的数据类型定义 + */ +export type Properties = { + /** + * @default topright + */ + position: PositionName; + /** + * 是否展示图片 + * @default false + */ + isTextMode: boolean; + /** + * 是否多选模式 + * @default true + */ + isMultiple: boolean; + /** + * 筛选图层配置 + */ + layerFilter: { + /**图层id */ + id: string; + /**图层名称 */ + name?: string; + /**展示图片url */ + img?: string; + /**是否展示 */ + visible: boolean; + }[]; +}; + +export const setReactions = (when: string) => { + return { + dependencies: ['isTextMode'], + when, + fulfill: { + schema: { + 'x-visible': false, + }, + }, + otherwise: { + schema: { + 'x-visible': true, + }, + }, + }; +}; + +export default (props: WidgetRegisterFormProps): WidgetRegisterForm => { + const layers = (props.layers || []).map((item) => { + return { + id: item?.id, + layerName: '', + name: item.metadata.name, + img: '', + visible: true, + }; + }); + + const schema = { + position: { + title: '放置方位', + type: 'string', + 'x-decorator': 'FormItem', + 'x-component': 'ControlPositionSelect', + default: 'bottomright', + }, + isTextMode: { + title: '是否展示图片', + type: 'boolean', + 'x-decorator': 'FormItem', + 'x-component': 'Switch', + default: false, + }, + isMultiple: { + title: '是否多选模式', + type: 'boolean', + 'x-decorator': 'FormItem', + 'x-component': 'Switch', + default: true, + }, + layerFilter: { + type: 'array', + title: '筛选图层配置', + 'x-decorator': 'FormItem', + 'x-decorator-props': { + labelWidth: '100%', + wrapperWidth: '100%', + layout: 'vertical', + }, + 'x-component': 'ArrayTable', + 'x-component-props': { + pagination: { pageSize: 10 }, + scroll: { x: '100%' }, + }, + default: layers, + items: { + type: 'object', + properties: { + column1: { + type: 'void', + 'x-component': 'ArrayTable.Column', + 'x-component-props': { width: 150, title: '图层名称' }, + properties: { + name: { + type: 'string', + 'x-decorator': 'FormItem', + 'x-component': 'Input', + }, + }, + }, + column2: { + type: 'void', + 'x-component': 'ArrayTable.Column', + 'x-component-props': { width: 115, title: '展示图片url' }, + 'x-reactions': setReactions('{{!$deps[0]}}'), + properties: { + img: { + type: 'string', + 'x-decorator': 'FormItem', + 'x-component': 'Input', + 'x-reactions': setReactions('{{!$deps[0]}}'), + }, + }, + }, + column3: { + type: 'void', + 'x-component': 'ArrayTable.Column', + 'x-component-props': { title: '是否展示', with: 60 }, + properties: { + visible: { + type: 'boolean', + 'x-decorator': 'FormItem', + 'x-component': 'Checkbox', + default: true, + }, + }, + }, + column4: { + type: 'void', + 'x-component': 'ArrayTable.Column', + 'x-component-props': { title: '图层id', with: 60 }, + properties: { + id: { + type: 'string', + 'x-decorator': 'FormItem', + 'x-component': 'Input', + }, + }, + }, + }, + }, + }, + }; + return { schema }; +}; diff --git a/packages/li-core-assets/src/widgets/LayerSwitchControl/style.ts b/packages/li-core-assets/src/widgets/LayerSwitchControl/style.ts new file mode 100644 index 00000000..e72d2639 --- /dev/null +++ b/packages/li-core-assets/src/widgets/LayerSwitchControl/style.ts @@ -0,0 +1,18 @@ +import { css } from '@emotion/css'; + +import { theme } from 'antd'; + +export default () => { + const { useToken } = theme; + const { token } = useToken(); + const { colorBgContainer, colorTextSecondary } = token; + + return { + layerSwitch: css` + background: ${colorBgContainer} !important; + .l7-iconfont { + fill: ${colorTextSecondary} !important; + } + `, + }; +}; diff --git a/packages/li-editor/src/widgets/WidgetsPanel/WidgetAttribute/WidgetForm/SchemaField.tsx b/packages/li-editor/src/widgets/WidgetsPanel/WidgetAttribute/WidgetForm/SchemaField.tsx index d351d62e..d4802469 100644 --- a/packages/li-editor/src/widgets/WidgetsPanel/WidgetAttribute/WidgetForm/SchemaField.tsx +++ b/packages/li-editor/src/widgets/WidgetsPanel/WidgetAttribute/WidgetForm/SchemaField.tsx @@ -17,6 +17,7 @@ import { Select, Space, Switch, + ArrayTable, } from '@formily/antd-v5'; import type { ISchema } from '@formily/json-schema'; import { createSchemaField } from '@formily/react'; @@ -40,6 +41,7 @@ const SchemaField = createSchemaField({ ControlPositionSelect, TimeGranularitySelect, FilterConfiguration, + ArrayTable, }, });