khammami/sfax-fiber-scanner
GitHub: khammami/sfax-fiber-scanner
一款基于 Leaflet.js 的交互式 Web 应用,用于扫描突尼斯斯法克斯地区的 GPON 光纤覆盖情况并可视化结果。
Stars: 1 | Forks: 0
# Sfax Fiber (GPON) 覆盖扫描器
一个独立的 Web 应用程序,用于系统地扫描突尼斯斯法克斯地区,以使用 Tunisie Telecom API 检查光纤 (GPON) 覆盖情况。该应用程序在交互式地图上显示结果,并提供全面的统计和导出功能。
## 功能特点
- 🗺️ **交互式地图**:基于 Leaflet.js 和 OpenStreetMap 瓦片构建
- 🔍 **精细网格扫描**:可配置的扫描区域和网格密度(点间距约 200 米)
- 📊 **实时可视化**:彩色圆圈标记(绿色=可用,红色=不可用,黄色=错误)
- 📈 **进度跟踪**:扫描期间实时显示进度条和统计数据
- 🔄 **重试不可用点位**:重新扫描标记为"不可用"的点位,检查状态是否已更改
- 🔥 **热力图图层**:可选的覆盖数据热力图可视化
- 📥 **导出结果**:将扫描数据下载为 JSON 或 CSV 格式
- 💾 **结果持久化**:自动保存到 localStorage,页面加载时自动恢复
- 🎯 **自定义边界**:在地图上绘制矩形来定义自定义扫描区域
- ⚙️ **可配置设置**:调整扫描边界、步长和 API 请求延迟
- 📱 **响应式设计**:支持桌面和移动设备
## 本地开发
要本地运行应用程序且不出现 CORS 错误,请使用内置的开发服务器:
```
npm install
npm run dev
```
然后在浏览器中打开 ****。
开发服务器的功能:
- 提供 `index.html`、`script.js`、`style.css` 和其他静态文件
- 将 `/api/rsm/*` 的 API 请求代理到 `https://gis.tunisietelecom.tn/rsm/*`
## 使用方法
1. **打开应用程序**
- 运行 `npm run dev` 并打开 ****(参见上面的[本地开发](#local-development))
- 或部署到 GitHub Pages / 自定义域名 — API 调用直接发送,无需代理
2. **配置扫描区域**
- 使用默认的斯法克斯区域边界(纬度 34.70-34.78,经度 10.72-10.80)
- 或在控制面板中调整纬度/经度的最小/最大值
- 或启用"绘制自定义边界"并在地图上绘制矩形
3. **调整设置**
- **步长**:扫描点之间的距离(度),默认:0.002° ≈ 200 米
- **延迟**:API 请求之间的时间(毫秒),默认:500 毫秒
- 应用程序会自动计算总点数
4. **开始扫描**
- 点击"开始扫描"开始
- 使用"暂停"临时停止(稍后可以继续)
- 使用"停止"完全结束扫描
- 进度通过进度条实时显示
5. **查看结果**
- 🟢 绿色标记 = 光纤 (GPON) 可用
- 🔴 红色标记 = 光纤不可用
- 🟡 黄色标记 = 错误或跳过的点
- 点击任何标记查看详细信息
6. **导出和保存**
- 点击"导出 JSON"或"导出 CSV"下载结果
- 结果自动保存到浏览器 localStorage
- 重新加载页面以恢复之前的扫描数据
7. **重试不可用点位**
- 扫描完成后,点击"🔄 重试不可用"重新扫描标记为"不可用"的点位
- 用于检查光纤覆盖是否已部署到之前不可用的位置
- 系统将显示要重试的点位数并更新统计信息
- 更新的标记将反映新状态(可能变为可用或仍然不可用)
## 工作原理
### Token 生成
Tunisie Telecom API 每个请求都需要一个唯一的 token:
1. 从 `getAppVersion` 端点获取服务器时间
2. 提取并解码时间戳
3. 使用特定偏移量计算 token 值
4. 附加 10 个字符的随机字符串
5. **每个 API 请求都会生成自己的新 token**
```
async function getToken() {
const response = await fetch("https://gis.tunisietelecom.tn/rsm/RSMService.svc/getAppVersion");
const data = await response.json();
// ... token calculation logic
return token;
}
async function checkCoverage(lat, lng) {
// Generate fresh token for this specific request
const token = await getToken();
// ... make API call with token
}
```
### 坐标编码
坐标在发送到 API 之前会被编码:
```
function codeCoordinates(x, y) {
const Ax = 100000.0, Ay = 100000.0;
const Bx = 123456.0, By = 654321.0;
return {
xCoded: (x * Ax) - Bx,
yCoded: (y * Ay) - By
};
}
```
### 覆盖检查
对于网格中的每个点:
1. 编码坐标
2. 向 `TaghtiaUltimate` 端点发送 POST 请求
3. 检查响应中的 GPON 可用性
4. 在地图上以适当颜色显示结果
5. 为失败的请求添加重试逻辑
### 网格扫描
应用程序根据以下内容生成点网格:
- 纬度范围(最小到最大)
- 经度范围(最小到最大)
- 步长(默认 0.002° ≈ 200 米)
点按顺序扫描,请求之间有可配置的延迟。
## 技术栈
- **HTML5** - 应用程序结构
- **CSS3** - 样式和响应式设计
- **JavaScript (ES6+)** - 核心逻辑和 API 集成
- **Leaflet.js 1.9.4** - 交互式地图库
- **Leaflet.draw** - 用于自定义边界的矩形绘制
- **Leaflet.heat** - 热力图可视化
- **Bootstrap 5.3** - UI 组件和响应式网格
- **OpenStreetMap** - 免费地图瓦片(无需 API 密钥)
## API 参考
本应用程序使用 Tunisia Telecom 覆盖 API(逆向工程):
**基础 URL**:`https://gis.tunisietelecom.tn/rsm/RSMService.svc/`
**端点**:
- `getAppVersion` - 获取服务器时间用于 token 生成
- `TaghtiaUltimate` - 检查坐标的覆盖情况
**GPON 可用性检查**:
```
if (result.taghtiaGPON.Code_taghtia == 200 &&
result.taghtiaGPON.Message_taghtia == "OK" &&
result.taghtiaGPON.Taghtia == "OUI") {
// GPON Fiber is available
}
```
## 浏览器兼容性
- ✅ Chrome/Edge (v90+)
- ✅ Firefox (v88+)
- ✅ Safari (v14+)
- ✅ 移动浏览器(iOS Safari、Chrome Mobile)
## 项目结构
```
sfax-fiber-scanner/
├── index.html # Main HTML page with map and UI
├── style.css # Styles and responsive design
├── script.js # JavaScript logic and API integration
├── server.js # Local dev server with API proxy (Node.js)
├── package.json # npm dependencies and dev script
└── README.md # This file
```
## 致谢
本项目灵感来源于并使用了从以下项目逆向工程的 API 信息:
- [Jev1337/More-Taghtia](https://github.com/Jev1337/More-Taghtia)
## 免责声明
- 使用的 API 属于 **Tunisie Telecom**,并非官方公开
- 此工具应负责任地使用,不得用于商业目的
- 作者不对本应用程序的任何滥用负责
- 请尊重速率限制,不要使 API 服务器过载
- 这是一个非官方工具,与 Tunisie Telecom 没有关联
- 检查 TT 覆盖的官方网站:[Taghtia](https://gis.tunisietelecom.tn/mytaghtia/)
## 许可证
MIT 许可证
版权所有 (c) 2026
特此免费授予获得本软件及相关文档文件("软件")副本的任何人不受限制地处理本软件的权利,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或出售本软件副本的权利,并允许获得本软件的人员在满足以下条件的情况下这样做:
上述版权声明和本许可声明应包含在本软件的所有副本或重要部分中。
本软件按"原样"提供,不提供任何形式的明示或暗示保证,包括但不限于对适销性、特定用途适用性和非侵权性的保证。在任何情况下,作者或版权持有人均不对任何索赔、损害或其他责任承担责任,无论是在合同、侵权或其他诉讼中,均由本软件或本软件的使用或其他交易引起或与之相关。
## 支持
如果您遇到任何问题或有疑问,请在 GitHub 上提交 issue。
**用 ❤️ 为斯法克斯社区制作**
标签:API集成, CSV, GNU通用公共许可证, GPON, JSON, Leaflet, localStorage, MITM代理, Node.js, OpenStreetMap, Tunisie Telecom, 云存储安全, 光纤覆盖, 可观测性, 响应式设计, 地图可视化, 地理信息系统, 实时统计, 数据导出, 热力图, 突尼斯, 网格扫描, 网络扫描, 自定义脚本, 进度跟踪