feat(zhst/map): 添加例子
This commit is contained in:
parent
3bd50deeb3
commit
3666fc4ed1
91
packages/map/src/clusters/demo/basic.tsx
Normal file
91
packages/map/src/clusters/demo/basic.tsx
Normal file
@ -0,0 +1,91 @@
|
||||
import React, { useRef, useEffect, useState } from 'react';
|
||||
import { MapBox, MapProps } from '@zhst/map';
|
||||
import axios from 'axios';
|
||||
import { FloatButton, Switch } from '@zhst/meta';
|
||||
|
||||
const demo = () => {
|
||||
const [showCluster, setShowCluster] = useState(true)
|
||||
const [sluterData, setSluterData] = useState<MapProps['clusterData']>()
|
||||
const mapRef = useRef(null);
|
||||
|
||||
// 初始化
|
||||
const handleMapLoad = (e: mapboxgl.MapboxEvent<undefined>) => {
|
||||
const map = e.target;
|
||||
|
||||
if (!map) return
|
||||
|
||||
map.flyTo({
|
||||
// center: [120,30],
|
||||
// zoom: map?.getMaxZoom(),
|
||||
});
|
||||
};
|
||||
|
||||
const getData = async () => {
|
||||
let res = await axios({
|
||||
method: 'post',
|
||||
url: 'http://10.0.0.120:30003/singer.DeviceService/ListCamera',
|
||||
headers: {
|
||||
Authorization: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MTcwNDAzNzEsImp0aSI6IjExMjgiLCJpYXQiOjE3MTY3ODExNzEsInVzZXJJZCI6MSwidXNlcm5hbWUiOiJhZG1pbiIsImRhdGFSaWdodCI6MiwiY2FtZXJhUmlnaHQiOjEsImdwdVJpZ2h0IjoxLCJ1c2VybGVhZGVySWQiOjAsIm9yZ2FuaXphdGlvbklkIjoxLCJyb2xlSWQiOjF9.XHbXIkXkfUuvqV6_qSV4d20xj-s7I0qOQZgL-zspMDc'
|
||||
},
|
||||
data: {"labelData":[],"filter":{"realtimeProcessingFilter":0,"cameraFilter":[{"opt":"ORNOT","cameraOpt":"CAMERAOPT_TYPE","value":"100"}]},"maxResults":50}
|
||||
});
|
||||
if (res.status === 200) {
|
||||
let markers = []
|
||||
let sluters = {
|
||||
features: []
|
||||
}
|
||||
res.data.cameras?.forEach(camera => {
|
||||
markers.push({
|
||||
key: camera.id,
|
||||
id: camera.id,
|
||||
title: camera.name,
|
||||
population: camera.id,
|
||||
checked: false,
|
||||
disabled: false,
|
||||
showCheckBox: true,
|
||||
status: ['blue', 'yellow', 'red'][Math.floor(Math.random() * 3)],
|
||||
latitude: camera.latitude,
|
||||
longitude: camera.longitude
|
||||
})
|
||||
sluters.features.push({
|
||||
"geometry": {
|
||||
"type": "Point",
|
||||
"coordinates": [
|
||||
camera.longitude,
|
||||
camera.latitude,
|
||||
50
|
||||
]
|
||||
}
|
||||
})
|
||||
})
|
||||
setSluterData(sluters)
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
getData()
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div>
|
||||
<FloatButton>
|
||||
<Switch value={true}/>
|
||||
</FloatButton>
|
||||
<MapBox
|
||||
onLoad={handleMapLoad}
|
||||
ref={mapRef}
|
||||
showToolBar={false}
|
||||
width='100%'
|
||||
height='800px'
|
||||
showCluster={showCluster}
|
||||
clusterProps={{
|
||||
data: sluterData
|
||||
}}
|
||||
// customMarkerRender={(_data) => <div>自定义标记</div>}
|
||||
>
|
||||
</MapBox>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default demo;
|
24
packages/map/src/clusters/index.md
Normal file
24
packages/map/src/clusters/index.md
Normal file
@ -0,0 +1,24 @@
|
||||
---
|
||||
category: Components
|
||||
subtitle: 聚合点
|
||||
title: Cluster 聚合点
|
||||
toc: content
|
||||
group:
|
||||
title: 数据展示
|
||||
order: 1
|
||||
---
|
||||
|
||||
<code src="./demo/basic.tsx">基本用法</code>
|
||||
|
||||
## API
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| clusterData | 聚合数据集合 | mapboxgl.GeoJSONSourceRaw['data'] | {} | - |
|
||||
| showCluster | 显示/隐藏聚合点 | boolean | {} | - |
|
||||
| type | 数据接收类型(对clusterData生效) | string | geojson | - |
|
||||
| cluster | 是否打开聚合功能 | boolean | {} | - |
|
||||
| clusterMaxZoom | 最大生效层级 | number | 14 | - |
|
||||
| clusterRadius | 聚合半径 | number | 50 | - |
|
||||
|
||||
> 更多参数参考 react-map-gl 的 Source 组件
|
@ -14,13 +14,14 @@ import {
|
||||
import drawRectMode from 'mapbox-gl-draw-rectangle-mode'
|
||||
// @ts-ignore
|
||||
import drawStaticMode from '@mapbox/mapbox-gl-draw-static-mode'
|
||||
// @ts-ignore
|
||||
import drawCircleMode from './Draw/drawCircleMode.draw.js'
|
||||
import { useControl } from 'react-map-gl';
|
||||
import type { ControlPosition } from 'react-map-gl';
|
||||
import { MapContextValue } from 'react-map-gl/dist/esm/components/map';
|
||||
|
||||
export type DrawControlProps = ConstructorParameters<typeof MapboxDraw>[0] & {
|
||||
position?: ControlPosition;
|
||||
|
||||
onCreate?: (evt: {features: object[]}) => void;
|
||||
onUpdate?: (evt: {features: object[]; action: string}) => void;
|
||||
onDelete?: (evt: {features: object[]}) => void;
|
||||
@ -50,7 +51,7 @@ const DrawControl = forwardRef<DrawControlRefProps, DrawControlProps>((props, re
|
||||
// draw_line_select: drawLineSelectMode,
|
||||
draw_rect: drawRectMode,
|
||||
drag_circle: DragCircleMode,
|
||||
draw_circle : CircleMode,
|
||||
draw_circle : drawCircleMode,
|
||||
direct_select: DirectMode,
|
||||
simple_select: SimpleSelectMode,
|
||||
static: drawStaticMode,
|
||||
@ -101,7 +102,8 @@ const DrawControl = forwardRef<DrawControlRefProps, DrawControlProps>((props, re
|
||||
DrawControl.defaultProps = {
|
||||
onCreate: () => {},
|
||||
onUpdate: () => {},
|
||||
onDelete: () => {}
|
||||
onDelete: () => {},
|
||||
|
||||
};
|
||||
|
||||
export default DrawControl
|
79
packages/map/src/drawControl/demo/basic.tsx
Normal file
79
packages/map/src/drawControl/demo/basic.tsx
Normal file
@ -0,0 +1,79 @@
|
||||
import React, { useRef, useEffect, useState } from 'react';
|
||||
import { getDistancesByStringLine, MapBox, Marker } from '@zhst/map';
|
||||
import { FloatButton, Switch } from '@zhst/meta';
|
||||
|
||||
const demo = () => {
|
||||
const mapRef = useRef(null);
|
||||
const [canDraw, setCanDraw] = useState(false)
|
||||
const [toolsBarOpen, setToolsBarOpen] = useState(false)
|
||||
const [rangingList, setRangingList] = useState([])
|
||||
// 初始化
|
||||
const handleMapLoad = (e: mapboxgl.MapboxEvent<undefined>) => {
|
||||
const map = e.target;
|
||||
|
||||
if (!map) return
|
||||
|
||||
map.flyTo({
|
||||
// center: [120,30],
|
||||
// zoom: map?.getMaxZoom(),
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div>
|
||||
<FloatButton>
|
||||
<Switch value={true}/>
|
||||
</FloatButton>
|
||||
<MapBox
|
||||
onLoad={handleMapLoad}
|
||||
ref={mapRef}
|
||||
width='100%'
|
||||
height='800px'
|
||||
draw={canDraw}
|
||||
toolsBarOpen={toolsBarOpen}
|
||||
onToolClick={e => {
|
||||
setCanDraw(pre => !pre)
|
||||
setToolsBarOpen(pre => !pre)
|
||||
}}
|
||||
onDrawCreate={e => {
|
||||
const geojson = e.features[0]
|
||||
// 防止绘制完成后,地图自动切换到选中状态
|
||||
setTimeout(async () => {
|
||||
mapRef.current.drawer.changeMode('simple_select')
|
||||
}, 100);
|
||||
const polygonJson = getDistancesByStringLine(geojson) || []
|
||||
setRangingList(polygonJson.distanceArr)
|
||||
}}
|
||||
onDrawDelete={e => setRangingList([])}
|
||||
onDrawUpdate={e => {
|
||||
const geojson = e.features[0]
|
||||
const polygonJson = getDistancesByStringLine(geojson) || []
|
||||
setRangingList(polygonJson.distanceArr)
|
||||
}}
|
||||
drawerProps={{
|
||||
onActionable: e => console.log('e', e)
|
||||
}}
|
||||
>
|
||||
{rangingList?.map((item, index) => {
|
||||
return (
|
||||
<Marker
|
||||
key={index}
|
||||
anchor="bottom"
|
||||
longitude={item.to[0]}
|
||||
latitude={item.to[1]}
|
||||
// !! 阻止原生的冒泡
|
||||
onClick={e => e.originalEvent.stopPropagation()}
|
||||
>
|
||||
<div style={{ padding: '3px 6px', background: '#fff', border: '1px solid #000' }} >{(item.totalLength)}km</div>
|
||||
</Marker>
|
||||
)
|
||||
})}
|
||||
</MapBox>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default demo;
|
83
packages/map/src/drawControl/index.md
Normal file
83
packages/map/src/drawControl/index.md
Normal file
@ -0,0 +1,83 @@
|
||||
---
|
||||
category: Components
|
||||
subtitle: 地图绘制
|
||||
title: Draw 地图绘制
|
||||
toc: content
|
||||
group:
|
||||
title: 地图操作
|
||||
order: 1
|
||||
---
|
||||
|
||||
|
||||
<code src="./demo/basic.tsx">基本用法</code>
|
||||
|
||||
## API
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| draw | 是否绘制 | boolean | false | - |
|
||||
| toolsBarOpen | 工具栏是否打开 | boolean | false | - |
|
||||
| onToolClick | 工具Icon点击事件 | (e: React.MouseEvent<HTMLElement, MouseEvent>) => void | false | - |
|
||||
| buttonList | 工具栏按钮列表 | IButtonList | defaultButtonList | - |
|
||||
| mapRef.current.drawer | 绘制组件的Ref,参考@mapbox/mapbox-gl-draw | DrawControlRefProps | - | - |
|
||||
| onCreate | 创建监听 | (evt: {features: object[]}) => void; | - | - |
|
||||
| onUpdate | 更新监听 | (evt: {features: object[]}) => void; | - | - |
|
||||
| onDelete | 删除监听 | (evt: {features: object[]}) => void; | - | - |
|
||||
| onRender | 渲染监听 | (evt: {features: object[]}) => void; | - | - |
|
||||
| onCombine | 组合监听 | (evt: {features: object[]}) => void; | - | - |
|
||||
| onUncombine | 分离监听 | (evt: {features: object[]}) => void; | - | - |
|
||||
| onModeChange | 模式切换监听 | (evt: {features: object[]}) => void; | - | - |
|
||||
| onActionable | 是否绘制 | (evt: {features: object[]}) => void; | - | - |
|
||||
| onSelectionChange | 选中目标切换监听 | (evt: {features: object[]}) => void; | - | - |
|
||||
|
||||
```js
|
||||
interface IButtonList {
|
||||
label: string
|
||||
key: string
|
||||
icon?: ReactNode | string
|
||||
onClick?: () => void
|
||||
}[]
|
||||
// 默认按钮列表
|
||||
const defaultButtonList = [
|
||||
{
|
||||
label: '圆形框选',
|
||||
key: 'circle',
|
||||
icon: 'icon-yuan',
|
||||
onClick: () => drawControlRef.current?.drawer?.changeMode?.('draw_circle')
|
||||
},
|
||||
{
|
||||
label: '矩形框选',
|
||||
key: 'rect',
|
||||
icon: 'icon-fang',
|
||||
onClick: () => drawControlRef.current?.drawer?.changeMode?.('draw_rect'),
|
||||
popoverProps: {
|
||||
placement: 'bottom',
|
||||
content: '自定义内容'
|
||||
}
|
||||
},
|
||||
{
|
||||
label: '多边形框选',
|
||||
key: 'more',
|
||||
icon: 'icon-duobianxing',
|
||||
onClick: () => drawControlRef.current?.drawer?.changeMode?.('draw_polygon')
|
||||
},
|
||||
{
|
||||
label: '路径框选',
|
||||
key: 'path',
|
||||
icon: 'icon-lujingkuangxuannor',
|
||||
onClick: () => drawControlRef.current?.drawer?.changeMode?.('draw_line_string')
|
||||
},
|
||||
{
|
||||
label: '测距',
|
||||
key: 'path',
|
||||
icon: 'icon-ceju',
|
||||
onClick: () => drawControlRef.current?.drawer?.changeMode?.('draw_line_string')
|
||||
},
|
||||
{
|
||||
label: '清除',
|
||||
key: 'clear',
|
||||
icon: 'icon-gongjuxiangguanbi',
|
||||
onClick: () => drawControlRef.current?.drawer?.deleteAll()
|
||||
}
|
||||
]
|
||||
```
|
@ -1,2 +1,4 @@
|
||||
export { default as MapBox } from './MapBox';
|
||||
export { default as MapBox } from './mapBox';
|
||||
export type { MapProps, MapRefProps } from './mapBox';
|
||||
export * from 'react-map-gl'
|
||||
export * from './utils'
|
||||
|
@ -6,15 +6,15 @@ import { CSSProperties } from "react";
|
||||
import { MapRef, MapStyle, MapProps as MapBoxProps } from "react-map-gl";
|
||||
import classnames from 'classnames'
|
||||
import { merge } from '@zhst/func'
|
||||
import Tools, { ToolsProps } from './components/tools'
|
||||
import DrawControl, { DrawControlProps, DrawControlRefProps } from './components/drawControl';
|
||||
import { defaultMapConfig } from './utils/constants';
|
||||
import Tools, { ToolsProps } from '../tools'
|
||||
import DrawControl, { DrawControlProps, DrawControlRefProps } from '../drawControl';
|
||||
import { defaultMapConfig } from '../utils/constants';
|
||||
import './index.less';
|
||||
import mapboxDrawStyle from './utils/drawStyle';
|
||||
import Marker, { MarkerProps } from './components/marker';
|
||||
import PopUp, { PopUpProps } from './components/popup';
|
||||
import Cluster, { ClusterProps } from './components/clusters/Clusters';
|
||||
import { clusterLayer } from './components/clusters/layers';
|
||||
import mapboxDrawStyle from '../utils/drawStyle';
|
||||
import Marker, { MarkerProps } from '../marker';
|
||||
import PopUp, { PopUpProps } from '../popup';
|
||||
import Cluster from '../clusters/Clusters';
|
||||
import { clusterLayer } from '../clusters/layers';
|
||||
|
||||
const componentName = 'zhst-map'
|
||||
|
||||
@ -29,15 +29,17 @@ export interface MapProps extends MapBoxProps {
|
||||
mapRef?: MapRef
|
||||
style?: CSSProperties
|
||||
children?: JSX.Element | JSX.Element[] | Array<JSX.Element | undefined>
|
||||
sluterData?: any;
|
||||
clusterData?: mapboxgl.GeoJSONSourceRaw['data'];
|
||||
draw?: boolean
|
||||
showMarker?: boolean // 显示标记点
|
||||
showCluster?: boolean // 显示范围统计
|
||||
showToolBar?: boolean // 是否显示工具箱
|
||||
buttonList?: ToolsProps['buttonList']
|
||||
popUpInfo?: PopUpProps
|
||||
showPopUp?: boolean
|
||||
clusterProps?: ClusterProps
|
||||
clusterProps?: Partial<mapboxgl.GeoJSONSourceRaw>
|
||||
toolsBarOpen?: boolean
|
||||
drawerProps?: DrawControlProps
|
||||
customMarkerRender?: MarkerProps['customMarkerRender']
|
||||
onLoad?: (e: mapboxgl.MapboxEvent<undefined>) => void
|
||||
onDrawCreate?: (e: { features: object[], [key: string]: any }) => void
|
||||
@ -49,6 +51,7 @@ export interface MapProps extends MapBoxProps {
|
||||
}
|
||||
|
||||
export interface MapRefProps {
|
||||
drawer: DrawControlRefProps
|
||||
}
|
||||
|
||||
const MapBox = forwardRef<MapRefProps, MapProps>((props, ref) => {
|
||||
@ -59,23 +62,25 @@ const MapBox = forwardRef<MapRefProps, MapProps>((props, ref) => {
|
||||
width = '100%',
|
||||
draw,
|
||||
markerData = [],
|
||||
sluterData = [],
|
||||
clusterData,
|
||||
popUpInfo = {
|
||||
longitude: 0,
|
||||
latitude: 0
|
||||
},
|
||||
showPopUp,
|
||||
toolsBarOpen,
|
||||
showMarker = true,
|
||||
showMarker = false,
|
||||
showCluster = false,
|
||||
showToolBar = true,
|
||||
clusterProps,
|
||||
drawerProps,
|
||||
interactiveLayerIds = [],
|
||||
buttonList = [
|
||||
{
|
||||
label: '圆形框选',
|
||||
key: 'circle',
|
||||
icon: 'icon-yuan',
|
||||
onClick: () => drawControlRef.current?.drawer?.changeMode?.('simple_select')
|
||||
onClick: () => drawControlRef.current?.drawer?.changeMode?.('draw_circle')
|
||||
},
|
||||
{
|
||||
label: '矩形框选',
|
||||
@ -152,17 +157,20 @@ const MapBox = forwardRef<MapRefProps, MapProps>((props, ref) => {
|
||||
|
||||
useImperativeHandle(ref, () => ({
|
||||
mapRef: mapRef.current,
|
||||
drawer: drawControlRef.current?.drawer,
|
||||
// @ts-ignore
|
||||
drawer: drawControlRef.current?.drawer!,
|
||||
}))
|
||||
|
||||
return (
|
||||
//@ts-ignore
|
||||
<div className={classnames(`${componentName}`)}>
|
||||
<Tools
|
||||
open={toolsBarOpen}
|
||||
buttonList={buttonList}
|
||||
onToolClick={onToolClick}
|
||||
/>
|
||||
{showToolBar && (
|
||||
<Tools
|
||||
open={toolsBarOpen}
|
||||
buttonList={buttonList}
|
||||
onToolClick={onToolClick}
|
||||
/>
|
||||
)}
|
||||
{/* @ts-ignore */}
|
||||
<Map
|
||||
ref={mapRef}
|
||||
@ -190,11 +198,12 @@ const MapBox = forwardRef<MapRefProps, MapProps>((props, ref) => {
|
||||
{/* 范围统计标点 */}
|
||||
{showCluster && !showMarker && (
|
||||
<Cluster
|
||||
id={clusterLayer.id}
|
||||
type="geojson"
|
||||
cluster={true}
|
||||
clusterMaxZoom={14}
|
||||
clusterRadius={50}
|
||||
data={sluterData}
|
||||
data={clusterData}
|
||||
{...clusterProps}
|
||||
/>
|
||||
)}
|
||||
@ -205,8 +214,8 @@ const MapBox = forwardRef<MapRefProps, MapProps>((props, ref) => {
|
||||
onCreate={onDrawCreate}
|
||||
onUpdate={onDrawUpdate}
|
||||
onDelete={onDrawDelete}
|
||||
onSelectionChange={e => console.log('e', e)}
|
||||
{...drawConfig}
|
||||
{...drawerProps}
|
||||
/>
|
||||
)}
|
||||
{children}
|
7
packages/map/src/mapBox/index.ts
Normal file
7
packages/map/src/mapBox/index.ts
Normal file
@ -0,0 +1,7 @@
|
||||
/**
|
||||
* Created by jiangzhixiong on 2024/05/23
|
||||
*/
|
||||
import MapBox from './MapBox'
|
||||
export type { MapProps, MapRefProps } from './MapBox'
|
||||
|
||||
export default MapBox
|
0
packages/map/src/mapBox/interface.ts
Normal file
0
packages/map/src/mapBox/interface.ts
Normal file
@ -9,11 +9,17 @@ import {
|
||||
} from 'react-map-gl'
|
||||
import { Checkbox, ConfigProvider, Image } from '@zhst/meta'
|
||||
import classNames from 'classnames'
|
||||
import cameraBlue from '../../assets/icons/camera_blue.png'
|
||||
import cameraGreen from '../../assets/icons/camera_green.png'
|
||||
import cameraGrey from '../../assets/icons/camera_grey.png'
|
||||
import cameraRed from '../../assets/icons/camera_red.png'
|
||||
import cameraYellow from '../../assets/icons/camera_yellow.png'
|
||||
import cameraBlue from '../assets/icons/camera_blue.png'
|
||||
import cameraGreen from '../assets/icons/camera_green.png'
|
||||
import cameraGrey from '../assets/icons/camera_grey.png'
|
||||
import cameraRed from '../assets/icons/camera_red.png'
|
||||
import cameraYellow from '../assets/icons/camera_yellow.png'
|
||||
import markerBlue from '../assets/icons/marker_blue.png'
|
||||
import markerEscape from '../assets/icons/marker_escape.png'
|
||||
import markerGreen from '../assets/icons/marker_green.png'
|
||||
import markerRedBorder from '../assets/icons/marker_red_border.png'
|
||||
import markerYellow from '../assets/icons/marker_yellow.png'
|
||||
import markerRedTrack from '../assets/icons/marker_red_track.png'
|
||||
import './index.less'
|
||||
|
||||
const { ConfigContext } = ConfigProvider
|
||||
@ -24,6 +30,12 @@ const PIC_MAP = new Map([
|
||||
['camera_grey', cameraGrey],
|
||||
['camera_red', cameraRed],
|
||||
['camera_yellow', cameraYellow],
|
||||
['marker_blue', markerBlue],
|
||||
['marker_escape', markerEscape],
|
||||
['marker_green', markerGreen],
|
||||
['marker_red_border', markerRedBorder],
|
||||
['marker_yellow', markerYellow],
|
||||
['marker_red_track', markerRedTrack],
|
||||
])
|
||||
|
||||
// @ts-ignore
|
||||
@ -37,10 +49,9 @@ export interface MarkerProps extends MapboxMarkerProps {
|
||||
showCheckBox?: boolean
|
||||
showTooltip?: boolean
|
||||
type?: 'camera' | 'cluster' | 'marker';
|
||||
population?: string;
|
||||
status?: 'blue' | 'green' | 'yellow' | 'grey' | 'red_border' | 'escape' | 'escape_border' | 'red_track'; // 摄像头状态
|
||||
onClick?: (e?: MarkerEvent, data?: MarkerProps) => void;
|
||||
onMarkerClick?: (e?: MouseEvent, checked?: boolean, data?: MarkerProps) => void;
|
||||
onCheck?: (e?: MouseEvent, checked?: boolean, data?: MarkerProps) => void;
|
||||
customMarkerRender?: (data: MarkerProps) => ReactNode
|
||||
}
|
||||
|
||||
@ -57,7 +68,7 @@ const Marker = forwardRef<MarkerRefProps, MarkerProps>((props, ref) => {
|
||||
showCheckBox,
|
||||
showTooltip,
|
||||
onClick,
|
||||
onMarkerClick,
|
||||
onCheck,
|
||||
customMarkerRender,
|
||||
...rest
|
||||
} = props
|
||||
@ -89,7 +100,7 @@ const Marker = forwardRef<MarkerRefProps, MarkerProps>((props, ref) => {
|
||||
onClick={(e) => {
|
||||
e.stopPropagation()
|
||||
// @ts-ignore
|
||||
onMarkerClick?.(e, checked, props)
|
||||
onCheck?.(e, checked, props)
|
||||
}}
|
||||
/>
|
||||
)}
|
75
packages/map/src/marker/demo/basic.tsx
Normal file
75
packages/map/src/marker/demo/basic.tsx
Normal file
@ -0,0 +1,75 @@
|
||||
import React, { useRef, useEffect, useState } from 'react';
|
||||
import { MapBox, MarkerProps } from '@zhst/map';
|
||||
import { FloatButton, Switch } from '@zhst/meta';
|
||||
import axios from 'axios'
|
||||
|
||||
const demo = () => {
|
||||
const mapRef = useRef(null);
|
||||
const [markerData, setMarkerData] = useState<MarkerProps[]>([])
|
||||
const [showMarker, setShowMarker] = useState(true)
|
||||
// 初始化
|
||||
const handleMapLoad = (e: mapboxgl.MapboxEvent<undefined>) => {
|
||||
const map = e.target;
|
||||
|
||||
if (!map) return
|
||||
|
||||
map.flyTo({
|
||||
// center: [120,30],
|
||||
// zoom: map?.getMaxZoom(),
|
||||
});
|
||||
};
|
||||
|
||||
const getData = async () => {
|
||||
let res = await axios({
|
||||
method: 'post',
|
||||
url: 'http://10.0.0.120:30003/singer.DeviceService/ListCamera',
|
||||
headers: {
|
||||
Authorization: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MTcwNDAzNzEsImp0aSI6IjExMjgiLCJpYXQiOjE3MTY3ODExNzEsInVzZXJJZCI6MSwidXNlcm5hbWUiOiJhZG1pbiIsImRhdGFSaWdodCI6MiwiY2FtZXJhUmlnaHQiOjEsImdwdVJpZ2h0IjoxLCJ1c2VybGVhZGVySWQiOjAsIm9yZ2FuaXphdGlvbklkIjoxLCJyb2xlSWQiOjF9.XHbXIkXkfUuvqV6_qSV4d20xj-s7I0qOQZgL-zspMDc'
|
||||
},
|
||||
data: {"labelData":[],"filter":{"realtimeProcessingFilter":0,"cameraFilter":[{"opt":"ORNOT","cameraOpt":"CAMERAOPT_TYPE","value":"100"}]},"maxResults":50}
|
||||
});
|
||||
if (res.status === 200) {
|
||||
let markers = []
|
||||
res.data.cameras?.forEach(camera => {
|
||||
markers.push({
|
||||
key: camera.id,
|
||||
id: camera.id,
|
||||
title: camera.name,
|
||||
checked: false,
|
||||
disabled: false,
|
||||
showCheckBox: true,
|
||||
status: ['blue', 'yellow', 'red'][Math.floor(Math.random() * 3)],
|
||||
latitude: camera.latitude,
|
||||
longitude: camera.longitude
|
||||
})
|
||||
})
|
||||
setMarkerData(markers)
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
getData()
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div>
|
||||
<FloatButton>
|
||||
<Switch value={true}/>
|
||||
</FloatButton>
|
||||
<MapBox
|
||||
onLoad={handleMapLoad}
|
||||
ref={mapRef}
|
||||
width='100%'
|
||||
height='800px'
|
||||
markerData={markerData || []}
|
||||
showMarker={showMarker}
|
||||
onMarkerClick={(e, status, data) => {
|
||||
console.log('marker', data)
|
||||
}}
|
||||
>
|
||||
</MapBox>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default demo;
|
53
packages/map/src/marker/index.md
Normal file
53
packages/map/src/marker/index.md
Normal file
@ -0,0 +1,53 @@
|
||||
---
|
||||
category: Components
|
||||
subtitle: 标签
|
||||
title: Marker 标签
|
||||
toc: content
|
||||
group:
|
||||
title: 数据展示
|
||||
order: 1
|
||||
---
|
||||
|
||||
|
||||
<code src="./demo/basic.tsx">基本用法</code>
|
||||
|
||||
## API
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| key | 键 | string | - | - |
|
||||
| id | id | string | - | - |
|
||||
| title | 标题 | string | - | - |
|
||||
| disabled | 是否可选 | boolean | - | - |
|
||||
| checked | 是否选中 | boolean | - | - |
|
||||
| showCheckBox | 是否展示选择框 | boolean | - | - |
|
||||
| showTooltip | 是否显示tooltip | boolean | - | - |
|
||||
| type | 标签类型,目前只支持camera | 'camera' 'cluster' 'marker' | camera | - |
|
||||
| status | 状态值 | IStatus | blue | - |
|
||||
| onClick | 点击事件 | (e?: MarkerEvent, data?: MarkerProps) => void; | - | - |
|
||||
| onCheck | ☑️选中事件 | (e?: MouseEvent, checked?: boolean, data?: MarkerProps) => void; | - | - |
|
||||
| customMarkerRender | 自定义marker | (data: MarkerProps) => ReactNode | - | - |
|
||||
|
||||
> 更多属性参考:react-map-gl 组件: MarkerProps
|
||||
|
||||
## IStatus
|
||||
|
||||
```js
|
||||
// 支持的状态,需要配合当前有的标记使用
|
||||
type IStatus = 'blue' | 'green' | 'yellow' | 'grey' | 'red_border' | 'escape' | 'escape_border' | 'red_track'
|
||||
|
||||
// 目前支持的标记
|
||||
const PIC_MAP = new Map([
|
||||
['camera_blue', cameraBlue],
|
||||
['camera_green', cameraGreen],
|
||||
['camera_grey', cameraGrey],
|
||||
['camera_red', cameraRed],
|
||||
['camera_yellow', cameraYellow],
|
||||
['marker_blue', markerBlue],
|
||||
['marker_escape', markerEscape],
|
||||
['marker_green', markerGreen],
|
||||
['marker_red_border', markerRedBorder],
|
||||
['marker_yellow', markerYellow],
|
||||
['marker_red_track', markerRedTrack],
|
||||
])
|
||||
```
|
@ -141,4 +141,5 @@ const mapboxDrawStyle = [
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
export default mapboxDrawStyle;
|
||||
|
0
packages/map/src/utils/index.md
Normal file
0
packages/map/src/utils/index.md
Normal file
Loading…
Reference in New Issue
Block a user