UNPKG

tak-server-mcp-skyfi

Version:

Model Context Protocol (MCP) server for TAK Server integration with geospatial support

251 lines 10.4 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.calculateDistanceTool = void 0; const turf = __importStar(require("@turf/turf")); exports.calculateDistanceTool = { name: 'tak_calculate_distance', description: 'Calculate distances between entities, points, or coordinates', category: 'geospatial', requiresAuth: true, requiresWrite: false, inputSchema: { type: 'object', properties: { from: { type: 'object', properties: { entityId: { type: 'string', description: 'Entity ID to calculate distance from' }, coordinates: { type: 'array', items: { type: 'number' }, minItems: 2, maxItems: 2, description: 'Coordinates [lat, lon] to calculate distance from' } }, description: 'Starting point (provide either entityId or coordinates)' }, to: { type: 'object', properties: { entityId: { type: 'string', description: 'Entity ID to calculate distance to' }, coordinates: { type: 'array', items: { type: 'number' }, minItems: 2, maxItems: 2, description: 'Coordinates [lat, lon] to calculate distance to' } }, description: 'Destination point (provide either entityId or coordinates)' }, units: { type: 'string', enum: ['meters', 'kilometers', 'miles', 'nauticalmiles'], default: 'meters', description: 'Units for distance measurement' }, method: { type: 'string', enum: ['greatcircle', 'euclidean'], default: 'greatcircle', description: 'Calculation method' }, batch: { type: 'array', items: { type: 'object', properties: { entityId: { type: 'string' }, coordinates: { type: 'array', items: { type: 'number' }, minItems: 2, maxItems: 2 } } }, description: 'Calculate distances from "from" point to multiple destinations' } }, oneOf: [ { required: ['from', 'to'] }, { required: ['from', 'batch'] } ] }, handler: async (context) => { const { takClient, params, logger } = context; try { // Helper function to get coordinates const getCoordinates = async (point) => { if (point.coordinates) { return point.coordinates; } if (point.entityId) { const entities = await takClient.getEntities(); const entity = entities.find(e => e.uid === point.entityId); if (!entity) { throw new Error(`Entity ${point.entityId} not found`); } return [entity.location.lat, entity.location.lon]; } throw new Error('Either entityId or coordinates must be provided'); }; // Get from coordinates const fromCoords = await getCoordinates(params.from); const fromPoint = turf.point([fromCoords[1], fromCoords[0]]); // turf uses [lon, lat] // Handle single distance calculation if (params.to) { const toCoords = await getCoordinates(params.to); const toPoint = turf.point([toCoords[1], toCoords[0]]); const distance = turf.distance(fromPoint, toPoint, { units: params.units || 'meters' }); const bearing = turf.bearing(fromPoint, toPoint); // Calculate additional info const midpoint = turf.midpoint(fromPoint, toPoint); const travelTime = calculateTravelTime(distance, params.units || 'meters'); return { success: true, data: { from: { entityId: params.from.entityId, coordinates: fromCoords }, to: { entityId: params.to.entityId, coordinates: toCoords }, distance: distance, units: params.units || 'meters', bearing: bearing, backBearing: (bearing + 180) % 360, midpoint: [midpoint.geometry.coordinates[1], midpoint.geometry.coordinates[0]], estimatedTravelTime: travelTime }, metadata: { timestamp: new Date().toISOString(), calculationMethod: params.method || 'greatcircle' } }; } // Handle batch distance calculations if (params.batch) { const results = await Promise.all(params.batch.map(async (destination) => { try { const toCoords = await getCoordinates(destination); const toPoint = turf.point([toCoords[1], toCoords[0]]); const distance = turf.distance(fromPoint, toPoint, { units: params.units || 'meters' }); const bearing = turf.bearing(fromPoint, toPoint); return { to: { entityId: destination.entityId, coordinates: toCoords }, distance: distance, bearing: bearing }; } catch (error) { return { to: destination, error: error instanceof Error ? error.message : 'Failed to calculate distance' }; } })); // Sort by distance const validResults = results.filter(r => !r.error); validResults.sort((a, b) => a.distance - b.distance); return { success: true, data: { from: { entityId: params.from.entityId, coordinates: fromCoords }, distances: results, nearest: validResults[0], farthest: validResults[validResults.length - 1], units: params.units || 'meters' }, metadata: { timestamp: new Date().toISOString(), calculationMethod: params.method || 'greatcircle', totalCalculations: params.batch.length, successfulCalculations: validResults.length } }; } } catch (error) { logger.error('Failed to calculate distance:', error); return { success: false, error: { code: 'TAK_CALCULATION_ERROR', message: 'Failed to calculate distance', details: error instanceof Error ? error.message : 'Unknown error' } }; } } }; // Helper function to estimate travel time based on distance function calculateTravelTime(distance, units) { // Convert to meters if needed let distanceInMeters = distance; if (units === 'kilometers') distanceInMeters = distance * 1000; if (units === 'miles') distanceInMeters = distance * 1609.34; if (units === 'nauticalmiles') distanceInMeters = distance * 1852; return { walking: Math.round(distanceInMeters / 1.4 / 60), // 5 km/h vehicle: Math.round(distanceInMeters / 16.67 / 60), // 60 km/h helicopter: Math.round(distanceInMeters / 55.56 / 60), // 200 km/h units: 'minutes' }; } //# sourceMappingURL=calculate-distance.js.map