UNPKG

carthorse

Version:

A geospatial trail data processing pipeline for building 3D trail databases with elevation data

255 lines โ€ข 12.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.PostgresRoutingGraphProcessor = void 0; class PostgresRoutingGraphProcessor { constructor(routingService, databaseService) { this.routingService = routingService; this.databaseService = databaseService; } async buildRoutingGraph(schemaName, config) { console.log(`๐Ÿ›ค๏ธ Building routing graph for schema '${schemaName}'`); console.log(`๐Ÿ“‹ Configuration:`); console.log(` - Node tolerance: ${config.nodeTolerance}m`); console.log(` - Edge tolerance: ${config.edgeTolerance}m`); console.log(` - Min trail length: ${config.minTrailLengthMeters}m`); console.log(` - Enable intersection detection: ${config.enableIntersectionDetection}`); console.log(` - Enable node generation: ${config.enableNodeGeneration}`); console.log(` - Enable edge generation: ${config.enableEdgeGeneration}`); console.log(` - Enable network validation: ${config.enableNetworkValidation}`); const errors = []; const warnings = []; try { let intersectionCount = 0; let nodeCount = 0; let edgeCount = 0; let orphanedNodesRemoved = 0; let orphanedEdgesRemoved = 0; // Step 1: Detect intersections if (config.enableIntersectionDetection) { console.log(`๐Ÿ” Step 1: Detecting trail intersections...`); const intersectionResult = await this.routingService.detectIntersections(schemaName, config.nodeTolerance); intersectionCount = intersectionResult.intersectionCount; console.log(`โœ… Detected ${intersectionCount} intersections`); } else { console.log(`โญ๏ธ Skipping intersection detection as requested`); } // Step 2: Generate routing nodes if (config.enableNodeGeneration) { console.log(`๐Ÿ“ Step 2: Generating routing nodes...`); const nodeResult = await this.routingService.generateRoutingNodes(schemaName, config.nodeTolerance); nodeCount = nodeResult.nodeCount; console.log(`โœ… Generated ${nodeCount} routing nodes`); console.log(` - Endpoint nodes: ${nodeResult.nodeTypes.endpoint}`); console.log(` - Intersection nodes: ${nodeResult.nodeTypes.intersection}`); } else { console.log(`โญ๏ธ Skipping node generation as requested`); } // Step 3: Generate routing edges if (config.enableEdgeGeneration) { console.log(`๐Ÿ›ค๏ธ Step 3: Generating routing edges...`); const edgeResult = await this.routingService.generateRoutingEdges(schemaName, config.edgeTolerance); edgeCount = edgeResult.edgeCount; orphanedNodesRemoved = edgeResult.orphanedNodesRemoved; orphanedEdgesRemoved = edgeResult.orphanedEdgesRemoved; console.log(`โœ… Generated ${edgeCount} routing edges`); console.log(` - Orphaned nodes removed: ${orphanedNodesRemoved}`); console.log(` - Orphaned edges removed: ${orphanedEdgesRemoved}`); } else { console.log(`โญ๏ธ Skipping edge generation as requested`); } // Step 4: Validate routing network let isConnected = false; let isolatedNodes = 0; let orphanedEdges = 0; let connectivityStats = { totalNodes: 0, connectedNodes: 0, leafNodes: 0, avgDegree: 0 }; if (config.enableNetworkValidation) { console.log(`๐Ÿ” Step 4: Validating routing network...`); const validationResult = await this.routingService.validateRoutingNetwork(schemaName); isConnected = validationResult.isConnected; isolatedNodes = validationResult.isolatedNodes; orphanedEdges = validationResult.orphanedEdges; connectivityStats = validationResult.connectivityStats; if (!isConnected) { warnings.push(`Routing network is not fully connected (${isolatedNodes} isolated nodes, ${orphanedEdges} orphaned edges)`); } } else { console.log(`โญ๏ธ Skipping network validation as requested`); } console.log(`โœ… Routing graph construction completed successfully`); console.log(`๐Ÿ“Š Final graph statistics:`); console.log(` - Nodes: ${nodeCount}`); console.log(` - Edges: ${edgeCount}`); console.log(` - Intersections: ${intersectionCount}`); console.log(` - Connected: ${isConnected ? 'Yes' : 'No'}`); console.log(` - Isolated nodes: ${isolatedNodes}`); console.log(` - Orphaned edges: ${orphanedEdges}`); return { success: true, nodeCount, edgeCount, intersectionCount, orphanedNodesRemoved, orphanedEdgesRemoved, isConnected, isolatedNodes, orphanedEdges, connectivityStats, errors, warnings }; } catch (error) { console.error('โŒ Routing graph construction failed:', error); return { success: false, nodeCount: 0, edgeCount: 0, intersectionCount: 0, orphanedNodesRemoved: 0, orphanedEdgesRemoved: 0, isConnected: false, isolatedNodes: 0, orphanedEdges: 0, connectivityStats: { totalNodes: 0, connectedNodes: 0, leafNodes: 0, avgDegree: 0 }, errors: [error instanceof Error ? error.message : String(error)], warnings }; } } async optimizeRoutingGraph(schemaName, config) { console.log(`๐Ÿ”ง Optimizing routing graph for schema '${schemaName}'`); console.log(`๐Ÿ“‹ Optimization configuration:`); console.log(` - Remove isolated nodes: ${config.removeIsolatedNodes}`); console.log(` - Remove orphaned edges: ${config.removeOrphanedEdges}`); console.log(` - Merge close nodes: ${config.mergeCloseNodes}`); console.log(` - Node merge tolerance: ${config.nodeMergeTolerance}m`); const errors = []; const warnings = []; try { let nodesRemoved = 0; let edgesRemoved = 0; let nodesMerged = 0; // Remove isolated nodes if (config.removeIsolatedNodes) { console.log(`๐Ÿงน Removing isolated nodes...`); nodesRemoved = await this.routingService.cleanupOrphanedNodes(schemaName); console.log(`โœ… Removed ${nodesRemoved} isolated nodes`); } // Remove orphaned edges if (config.removeOrphanedEdges) { console.log(`๐Ÿงน Removing orphaned edges...`); const orphanedEdgesResult = await this.databaseService.executeQuery(` DELETE FROM ${schemaName}.routing_edges WHERE source NOT IN (SELECT id FROM ${schemaName}.routing_nodes) OR target NOT IN (SELECT id FROM ${schemaName}.routing_nodes) `); edgesRemoved = orphanedEdgesResult.rowCount; console.log(`โœ… Removed ${edgesRemoved} orphaned edges`); } // Merge close nodes (if implemented) if (config.mergeCloseNodes) { console.log(`๐Ÿ”— Merging close nodes (tolerance: ${config.nodeMergeTolerance}m)...`); // This would be a more complex operation that merges nodes within the tolerance // For now, we'll just log that it's not implemented warnings.push('Node merging is not yet implemented'); } console.log(`โœ… Routing graph optimization completed successfully`); console.log(`๐Ÿ“Š Optimization results:`); console.log(` - Nodes removed: ${nodesRemoved}`); console.log(` - Edges removed: ${edgesRemoved}`); console.log(` - Nodes merged: ${nodesMerged}`); return { success: true, nodesRemoved, edgesRemoved, nodesMerged, errors, warnings }; } catch (error) { console.error('โŒ Routing graph optimization failed:', error); return { success: false, nodesRemoved: 0, edgesRemoved: 0, nodesMerged: 0, errors: [error instanceof Error ? error.message : String(error)], warnings }; } } async validateRoutingGraph(schemaName) { console.log(`๐Ÿ” Validating routing graph for schema '${schemaName}'`); try { const validationResult = await this.routingService.validateRoutingNetwork(schemaName); // Get node and edge counts const nodeCountResult = await this.databaseService.executeQuery(`SELECT COUNT(*) FROM ${schemaName}.routing_nodes`); const edgeCountResult = await this.databaseService.executeQuery(`SELECT COUNT(*) FROM ${schemaName}.routing_edges`); const intersectionCountResult = await this.databaseService.executeQuery(`SELECT COUNT(*) FROM ${schemaName}.intersection_points`); const nodeCount = parseInt(nodeCountResult.rows[0].count); const edgeCount = parseInt(edgeCountResult.rows[0].count); const intersectionCount = parseInt(intersectionCountResult.rows[0].count); console.log(`โœ… Routing graph validation completed`); console.log(`๐Ÿ“Š Graph statistics:`); console.log(` - Nodes: ${nodeCount}`); console.log(` - Edges: ${edgeCount}`); console.log(` - Intersections: ${intersectionCount}`); console.log(` - Connected: ${validationResult.isConnected ? 'Yes' : 'No'}`); console.log(` - Isolated nodes: ${validationResult.isolatedNodes}`); console.log(` - Orphaned edges: ${validationResult.orphanedEdges}`); return { success: validationResult.isConnected, nodeCount, edgeCount, intersectionCount, orphanedNodesRemoved: 0, orphanedEdgesRemoved: 0, isConnected: validationResult.isConnected, isolatedNodes: validationResult.isolatedNodes, orphanedEdges: validationResult.orphanedEdges, connectivityStats: validationResult.connectivityStats, errors: validationResult.isConnected ? [] : ['Routing graph is not fully connected'], warnings: [] }; } catch (error) { console.error('โŒ Routing graph validation failed:', error); return { success: false, nodeCount: 0, edgeCount: 0, intersectionCount: 0, orphanedNodesRemoved: 0, orphanedEdgesRemoved: 0, isConnected: false, isolatedNodes: 0, orphanedEdges: 0, connectivityStats: { totalNodes: 0, connectedNodes: 0, leafNodes: 0, avgDegree: 0 }, errors: [error instanceof Error ? error.message : String(error)], warnings: [] }; } } } exports.PostgresRoutingGraphProcessor = PostgresRoutingGraphProcessor; //# sourceMappingURL=RoutingGraphProcessor.js.map