react-swipe-map
v1.0.7
Published
A React component that displays two leaflet maps side by side
Readme
react-swipe-map
一个基于 React 和 Leaflet 的卷帘地图组件,支持左右图层对比展示,适用于地图数据对比、变化检测等场景。
✨ 特性
- 🗺️ 基于 Leaflet 的卷帘地图组件
- 🔄 支持卷帘模式和普通地图模式切换
- 📍 支持左右图层独立管理
- 🎨 支持自定义控件图标
- 🗂️ 支持底图切换
- 📦 开箱即用,简单易用
📦 安装
npm install react-swipe-map
# 或
yarn add react-swipe-map
# 或
pnpm add react-swipe-map🚀 快速开始
基本使用
import { useEffect, useMemo, useRef, useState } from "react";
import L from "leaflet";
import "leaflet/dist/leaflet.css";
import "./App.scss";
// @ts-ignore
// import { Map } from "react-roll-map-testone";
import Map from "./react-leaflet-side-by-side/index";
// import {}
import RollMapIcon from "./assets/roll-map.png";
import NormalMapIcon from "./assets/normal-map.png";
import BaseMapSelectIcon from "./assets/base-map-select.png";
// @ts-ignore
// import Map from "react-swipe-map";
import { Button } from "antd";
let baseMapList = [
{
mapUrl:
"",
center: [30.5984, 114.3118],
zoomOffset: 0,
zoom: 6,
maxZoom: 18,
type: "4326",
id: "imagesky4326",
name: "天地图WMTS影像(4326)",
checked: false,
},
{
id: "1154781632637710336",
name: "4490天地图影像注记",
icon: "ca3fe93b207545558ba5c601a8d36c31",
mapUrl: "",
type: "4326",
centre: [23.641, 112.983],
bounds: null,
zoom: 7,
zoomOffset: 1,
checked: true,
},
];
function App() {
const [isRollMap, setIsRollMap] = useState(false);
const rollMapRef = useRef(null);
// 在左侧图层上添加一个marker
const addMarkerToLeft = () => {
if (!rollMapRef.current) return;
const marker = L.marker([30.5984, 114.3118], {
pane: "leftPane",
});
(rollMapRef.current as any).addLeftLayers([marker]);
};
const addGeoJsonToRight = () => {
if (!rollMapRef.current) return;
const geojson = L.geoJSON(
{
type: "Feature",
geometry: {
type: "Polygon",
coordinates: [
[
[115.796, 40.4934],
[116.377, 40.3945],
[116.236, 39.9146],
[115.659, 40.0129],
[115.796, 40.4934],
],
],
},
} as any,
{
pane: "rightPane",
style: {
color: "red",
weight: 3,
opacity: 0.5,
fillColor: "red",
fillOpacity: 0.2,
},
},
);
(rollMapRef.current as any).addRightLayers([geojson]);
// 定位到geojson
((rollMapRef.current as any).getMapRef() as L.Map).fitBounds(
geojson.getBounds(),
);
};
return (
<>
<div className="app-container">
<div className="app-content">
<Map
ref={rollMapRef}
leftLayers={[]}
rightLayers={[]}
rollIcon={RollMapIcon}
normalIcon={NormalMapIcon}
baseMapSelectIcon={BaseMapSelectIcon}
baseMapList={baseMapList}
onIsRollMapChange={setIsRollMap}
></Map>
</div>
<div className="app-right">
<Button onClick={addMarkerToLeft} disabled={!isRollMap}>
添加marker到左侧图层
</Button>
<Button onClick={addGeoJsonToRight} disabled={!isRollMap}>
添加geojson到右侧图层
</Button>
</div>
</div>
</>
);
}
export default App;📖 API 文档
Props
| 参数 | 说明 | 类型 | 默认值 | 必填 |
| ------------------- | ---------------- | ------------------------------------ | ------------------------------------------ | ---- |
| leftLayers | 左侧图层列表 | L.Layer[] | [] | 否 |
| rightLayers | 右侧图层列表 | L.Layer[] | [] | 否 |
| mapSettings | 地图配置 | { center: number[], zoom: number } | { center: [35.8617, 104.1954], zoom: 4 } | 否 |
| rollIcon | 卷帘模式图标 | any | 内置图标 | 否 |
| normalIcon | 普通模式图标 | any | 内置图标 | 否 |
| baseMapSelectIcon | 底图选择图标 | any | 内置图标 | 否 |
| baseMapList | 底图列表 | BaseMapConfig[] | [] | 否 |
| onIsRollMapChange | 卷帘模式变化回调 | (isRollMap: boolean) => void | - | 否 |
BaseMapConfig
interface BaseMapConfig {
id: string;
name: string;
mapUrl: string;
type: "4326" | "3857";
centre?: [number, number];
zoom?: number;
zoomOffset?: number;
maxZoom?: number;
checked?: boolean;
icon?: string;
}Ref Methods
通过 ref 可以访问以下方法:
| 方法名 | 说明 | 类型 |
| --------------------- | ---------------------- | ----------------------------- |
| addLeftLayers | 添加左侧图层 | (layers: L.Layer[]) => void |
| addRightLayers | 添加右侧图层 | (layers: L.Layer[]) => void |
| clearLeftLayers | 清除左侧图层 | () => void |
| clearRightLayers | 清除右侧图层 | () => void |
| getMapInstance | 获取地图实例 | () => L.Map \| null |
| toggleRollMap | 切换卷帘模式 | (enabled: boolean) => void |
| getIsRollMap | 获取当前是否为卷帘模式 | () => boolean |
| getLeftLayersGroup | 获取左侧图层组 | () => L.LayerGroup \| null |
| getRightLayersGroup | 获取右侧图层组 | () => L.LayerGroup \| null |
| getMapRef | 获取地图引用 | () => L.Map \| null |
🎯 使用场景
- 🗺️ 地图数据对比:对比不同时期的地图数据
- 📍 变化检测:检测地理数据的变化情况
- 🎨 图层对比:对比不同图层的数据差异
- 📊 数据分析:辅助地理数据分析和可视化
💡 注意事项
Leaflet 样式:使用前需要引入 Leaflet 的 CSS 文件:
import "leaflet/dist/leaflet.css";Pane 设置:添加图层时,可以通过
pane参数指定图层所属的 pane:leftPane:左侧图层rightPane:右侧图层
卷帘模式:只有在卷帘模式下,左右图层才会分开显示
图层管理:使用
addLeftLayers和addRightLayers方法添加图层时,会自动更新卷帘控制器
🔧 依赖
- React >= 18.2.0
- React DOM >= 18.2.0
- Leaflet >= 1.9.4
- leaflet-side-by-side >= 2.2.0
- antd >= 6.2.3
📝 更新日志
v1.0.2 (当前版本)
- ✨ 初始版本发布
- 🗺️ 支持卷帘地图基本功能
- 🔄 支持卷帘模式和普通地图模式切换
- 📍 支持左右图层独立管理
- 🎨 支持自定义控件图标
- 🗂️ 支持底图切换
🚧 后续优化计划
- [ ] 添加更多地图控件(比例尺、鹰眼图等)
- [ ] 支持更多地图服务(WMS、WFS 等)
- [ ] 优化性能,减少不必要的渲染
- [ ] 添加更多示例和文档
- [ ] 支持 TypeScript 类型定义优化
- [ ] 添加单元测试
- [ ] 支持自定义主题
- [ ] 支持移动端适配
🤝 贡献
欢迎提交 Issue 和 Pull Request!
📄 许可证
MIT License
📮 联系方式
如有问题或建议,请通过以下方式联系:
- 提交 Issue:GitHub Issues
- 邮件:[email protected]
⭐ 如果这个项目对你有帮助,请给一个 Star 支持一下!
