kevtoe/worldview

GitHub: kevtoe/worldview

一个基于 CesiumJS 的实时 3D 地球仪态势感知仪表板,聚合航班、卫星、船舶、地震、交通和 CCTV 等多源公开数据,提供沉浸式的全球实时态势可视化。

Stars: 216 | Forks: 38

Worldview real-time global intelligence cover

WORLDVIEW

将世界视为一个实时系统。
在一个交互式 3D 地球仪上探索航班、卫星、船舶、地震、交通和公共 CCTV 直播流。

打开实时地球仪 · 部署你自己的副本

React 19 TypeScript CesiumJS Vite 7 Tailwind 4 Express 5

Live demo Deploy with Vercel

https://github.com/user-attachments/assets/b2bd05d2-f7be-49c8-a8c6-452b6b60cb34 ## 概述 Worldview 是一个全栈态势感知仪表板,它将多个实时的公开数据源聚合到一个交互式 3D 地球仪上。它将高密度的战术界面与可选的 CRT、夜视和热成像渲染模式结合在一起——既不隐藏底层数据源,也不要求必须配置所有 API key 才能开始使用。 ### 核心功能 | 图层 | 数据源 | 更新频率 | 描述 | |---|---|---|---| | ✈️ **航班** | FlightRadar24 + adsb.fi | 5–20 秒 | 全球约 27,000 架航空器,包含高度分层、航线弧、航位推算 | | 🛰️ **卫星** | CelesTrak TLE + SGP4 | 2 秒推算 | 实时轨道位置、轨道路径、地面轨迹、天底线 | | 🌋 **地震** | USGS GeoJSON | 60 秒 | 过去 24 小时内,震级缩放的脉冲标记并带有颜色编码 | | 🚗 **交通** | OpenStreetMap Overpass | 按需 | 道路网络覆盖层,带有动态车辆粒子模拟 | | 🚢 **海军 / AIS** | AISStream.io WebSocket | 30 秒(20 秒突发 + 60 秒缓存) | 全球船舶追踪,包含船舶类型分类、航向轨迹、航位推算 | | 📹 **CCTV** | TfL, Austin TX, Transport NSW | 5 分钟 | 来自伦敦、奥斯汀和新南威尔士州的实时摄像头流 | ## 截图 界面特性包括: - **启动画面** — 采用打字机动画的军用风格启动序列 - **操作面板**(左侧) — 图层开关、着色器模式、高度过滤器 - **情报流**(右侧) — 来自所有数据源的实时事件流 - **状态栏**(底部) — 摄像机坐标(DMS)、UTC 时钟、实体计数 - **追踪实体面板** — 锁定详情视图(按 ESC 解锁) - **十字准星覆盖层** — 屏幕中心的瞄准目标 ## 技术栈 ### 前端 - **React 19** — 带有 hooks 的函数式组件 - **TypeScript 5.9** — 严格模式,bundler 模块解析 - **CesiumJS 1.138**(通过 **Resium**) — 3D 地球仪渲染 - **Tailwind CSS v4** — 实用优先的样式,带有自定义战术颜色 token - **Vite 7** — 带有 HMR、Cesium 插件、API 代理的开发服务器 - **satellite.js** — SGP4/SDP4 卫星轨道推算 ### 后端 - **Express 5** — API 代理服务器 - **node-cache** — 带有 TTL 的内存响应缓存 - **WebSocket (ws)** — 实时航班数据推送通道 + 用于 AIS 船舶数据的 AISStream.io 突发 WebSocket - **dotenv** — 环境变量管理 ### 渲染技术 - **命令式 Cesium primitives** — 使用 `BillboardCollection`、`PointPrimitiveCollection`、`PolylineCollection`、`LabelCollection` 实现 27K+ 实体的高性能渲染 - **航位推算** — 在 API 更新之间以 60 fps 推算航空器位置 - **GLSL 后处理** — 通过 `PostProcessStage` 实现 CRT 扫描线、夜视绿色荧光屏、FLIR 热成像调色板 - **CallbackProperty** — 在不触发 React 重新渲染的情况下实现平滑的实体追踪 ## 快速开始 ### 前置条件 - **Node.js** ≥ 18 - **npm** ≥ 9 ### 安装 ``` # 克隆 repository git clone https://github.com/kevtoe/worldview.git cd worldview # 安装 dependencies npm install ``` ### 环境配置 复制示例文件并填入你的凭据: ``` cp .env.example .env cp server/.env.example server/.env ``` 然后使用你自己的 API key 编辑每个文件(参见下方的[获取 API Keys](#obtaining-api-keys))。 **`.env`** — 客户端(Vite 在构建时注入 `VITE_*` 变量): | 变量 | 是否必需? | 用途 | |---|---|---| | `VITE_GOOGLE_API_KEY` | 可选 | Google Maps 3D 拟真图块(回退至 OpenStreetMap) | | `VITE_CESIUM_ION_TOKEN` | 可选 | Cesium Ion 地形/影像服务 | | `WINDY_API_KEY` | 可选 | Windy 网络摄像头 API(保留,尚未激活) | | `NSW_TRANSPORT_API_KEY` | 可选 | Transport for NSW 摄像头 | | `AISSTREAM_API_KEY` | 可选 | AISStream.io 全球 AIS 船舶追踪 | **`server/.env`** — 服务器端(由 `dotenv` 加载): | 变量 | 是否必需? | 用途 | |---|---|---| | `GOOGLE_MAPS_API_KEY` | 可选 | 服务器端 Google Maps(当前未使用) | | `OPENSKY_CLIENT_ID` | 可选 | OpenSky Network OAuth2 凭据 | | `OPENSKY_CLIENT_SECRET` | 可选 | OpenSky Network OAuth2 凭据 | | `AISSTREAM_API_KEY` | 可选 | AISStream.io 全球 AIS 船舶追踪 | ## 获取 API Keys ### 🗺️ Google Maps API Key(用于 3D 拟真图块) 1. 前往 [Google Cloud Console](https://console.cloud.google.com/) 2. 创建一个新项目(或选择现有项目) 3. 导航至 **APIs & Services → Library** 4. 启用 **Map Tiles API** 5. 前往 **APIs & Services → Credentials → Create Credentials → API Key** 6. **重要提示 — 立即限制你的 key**(参见下方的[保护你的 Google API Key](#securing-your-google-api-key)) 7. 将 key 复制到 `.env` 文件中的 `VITE_GOOGLE_API_KEY` 里 ### 🛰️ Cesium Ion Token(可选) 1. 在 [cesium.com/ion](https://ion.cesium.com/tokens) 注册一个免费账号 2. 前往 **Access Tokens** → 复制你的默认 token 3. 粘贴到 `.env` 中的 `VITE_CESIUM_ION_TOKEN` 里 ### 📹 Transport for NSW API Key(用于澳大利亚 CCTV 摄像头) 1. 在 [opendata.transport.nsw.gov.au](https://opendata.transport.nsw.gov.au/) 注册 2. 前往 **My Applications** → **Create Application** 3. 订阅 **Traffic & Cameras** API 4. 将你的 API key 复制到 `.env` 中的 `NSW_TRANSPORT_API_KEY` 里 ### 🚢 AISStream.io API Key(用于海军 / AIS 船舶追踪) 1. 在 [aisstream.io](https://aisstream.io/) 注册一个免费账号 2. 登录 → 导航至你的 Dashboard 3. 生成一个 API key 4. 粘贴到 `.env` 和 `server/.env` 的 `AISSTREAM_API_KEY` 中 ### ✈️ OpenSky Network(可选,用于 WebSocket 航班数据) 1. 在 [opensky-network.org](https://opensky-network.org/) 注册 2. 登录 → 前往 **OAuth** → **Create Client** 3. 将 client ID 和 secret 复制到 `server/.env` 中 ### 运行应用程序 ``` # 启动 backend proxy server(端口 3001) npm run dev:server # 在单独的终端中,启动 Vite dev server(端口 5173) npm run dev # 或者同时启动两者 npm run dev:all ``` 在浏览器中打开 [http://localhost:5173](http://localhost:5173)。 ### 生产环境构建 ``` npm run build npm run preview ``` ## 部署到 Vercel 本项目通过 `vercel.json` 预配置了 [Vercel](https://vercel.com/)。Express 后端将作为 Vercel Serverless Function 运行。 ### 1. 部署你的副本 [![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fkevtoe%2Fworldview) 模板会导入此代码仓库,通过 `vercel.json` 识别 Vite,并立即部署无需 key 的回退体验。之后可添加可选的 API 凭据以解锁更丰富的数据源。 ### 2. 设置环境变量 在你的 Vercel 项目仪表板中: 1. 前往 **Settings → Environment Variables** 2. 添加来自两个 `.env` 文件的每个 key: | 变量 | 环境 | |---|---| | `VITE_GOOGLE_API_KEY` | Production, Preview | | `VITE_CESIUM_ION_TOKEN` | Production, Preview | | `WINDY_API_KEY` | Production, Preview | | `NSW_TRANSPORT_API_KEY` | Production, Preview | | `GOOGLE_MAPS_API_KEY` | Production, Preview | | `OPENSKY_CLIENT_ID` | Production, Preview | | `OPENSKY_CLIENT_SECRET` | Production, Preview | | `AISSTREAM_API_KEY` | Production, Preview | ## 架构 ### 系统架构 ``` ┌──────────────────────────────────────────────────────────┐ │ Browser (Vite Dev) │ │ │ │ ┌─────────────┐ ┌─────────────┐ ┌──────────────────┐ │ │ │ React Hooks │ │ App.tsx │ │ UI Components │ │ │ │ (data fetch) │──│ (state mgr) │──│ OperationsPanel │ │ │ │ │ │ │ │ IntelFeed │ │ │ └──────┬───────┘ └──────┬──────┘ │ StatusBar │ │ │ │ │ │ CCTVPanel │ │ │ │ ┌──────┴──────┐ │ TrackedEntity │ │ │ │ │ GlobeViewer │ └──────────────────┘ │ │ │ │ (Cesium) │ │ │ │ │ ┌─────────┐ │ │ │ │ │ │ Layers │ │ │ │ │ │ │ Flight │ │ │ │ │ │ │ Sats │ │ │ │ │ │ │ Quakes │ │ │ │ │ │ │ Traffic │ │ │ │ │ │ │ CCTV │ │ │ │ │ │ └─────────┘ │ │ │ │ └─────────────┘ │ └─────────┼──────────────────────────────────────────────────┘ │ /api/* proxy ┌─────────▼──────────────────────────────────────────────────┐ │ Express Proxy Server (:3001) │ │ │ │ ┌──────────┐ ┌───────────┐ ┌──────────────────────────┐ │ │ │ node-cache│ │ WebSocket │ │ REST Endpoints │ │ │ │ (TTL) │ │ (ws) │ │ /api/flights │ │ │ └──────────┘ └───────────┘ │ /api/flights/live │ │ │ │ /api/satellites │ │ │ │ /api/earthquakes │ │ │ │ /api/traffic/roads │ │ │ │ /api/ships │ │ │ │ /api/cctv │ │ │ │ /api/cctv/image (proxy) │ │ │ │ /api/health │ │ │ └──────────────────────────┘ │ └─────────────────────────┬──────────────────────────────────┘ │ ┌───────────────┼───────────────┬───────────────┐ ▼ ▼ ▼ ▼ ┌─────────────┐ ┌─────────────┐ ┌──────────────┐ ┌──────────────┐ │ FlightRadar │ │ USGS │ │ TfL / Austin │ │ AISStream.io │ │ adsb.fi │ │ CelesTrak │ │ NSW Transport│ │ (AIS WSS) │ │ OpenSky │ │ Overpass API│ │ │ │ │ └─────────────┘ └─────────────┘ └──────────────┘ └──────────────┘ ``` ### 数据流 1. **React hooks** 以特定于图层的间隔轮询 Express 代理服务器 2. **Express** 缓存上游 API 响应,管理 OAuth2 token,并隐藏凭据 3. **App.tsx** 管理全局状态 — 图层可见性、摄像机位置、追踪的实体、着色器模式 4. **图层组件** 通过 props 接收数据,并以命令式方式渲染到 Cesium 场景中 5. **UI 组件** 以 React DOM 覆盖层的形式显示控件、流和状态信息 ### 双重航班数据策略 WorldView 融合了两个航空器数据源以实现最佳覆盖: | 数据源 | 覆盖范围 | 更新频率 | 数据丰富度 | |---|---|---|---| | FlightRadar24 | 全球(7 个区域) | 20 秒 | 出发/目的地机场、航空公司 | | adsb.fi | 区域(250 海里半径) | 5 秒 | 高频位置更新 | - 缩小视图时:仅使用 FR24 全球数据 - 放大视图时:adsb.fi 替换 FR24 显示附近的航空器(通过 ICAO24 去重) - 来自 FR24 的航线信息会进行交叉引用,以丰富 adsb.fi 的数据 ## 项目结构 ``` worldview/ ├── server/ # Backend proxy (Node.js ESM) │ ├── index.js # All routes, WebSocket, AIS burst, caching │ ├── .env # Server secrets │ └── data/ │ └── sydneyRoads.js # Static fallback road geometry ├── src/ │ ├── App.tsx # Root component — state, hooks, composition │ ├── main.tsx # ReactDOM entrypoint │ ├── index.css # Tailwind v4 + tactical theme + Cesium overrides │ ├── components/ │ │ ├── globe/ │ │ │ ├── GlobeViewer.tsx # Cesium Viewer (3D tiles, OSM, shader mgmt) │ │ │ └── EntityClickHandler.tsx # Click-to-track, ESC unlock │ │ ├── layers/ │ │ │ ├── FlightLayer.tsx # 27K aircraft (imperative, dead-reckoning) │ │ │ ├── SatelliteLayer.tsx # SGP4 orbit propagation │ │ │ ├── EarthquakeLayer.tsx # Pulsing seismic markers │ │ │ ├── TrafficLayer.tsx # Roads + animated vehicles │ │ │ ├── ShipLayer.tsx # AIS vessels (imperative, dead-reckoning) │ │ │ └── CCTVLayer.tsx # Camera markers (imperative) │ │ └── ui/ │ │ ├── OperationsPanel.tsx # Layer/shader/filter controls │ │ ├── IntelFeed.tsx # Real-time event feed │ │ ├── CCTVPanel.tsx # Camera grid + preview │ │ ├── StatusBar.tsx # Coords, clock, data counts │ │ ├── SplashScreen.tsx # Boot sequence │ │ ├── TrackedEntityPanel.tsx # Lock-on detail │ │ └── Crosshair.tsx # SVG targeting reticle │ ├── data/ │ │ └── airports.ts # IATA → coordinates lookup │ ├── hooks/ │ │ ├── useFlights.ts # Global FR24 polling │ │ ├── useFlightsLive.ts # Regional adsb.fi polling │ │ ├── useSatellites.ts # TLE fetch + SGP4 pipeline │ │ ├── useEarthquakes.ts # USGS polling │ │ ├── useTraffic.ts # Road fetch + vehicle simulation │ │ ├── useShips.ts # AIS vessel polling + burst WebSocket │ │ └── useCameras.ts # CCTV aggregation │ ├── shaders/ │ │ └── postprocess.ts # GLSL: CRT, NVG, FLIR │ └── types/ │ └── camera.ts # CameraFeed, CameraSource types ├── .env # Client-side env vars ├── package.json ├── vite.config.ts # Vite + React + Cesium + Tailwind + proxy ├── tsconfig.json # Project references ├── tsconfig.app.json # Strict TS for src/ └── eslint.config.js ``` ## 功能详情 ### 🎯 实体追踪 点击地球仪上的任何实体即可将摄像机锁定在其上。视图将以适当的偏移量实时跟随该实体: - **航空器** — 50 公里 trailing offset 及航向对齐 - **卫星** — 200 公里偏移量,用于轨道观赏 - **地震** — 震中上方 100 公里的俯视图 - **船舶** — 20 公里偏移量,低角度并带有航向对齐 - **CCTV 摄像头** — 2 公里偏移量,45° 视角 按 **ESC** 键解锁追踪,而不移动摄像机。 ### 🔭 光学模式(后处理) | 模式 | 效果 | |---|---| | **Standard** | 无后处理 | | **CRT** | 扫描线、色差、桶形畸变、暗角 | | **NVG** | 绿色荧光屏、噪点颗粒、泛光、暗角 | | **FLIR** | 白热热成像调色板、Sobel 边缘检测、高对比度 | ### 🗺️ 地图图块 | 模式 | 描述 | |---|---| | **Google 3D** | Google 拟真 3D 图块(需要 API key) | | **OSM** | OpenStreetMap 2D 影像(无需 key — 默认回退) | ### ✈️ 航班图层详情 - **高度带过滤:** 巡航 (>35K ft)、高 (25–35K)、中 (10–25K低 (1–10K)、地面 (<1K) - **航线弧:** 出发/目的地机场之间的大圆路径,带有高度曲线 - **航位推算:** 在数据更新之间以 60 fps 平滑进行位置插值 - **颜色编码:** 青色(巡航) → 绿色(高) → 琥珀色(中) → 橙色(低) ### 🛰️ 卫星图层详情 - **SGP4 推算:** 根据 TLE 轨道根数获取实时位置,每 2 秒更新一次 - **轨道路径:** 90 点折线,显示预测 90 分钟的轨迹 - **地面轨迹:** 轨道路径的表面投影 - **天底线:** 从卫星垂直向下指向正下方地面的线 - **ISS 高亮:** 国际空间站采用独特的样式 ### 🚢 海军 / AIS 图层详情 - **突发 WebSocket 模式:** 在缓存未命中时连接到 AISStream.io 20 秒,在全球范围内收集 2,000–4,000 艘船舶,然后缓存 60 秒 - **仅移动过滤:** `?moving=1` 排除系泊、抛锚和搁浅的船舶(navStatus 代码)+ SOG < 0.5 节阈值 - **船舶类型分类:** 9 个类别 — 货船(蓝色)、油轮(橙色)、客船(绿色)、渔船(琥珀色)、军舰(红色)、拖船/引航船(紫色)、游艇(青色)、高速船(粉色)、其他(灰色) - **航向轨迹:** 基于对地航向,在每艘船后方形成的短尾迹折线 - **航位推算:** 在数据更新之间使用 SOG 和 COG 以 60 fps 平滑进行位置插值 - **地球仪遮挡:** 地球背面的船舶会自动隐藏 - **加载指示器:** 在首次突发 WebSocket 完成时显示琥珀色脉冲“LOADING”状态 ### 📹 CCTV 系统 - **多源聚合:** 伦敦(TfL JamCams)、奥斯汀(Open Data)、澳大利亚新南威尔士州(Transport API) - **国家/地区过滤:** 按国家/地区切换摄像头(GB、US、AU) - **图片代理:** 后端代理摄像头图片以避免 CORS 问题 - **缩略图网格:** 分页摄像头网格(每页 30 个),带有懒加载预览 - **飞至:** 点击任何摄像头即可将地球仪视图锁定到其位置 ## API 端点(后端代理) | 方法 | 端点 | 缓存 TTL | 描述 | |---|---|---|---| | `GET` | `/api/flights` | 30 秒 | 全球航空器(FR24 → adsb.fi 回退) | | `GET` | `/api/flights/live?lat=X&lon=Y&dist=Z` | 4 秒 | 区域高频航空器(adsb.fi) | | `GET` | `/api/satellites?group=stations` | 2 小时 | TLE 文本数据(3 行格式) | | `GET` | `/api/earthquakes` | 60 秒 | USGS GeoJSON 订阅流(过去 24 小时) | | `GET` | `/api/traffic/roads?south=X&west=Y&north=Z&east=W` | 24 小时 | 来自 Overpass API 的道路网络 | | `GET` | `/api/ships?moving=1` | 60 秒(20 秒突发) | 通过 AISStream.io 突发 WebSocket 获取全球 AIS 船舶位置 | | `GET` | `/api/cctv?country=XX&source=YY` | 5 分钟 | 聚合的 CCTV 摄像头流 | | `GET` | `/api/cctv/image?url=ENCODED_URL` | 60 秒 | CORS 图片代理 | | `GET` | `/api/health` | — | 服务器健康状态 + 缓存统计 | | `WS` | `/ws` | — | 实时航班推送(通过 JSON 订阅) | ## 设计系统 ### 调色板 | Token | Hex | 用法 | |---|---|---| | `wv-black` | `#0A0A0A` | 背景 | | `wv-dark` | `#111111` | 面板背景 | | `wv-panel` | `#1A1A1A` | 凸起的表面 | | `wv-border` | `#2A2A2A` | 边框、分隔线 | | `wv-muted` | `#666666` | 禁用/次要文本 | | `wv-text` | `#CCCCCC` | 主要文本 | | `wv-cyan` | `#00D4FF` | 主要强调色、航班 | | `wv-green` | `#39FF14` | 卫星、成功状态 | | `wv-amber` | `#FF9500` | 警告、地震 | | `wv-red` | `#FF3B30` | 错误、CCTV、警报 | | `wv-teal` | `#00BFA5` | 次要强调色 | ### 字体 等宽字体栈:`JetBrains Mono`、`Fira Code`、`SF Mono`、`monospace` ### UI 效果 - **面板玻璃效果** — `backdrop-blur(12px)` 搭配 85% 黑色背景 - **扫描线覆盖层** — 8 秒钟从上到下的动态扫描 - **辉光类** — `.glow-cyan`、`.glow-green`、`.glow-amber` 文本阴影效果 ## 开发 ### 脚本 | 命令 | 描述 | |---|---| | `npm run dev` | 启动 Vite 开发服务器(端口 5173) | | `npm run dev:server` | 启动 Express 代理(端口 3001) | | `npm run dev:all` | 并发启动两个服务器 | | `npm run build` | TypeScript 编译 + Vite 生产环境构建 | | `npm run lint` | 对所有 `.ts`/`.tsx` 文件运行 ESLint | | `npm run preview` | 在本地提供生产环境构建的服务 | ### 添加新的数据图层 1. 在 `src/hooks/` 中**创建一个 hook** — 从后端获取数据,返回类型化状态 2. 在 `src/components/layers/` 中**创建一个图层组件** — 渲染 Cesium primitives 3. 在 `server/index.js` 中**添加一个代理端点** — 缓存上游 API,隐藏凭据 4. **接入 App.tsx** — 添加图层切换状态,调用 hook,将数据传递给图层组件 5. **更新 OperationsPanel** — 为新图层添加切换控件 6. **更新 StatusBar** — 添加实体计数显示 ### 性能指南 - 对于包含 >100 个实体的图层,请使用**命令式 Cesium primitives**(`BillboardCollection`、`PointPrimitiveCollection`) - 避免在循环中为大型数据集创建 **Resium ``** 元素 - 大量使用 `useCallback` 和 `useMemo` — Cesium 渲染循环对引用变化很敏感 - 对于 Cesium 实体位置,优先使用 `CallbackProperty` 而非 React state - 为移动的实体实现**航位推算**,以在数据更新之间保持 60 fps ## 故障排除 | 问题 | 解决方案 | |---|---| | 空白的地球仪 / 无图块 | 检查 `VITE_GOOGLE_API_KEY` 是否有效且启用了 Maps JavaScript API;应用程序会自动回退到 OSM | | 无航班/卫星/地震数据 | 确保后端代理正在运行(`npm run dev:server`) | | CCTV 图片不加载 | 后端必须正在运行才能通过 `/api/cctv/image` 代理图片 | | 控制台出现 "429 Too Many Requests" | 触发上游 API 速率限制;缓存层降低了频率,请等待 TTL 到期 | | Overpass API 超时 | 交通图层回退到静态的悉尼 CBD 道路数据 | | 卫星未显示 | TLE API 可能暂时宕机;CelesTrak 被用作自动回退 | | 船舶未加载 / 图层为空 | 确保在 `server/.env` 中设置了 `AISSTREAM_API_KEY`;在突发 WebSocket 收集数据期间,初始加载大约需要 20 秒 | | 只能看到少数船舶 | 通过移除 `?moving=1` 关闭仅移动过滤器;某些地区的 AIS 覆盖较少 | | Google 3D 图块错误 | API key 可能无效或配额已超;系统会自动应用 OSM | ## 致谢 ### 数据来源 - [FlightRadar24](https://www.flightradar24.com/) — 全球航班追踪 - [adsb.fi](https://adsb.fi/) — 开放 ADS-B 航空器数据 - [OpenSky Network](https://opensky-network.org/) — 开放航空器监视数据 - [USGS Earthquake Hazards](https://earthquake.usgs.gov/) — 实时地震流 - [CelesTrak](https://celestrak.org/) — 卫星 TLE 轨道数据 - [TLE API](https://tle.ivanstanojevic.me/) — 卫星 TLE 数据服务 - [OpenStreetMap / Overpass API](https://overpass-api.de/) — 道路网络数据 - [Transport for London](https://api.tfl.gov.uk/) — 伦敦交通摄像头 - [City of Austin Open Data](https://data.austintexas.gov/) — 奥斯汀交通摄像头 - [Transport for NSW](https://opendata.transport.nsw.gov.au/) — 新南威尔士州交通摄像头 - [AISStream.io](https://aisstream.io/) — 通过 WebSocket 进行全球 AIS 船舶追踪 ### 技术 - [CesiumJS](https://cesium.com/) + [Resium](https://resium.reearth.io/) — 3D 地球仪渲染 - [satellite.js](https://github.com/shashwatak/satellite-js) — SGP4/SDP4 轨道推算 - [Turf.js](https://turfjs.org/) — 地理空间分析实用工具 ## 安全 所有敏感值均从 `.env` 文件中加载,这些文件通过 `.gitignore` 排除。如果你 fork 或 clone 此代码仓库,你必须提供自己的 API key。 如果你发现凭据泄露或安全问题,请立即提 issue。 ### 推送前的快速检查清单 - [ ] `.env` 和 `server/.env` 已在 `.gitignore` 中(默认已包含) - [ ] 源代码文件中没有硬编码 API key - [ ] Google API key 已应用 HTTP referrer 限制 - [ ] Google API key 仅限于 Map Tiles API - [ ] 已在 Google Cloud Console 中配置预算警报 ## 许可证 基于 [MIT 许可证](LICENSE) 发布 — 可免费使用、修改、fork 并在此基础上进行构建,包括商业用途。 ### 第三方数据和 API 条款 MIT 许可证涵盖**本项目自身的源代码**。它没有也无法对本应用程序调用的外部服务授予任何权利。在[致谢](#acknowledgements)下列出的每一个数据源 — Google 拟真 3D 图块、FlightRadar24、adsb.fi、OpenSky、CelesTrak、USGS、Overpass、TfL、Transport NSW、AISStream 及其他 — 都有其各自的服务条款、许可和速率限制。其中几项限制商业或高频大量使用。**在部署超出个人或演示用途的任何内容之前,请检查你启用的每个提供商的条款。** **你有责任保护自己的 API key 并管理自己的 API 使用费用。** 对于因配置错误或不受限制的 API 凭据产生的费用,作者不承担任何责任。
标签:3D地球, CesiumJS, HTTP/HTTPS抓包, MITM代理, 实时数据, 态势感知, 自动化攻击