diff --git a/README.md b/README.md index 001acfe..41e2ff7 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,9 @@ This proof-of-concept tracker monitors vessels like **ZHONG DA 79** - a Chinese - **Multi-source AIS** - Support for AISStream, AISHub, and Marinesia APIs - **Ship markers with heading** - Vessel icons rotate based on course - **Vessel-type color coding** - Different colors for cargo, tanker, passenger, military, etc. +- **Track with timestamps** - Click vessel to see historical track with time markers + - Green marker = track start, Red marker = latest position + - Hover for timestamp, speed, and course at each point - **Viewport-optimized rendering** - Handles 10,000+ live vessels without browser lag - **SQLite WAL mode** - Better concurrent database access @@ -510,12 +513,23 @@ Situational awareness for undersea cable and pipeline incidents, with anchor dra ### Baltic Sea Infrastructure -| Infrastructure | Type | Route | Protection Zone | -|----------------|------|-------|-----------------| -| C-Lion1 | Telecom Cable | Helsinki-Rostock | 5 nm | -| Estlink-2 | Power Cable | Estonia-Finland | 3 nm | -| Estlink-1 | Power Cable | Estonia-Finland | 3 nm | -| Balticconnector | Gas Pipeline | Estonia-Finland | 5 nm | +**33 infrastructure assets** loaded from `data/infrastructure.json`: + +| Type | Count | Examples | +|------|-------|----------| +| Telecom/Fiber Cables | 12 | C-Lion1, BCS East-West Interlink, EESF-1/2, Eastern Light | +| Power Cables (HVDC) | 10 | Estlink-1/2, NordBalt, SwePol, Fenno-Skan 1/2 | +| Gas Pipelines | 4 | Balticconnector, Nord Stream 1/2, Europipe II | +| Offshore Wind Farms | 7 | Kriegers Flak, Arkona, Wikinger | + +**Recent Incidents Tracked:** +| Infrastructure | Date | Vessel | Status | +|----------------|------|--------|--------| +| C-Lion1 | Dec 31, 2025 | Under investigation | Damaged | +| Estlink-2 | Dec 25, 2025 | Eagle S | Damaged | +| EESF-1 | Dec 25, 2025 | Eagle S | Damaged | +| BCS East-West Interlink | Nov 17, 2024 | Yi Peng 3 | Damaged | +| Balticconnector | Oct 8, 2023 | Newnew Polar Bear | Damaged | ### Detection Capabilities @@ -546,8 +560,13 @@ Situational awareness for undersea cable and pipeline incidents, with anchor dra - **Infrastructure overlay** - Colored lines for cables/pipelines with labels - **Protection zones** - Dashed circles showing exclusion areas -- **Toggle button** - Enable/disable infrastructure layer +- **Toggle button** - Enable/disable infrastructure layer (blue cable icon) +- **Legend panel** - Color key in bottom-left corner when layer active + - 🟣 Purple = Telecom/Fiber cables + - 🟡 Yellow = Power cables (HVDC) + - 🟠 Orange (dashed) = Gas pipelines - **Click for details** - Popup with operator, capacity, incident notes +- **Track timestamps** - Hover on track markers to see position time, speed, course ### Usage Example @@ -781,19 +800,32 @@ Free API integration for vessel event data - AIS gaps, encounters, loitering, po 1. Register at https://globalfishingwatch.org/our-apis/ (free) 2. Get API token -3. Configure via API: +3. Configure via one of these methods: + +**Option A: UI Entry (Recommended)** +- Click any vessel in the watchlist +- Scroll to "Global Fishing Watch" section +- Paste your token and click Save +- Reload the page +**Option B: API Configuration** ```bash curl -X POST http://localhost:8080/api/gfw/configure \ -H "Content-Type: application/json" \ -d '{"token": "YOUR_GFW_TOKEN"}' ``` -Or set environment variable: +**Option C: Environment Variable** ```bash export GFW_API_TOKEN=your_token_here ``` +**Option D: Config File** +Create `gfw_config.json`: +```json +{"api_token": "your_token_here"} +``` + ### API Endpoints | Method | Endpoint | Description | diff --git a/gfw_integration.py b/gfw_integration.py index 236b30a..0ae66c3 100644 --- a/gfw_integration.py +++ b/gfw_integration.py @@ -671,11 +671,43 @@ def get_gfw_client() -> GFWClient: return _client +def reload_token() -> str: + """Reload GFW token from config file.""" + global GFW_TOKEN + token = os.environ.get("GFW_API_TOKEN", "") + if not token and os.path.exists(CONFIG_PATH): + try: + with open(CONFIG_PATH) as f: + config = json.load(f) + token = config.get('api_token', '') + except: + pass + GFW_TOKEN = token + return token + + def is_configured() -> bool: """Check if GFW API token is configured.""" + global GFW_TOKEN + # Reload from file if not set (in case config was updated) + if not GFW_TOKEN: + reload_token() return bool(GFW_TOKEN) +def save_token(token: str) -> bool: + """Save GFW API token to config file.""" + global GFW_TOKEN + try: + with open(CONFIG_PATH, 'w') as f: + json.dump({'api_token': token}, f) + GFW_TOKEN = token + return True + except Exception as e: + print(f"Error saving GFW token: {e}") + return False + + def search_vessel(query: str = None, mmsi: str = None, imo: str = None, name: str = None) -> dict: """Search for vessel identity.""" diff --git a/server.py b/server.py index adfba21..188ee4f 100644 --- a/server.py +++ b/server.py @@ -151,6 +151,7 @@ get_dark_fleet_indicators as gfw_get_dark_fleet_indicators, check_sts_zone as gfw_check_sts_zone, save_token as gfw_save_token, + reload_token as gfw_reload_token, get_sar_detections as gfw_get_sar_detections, find_dark_vessels as gfw_find_dark_vessels ) diff --git a/static/index.html b/static/index.html index d058701..725490a 100644 --- a/static/index.html +++ b/static/index.html @@ -720,6 +720,47 @@
+ +
+
+ 🔌 Infrastructure + +
+
+
+
+ Telecom/Fiber Cable +
+
+
+ Power Cable (HVDC) +
+
+
+ Gas Pipeline +
+
+
+ Protection Zone +
+
+ 0 assets loaded
+ Click cable for details +
+
+
+