Atharva1318-dev/CrisisConnect
GitHub: Atharva1318-dev/CrisisConnect
一套将市民、救援机构和协调员连接在一起的全栈危机管理平台,通过AI验证、信任评分和地理共识机制实现更快速、可靠的紧急响应。
Stars: 0 | Forks: 2
# 🚨 CrisisConnect
**AI 驱动的紧急响应管理平台**
一个用于快速灾难响应的先进平台,将市民、紧急救援机构和协调员连接在一个统一的生态系统中。具备 AI 驱动的事件验证、深度伪造检测、智能资源分配和实时协调功能。
## 🎬 演示视频
https://github.com/user-attachments/assets/714b7c08-76cd-4ba2-96f9-8f71569d0351
_演示展示:事件报告 → AI 验证 → 调度 → 实时仪表盘 → 解决_
## ✨ 主要特性
- **多模态事件报告** - 语音 (SOS) 和图像/文本报告
- **AI 驱动的验证** - 视觉分析、语音情感检测和语义对齐
- **深度伪造检测** - EXIF 分析和 AI 生成检测,准确率达 95% 以上
- **智能信任评分** - 从多个数据源综合得出的 0-100 可信度评分
- **基于位置的共识评分** - ⭐ **当检测到附近有更多事件时会提高评分**
- **智能优先级编码** - 根据验证结果自动分配从 OMEGA 到 X-RAY 的优先级代码
- **实时资源跟踪** - 带 GPS 跟踪的资源,具有邻近匹配和分配功能
- **多角色仪表盘** - 为市民、机构和协调员定制的界面
- **危机新闻源** - AI 总结、分类的新闻聚合及情感分析
- **交互式热力图** - 带聚类的地理事件密度可视化
- **请求管理** - 具有审批流程的正式资源请求系统
## 🏗️ 技术栈
**前端:**
- React 19 + Vite
- Redux Toolkit, Tailwind CSS
- Leaflet + React-Leaflet (地图), Recharts (分析)
- Firebase (认证), Axios (HTTP)
**后端:**
- Node.js + Express.js
- MongoDB + Mongoose (带地理空间索引)
- Google Generative AI (Gemini)
- Ollama Gemma3:4B (深度伪造检测)
- Tesseract.js (OCR), Sharp (图像处理)
**API 与服务:**
- Cloudinary (媒体存储)
- Twilio (短信通知)
- Tavily (新闻聚合)
- exif-parser, JWT, Bcrypt
## 📚 文档
**⭐ 完整的项目文档**:请参阅 [DETAILED_README.md](./DETAILED_README.md)
详细的自述文件包括:
- ✅ 完整的系统架构和数据流
- ✅ 事件处理管道的全部 4 个阶段
- ✅ 取证分析与深度伪造检测详解
- ✅ AI 分析(视觉、语音、语义)
- ✅ 信任评分公式 (A, B, C)
- ✅ 优先级编码系统 (OMEGA → X-RAY)
- ✅ 资源管理与分配
- ✅ 带示例的数据库模式
- ✅ 包含请求/响应的完整 API 文档
- ✅ 环境变量参考
- ✅ 部署指南
## 🌐 API 概览
有关详细的设置、配置和 API 文档,请参阅 [DETAILED_README.md](./DETAILED_README.md)
## 🎯 系统流程图
```
┌─────────────────────────────────────────────────────────────┐
│ │
│ CITIZEN AGENCY COORDINATOR │
│ (Reports) (Responds) (Allocates) │
│ │ │ │ │
└─────┼──────────────────────┼───────────────────────┼──────────┘
│ │ │
v v v
┌──────────────────────────────────────────────────────────┐
│ React Frontend (Port 5173) │
│ ├─ Login/Auth │
│ ├─ SOS Trigger (Voice/Image) │
│ ├─ Real-time Map View │
│ ├─ Dashboard & Analytics │
│ └─ Resource Requests │
└──────────────────┬───────────────────────────────────────┘
│ HTTP/WebSocket
┌──────────────────v───────────────────────────────────────┐
│ Node.js + Express Backend (Port 5000) │
│ ┌────────────────────────────────────────────────────┐ │
│ │ 4-PHASE PROCESSING PIPELINE │ │
│ ├─ Phase 1: Forensics (Deepfake Detection) │ │
│ ├─ Phase 2: Vision/Voice Analysis (Parallel/Either-Or) │ │
│ ├─5-PHASE PROCESSING PIPELINE │ │
│ ├─ Phase 1: Forensics (Deepfake Detection) │ │
│ ├─ Phase 2: Vision/Voice Analysis │ │
│ ├─ Phase 3: Semantic Alignment │ │
│ ├─ Phase 4: Trust Scoring + Location Consensus │ │
│ └─ Phase 5: Priority Code Assignment
│ │ │
v v v
MongoDB Cloudinary External APIs
(Database) (Media CDN) (Google, Tavily, etc)
```
## 🔄 事件处理管道 (4 个阶段)
### 阶段 1️⃣:取证分析5 个阶段)
### 阶段 1️⃣:取证分析
以 95% 以上的准确率检测 AI 生成和深度伪造图像
**输入**:图像/语音数据
**分析**:
- **EXIF 元数据检查**:扫描 AI 工具签名(Midjourney、Stable Diffusion、DALL-E、Gemini 等)
- **像素级认证**:分析噪点模式、压缩伪影
- **口袋检测**:识别设备在录制时是否处于口袋中
- **水印分析**:检测素材图/AI 生成的指示标志
**输出**:
```
{
"isFake": false,
"confidenceScore": 92,
"realismFactor": 0.95,
"isPocket": false,
"verdict": "Authentic - Real device, valid metadata"
}
```
**特殊情况**:
- ✅ 被标记的 AI 生成图像不会自动被拒绝
- ✅ PNG 文件将受到更严格的审查(最高信任评分上限为 30)
- ✅ 口袋模式会降低视觉评分
### 阶段 2️⃣:视觉/语音分析
**路径 A:图像分析**(如果提供了图像)
- 使用 Google Gemini Vision API
- 检测:火灾、烟雾、血液、碎片、人员、洪水等。
- 返回:`detected_objects[]`、`confidence`、`scene_description`
- 严重程度映射:严重 → 高 → 中 → 低
**路径 B:语音分析**(如果提供了音频)
- 语音转文本
- 关键词提取(例如,“被困”、“垂死”、“火灾”、“流血”)
- 情感分析:恐慌 (100%) → 中性 (50%) → 平静 (30%)
- 紧急度评分:1-10 级
- 情绪状态检测
**组合处理**:
- 如果两种输入都可用,则并行运行
- 如果是单一输入,则二选一运行
- 在阶段 3 之前同步输出
### 阶段 3️⃣:语义对齐
**目的**:交叉验证视觉和语音数据
**对齐评分** (0-100):
- 完美匹配:视觉=火灾 + 语音="火灾" → **95% 以上对齐** ✅
- 良好匹配:视觉=烟雾 + 语音="火灾" → **75-85% 对齐**
- 部分匹配:视觉=碎片 + 语音="救命" → **50-60% 对齐** ⚠️
- 不匹配:视觉=汽车 + 语音="火灾" → **低于 50% 对齐** ❌(未通过交叉验证)
**影响**:
- 高对齐度会提升最终信任评分(20% 权重)
- 低对齐度会触发人工审核标记
- 严重不匹配会使评分降低 15-25 分
### 阶段 4️⃣:带位置共识的信任评分
#### 📍 **位置共识评分** ⭐
这是一项关键功能,**当附近报告更多事件时会提高评分**:
```
// Algorithm: Geospatial Query within 1km radius, 15-minute window
const calculateLocationConsensus = async (latitude, longitude) => {
const radiusMeters = 1000; // 1km radius
const timeWindow = "15 minutes"; // Recent incidents
const nearbyIncidents = await Incident.find({
location: {
$geoWithin: {
$centerSphere: [[longitude, latitude], radiusInRadians],
},
},
createdAt: { $gte: fifteenMinutesAgo },
status: { $in: ["Pending", "Active"] },
}).count();
// Scoring based on cluster density
if (nearbyIncidents >= 3) return 100; // Strong consensus
if (nearbyIncidents >= 2) return 75; // Good consensus
if (nearbyIncidents >= 1) return 50; // Weak consensus
return 0; // Isolated incident
};
```
**工作原理**:
1. 当在坐标 (纬度, 经度) 处报告事件时
2. 系统搜索 **1 公里半径**和 **15 分钟**内的其他事件
3. 计算状态为“待定”或“活跃”的事件
4. 分配共识评分:
- **3 起以上事件** → 评分:**100**(已确认群体事件)
- **2 起事件** → 评分:**75**(多起报告)
- **1 起事件** → 评分:**50**(另一起报告)
- **0 起事件** → 评分:**0**(孤立报告)
**对信任评分的影响**:
- 公式 A(图像):30% 权重 → **可能增加 +9-30 分**
- 公式 B(语音):30% 权重 → **可能增加 +10-30 分**
- 公式 C(混合):20-30% 权重 → **可能增加 +6-30 分**
**真实世界示例**:
```
Area: Downtown District
Time: 14:32
Incident 1: Image report "Fire in building A"
→ Location: [40.7128, -74.0060]
→ Nearby incidents: 0
→ Location Consensus Score: 0
→ Base Score: 60 → Final: 60
Incident 2: Voice report "Fire! Help!" (14:33)
→ Location: [40.7129, -74.0061] (50m away)
→ Nearby incidents: 1 (Incident 1)
→ Location Consensus Score: 50
→ Base Score: 70 → Final: 84 ✅ (Boosted due to area consensus)
Incident 3: Image report "Fire spreading" (14:34)
→ Location: [40.7130, -74.0062] (150m away)
→ Nearby incidents: 2 (Incident 1, 2)
→ Location Consensus Score: 75
→ Base Score: 75 → Final: 95 ✅✅ (Strong confirmation)
Incident 4: Voice report "Fire at central station" (14:35)
→ Location: [40.7131, -74.0063] (250m away)
→ Nearby incidents: 3 (Incident 1, 2, 3)
→ Location Consensus Score: 100
→ Base Score: 80 → Final: 98 ✅✅✅ (Mass event confirmed)
```
#### 📊 **公式 A:图像 + 文本模式**
当图像是主要输入时使用
```
Trust Score = (Visual Score × 0.5 + Alignment Score × 0.2 + Location Consensus × 0.3)
× Realism Factor
× Format Factor (PNG: 0-30 cap, others: normal)
Components:
├─ Visual Score (0-90):
│ ├─ Fire/Collapse detected: 90
│ ├─ Blood/Flood detected: 80
│ └─ General emergency: 70
├─ Alignment Score (0-100):
│ └─ Vision vs Voice keyword matching
├─ Location Consensus (0-100): ⭐ NEW
│ └─ Number of nearby incidents (1km, 15min)
└─ Realism Factor (0-1.0):
└─ Deepfake penalty if isFake
Final Score: 0-100
```
**示例**:
- 火灾图像,高对齐度,附近有 2 起事件
- (90 × 0.5) + (85 × 0.2) + (75 × 0.3) = 45 + 17 + 22.5 = **84.5**
- 低置信度图像,对齐度差,孤立报告
- (45 × 0.5) + (30 × 0.2) + (0 × 0.3) = 22.5 + 6 + 0 = **28.5**
#### 🎤 **公式 B:语音 SOS 模式**
当语音是主要输入时使用
```
Trust Score = (Keyword Score × 0.5 + Sentiment Score × 0.2 + Location Consensus × 0.3)
Components:
├─ Keyword Score (0-100):
│ ├─ "Dying/Trapped": 95
│ ├─ "Fire/Burning": 90
│ ├─ "Blood/Injury": 85
│ └─ "Help/Emergency": 75
├─ Sentiment Score (0-100):
│ ├─ Panic: 85
│ ├─ Neutral: 50
│ └─ Calm: 30
└─ Location Consensus (0-100): ⭐ NEW
└─ Number of nearby incidents
Final Score: 0-100
```
**示例**:
- 语音呼喊“火灾!被困!救命!”,恐慌情绪,附近有 3 起事件
- (95 × 0.5) + (85 × 0.2) + (100 × 0.3) = 47.5 + 17 + 30 = **94.5**
- 语音说“你好?”,平静情绪,孤立报告
- (30 × 0.5) + (30 × 0.2) + (0 × 0.3) = 15 + 6 + 0 = **21**
#### 📱 **公式 C:混合摇一摇模式**
当语音和图像/口袋数据都可用时使用
```
Trust Score (Normal Phone):
= (Visual × 0.4) + (Audio × 0.4) + (Location Consensus × 0.2)
Trust Score (Pocket Mode):
= (Visual × 0.1) + (Audio × 0.6) + (Location Consensus × 0.3)
Audio Score calculated using Formula B internally
```
**口袋模式**:降低摄像头重要性,提高语音重要性
### 阶段 5️⃣:优先级代码判定
分配紧急响应级别 (OMEGA 到 X-RAY)
#### **OMEGA:重大灾难** 🚨
- **触发条件**:1 分钟内在 1 公里半径内发生 10 起以上事件
- **响应级别**:5(最高)
- **自动调度**:是
- **调度 50 项以上资源,启动应急行动中心**
#### **DELTA:危及生命的紧急情况** 🚨
- **触发条件**:信任评分 ≥ 75 +(包含被困/垂死/失去意识关键词 或 建筑倒塌)
- **响应级别**:5
- **自动调度**:是
- **调度救护车、消防车、救援队**
#### **CHARLIE:重大紧急情况** 🟡
- **触发条件**:信任评分 ≥ 60 且(检测到火灾/洪水/多人受伤/事故)
- **响应级别**:4
- **自动调度**:是
- **调度多种资源类型**
#### **BRAVO:中度紧急情况** 🔵
- **触发条件**:信任评分 ≥ 45 且(检测到紧急对象 或 位置共识 ≥ 50)
- **响应级别**:3
- **自动调度**:否
- **调度前需人工审核**
#### **ALPHA:标准报告** 🟢
- **触发条件**:信任评分 < 45 或 低置信度
- **响应级别**:2
- **自动调度**:否
- **需要操作员审核**
#### **X-RAY:垃圾信息/已标记** ⚠️
- **触发条件**:检测到 AI 生成的图像 或 多次虚假报告
- **响应级别**:0
- **自动调度**:否
- **已被标记待审核**
## 🎯 工作原理(端到端)
```
1. CITIZEN INITIATES
├─ Presses SOS button
├─ Records voice or selects image
2. DATA UPLOADED
├─ Audio/Image → Cloudinary CDN
└─ Location + Metadata captured
3. AI VERIFICATION (4 phases)
├─ Deepfake detection: 95%+ accuracy
├─ Vision/Voice analysis: Detects objects & extracts keywords
├─ Semantic alignment: Cross-validates
└─ Trust scoring: Final 0-100 score
4. AUTO-DISPATCH (if trust > 50)
├─ Finds nearest resources (geo-spatial query)
├─ Reserves ambulances/fire trucks
├─ Sends SMS alerts to agencies
├─ Updates real-time dashboard
└─ Tracks response times
5. AGENCY RESPONSE
├─ Agencies see incident on dashboard
├─ Dispatch teams to location
├─ Update status in real-time
└─ Upload response photos/notes
6. COORDINATOR OVERSIGHT
├─ Allocates resources between agencies
├─ Approves/rejects resource requests
├─ Views region-wide analytics
└─ Manages system-wide alerts
7. RESOLUTION
├─ Incident marked "Resolved"
├─ Analytics calculated
├─ Audit trail saved
└─ Performance metrics updated
```
## 🌟 核心特性详解
### 1. 多模态事件报告
- **语音 SOS**:点击按钮 → 录制语音 → 在 60 秒内自动调度
- **图像 + 文本**:拍照 → 描述 → 深度伪造分析
- **支持的语言**:英语、孟加拉语、印地语、古吉拉特语、意大利语、俄语、阿拉伯语、中文、马拉地语
### 2. AI 驱动的验证(准确率 95% 以上)
- 通过 Ollama 进行深度伪造检测(本地推理)
- EXIF 元数据分析
- 像素级认证检查
### 3. 实时资源跟踪
- 在地图上显示 GPS 跟踪的资源
- 基于邻近度的匹配
- 状态更新(可用 → 已部署 → 可用)
- 用于实现低于 100ms 查询的地理空间索引
### 4. 多角色仪表盘
- **市民**:报告事件,查看附近事件,联系机构
- **机构**:管理团队,跟踪资源,更新状态
- **协调员**:系统概览,资源分配,数据分析
### 5. 危机新闻聚合
- 通过 Tavily API 获取实时新闻
- 使用 Gemini 进行 AI 总结
- 情感分析与分类
- 每 30 分钟更新一次
## 🌟 端到端工作流程示例
### 场景:市中心公寓火灾
**14:32:15 - 市民 1 报告**
```
Input: Image of fire in building + voice "FIRE! HELP!"
Forensics: Real image, valid EXIF
Vision: Fire (95%), Smoke (90%)
Voice: Keywords ["FIRE", "HELP"], Sentiment: Panic
Location: [40.7128, -74.0060]
Location Consensus: 0 (first report)
Phase 4 Scoring:
Formula C (Hybrid):
Visual: 90
Audio: 95
Location: 0
Result: (90×0.4) + (95×0.4) + (0×0.2) = 74
Phase 5 Priority: BRAVO (Trust 74 + Emergency objects detected)
Action: ⏳ Waiting for manual review
```
**14:33:20 - 市民 2 报告** ← (68 秒后)
```
Input: Voice report only "FIRE! TRAPPED!"
Forensics: N/A (voice only)
Voice: Keywords ["FIRE", "TRAPPED"], Sentiment: Panic, Urgency: 9/10
Location: [40.7129, -74.0061] (50m from Citizen 1)
Location Consensus: 50 (1 other incident detected) ⭐
Phase 4 Scoring:
Formula B (Voice):
Keywords: 95
Sentiment: 85
Location Consensus: 50 ← BOOSTED by area consensus
Result: (95×0.5) + (85×0.2) + (50×0.3) = 80.5
Phase 5 Priority: DELTA (Trust 80.5 ≥ 75 + "TRAPPED" keyword)
Action: 🚨 AUTO-DISPATCH TRIGGERED
→ 2 Ambulances (2km away)
→ 3 Fire Trucks (1.5km away)
→ Rescue Team (3km away)
→ SMS alerts to agencies
```
**14:34:10 - 市民 3 报告** ← (50 秒后)
```
Input: Image of fire spreading
Location: [40.7130, -74.0062] (100m from center)
Location Consensus: 75 (2 other incidents detected) ⭐⭐
Phase 4 Scoring:
Formula A (Image):
Visual: 95
Alignment: 85
Location Consensus: 75 ← STRONGLY BOOSTED
Result: (95×0.5 + 85×0.2 + 75×0.3) = 80.5
Phase 5 Priority: DELTA
Action: 🚨 COORDINATES RESOURCES, Updates status to "ACTIVE"
```
**14:35:05 - 市民 4 报告** ← (55 秒后)
```
Input: Image + voice report
Location: [40.7131, -74.0063] (150m away)
Location Consensus: 100 (3 other incidents! Mass event!) ⭐⭐⭐
Phase 4 Scoring: 88.2
Phase 5 Priority: CRITICAL CASE
→ Coordinator receives: "MASS FIRE EVENT NEAR DOWNTOWN CENTER"
→ Escalates to EMERGENCY OPERATIONS CENTER
→ Deploys: 10+ additional resources
→ Notifies: Public alerts, evacuation orders
```
## 🗄️ 数据库模式
### 事件模型
```
{
// Basic Info
type: "Fire" | "Flood" | "Medical" | "Accident" | etc,
severity: "Low" | "Medium" | "High" | "Critical",
mode: "VOICE" | "IMAGE_TEXT" | "SHAKE_HYBRID",
description: String,
// Location (Geospatial Indexing for fast queries)
location: {
type: "Point",
coordinates: [longitude, latitude] // GeoJSON format
},
// Phase 1: Forensics
forensics: {
isFake: Boolean,
confidenceScore: Number (0-100),
realismFactor: Number (0-1),
isPocket: Boolean,
deepfakeIndicators: [String],
analysis: { camera, aiDetected, pixelAnalysis, exifData }
},
// Phase 2-3: AI Analysis & Semantics
aiAnalysis: {
vision: {
detected: ["Fire", "Smoke", "People"],
confidence: Number,
severity: String
},
voice: {
keywords: ["Help", "Trapped", "Fire"],
sentiment: "panic" | "calm" | "neutral",
urgency: Number (1-10)
},
semantics: {
alignmentScore: Number (0-100),
description: String
}
},
// Phase 4: Trust Scoring ⭐ WITH LOCATION CONSENSUS
trustScore: {
totalScore: Number (0-100),
formula: "FORMULA_A" | "FORMULA_B" | "FORMULA_C",
breakdown: {
visual: Number,
audio: Number,
alignment: Number,
consensus: Number ← Location consensus component
},
locationConsensus: {
nearbyIncidents: Number, ← Count of incidents nearby
score: Number (0-100),
radius: 1000, // meters
timeWindow: "15 minutes"
}
},
// Phase 5: Priority Coding
priorityCode: {
code: "OMEGA" | "DELTA" | "CHARLIE" | "BRAVO" | "ALPHA" | "X-RAY",
description: String,
dispatchLevel: Number (0-5),
autoDispatch: Boolean
},
// Status & Tracking
status: "Pending" | "Active" | "Resolved" | "Spam",
reportedBy: ObjectId (User reference),
respondedBy: ObjectId (User reference),
dispatchedResources: [ObjectId], // Resource references
// Audit Log
verificationLog: [{
phase: String,
timestamp: Date,
result: Object
}],
createdAt: Date,
updatedAt: Date
}
```
### 数据库索引
```
// 2dsphere index for geospatial queries (fastest)
db.incidents.createIndex({ location: "2dsphere" });
// Time-based queries (for 15-minute window)
db.incidents.createIndex({ createdAt: -1 });
// Trust score sorting/filtering
db.incidents.createIndex({ trustScore: -1 });
// Priority code filtering
db.incidents.createIndex({ "priorityCode.code": 1 });
// User-based queries
db.incidents.createIndex({ reportedBy: 1 });
```
## 🚀 API 端点
### 事件 API
#### 创建事件(多模态)
```
POST /api/incidents/create
Request:
{
"type": "Fire",
"description": "Apartment fire",
"latitude": 40.7128,
"longitude": -74.0060,
"audioFile": , // OR
"imageFile": , // OR
"text": "Fire in building"
}
Response:
{
"id": "incident_123",
"trustScore": 85.5,
"priorityCode": "DELTA",
"locationConsensus": {
"nearbyIncidents": 2,
"score": 75
},
"dispatchedResources": [
{ "type": "Ambulance", "eta": "3 mins" },
{ "type": "Fire Truck", "eta": "2 mins" }
]
}
```
#### 获取附近事件
```
GET /api/incidents/nearby?latitude=40.7128&longitude=-74.0060&radius=1000
Response:
{
"incidents": [
{
"id": "incident_123",
"type": "Fire",
"trustScore": 85.5,
"distance": 150 // meters
},
...
],
"count": 3,
"locationConsensusScore": 75
}
```
#### 获取事件分析
```
GET /api/incidents/analytics?region=downtown&timeframe=24h
Response:
{
"totalIncidents": 45,
"byType": {
"Fire": 8,
"Medical": 25,
"Accident": 12
},
"avgTrustScore": 72.3,
"dispatchedCount": 38,
"avgResponseTime": "4.2 mins",
"hotspots": [
{
"location": [40.7128, -74.0060],
"incidents": 12,
"severity": "High"
}
]
}
```
## 🔒 安全特性
- **JWT 认证**:基于 Token 的 API 访问
- **Bcrypt 哈希**:带加盐轮次的密码哈希
- **EXIF 擦除**:移除媒体中的敏感元数据
- **XSS防护**:输入清理和输出编码
- **速率限制**:限制请求以防止滥用
- **AI 检测**:捕捉并标记 AI 生成的虚假报告
- **位置隐私**:坐标与用户身份分开存储
## 🌍 支持的语言
英语、孟加拉语、印地语、古吉拉特语、意大利语、俄语、阿拉伯语、中文(简体与繁体)、马拉地语
## 📊 性能指标
- **地理空间查询**:<100ms(使用 2dsphere 索引)
- **AI 视觉分析**:约 2-3 秒 (Google Gemini)
- **语音分析**:约 1-2 秒(语音转文本 + 关键词)
- **深度伪造检测**:约 1-2 秒(EXIF + 像素分析)
- **信任评分计算**:<500ms(包括位置共识查询)
- **端到端处理**:通常为 4-8 秒
- **自动调度时间**:从报告到通知资源不到 10 秒
## 📦 环境变量
```
# MongoDB
MONGO_URI=mongodb+srv://user:password@cluster.mongodb.net/crisisconnect
# APIs
GOOGLE_API_KEY=your_google_api_key
GEMINI_API_KEY=your_gemini_api_key
TAVILY_API_KEY=your_tavily_api_key
# Cloudinary
CLOUDINARY_CLOUD_NAME=your_cloud_name
CLOUDINARY_API_KEY=your_api_key
CLOUDINARY_API_SECRET=your_api_secret
# Twilio
TWILIO_SID=your_twilio_sid
TWILIO_AUTH_TOKEN=your_auth_token
TWILIO_PHONE=+1234567890
# JWT
JWT_SECRET=your_jwt_secret
JWT_EXPIRE=7d
# 端口
PORT=5000
FRONTEND_PORT=5173
# Ollama (本地 Deepfake 检测)
OLLAMA_BASE_URL=http://localhost:11434
```
## 🎯 核心算法与公式
### 位置共识评分算法
**输入**:纬度,经度
**输出**:共识评分 (0-100),附近事件计数
```
1. Define search parameters:
- Radius: 1000 meters (1 km)
- Time Window: 15 minutes
- Status Filter: "Pending" or "Active"
2. Query MongoDB with geospatial $geoWithin $centerSphere:
db.incidents.find({
location: { $geoWithin: { $centerSphere: [[lon, lat], radiusInRadians] } },
createdAt: { $gte: Date.now() - 15*60*1000 },
status: { $in: ["Pending", "Active"] }
})
3. Count results:
- if count >= 3: score = 100
- if count == 2: score = 75
- if count == 1: score = 50
- if count == 0: score = 0
4. Return { nearbyIncidents, score, radius, timeWindow }
```
### 信任评分权重
```
Formula A (Image-Primary):
PreScore = (Visual × 0.5) + (Alignment × 0.2) + (LocationConsensus × 0.3)
FinalScore = min(100, PreScore × RealismFactor)
Formula B (Voice-Primary):
FinalScore = min(100, (Keyword × 0.5) + (Sentiment × 0.2) + (LocationConsensus × 0.3))
Formula C (Hybrid/Shake):
- Normal: (Visual × 0.4) + (Audio × 0.4) + (LocationConsensus × 0.2)
- Pocket: (Visual × 0.1) + (Audio × 0.6) + (LocationConsensus × 0.3)
```
## 🔧 安装与设置
### 后端设置
```
cd backend
npm install
# 创建 .env 文件
cp .env.example .env
# 填入你的 API 密钥
# 启动 MongoDB
mongod
# 创建地理空间索引
node fix_resources.js
# 运行后端
npm start
```
### 前端设置
```
cd frontend
npm install
# 创建 .env 文件
VITE_API_URL=http://localhost:5000
VITE_FIREBASE_CONFIG=your_firebase_config
npm run dev
```
## 🧪 测试基于位置的评分
### 手动测试用例
```
# 终端 1:启动后端
cd backend && npm start
# 终端 2:测试相同位置的 incidents
curl -X POST http://localhost:5000/api/incidents/create \
-F "type=Fire" \
-F "latitude=40.7128" \
-F "longitude=-74.0060" \
-F "description=Test incident 1" \
# Expected: locationConsensus.score = 0 (first incident)
# 等待 10 秒,然后:
curl -X POST http://localhost:5000/api/incidents/create \
-F "type=Fire" \
-F "latitude=40.71281" \
-F "longitude=-74.00601" \
-F "description=Test incident 2" \
# Expected: locationConsensus.score = 50 (1 nearby incident)
# 再次:
curl -X POST http://localhost:5000/api/incidents/create \
-F "type=Fire" \
-F "latitude=40.71282" \
-F "longitude=-74.00602" \
-F "description=Test incident 3" \
# Expected: locationConsensus.score = 75 (2 nearby incidents)
# 再次:
curl -X POST http://localhost:5000/api/incidents/create \
-F "type=Fire" \
-F "latitude=40.71283" \
-F "longitude=-74.00603" \
-F "description=Test incident 4" \
# Expected: locationConsensus.score = 100 (3+ nearby incidents) ⭐
```
## 🐛 故障排除
### 问题:位置共识评分始终为 0
**解决方案**:确保 MongoDB 地理空间索引存在:
```
db.incidents.createIndex({ location: "2dsphere" });
```
### 问题:未检测到附近事件
**解决方案**:检查事件坐标是否为 [经度, 纬度] GeoJSON 格式:
```
// ✅ Correct
location: { type: "Point", coordinates: [-74.0060, 40.7128] }
// ❌ Wrong
location: { type: "Point", coordinates: [40.7128, -74.0060] }
```
### 问题:位置共识查询缓慢
**解决方案**:确保存在以下索引:
```
db.incidents.createIndex({ location: "2dsphere" });
db.incidents.createIndex({ createdAt: -1 });
db.incidents.createIndex({ status: 1 });
```
## 📝 许可证
MIT 许可证 - 请参阅 LICENSE 文件
## 🤝 贡献
欢迎贡献!请遵循代码风格指南,并为新功能添加测试。
## 📞 支持
如有问题或疑问,请提交 GitHub issue 或联系开发团队。
标签:AI风险缓解, AI验证, Express.js, Gemma3, GNU通用公共许可证, GPS追踪, Leaflet, LLM评估, MITM代理, MongoDB, Mongoose, Node.js, OCR, Ollama, React, Redux Toolkit, SOS求救, Syscalls, Tailwind CSS, Tesseract.js, Vite, 信任评分, 公共安全, 危机管理, 图像处理, 地理空间索引, 多模态报告, 实时仪表盘, 工作流管理, 应急响应平台, 情感分析, 新闻聚合, 智能资源分配, 深度伪造检测, 灾害响应, 热力图, 自定义脚本, 资源调度