# VuePress PhotoMap Plugin

一个强大的VuePress2插件，用于在文章中展示带有地理位置信息的照片地图，类似Apple相册的PhotoMap功能。该插件专门适配vuepress-plume主题。

## ✨ 功能特性

- 📍 **自动GPS解析**: 从照片EXIF数据中自动提取GPS坐标信息
- 🗺️ **交互式地图**: 基于MapLibre GL JS v5.6.2的高性能地图显示
- 🏔️ **3D地形效果**: 支持地形高程、山体阴影和大气效果
- 🌍 **地球投影**: 支持地球投影和混合卫星地图样式
- 🖼️ **照片查看器**: 集成PhotoSwipe提供优雅的照片浏览体验
- 📱 **响应式设计**: 完美适配桌面和移动设备
- 🎨 **美观界面**: 现代化设计，支持深色模式
- ♿ **无障碍访问**: 支持键盘导航和屏幕阅读器
- ⚡ **性能优化**: 异步加载，内存管理，缓存机制

## 📦 安装

```bash
npm install vuepress-plugin-photomap
# 或
yarn add vuepress-plugin-photomap
# 或
pnpm add vuepress-plugin-photomap
```

## 🚀 快速开始

### 1. 配置插件

在你的VuePress配置文件中添加插件：

```typescript
// .vuepress/config.ts
import { defineUserConfig } from 'vuepress'
import { photoMapPlugin } from 'vuepress-plugin-photomap'

export default defineUserConfig({
  plugins: [
    photoMapPlugin({
      // 基本地图配置
      mapStyle: 'https://demotiles.maplibre.org/style.json',
      defaultZoom: 10,
      maxZoom: 18,
      markerSize: 40,
      
      // 功能开关
      enablePhotoSwipe: true,
      enableTerrain: true,          // 启用地形效果
      enableSatelliteHybrid: true,  // 启用混合卫星地图
      
      // 地形配置
      terrainExaggeration: 1,       // 地形夸张程度 (0.5-2.0)
      
      // MapTiler API密钥 (用于地形和卫星地图)
      mapTilerApiKey: 'YOUR_MAPTILER_API_KEY'  // 请替换为你的API密钥
    })
  ]
})
```

### 2. 在Markdown中使用

在你的Markdown文件中使用photomap容器：

```markdown
::: photomap
![海滩风景](./images/beach.jpg)
![山峰日出](./images/mountain.jpg)
![城市夜景](./images/city.jpg)
:::
```

**🆕 新增样式选项**：

```markdown
<!-- 地形图模式，启用3D -->
::: photomap type="terrain" enable3D="true"
![山景照片](./images/mountain.jpg)
:::

<!-- 简约地图，2D模式 -->
::: photomap type="simple" enable3D="false"
![街景照片](./images/street.jpg)
:::

<!-- 卫星图，关闭大气效果 -->
::: photomap type="satellite" enableAtmosphere="false"
![城市照片](./images/city.jpg)
:::

<!-- 自定义地形夸张度，显示样式切换器 -->
::: photomap terrainExaggeration="2" showStyleSwitcher="true"
![峡谷照片](./images/canyon.jpg)
:::
```

### 3. 获取 MapTiler API 密钥

为了启用地形效果和混合卫星地图，你需要获取一个免费的 MapTiler API 密钥：

1. 访问 [MapTiler 官网](https://www.maptiler.com/)
2. 注册免费账户
3. 在控制台中创建新的 API 密钥
4. 将密钥添加到你的 VuePress 配置中

> **注意**: MapTiler 提供慷慨的免费配额，对于大多数个人博客来说足够使用。

## ⚙️ 配置选项

| 选项 | 类型 | 默认值 | 描述 |
|------|------|--------|------|
| `mapStyle` | `string` | `'auto'` | 地图样式URL（自动根据类型选择） |
| `defaultZoom` | `number` | `10` | 默认缩放级别 |
| `maxZoom` | `number` | `18` | 最大缩放级别 |
| `markerSize` | `number` | `40` | 照片标记大小（像素） |
| `clusterRadius` | `number` | `50` | 标记聚合半径 |
| `enablePhotoSwipe` | `boolean` | `true` | 是否启用PhotoSwipe图片查看器 |
| `photoSwipeOptions` | `object` | `{}` | PhotoSwipe自定义选项 |
| `enableTerrain` | `boolean` | `true` | 是否启用3D地形效果 |
| `enableSatelliteHybrid` | `boolean` | `true` | 是否启用混合卫星地图 |
| `enableAtmosphere` | `boolean` | `true` | 是否启用大气效果 |
| `terrainExaggeration` | `number` | `1` | 地形夸张程度（0.5-2.0） |
| `mapTilerApiKey` | `string` | `''` | MapTiler API密钥（用于地形和卫星地图） |
| **🆕 新增选项** | | | |
| `mapType` | `'satellite' \| 'terrain' \| 'simple'` | `'satellite'` | 地图类型 |
| `enable3D` | `boolean` | `true` | 是否启用3D模式 |
| `showStyleSwitcher` | `boolean` | `true` | 是否显示样式切换器 |

## 📖 详细用法

### 基础用法

最简单的使用方式是在photomap容器中放置图片：

```markdown
::: photomap
![描述文本](图片路径或URL)
:::
```

### 高级用法

你可以在一个photomap容器中包含多张图片：

```markdown
::: photomap
![2023年春游 - 樱花盛开的公园](./photos/sakura-park.jpg)
![登山途中 - 云海景观](./photos/mountain-clouds.jpg)
![城市探索 - 夜晚的天际线](./photos/city-skyline.jpg)
![海滨度假 - 日落时分](./photos/sunset-beach.jpg)
:::
```

### 图片要求

为了正常显示在地图上，图片需要包含GPS EXIF数据。支持的图片格式：

- JPEG/JPG（推荐，最好的EXIF支持）
- PNG（部分支持EXIF）
- TIFF
- WebP（现代浏览器）

## 🛠️ 开发指南

### 项目结构

```
src/
├── index.ts                 # 插件入口文件
├── client/
│   ├── clientConfig.ts      # 客户端配置
│   ├── components/
│   │   └── PhotoMap.vue     # 主要地图组件
│   ├── composables/
│   │   ├── useExifReader.ts # EXIF数据读取
│   │   ├── useMapLibre.ts   # 地图功能封装
│   │   └── usePhotoSwipe.ts # PhotoSwipe集成
│   ├── utils/
│   │   ├── coordinateConvert.ts # 坐标转换工具
│   │   └── imageLoader.ts   # 图片加载工具
│   └── styles/
│       └── photomap.scss    # 组件样式
```

### 本地开发

```bash
# 克隆项目
git clone <repository-url>
cd vuepress-plugin-photomap

# 安装依赖
npm install

# 开发模式
npm run dev

# 构建
npm run build
```

## 🎨 自定义样式

插件提供了丰富的CSS类名供自定义样式：

```css
/* 主容器 */
.photomap-container {
  /* 自定义样式 */
}

/* 地图容器 */
.photomap-map {
  /* 自定义地图样式 */
}

/* 照片标记 */
.photo-marker {
  /* 自定义标记样式 */
}

/* 照片列表 */
.photomap-photos {
  /* 自定义照片列表样式 */
}
```

## 🌍 地图样式

支持任何兼容MapLibre GL JS的地图样式：

### 免费地图样式

```typescript
// OpenStreetMap风格
mapStyle: 'https://demotiles.maplibre.org/style.json'

// 地形图风格
mapStyle: 'https://api.maptiler.com/maps/terrain/style.json?key=YOUR_KEY'
```

### 商业地图样式

```typescript
// Mapbox（需要API密钥）
mapStyle: 'mapbox://styles/mapbox/streets-v11'

// Google Maps风格（需要配置）
mapStyle: 'https://maps.googleapis.com/...'
```

## 🔧 故障排除

### 常见问题

1. **图片不显示在地图上**
   - 确保图片包含GPS EXIF数据
   - 检查图片URL是否可访问
   - 验证图片格式支持

2. **地图无法加载**
   - 检查网络连接
   - 验证地图样式URL
   - 确保MapLibre GL JS正确加载

3. **PhotoSwipe不工作**
   - 检查enablePhotoSwipe配置
   - 确保PhotoSwipe依赖正确安装

### 调试模式

开启浏览器开发者工具，查看控制台错误信息：

```javascript
// 在浏览器控制台中检查PhotoMap实例
console.log(window.__PHOTOMAP_DEBUG__)
```

## 📋 浏览器支持

- ✅ Chrome 61+
- ✅ Firefox 60+
- ✅ Safari 11.1+
- ✅ Edge 79+
- ⚠️ IE 11（有限支持）

## 🤝 贡献

欢迎贡献代码！请阅读 [CONTRIBUTING.md](./CONTRIBUTING.md) 了解详细信息。

### 开发流程

1. Fork 项目
2. 创建功能分支
3. 提交变更
4. 推送分支
5. 创建 Pull Request

## 📄 许可证

[MIT License](./LICENSE)

## 🙏 致谢

感谢以下开源项目：

- [VuePress](https://vuepress.vuejs.org/)
- [MapLibre GL JS](https://maplibre.org/)
- [PhotoSwipe](https://photoswipe.com/)
- [exif-js](https://github.com/exif-js/exif-js)

## 📞 支持

如果你遇到问题或有建议，请：

- 🐛 [提交Issue](https://github.com/your-username/vuepress-plugin-photomap/issues)
- 💬 [参与讨论](https://github.com/your-username/vuepress-plugin-photomap/discussions)
- 📧 发邮件至: your-email@example.com

---

<div align="center">
  Made with ❤️ for the VuePress community
</div>
