# Heritage Globe - 中国文物全球分布地图 ## 项目概述 基于 OpenGridWorks 技术架构,构建一个展示中国流散文物全球分布的交互式地图系统。 ## 技术栈 ### 核心框架 - **Next.js 15** - React 服务端渲染框架 - **TypeScript** - 类型安全 - **Tailwind CSS** - 样式系统 ### 地图引擎 - **MapLibre GL JS 4.x** - 开源矢量地图引擎(Mapbox GL 的开源替代) - **PMTiles** - 云原生瓦片格式,支持按需加载 ### 数据层 - **GeoJSON** - 文物坐标数据格式 - **Tippecanoe** - GeoJSON → PMTiles 转换工具 ### UI 组件 - **Radix UI** - 无障碍组件库(对话框、下拉菜单等) - **Lucide React** - 图标库 ### 国际化 - **next-intl** - Next.js 国际化解决方案 - 支持中文(简体)/ English 双语切换 - URL 路径自动添加语言前缀(/zh、/en) ## 项目结构 ``` heritage-globe/ ├── app/ # Next.js App Router │ ├── [locale]/ # 国际化路由 │ │ ├── layout.tsx # 语言布局 │ │ └── page.tsx # 首页(地图页) │ ├── layout.tsx # 根布局 │ └── globals.css # 全局样式 ├── messages/ # 翻译文件 │ ├── zh.json # 中文翻译 │ └── en.json # 英文翻译 ├── components/ # React 组件 │ ├── map/ # 地图相关组件 │ │ ├── MapContainer.tsx # 地图容器 │ │ ├── LayerControl.tsx # 图层控制 │ │ └── RelicMarker.tsx # 文物标记 │ ├── sidebar/ # 侧边栏组件 │ │ ├── Sidebar.tsx # 侧边栏容器 │ │ ├── FilterPanel.tsx # 筛选面板 │ │ └── SearchBox.tsx # 搜索框 │ └── ui/ # 通用 UI 组件 ├── lib/ # 工具函数 │ ├── map-utils.ts # 地图工具函数 │ ├── pmtiles-loader.ts # PMTiles 加载器 │ └── data-processor.ts # 数据处理 ├── public/ # 静态资源 │ ├── tiles/ # PMTiles 瓦片文件 │ └── icons/ # 自定义图标 ├── data/ # 原始数据 │ └── relics.geojson # 文物 GeoJSON 数据 └── types/ # TypeScript 类型定义 └── relic.ts ``` ## 搭建步骤 ### 阶段 1: 项目初始化 ```bash # 创建 Next.js 项目 npx create-next-app@latest . --typescript --tailwind --app --no-src-dir --import-alias "@/*" # 安装核心依赖 npm install maplibre-gl pmtiles # 安装 UI 组件 npm install @radix-ui/react-dialog @radix-ui/react-select @radix-ui/react-slider npm install lucide-react # 安装国际化 npm install next-intl # 安装开发工具 npm install -D @types/geojson ``` ### 阶段 2: 国际化配置 **2.1 创建翻译文件** `messages/zh.json`: ```json { "nav": { "title": "中国文物全球分布", "search": "搜索文物或博物馆" }, "map": { "layers": "图层", "filters": "筛选器", "reset": "重置" }, "dynasty": { "shang": "商周", "qin": "秦汉", "tang": "隋唐", "song": "宋元", "ming": "明清" }, "category": { "bronze": "青铜器", "porcelain": "瓷器", "painting": "书画", "jade": "玉器" } } ``` `messages/en.json`: ```json { "nav": { "title": "Chinese Cultural Relics Worldwide", "search": "Search relics or museums" }, "map": { "layers": "Layers", "filters": "Filters", "reset": "Reset" }, "dynasty": { "shang": "Shang-Zhou", "qin": "Qin-Han", "tang": "Sui-Tang", "song": "Song-Yuan", "ming": "Ming-Qing" }, "category": { "bronze": "Bronze", "porcelain": "Porcelain", "painting": "Painting", "jade": "Jade" } } ``` **2.2 配置 next-intl** `i18n.ts`: ```typescript import { getRequestConfig } from 'next-intl/server'; export default getRequestConfig(async ({ locale }) => ({ messages: (await import(`./messages/${locale}.json`)).default })); ``` `middleware.ts`: ```typescript import createMiddleware from 'next-intl/middleware'; export default createMiddleware({ locales: ['zh', 'en'], defaultLocale: 'zh', localeDetection: true }); export const config = { matcher: ['/', '/(zh|en)/:path*'] }; ``` ### 阶段 3: 地图基础设施 **3.1 配置 MapLibre GL CSS** - 在 `app/[locale]/layout.tsx` 中引入 `maplibre-gl/dist/maplibre-gl.css` **3.2 创建地图容器组件** - `components/map/MapContainer.tsx` - 初始化 MapLibre 地图实例 - 设置中国为初始中心点(北京:116.4074, 39.9042) - 使用 Carto 深色底图 **3.3 创建语言切换器** ```typescript // components/LanguageSwitcher.tsx 'use client'; import { useLocale } from 'next-intl'; import { useRouter, usePathname } from 'next/navigation'; export function LanguageSwitcher() { const locale = useLocale(); const router = useRouter(); const pathname = usePathname(); const toggleLanguage = () => { const newLocale = locale === 'zh' ? 'en' : 'zh'; router.push(pathname.replace(`/${locale}`, `/${newLocale}`)); }; return ( ); } ``` **3.4 集成 PMTiles** - `lib/pmtiles-loader.ts` - 实现 PMTiles Protocol 注册 - 支持本地和远程瓦片加载 ### 阶段 4: 数据层 **4.1 定义数据结构(支持双语)** ```typescript // types/relic.ts interface Relic { id: string; name: { zh: string; // 中文名称 en: string; // 英文名称 }; dynasty: string; // 朝代(使用 key,如 "tang") category: string; // 类别(使用 key,如 "bronze") currentLocation: { zh: string; // 中文地点 en: string; // 英文地点 }; museum: { zh: string; // 中文机构名 en: string; // 英文机构名 }; coordinates: [number, number]; // 经纬度 year?: string; // 年代 description?: { zh: string; en: string; }; imageUrl?: string; // 图片 URL protectionLevel?: string; // 保护级别 } ``` **4.2 准备示例数据(双语)** - 创建 `data/relics.geojson` - 至少包含 10-20 个示例文物点位 - 覆盖英国、法国、美国、日本等主要国家 **4.3 生成 PMTiles** ```bash # 安装 tippecanoe(macOS) brew install tippecanoe # 转换 GeoJSON → PMTiles tippecanoe -o public/tiles/relics.pmtiles \ --minimum-zoom=0 \ --maximum-zoom=14 \ --drop-densest-as-needed \ --extend-zooms-if-still-dropping \ data/relics.geojson ``` ### 阶段 5: 图层系统 **4.1 朝代图层** - 根据朝代(商周、秦汉、隋唐、宋元、明清等)分层 - 不同朝代使用不同颜色标识 - 支持单独开关 **4.2 类别图层** - 青铜器、瓷器、书画、玉器、石刻等 - 使用不同图标表示 **4.3 气泡样式** - 根据文物重要性(保护级别)调整大小 - 聚类显示(缩小时自动聚合) ### 阶段 6: 交互功能 **5.1 侧边栏控制面板** - 图层树形结构(类似 OpenGridWorks) - 拖拽排序 - 开关动画 **5.2 筛选器** - 朝代范围滑块 - 类别多选 - 保护级别筛选 - 国家/地区筛选 **5.3 搜索功能** - 文物名称模糊搜索 - 收藏机构搜索 - 搜索结果定位到地图 **5.4 详情弹窗** - 点击文物标记显示详情卡片 - 展示图片、名称、年代、描述等 - 提供外部链接(如博物馆官网) ### 阶段 7: 视觉优化 **6.1 主题样式** - 采用深色主题(类似 OpenGridWorks) - 定义 CSS 变量统一配色 **6.2 响应式设计** - 桌面端:侧边栏固定 - 移动端:抽屉式侧边栏 **6.3 动画效果** - 图层切换动画 - 标记 hover 效果 - 平滑缩放过渡 ### 阶段 8: 高级功能(可选) **7.1 时间轴** - 按文物流失年代播放动画 - 展示流散历程 **7.2 统计面板** - 总文物数量 - 分布国家统计 - 朝代占比图表 **7.3 分享功能** - 生成带参数的分享链接 - 截图导出 **7.4 预设视图** - "丝绸之路文物" - "战争掠夺文物" - "敦煌流散文物" ## 核心配置文件 ### `next.config.js` ```javascript /** @type {import('next').NextConfig} */ const nextConfig = { webpack: (config) => { // 支持 PMTiles 二进制文件 config.module.rules.push({ test: /\.pmtiles$/, type: 'asset/resource', }); return config; }, }; module.exports = nextConfig; ``` ### `tailwind.config.ts` ```typescript import type { Config } from 'tailwindcss'; const config: Config = { darkMode: 'class', content: [ './app/**/*.{js,ts,jsx,tsx,mdx}', './components/**/*.{js,ts,jsx,tsx,mdx}', ], theme: { extend: { colors: { map: { bg: '#0a0e27', panel: '#1a1e3a', accent: '#3b82f6', }, }, }, }, plugins: [], }; export default config; ``` ## 开发流程 1. **初始化项目** → 安装依赖 2. **搭建地图** → 验证 MapLibre 正常渲染 3. **加载数据** → 展示示例文物点位 4. **实现图层** → 按朝代/类别分层 5. **添加交互** → 点击、筛选、搜索 6. **优化样式** → 深色主题、响应式 7. **测试部署** → Vercel 一键部署 ## 数据来源建议 - **公开数据集**: UNESCO、大英博物馆、卢浮宫等开放数据 - **研究报告**: 流失文物统计报告 - **众包贡献**: 社区上传补充 ## 参考资源 - [MapLibre GL JS 文档](https://maplibre.org/maplibre-gl-js/docs/) - [PMTiles 规范](https://github.com/protomaps/PMTiles) - [OpenGridWorks](https://opengridworks.com) - 参考实现 - [GeoJSON 规范](https://geojson.org/) ## 许可证 MIT License - 开源友好 --- **预计开发时间**: 2-3 天(核心功能) **扩展功能**: 根据需求迭代