@sailboat-computer/data-storage
Version:
Shared data storage library for sailboat computer v3
214 lines (197 loc) • 6.62 kB
text/typescript
/**
* Sea state data fixtures for testing
*/
import { StoredData } from '../../src/types';
/**
* Generate a single sea state data point
*
* @param latitude - Latitude
* @param longitude - Longitude
* @param timestamp - Timestamp
* @param options - Additional options
* @returns Sea state data point
*/
export function createSeaStateDataPoint(
latitude: number,
longitude: number,
timestamp: string,
options: {
waveHeight?: number;
wavePeriod?: number;
waveDirection?: number;
swellHeight?: number;
swellPeriod?: number;
swellDirection?: number;
seaTemperature?: number;
currentSpeed?: number;
currentDirection?: number;
tags?: Record<string, string>;
} = {}
): StoredData {
return {
data: {
latitude,
longitude,
waveHeight: options.waveHeight ?? 1.2,
wavePeriod: options.wavePeriod ?? 8,
waveDirection: options.waveDirection ?? 240,
swellHeight: options.swellHeight ?? 0.8,
swellPeriod: options.swellPeriod ?? 12,
swellDirection: options.swellDirection ?? 260,
seaTemperature: options.seaTemperature ?? 15.5,
currentSpeed: options.currentSpeed ?? 0.5,
currentDirection: options.currentDirection ?? 180
},
metadata: {
id: `sea-state-${Date.now()}-${Math.floor(Math.random() * 1000)}`,
category: 'sea.state',
timestamp,
tags: options.tags ?? { source: 'buoy', location: 'golden-gate' }
}
};
}
/**
* Generate a rough sea state data point
*
* @param latitude - Latitude
* @param longitude - Longitude
* @param timestamp - Timestamp
* @returns Rough sea state data point
*/
export function createRoughSeaStateDataPoint(
latitude: number,
longitude: number,
timestamp: string
): StoredData {
return createSeaStateDataPoint(latitude, longitude, timestamp, {
waveHeight: 3.5,
wavePeriod: 6,
waveDirection: 220,
swellHeight: 2.2,
swellPeriod: 10,
swellDirection: 240,
currentSpeed: 1.2,
currentDirection: 200,
tags: { source: 'buoy', location: 'golden-gate', condition: 'rough' }
});
}
/**
* Generate a grid of sea state data points
*
* @param centerLat - Center latitude
* @param centerLon - Center longitude
* @param gridSize - Grid size in degrees
* @param gridPoints - Number of points per side
* @param baseTime - Base timestamp
* @returns Grid of sea state data points
*/
export function createSeaStateDataGrid(
centerLat: number,
centerLon: number,
gridSize: number,
gridPoints: number,
baseTime: Date
): StoredData[] {
const result: StoredData[] = [];
const halfGrid = gridSize / 2;
const step = gridSize / (gridPoints - 1);
for (let i = 0; i < gridPoints; i++) {
for (let j = 0; j < gridPoints; j++) {
const lat = centerLat - halfGrid + i * step;
const lon = centerLon - halfGrid + j * step;
const time = new Date(baseTime.getTime() - (i * gridPoints + j) * 3600000); // 1 hour intervals
// Create normal sea state data
result.push(createSeaStateDataPoint(lat, lon, time.toISOString(), {
waveHeight: 0.5 + Math.sin((i + j) / 10 * Math.PI) * 0.5,
wavePeriod: 8 + Math.cos((i - j) / 8 * Math.PI) * 2,
seaTemperature: 15 + Math.sin((i * j) / 20 * Math.PI) * 2,
tags: {
source: 'buoy',
location: 'golden-gate',
grid: `${Math.floor(lat * 20)},${Math.floor(lon * 20)}`
}
}));
}
}
// Add rough seas in the middle
const roughTime = new Date(baseTime.getTime() - Math.floor(gridPoints * gridPoints / 2) * 3600000);
result.push(createRoughSeaStateDataPoint(centerLat, centerLon, roughTime.toISOString()));
return result;
}
/**
* Generate a time series of sea state data at a single location
*
* @param latitude - Latitude
* @param longitude - Longitude
* @param count - Number of data points
* @param interval - Interval in milliseconds
* @param baseTime - Base timestamp
* @returns Time series of sea state data
*/
export function createSeaStateTimeSeries(
latitude: number,
longitude: number,
count: number,
interval: number,
baseTime: Date
): StoredData[] {
const result: StoredData[] = [];
for (let i = 0; i < count; i++) {
const time = new Date(baseTime.getTime() - i * interval);
// Create sea state data with tidal and daily cycles
result.push(createSeaStateDataPoint(latitude, longitude, time.toISOString(), {
waveHeight: 0.5 + Math.sin(i / 12 * Math.PI * 2) * 0.5 + Math.random() * 0.5, // 12-hour cycle
wavePeriod: 6 + Math.sin(i / 24 * Math.PI * 2) * 2 + Math.random(), // Daily cycle
swellHeight: 0.3 + Math.sin(i / 48 * Math.PI * 2) * 0.3 + Math.random() * 0.2, // 2-day cycle
seaTemperature: 15 + Math.sin(i / 24 * Math.PI * 2) * 1 + Math.random(), // Daily cycle
currentSpeed: 0.2 + Math.sin(i / 12 * Math.PI * 2) * 0.3 + Math.random() * 0.1, // 12-hour cycle (tidal)
currentDirection: (180 + Math.sin(i / 12 * Math.PI * 2) * 90) % 360, // 12-hour cycle (tidal)
tags: {
source: 'buoy',
location: 'golden-gate',
timestamp: time.toISOString()
}
}));
}
return result;
}
/**
* Generate a coastal current pattern
*
* @param coastLat - Coast latitude
* @param coastLon - Coast longitude
* @param pointCount - Number of points along coast
* @param distanceFromCoast - Distance from coast in degrees
* @param baseTime - Base timestamp
* @returns Coastal current pattern data
*/
export function createCoastalCurrentPattern(
coastLat: number,
coastLon: number,
pointCount: number,
distanceFromCoast: number,
baseTime: Date
): StoredData[] {
const result: StoredData[] = [];
const coastLength = 0.5; // degrees
const step = coastLength / (pointCount - 1);
for (let i = 0; i < pointCount; i++) {
const lat = coastLat - coastLength / 2 + i * step;
const lon = coastLon + distanceFromCoast;
const time = new Date(baseTime.getTime() - i * 3600000); // 1 hour intervals
// Create coastal current data
result.push(createSeaStateDataPoint(lat, lon, time.toISOString(), {
waveHeight: 0.8 + Math.sin(i / pointCount * Math.PI) * 0.3,
currentSpeed: 0.8 + Math.sin(i / pointCount * Math.PI * 2) * 0.4,
currentDirection: (180 + Math.sin(i / pointCount * Math.PI * 4) * 45) % 360,
seaTemperature: 14 + Math.sin(i / pointCount * Math.PI * 2) * 2,
tags: {
source: 'model',
location: 'coastal-current',
point: `${i}`,
distance: `${distanceFromCoast}`
}
}));
}
return result;
}