[English](./README.md) | 简体中文

# @ray-js/gyro-map-component

[![latest](https://img.shields.io/npm/v/@ray-js/gyro-map-component/latest.svg)](https://www.npmjs.com/package/@ray-js/gyro-map-component) [![download](https://img.shields.io/npm/dt/@ray-js/gyro-map-component.svg)](https://www.npmjs.com/package/@ray-js/gyro-map-component)

> 惯导扫地机地图组件

## 安装

```sh
$ yarn add @ray-js/gyro-map-component @ray-js/gyro-map-sdk
// 或者
$ npm install @ray-js/gyro-map-component @ray-js/gyro-map-sdk
```

## 开发

```sh
# 安装依赖
yarn

# 实时编译Demo代码
yarn start:tuya
```

## 使用

## GridMapComponent (栅格型地图)

### 组件属性

| 属性       | 类型                                                | 必填 | 描述                       |
| ---------- | --------------------------------------------------- | ---- | -------------------------- |
| config     | `DeepPartialGridMapConfig`                          | 否   | 地图配置选项               |
| onMapReady | `(funcs: MapApiFuncGridMap, mapId: string) => void` | 否   | 地图初始化完成时的回调函数 |

### 配置选项 (DeepPartialGridMapConfig)

#### 基础配置

| 属性                  | 类型          | 描述                       | 默认值                    |
| --------------------- | ------------- | -------------------------- | ------------------------- |
| backgroundColor       | `string`      | 地图背景色                 | '#f6f8fa'                 |
| fitMarginPercent      | `number`      | 地图缩放适配边距百分比     | 20                        |
| containerTop          | `string`      | 地图容器的 top 位置        | '0px'                     |
| containerLeft         | `string`      | 地图容器的 left 位置       | '0px'                     |
| containerWidth        | `string`      | 地图容器的宽度             | '100%'                    |
| containerHeight       | `string`      | 地图容器的高度             | '100%'                    |
| minZoom               | `number`      | 地图容器的最小缩放级别     | 0.5                       |
| maxZoom               | `number`      | 地图容器的最大缩放级别     | 2                         |
| robotColor            | `ColorSource` | 机器坐标点颜色             | '#2ca7ff'                 |
| robotRadius           | `number`      | 机器坐标点半径             | 10                        |
| cellSize              | `number`      | 栅格地图单元格大小（像素） | 20                        |
| mapCurrentColor       | `ColorSource` | 栅格地图当前点颜色         | 'rgba(44, 167, 255, 0.1)' |
| mapBarrierColor       | `ColorSource` | 栅格地图障碍物颜色         | '#8da8ba'                 |
| mapCleanColor         | `ColorSource` | 栅格地图清洁点颜色         | 'rgba(44, 167, 255, 0.1)' |
| mapUnknownColor       | `ColorSource` | 栅格地图未知点颜色         | 'rgba(255, 255, 255, 0)'  |
| showPath              | `boolean`     | 是否显示栅格地图路径       | true                      |
| pathColor             | `ColorSource` | 栅格地图路径颜色           | '#42657f'                 |
| pathWidth             | `number`      | 栅格地图路径宽度           | 4                         |
| robotStrokeColor      | `ColorSource` | 栅格地图机器人点边框颜色   | 'ffffff'                  |
| robotStrokeWidth      | `number`      | 栅格地图机器人点边框宽度   | 4                         |
| chargingStationSrc    | `string`      | 栅格地图充电桩图标路径     | -                         |
| chargingStationHeight | `number`      | 栅格地图充电桩图标高度     | 32                        |
| chargingStationWidth  | `number`      | 栅格地图充电桩图标宽度     | 32                        |

#### 地图 API 函数 (MapApiFuncGridMap)

地图初始化完成后，`onMapReady` 回调函数会提供以下 API 方法：

#### drawMap(mapData: GridMapData): void

绘制栅格地图。

**参数：**

- `mapData`: GridMapData - 地图数据，包含栅格地图的点类型数据

**用法：**

```javascript
const handleMapReady = (api, mapId) => {
  api.drawMap({
    origin: {x: 0, y: 0},
    width: 20,
    height: 20,
    data: [...] // 栅格地图点类型数据
  });
};
```

#### drawCleanPath(pathData: MapPoint[]): void

绘制清扫路径。

**参数：**

- `pathData`: MapPoint[] - 清扫路径点数组

**用法：**

```javascript
const handleMapReady = (api, mapId) => {
  api.drawCleanPath([
    { x: 5, y: 10 },
    { x: 10, y: 15 },
    { x: 15, y: 20 },
  ]);
};
```

#### drawChargingStation(position: MapPoint): void

绘制充电桩。

**参数：**

- `position`: MapPoint - 充电桩位置点

**用法：**

```javascript
const handleMapReady = (api, mapId) => {
  api.drawChargingStation({ x: 5, y: 5 });
};
```

### 使用示例

```tsx
import { GridMapComponent } from '@ray-js/gyro-map-component';
import { MapApiFuncGridMap } from '@ray-js/gyro-map-sdk';
export default () => {
  // 通过接口或mqtt流服务获取地图数据及配置（可参考模板）
  const { mapData, mapConfig } = useMapData(subRecordId);

  const [mapApi, setMapApi] = useState<MapApiFuncGridMap | null>(null);

  useEffect(() => {
    if (mapData && mapApi) {
      const gridMapData = parseGridMapData([mapData], mapConfig, false);

      const { mapData: convertedMapData, pathData: convertedPathData, pilePosition } = gridMapData;

      mapApi.drawMap(convertedMapData);
      convertedPathData.length > 0 && mapApi.drawCleanPath(convertedPathData);

      pilePosition && mapApi.drawChargingStation(pilePosition);
    }
  }, [mapData, mapApi]);

  return (
    <GridMapComponent
      config={{
        backgroundColor: '#f6f8fa',
        containerHeight: '80vh',
      }}
      onMapReady={setMapApi}
    />
  );
};
```

## CoverageMapComponent (涂抹型地图)

### 组件属性

| 属性       | 类型                                                    | 必填 | 描述                       |
| ---------- | ------------------------------------------------------- | ---- | -------------------------- |
| config     | `DeepPartial<CoverageMapConfig>`                        | 否   | 地图配置选项               |
| onMapReady | `(funcs: MapApiFuncCoverageMap, mapId: string) => void` | 否   | 地图初始化完成时的回调函数 |

### 配置选项 (CoverageMapConfig)

#### 基础配置

| 属性             | 类型          | 描述                   | 默认值    |
| ---------------- | ------------- | ---------------------- | --------- |
| backgroundColor  | `string`      | 地图背景色             | '#f6f8fa' |
| fitMarginPercent | `number`      | 地图缩放适配边距百分比 | 20        |
| containerTop     | `string`      | 地图容器的 top 位置    | '0px'     |
| containerLeft    | `string`      | 地图容器的 left 位置   | '0px'     |
| containerWidth   | `string`      | 地图容器的宽度         | '100%'    |
| containerHeight  | `string`      | 地图容器的高度         | '100%'    |
| minZoom          | `number`      | 地图容器的最小缩放级别 | 0.5       |
| maxZoom          | `number`      | 地图容器的最大缩放级别 | 2         |
| robotColor       | `ColorSource` | 机器坐标点颜色         | '#fe5332' |
| robotRadius      | `number`      | 机器坐标点半径         | 0.5       |
| borderColor      | `ColorSource` | 涂抹型地图边框颜色     | '#8da8ba' |
| borderWidth      | `number`      | 涂抹型地图边框宽度     | 1         |
| fillColor        | `ColorSource` | 涂抹型地图填充颜色     | '#e1f0fb' |
| fillWidth        | `number`      | 涂抹型地图填充宽度     | 1.5       |

#### 地图 API 函数 (MapApiFuncCoverageMap)

地图初始化完成后，`onMapReady` 回调函数会提供以下 API 方法：

#### drawMap(points: Array<MapPoint>): void

绘制涂抹型地图边界。

**参数：**

- `points`: Array<MapPoint> - 边界点数据，用于构建 SVG 路径

**用法：**

```javascript
const handleMapReady = (api, mapId) => {
  api.drawMap([
    { x: 0, y: 0 },
    { x: 10, y: 0 },
    { x: 10, y: 10 },
    { x: 0, y: 10 },
    { x: 0, y: 0 },
  ]);
};
```

#### drawRobot(point: MapPoint): void

绘制机器人位置。

**参数：**

- `point`: MapPoint - 机器人当前位置点

**用法：**

```javascript
const handleMapReady = (api, mapId) => {
  api.drawRobot({ x: 5, y: 5 });
};
```

### 使用示例

```tsx
import { CoverageMapComponent } from '@ray-js/gyro-map-component';
import { MapApiFuncCoverageMap } from '@ray-js/gyro-map-sdk';

export default () => {
  // 通过接口或mqtt流服务获取地图数据及配置（可参考模板）
  const { mapData, mapConfig } = useMapData(subRecordId);
  const [mapApi, setMapApi] = useState<MapApiFuncCoverageMap | null>(null);

  useEffect(() => {
    if (mapData && mapApi) {
      const { pointsData, currentPos } = parseMapData([mapData], mapConfig);

      mapApi.drawMap(pointsData);

      currentPos && mapApi.drawRobot(currentPos);
    }
  }, [mapData, mapApi]);

  return (
    <CoverageMapComponent
      config={{
        backgroundColor: '#f6f8fa',
        containerHeight: '80vh',
        borderColor: '#000000',
        borderWidth: 2,
        fillColor: '#87cefa',
        fillWidth: 1,
        robotColor: '#ff0000',
        robotRadius: 6,
      }}
      onMapReady={setMapApi}
    />
  );
};
```

## 注意事项

- **类型说明**:

  - `ColorSource` 类型表示可接受的颜色值格式，通常包括颜色字符串（如 '#RRGGBB'）或其他颜色表示方式
  - `DeepPartial<T>` 表示配置对象中的所有属性都是可选的，并且嵌套对象的属性也是可选的
  - `MapPoint` 类型表示具有 x 和 y 坐标的点对象，例如 `{ x: 10, y: 20 }`
  - `GridMapData` 包含栅格地图的宽度、高度和点类型数据数组

- **地图类型选择**:

  - **栅格型地图 (GridMap)**: 适用于需要精确显示障碍物、已清扫区域和未清扫区域的场景，常用于复杂室内环境下的精确导航和清扫路径记录
  - **涂抹型地图 (CoverageMap)**: 适用于只关注清扫覆盖范围的场景，通过边界绘制来展示清扫区域，视觉呈现更简洁

- **版本依赖**:
  - 确保安装匹配版本的依赖库 `@ray-js/gyro-map-sdk`，避免 API 不兼容问题
  - App 基线版本 >= **6.7.0**