UNPKG

carthorse

Version:

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

185 lines (177 loc) 9.17 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getStagingSchemaSql = getStagingSchemaSql; exports.getStagingIndexesSql = getStagingIndexesSql; exports.getSchemaQualifiedPostgisFunctionsSql = getSchemaQualifiedPostgisFunctionsSql; function getStagingSchemaSql(schemaName) { const dropTablesSql = [ 'trails', 'trail_hashes', 'trail_id_mapping', 'intersection_points', 'route_recommendations', 'split_trails' ].map(table => `DROP TABLE IF EXISTS ${schemaName}.${table} CASCADE;`).join('\n'); return ` ${dropTablesSql} -- Staging trails table CREATE TABLE ${schemaName}.trails ( id SERIAL PRIMARY KEY, app_uuid TEXT UNIQUE NOT NULL, osm_id TEXT, name TEXT NOT NULL, region TEXT NOT NULL, trail_type TEXT, surface TEXT, difficulty TEXT, source_tags JSONB, bbox_min_lng REAL, bbox_max_lng REAL, bbox_min_lat REAL, bbox_max_lat REAL, length_km REAL, elevation_gain REAL CHECK(elevation_gain IS NULL OR elevation_gain >= 0), elevation_loss REAL CHECK(elevation_loss IS NULL OR elevation_loss >= 0), max_elevation REAL, min_elevation REAL, avg_elevation REAL, source TEXT, created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW(), geometry GEOMETRY(LINESTRINGZ, 4326), CONSTRAINT ${schemaName}_trails_3d_geometry CHECK (ST_NDims(geometry) = 3), CONSTRAINT ${schemaName}_trails_valid_geometry CHECK (ST_IsValid(geometry)) ); -- Trail hash cache table (uses app_uuid instead of foreign key to avoid drop issues) CREATE TABLE ${schemaName}.trail_hashes ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), app_uuid TEXT NOT NULL, -- Changed from trail_id INTEGER to app_uuid TEXT geometry_hash TEXT NOT NULL, created_at TIMESTAMP DEFAULT NOW() ); -- Trail ID mapping table (UUID ↔ Integer ID lookup for pgRouting boundary) CREATE TABLE ${schemaName}.trail_id_mapping ( id SERIAL PRIMARY KEY, app_uuid TEXT UNIQUE NOT NULL, -- Original trail UUID trail_id INTEGER UNIQUE NOT NULL, -- pgRouting integer ID created_at TIMESTAMP DEFAULT NOW() ); -- Intersection points table CREATE TABLE ${schemaName}.intersection_points ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), point GEOMETRY(POINT, 4326), point_3d GEOMETRY(POINTZ, 4326), connected_trail_ids TEXT[], connected_trail_names TEXT[], node_type TEXT, distance_meters REAL, created_at TIMESTAMP DEFAULT NOW() ); -- Route recommendations table CREATE TABLE ${schemaName}.route_recommendations ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), route_uuid TEXT UNIQUE NOT NULL, region TEXT NOT NULL, input_length_km REAL CHECK(input_length_km > 0), input_elevation_gain REAL, recommended_length_km REAL CHECK(recommended_length_km > 0), recommended_elevation_gain REAL, route_type TEXT, route_shape TEXT, trail_count INTEGER, route_score REAL, similarity_score REAL CHECK(similarity_score >= 0 AND similarity_score <= 1), route_path JSONB, route_edges JSONB, route_name TEXT, complete_route_data TEXT, -- Complete route information as JSON (API service requirement) created_at TIMESTAMP DEFAULT NOW() ); -- Route trails table (for trail composition of routes) CREATE TABLE ${schemaName}.route_trails ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), route_uuid TEXT NOT NULL, trail_id TEXT NOT NULL, trail_name TEXT NOT NULL, segment_order INTEGER NOT NULL, segment_length_km REAL, segment_elevation_gain REAL, trail_type TEXT, surface TEXT, difficulty TEXT, created_at TIMESTAMP DEFAULT NOW() ); -- Split trails table (for 1:1 mapping with edges) CREATE TABLE ${schemaName}.split_trails ( id SERIAL PRIMARY KEY, original_trail_id INTEGER, segment_number INTEGER, app_uuid TEXT NOT NULL, name TEXT, trail_type TEXT, surface TEXT, difficulty TEXT, source_tags TEXT, osm_id TEXT, elevation_gain REAL, elevation_loss REAL, max_elevation REAL, min_elevation REAL, avg_elevation REAL, length_km REAL, source TEXT, geometry GEOMETRY(LINESTRINGZ, 4326), bbox_min_lng REAL, bbox_max_lng REAL, bbox_min_lat REAL, bbox_max_lat REAL, created_at TIMESTAMP DEFAULT NOW(), updated_at TIMESTAMP DEFAULT NOW() ); -- Create indexes CREATE INDEX IF NOT EXISTS idx_${schemaName}_trails_geometry ON ${schemaName}.trails USING GIST(geometry); CREATE INDEX IF NOT EXISTS idx_${schemaName}_intersection_points ON ${schemaName}.intersection_points USING GIST(point); CREATE INDEX IF NOT EXISTS idx_${schemaName}_route_recommendations_region ON ${schemaName}.route_recommendations(region); CREATE INDEX IF NOT EXISTS idx_${schemaName}_route_recommendations_score ON ${schemaName}.route_recommendations(route_score); `; } function getStagingIndexesSql(schemaName) { return ` CREATE INDEX IF NOT EXISTS idx_staging_trails_osm_id ON ${schemaName}.trails(osm_id); CREATE INDEX IF NOT EXISTS idx_staging_trails_bbox ON ${schemaName}.trails(bbox_min_lng, bbox_max_lng, bbox_min_lat, bbox_max_lat); CREATE INDEX IF NOT EXISTS idx_staging_trails_geometry ON ${schemaName}.trails USING GIST(geometry); CREATE INDEX IF NOT EXISTS idx_staging_intersection_points_point ON ${schemaName}.intersection_points USING GIST(point); `; } function getSchemaQualifiedPostgisFunctionsSql(schemaName, functionsSql) { return functionsSql // Rewrite all function definitions to use the staging schema (including those explicitly in public schema) .replace(/CREATE OR REPLACE FUNCTION public\.detect_trail_intersections/g, `CREATE OR REPLACE FUNCTION ${schemaName}.detect_trail_intersections`) .replace(/CREATE OR REPLACE FUNCTION public\.build_routing_nodes/g, `CREATE OR REPLACE FUNCTION ${schemaName}.build_routing_nodes`) .replace(/CREATE OR REPLACE FUNCTION public\.build_routing_edges/g, `CREATE OR REPLACE FUNCTION ${schemaName}.build_routing_edges`) .replace(/CREATE OR REPLACE FUNCTION public\.get_intersection_stats/g, `CREATE OR REPLACE FUNCTION ${schemaName}.get_intersection_stats`) .replace(/CREATE OR REPLACE FUNCTION public\.validate_intersection_detection/g, `CREATE OR REPLACE FUNCTION ${schemaName}.validate_intersection_detection`) .replace(/CREATE OR REPLACE FUNCTION public\.validate_spatial_data_integrity/g, `CREATE OR REPLACE FUNCTION ${schemaName}.validate_spatial_data_integrity`) // Also handle functions without explicit schema (default to public) .replace(/CREATE OR REPLACE FUNCTION detect_trail_intersections/g, `CREATE OR REPLACE FUNCTION ${schemaName}.detect_trail_intersections`) .replace(/CREATE OR REPLACE FUNCTION build_routing_nodes/g, `CREATE OR REPLACE FUNCTION ${schemaName}.build_routing_nodes`) .replace(/CREATE OR REPLACE FUNCTION build_routing_edges/g, `CREATE OR REPLACE FUNCTION ${schemaName}.build_routing_edges`) .replace(/CREATE OR REPLACE FUNCTION get_intersection_stats/g, `CREATE OR REPLACE FUNCTION ${schemaName}.get_intersection_stats`) .replace(/CREATE OR REPLACE FUNCTION validate_intersection_detection/g, `CREATE OR REPLACE FUNCTION ${schemaName}.validate_intersection_detection`) .replace(/CREATE OR REPLACE FUNCTION validate_spatial_data_integrity/g, `CREATE OR REPLACE FUNCTION ${schemaName}.validate_spatial_data_integrity`) // Also replace any references to public schema functions within the function bodies .replace(/public\.detect_trail_intersections\(/g, `${schemaName}.detect_trail_intersections(`) .replace(/public\.build_routing_nodes\(/g, `${schemaName}.build_routing_nodes(`) .replace(/public\.build_routing_edges\(/g, `${schemaName}.build_routing_edges(`) .replace(/public\.get_intersection_stats\(/g, `${schemaName}.get_intersection_stats(`) .replace(/public\.validate_intersection_detection\(/g, `${schemaName}.validate_intersection_detection(`) .replace(/public\.validate_spatial_data_integrity\(/g, `${schemaName}.validate_spatial_data_integrity(`) // Also replace unqualified function calls within function bodies .replace(/detect_trail_intersections\(/g, `${schemaName}.detect_trail_intersections(`) .replace(/build_routing_nodes\(/g, `${schemaName}.build_routing_nodes(`) .replace(/build_routing_edges\(/g, `${schemaName}.build_routing_edges(`) .replace(/get_intersection_stats\(/g, `${schemaName}.get_intersection_stats(`) .replace(/validate_intersection_detection\(/g, `${schemaName}.validate_intersection_detection(`) .replace(/validate_spatial_data_integrity\(/g, `${schemaName}.validate_spatial_data_integrity(`); } //# sourceMappingURL=staging-schema.js.map