Files
planet/backend/app/services/collectors/arcgis_landing.py
rayd1o 14d11cd99d feat(collectors): add ArcGIS landing points and cable-landing relation collectors
- Add ArcGISLandingPointCollector for FeatureServer/1 (landing points)
- Add ArcGISCableLandingRelationCollector for FeatureServer/3 (cable-landing relations)
- Register new collectors in __init__.py
- Fix earth cables.js with cable_id grouping for highlight
2026-03-12 16:37:18 +08:00

71 lines
2.5 KiB
Python

"""ArcGIS Landing Points Collector
Collects landing point data from ArcGIS GeoJSON API.
"""
from typing import Dict, Any, List
from datetime import datetime
from app.services.collectors.base import BaseCollector
class ArcGISLandingPointCollector(BaseCollector):
name = "arcgis_landing_points"
priority = "P1"
module = "L2"
frequency_hours = 168
data_type = "landing_point"
base_url = "https://services.arcgis.com/6DIQcwlPy8knb6sg/arcgis/rest/services/SubmarineCables/FeatureServer/1/query"
async def fetch(self) -> List[Dict[str, Any]]:
params = {"where": "1=1", "outFields": "*", "returnGeometry": "true", "f": "geojson"}
async with self._get_client() as client:
response = await client.get(self.base_url, params=params)
response.raise_for_status()
return self.parse_response(response.json())
def _get_client(self):
import httpx
return httpx.AsyncClient(timeout=60.0)
def parse_response(self, data: Dict[str, Any]) -> List[Dict[str, Any]]:
result = []
features = data.get("features", [])
for feature in features:
props = feature.get("properties", {})
geometry = feature.get("geometry", {})
lat = geometry.get("y") if geometry else None
lon = geometry.get("x") if geometry else None
try:
entry = {
"source_id": f"arcgis_lp_{props.get('OBJECTID', props.get('id', ''))}",
"name": props.get("Name", props.get("name", "Unknown")),
"country": props.get("country", ""),
"city": props.get("city", ""),
"latitude": str(lat) if lat else "",
"longitude": str(lon) if lon else "",
"value": "",
"unit": "",
"metadata": {
"objectid": props.get("OBJECTID"),
"cable_id": props.get("cable_id"),
"cable_name": props.get("cable_name"),
"facility": props.get("facility"),
"facility_type": props.get("facility_type"),
"status": props.get("status"),
"landing_point_id": props.get("landing_point_id"),
},
"reference_date": datetime.utcnow().strftime("%Y-%m-%d"),
}
result.append(entry)
except (ValueError, TypeError, KeyError):
continue
return result