-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: 缩放器新增显示实时 zoom 数值功能 * docs: 文档showZoom添加默认值 * feat: 区块新增城市联级选择器 * fix: 区块修复城市联级选择器ts报错问题 * docs: 新增区块-行政区划选择器 --------- Co-authored-by: syb01094648 <[email protected]> Co-authored-by: yanxiong <[email protected]>
- Loading branch information
1 parent
b9d6386
commit 036cc5b
Showing
3 changed files
with
209 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
--- | ||
toc: false | ||
order: 3 | ||
nav: | ||
title: 区块 | ||
path: /blocks | ||
order: 4 | ||
--- | ||
|
||
## 城市联级选择器 | ||
|
||
### 介绍 | ||
|
||
用于快速查找中国省/市/县行政区域并快速定位的控件,基于 Ant Design 中的 [Cascader](https://ant-design.antgroup.com/components/cascader-cn#api) 组件封装而成 | ||
|
||
### 代码演示 | ||
|
||
#### 默认示例 | ||
|
||
<code src="./administrative-select/demos/default.tsx" compact></code> | ||
|
||
### API | ||
|
||
| 参数 | 说明 | 类型 | 默认值 | | ||
| --- | --- | --- | --- | | ||
| autoFit | 是否控制地图自动平移到选项对应行政区域 | `boolean` | `true` | | ||
| enableBoundary | 是否在地图上展示行政区域边界 | `boolean` | `true` | | ||
| boundaryLayer | 边界线图层属性,可参考 [LineLayerProps](https://larkmap.antv.antgroup.com/components/layers/base-layers/line-layer#api) | `Omit<LineLayerProps, 'source'>` | `--` | | ||
|
||
其他参数可以参照 [Ant Design 5.0 Cascader](https://ant-design.antgroup.com/components/cascader-cn#api) |
156 changes: 156 additions & 0 deletions
156
docs/blocks/administrative-select/administrative-select.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
import type { LineLayerProps } from '@antv/larkmap'; | ||
import { LineLayer, useScene } from '@antv/larkmap'; | ||
import type { Feature, MultiLineString } from '@turf/turf'; | ||
import { bbox, featureCollection, multiLineString } from '@turf/turf'; | ||
import type { CascaderProps } from 'antd'; | ||
import { Cascader, message } from 'antd'; | ||
import React, { useEffect, useState } from 'react'; | ||
|
||
export interface AdministrativeSelectProps | ||
extends Omit<CascaderProps, 'options' | 'multiple'>, | ||
Partial<Pick<CascaderProps, 'value' | 'onChange'>> { | ||
/** | ||
* 是否平移 | ||
*/ | ||
autoFit?: boolean; | ||
/** | ||
* 是否显示边界 | ||
*/ | ||
enableBoundary?: boolean; | ||
/** | ||
* layer属性 | ||
*/ | ||
boundaryLayer?: Omit<LineLayerProps, 'source'>; | ||
} | ||
|
||
/** | ||
* 将获取的行政区域雷彪转换为 Cascader 的 options | ||
* @param list | ||
* @returns | ||
*/ | ||
const getCascadeData = (list: any[]) => { | ||
list.sort((a: { adcode: number }, b: { adcode: number }) => { | ||
return +a.adcode - +b.adcode; | ||
}); | ||
if (list.length) { | ||
return list.map((item: any) => { | ||
const { name, districts, adcode } = item; | ||
return { | ||
adcode, | ||
value: adcode, | ||
label: name, | ||
children: getCascadeData(districts), | ||
}; | ||
}); | ||
} else { | ||
return []; | ||
} | ||
}; | ||
|
||
export const AdministrativeSelect: React.FC<AdministrativeSelectProps> = ({ | ||
enableBoundary, | ||
autoFit, | ||
boundaryLayer, | ||
value: originValue, | ||
onChange, | ||
...props | ||
}) => { | ||
const [districtFeature, setDistrictFeature] = useState<Feature<MultiLineString> | null>(null); | ||
const scene = useScene(); | ||
const [options, setOptions] = useState(); | ||
const [value, setValue] = useState<AdministrativeSelectProps['value']>(originValue); | ||
|
||
useEffect(() => { | ||
setValue(originValue); | ||
}, [originValue]); | ||
|
||
useEffect(() => { | ||
fetch( | ||
'https://restapi.amap.com/v3/config/district?key=98d10f05a2da96697313a2ce35ebf1a2&keywords=中华人民共和国&subdistrict=3&extensions=base', | ||
) | ||
.then((res) => res.json()) | ||
.then((res) => { | ||
setOptions(getCascadeData(res.districts[0].districts)); | ||
}); | ||
}, []); | ||
|
||
// 当选项发生改变时,更新围栏数据 | ||
useEffect(() => { | ||
if (value) { | ||
const name = value[value.length - 1]; | ||
fetch( | ||
`https://restapi.amap.com/v3/config/district?keywords=${name}&subdistrict=0&key=98d10f05a2da96697313a2ce35ebf1a2&extensions=all`, | ||
) | ||
.then((res) => res.json()) | ||
.then((res) => { | ||
if (res.status === '1' && res.districts?.length && scene) { | ||
const positions: number[][][] = []; | ||
res.districts.forEach((district: any) => { | ||
(district.polyline as string).split('|').forEach((chunk) => { | ||
positions.push(chunk.split(';').map((item) => item.split(',').map((num) => +num))); | ||
}); | ||
}); | ||
|
||
const feature = multiLineString(positions); | ||
setDistrictFeature(feature); | ||
if (autoFit) { | ||
const [lng1, lat1, lng2, lat2] = bbox(feature); | ||
scene.fitBounds([ | ||
[lng1, lat1], | ||
[lng2, lat2], | ||
]); | ||
} | ||
} | ||
}) | ||
.catch(() => { | ||
message.error('围栏数据请求失败'); | ||
}); | ||
} | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
}, [value]); | ||
|
||
return ( | ||
<> | ||
<Cascader | ||
options={options} | ||
value={value} | ||
onChange={(newValue: string[], option: any) => { | ||
setValue(newValue); | ||
// @ts-ignore | ||
onChange?.(newValue, option); | ||
if (!value) { | ||
setDistrictFeature(null); | ||
} | ||
}} | ||
multiple={false} | ||
{...props} | ||
/> | ||
{enableBoundary && ( | ||
<LineLayer | ||
source={{ | ||
data: featureCollection(districtFeature ? [districtFeature] : []), | ||
}} | ||
{...boundaryLayer} | ||
/> | ||
)} | ||
</> | ||
); | ||
}; | ||
|
||
AdministrativeSelect.defaultProps = { | ||
placeholder: '可选择省/市/县', | ||
expandTrigger: 'hover', | ||
allowClear: true, | ||
changeOnSelect: true, | ||
enableBoundary: true, | ||
autoFit: true, | ||
showSearch: true, | ||
boundaryLayer: { | ||
shape: 'line', | ||
color: '#ff0000', | ||
size: 2, | ||
style: { | ||
opacity: 0.8, | ||
}, | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import type { LarkMapProps } from '@antv/larkmap'; | ||
import { CustomControl, LarkMap } from '@antv/larkmap'; | ||
import React from 'react'; | ||
import { AdministrativeSelect } from '../administrative-select'; | ||
|
||
const config: LarkMapProps = { | ||
mapType: 'Gaode', | ||
mapOptions: { | ||
style: 'light', | ||
center: [120.210792, 30.246026], | ||
zoom: 9, | ||
}, | ||
}; | ||
|
||
export default () => { | ||
return ( | ||
<LarkMap {...config} style={{ height: '300px' }}> | ||
<CustomControl> | ||
<AdministrativeSelect style={{ width: 250 }} /> | ||
</CustomControl> | ||
</LarkMap> | ||
); | ||
}; |