From fc83c2c6b4d54b8fd486f1d2f485963426d615a0 Mon Sep 17 00:00:00 2001 From: Theodore Kruczek Date: Fri, 19 Jul 2024 14:41:08 -0400 Subject: [PATCH] feat: :sparkles: add polar plots --- public/css/responsive-sm.css | 4 + public/img/icons/polar.png | Bin 0 -> 6102 bytes public/settings/settingsOverride.js | 2 + src/keeptrack.ts | 4 +- src/plugins/plugins.ts | 28 ++- src/plugins/polar-plot/polar-plot.ts | 266 +++++++++++++++++++++ src/plugins/sensor/custom-sensor-plugin.ts | 10 + src/plugins/sensor/sensorManager.ts | 4 + src/settings/settings.ts | 2 + src/settings/versionDate.js | 2 +- src/singletons/color-scheme-manager.ts | 16 +- 11 files changed, 325 insertions(+), 13 deletions(-) create mode 100644 public/img/icons/polar.png create mode 100644 src/plugins/polar-plot/polar-plot.ts diff --git a/public/css/responsive-sm.css b/public/css/responsive-sm.css index 332ebe282..d0444579e 100644 --- a/public/css/responsive-sm.css +++ b/public/css/responsive-sm.css @@ -83,4 +83,8 @@ max-width: 380px; right: 0px; } + + #polar-plot { + width: 100%; + } } diff --git a/public/img/icons/polar.png b/public/img/icons/polar.png new file mode 100644 index 0000000000000000000000000000000000000000..700a9116c1cbc4daa1c08d57f225692ee2884d4d GIT binary patch literal 6102 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 literal 0 HcmV?d00001 diff --git a/public/settings/settingsOverride.js b/public/settings/settingsOverride.js index 7e91770a2..36933ad21 100644 --- a/public/settings/settingsOverride.js +++ b/public/settings/settingsOverride.js @@ -69,6 +69,8 @@ const settingsOverride = { scenarioCreator: false, debrisScreening: true, videoDirector: false, + reports: true, + polarPlot: true, }, /* * searchLimit: 150, diff --git a/src/keeptrack.ts b/src/keeptrack.ts index b3e87eec1..8792a3834 100644 --- a/src/keeptrack.ts +++ b/src/keeptrack.ts @@ -621,9 +621,7 @@ theodore.kruczek at gmail dot com. * NOTE: We used to skip this when isDragging was true, but its so efficient that doesn't seem necessary anymore */ if (!settingsManager.isMobileModeEnabled) { - if (colorSchemeManagerInstance.currentColorScheme !== colorSchemeManagerInstance.default) { - colorSchemeManagerInstance.setColorScheme(colorSchemeManagerInstance.currentColorScheme); // avoid recalculating ALL colors - } + colorSchemeManagerInstance.setColorScheme(colorSchemeManagerInstance.currentColorScheme); // avoid recalculating ALL colors } } } diff --git a/src/plugins/plugins.ts b/src/plugins/plugins.ts index 9dde933fc..5fc5aa298 100644 --- a/src/plugins/plugins.ts +++ b/src/plugins/plugins.ts @@ -37,6 +37,8 @@ import { Planetarium } from './planetarium/planetarium'; * import { ricPlotPlugin } from './plot-analysis/ric-plots'; * import { time2LonPlotsPlugin } from './plot-analysis/time2lon'; */ +import { PolarPlotPlugin } from './polar-plot/polar-plot'; +import { ReportsPlugin } from './reports/reports'; import { satConstellationsPlugin } from './sat-constellations/sat-constellations'; import { SatelliteFov } from './satellite-fov/satellite-fov'; import { satellitePhotosPlugin } from './satellite-photos/satellite-photos'; @@ -112,6 +114,8 @@ export type KeepTrackPlugins = { topMenu?: boolean; updateSelectBox?: boolean; watchlist?: boolean; + reports?: boolean; + polarPlot?: boolean; }; // Register all core modules @@ -134,6 +138,12 @@ export const loadPlugins = async (keepTrackApi: KeepTrackApi, plugins: KeepTrack new WatchlistPlugin().init(); new WatchlistOverlay().init(); } + if (plugins.reports) { + new ReportsPlugin().init(); + } + if (plugins.polarPlot) { + new PolarPlotPlugin().init(); + } if (plugins.nextLaunch) { new NextLaunchesPlugin().init(); } @@ -287,14 +297,18 @@ export const uiManagerFinal = (plugins: any): void => { document.documentElement.style.setProperty('--bottom-menu-height', '0px'); } - // if (plugins.topMenu) { - // let topMenuHeight = parseInt(document.documentElement.style.getPropertyValue('--nav-bar-height').replace('px', '')); + /* + * if (plugins.topMenu) { + * let topMenuHeight = parseInt(document.documentElement.style.getPropertyValue('--nav-bar-height').replace('px', '')); + */ - // if (isNaN(topMenuHeight)) { - // topMenuHeight = 0; - // } - // document.documentElement.style.setProperty('--nav-bar-height', `${topMenuHeight + 50}px`); - // } + /* + * if (isNaN(topMenuHeight)) { + * topMenuHeight = 0; + * } + * document.documentElement.style.setProperty('--nav-bar-height', `${topMenuHeight + 50}px`); + * } + */ if (getEl('bottom-icons') && getEl('bottom-icons').innerText == '') { getEl('nav-footer').style.visibility = 'hidden'; diff --git a/src/plugins/polar-plot/polar-plot.ts b/src/plugins/polar-plot/polar-plot.ts new file mode 100644 index 000000000..d38dbaa7a --- /dev/null +++ b/src/plugins/polar-plot/polar-plot.ts @@ -0,0 +1,266 @@ +import { KeepTrackApiEvents } from '@app/interfaces'; +import { keepTrackApi } from '@app/keepTrackApi'; +import { getEl } from '@app/lib/get-el'; +import analysisPng from '@public/img/icons/polar.png'; + + +import { BaseObject, Degrees, DetailedSatellite, MILLISECONDS_PER_SECOND, secondsPerDay } from 'ootk'; +import { KeepTrackPlugin, clickDragOptions } from '../KeepTrackPlugin'; +import { SelectSatManager } from '../select-sat-manager/select-sat-manager'; + +interface PolarPlotData extends Array<[Degrees, Degrees]> { } + +export class PolarPlotPlugin extends KeepTrackPlugin { + static readonly PLUGIN_NAME = 'Polar Plot'; + dependencies = [SelectSatManager.PLUGIN_NAME]; + private selectSatManager_: SelectSatManager; + + constructor() { + super(PolarPlotPlugin.PLUGIN_NAME); + this.selectSatManager_ = keepTrackApi.getPlugin(SelectSatManager); + } + + private ctx_: CanvasRenderingContext2D; + private centerX_: number; + private centerY_: number; + private distanceUnit_: number; + private canvasSize_: number; + private fontRatio_ = 0.03; + private plotData_: PolarPlotData = []; + + isRequireSatelliteSelected = true; + isRequireSensorSelected = true; + + bottomIconElementName = 'menu-polar-plot'; + bottomIconLabel = 'Polar Plot'; + bottomIconImg = analysisPng; + bottomIconCallback: () => void = () => { + this.updatePlot_(); + }; + isIconDisabledOnLoad = true; + isIconDisabled = true; + sideMenuElementName: string = 'polar-plot-menu'; + sideMenuElementHtml: string = keepTrackApi.html` +
+
+ +
+
+ `; + + helpTitle = 'Polar Plot Menu'; + helpBody = keepTrackApi.html`The Polar Plot Menu is used to generate a 2D polar plot of the satellite's azimuth and elevation over time.`; + + dragOptions: clickDragOptions = { + isDraggable: true, + minWidth: 450, + maxWidth: 1000, + }; + + addJs(): void { + super.addJs(); + + keepTrackApi.register({ + event: KeepTrackApiEvents.staticOffsetChange, + cbName: this.PLUGIN_NAME, + cb: () => { + if (this.isMenuButtonActive) { + this.updatePlot_(); + } + }, + }); + + keepTrackApi.register({ + event: KeepTrackApiEvents.selectSatData, + cbName: this.PLUGIN_NAME, + cb: (obj: BaseObject) => { + if (obj?.isSatellite() && keepTrackApi.getSensorManager().isSensorSelected()) { + getEl(this.bottomIconElementName).classList.remove('bmenu-item-disabled'); + this.isIconDisabled = false; + // If it is open then refresh the plot + if (this.isMenuButtonActive) { + this.updatePlot_(); + } + } else { + getEl(this.bottomIconElementName).classList.add('bmenu-item-disabled'); + this.isIconDisabled = true; + } + }, + }); + } + + private updatePlot_(): void { + if (this.generatePlotData_()) { + // If there is data draw it + this.drawPlot_(); + } else { + getEl('polar-plot-content').innerHTML = 'Satellite is not in view for the next 48 hours'; + } + } + + private generatePlotData_(): boolean { + const sensor = keepTrackApi.getSensorManager().getSensor(); + const sat = this.selectSatManager_.getSelectedSat() as DetailedSatellite; + let isSomethingInView = false; + + this.plotData_ = []; + for (let i = 0; i < secondsPerDay * 3; i++) { + const now = keepTrackApi.getTimeManager().getOffsetTimeObj(i * MILLISECONDS_PER_SECOND); + const inView = sensor.isSatInFov(sat, now); + + if (inView) { + const rae = sensor.rae(sat, now); + + this.plotData_.push([rae.az, rae.el]); + isSomethingInView = true; + } else if (isSomethingInView) { + break; + } + } + + return isSomethingInView; + } + + private drawPlot_(): void { + this.setupCanvas_(); + this.drawPlotBackground_(); + this.drawOrbitLine_(); + this.drawStartAndEnd_(); + } + + private setupCanvas_() { + const canvas = document.getElementById('polar-plot') as HTMLCanvasElement; + + this.ctx_ = canvas.getContext('2d'); + this.canvasSize_ = Math.min(this.ctx_.canvas.width, this.ctx_.canvas.height); + + this.ctx_.imageSmoothingEnabled = true; + this.centerX_ = this.ctx_.canvas.width / 2; + this.centerY_ = this.ctx_.canvas.height / 2; + this.distanceUnit_ = this.canvasSize_ / (2.5 * 90); + + this.ctx_.clearRect(0, 0, this.ctx_.canvas.width, this.ctx_.canvas.height); + } + + private drawElevationLines_(): void { + let radius: number = 0; + let radians: number = 0; + + this.ctx_.beginPath(); + const altCircles = [15, 30, 45, 60, 75, 90]; + + for (const circleDistance of altCircles) { + radius = circleDistance * this.distanceUnit_; + this.ctx_.moveTo(this.centerX_ + radius, this.centerY_); + for (let th = 1; th <= 360; th++) { + radians = (Math.PI / 180) * th; + this.ctx_.lineTo(this.centerX_ + radius * Math.cos(radians), this.centerY_ + radius * Math.sin(radians)); + } + } + + this.ctx_.lineWidth = 1; + this.ctx_.stroke(); + } + + private drawStartAndEnd_(): void { + this.drawDot_(this.plotData_[0][1], this.plotData_[0][0], 'lightgreen'); + this.drawDot_(this.plotData_[this.plotData_.length - 1][1], this.plotData_[this.plotData_.length - 1][0], 'red'); + } + + private drawDot_(radius: number, radians: number, color: 'lightgreen' | 'red' = 'lightgreen') { + radians = (Math.PI / 180) * (radians - 90); + radius = (90 - radius) * this.distanceUnit_; + + this.ctx_.beginPath(); + this.ctx_.arc( + this.centerX_ + radius * Math.cos(radians), + this.centerY_ + radius * Math.sin(radians), + 15, + 0, + 2 * Math.PI, + false, + ); + this.ctx_.fillStyle = color; + this.ctx_.fill(); + } + + private drawOrbitLine_(): void { + this.ctx_.beginPath(); + this.ctx_.strokeStyle = 'rgb(255, 255, 255)'; + this.ctx_.lineWidth = 2; + + const dataLength = this.plotData_.length; + let radius = 0; + + for (let j = 0; j < dataLength; j++) { + const radians = (Math.PI / 180) * (this.plotData_[j][0] - 90); + + radius = (90 - this.plotData_[j][1]) * this.distanceUnit_; + if (j === 0) { + this.ctx_.beginPath(); + this.ctx_.moveTo(this.centerX_ + radius * Math.cos(radians), this.centerY_ + radius * Math.sin(radians)); + } + + this.ctx_.lineTo(this.centerX_ + radius * Math.cos(radians), this.centerY_ + radius * Math.sin(radians)); + } + this.ctx_.stroke(); + } + + private drawPlotBackground_(): void { + this.drawElevationLines_(); + this.drawPolarAxes_(); + + this.ctx_.font = `${this.canvasSize_ * this.fontRatio_}px serif`; + this.ctx_.strokeStyle = 'rgb(77, 172, 255)'; + this.ctx_.fillStyle = 'rgb(77, 172, 255)'; + this.ctx_.lineWidth = 1; + + this.labelAzimuthAxis_(); + this.labelElevationAxis_(); + } + + private drawPolarAxes_() { + const radius = 96 * this.distanceUnit_; + + this.ctx_.moveTo(this.centerX_, this.centerY_); + this.ctx_.lineTo(this.centerX_, this.centerY_ + radius); + this.ctx_.moveTo(this.centerX_, this.centerY_); + this.ctx_.lineTo(this.centerX_, this.centerY_ - radius); + this.ctx_.moveTo(this.centerX_, this.centerY_); + this.ctx_.lineTo(this.centerX_ + radius, this.centerY_); + this.ctx_.moveTo(this.centerX_, this.centerY_); + this.ctx_.lineTo(this.centerX_ - radius, this.centerY_); + } + + private labelElevationAxis_() { + this.ctx_.textAlign = 'center'; + this.ctx_.textBaseline = 'middle'; + const diagDist = this.canvasSize_ / 700; + + this.ctx_.fillText('90°', this.centerX_ + 18 * diagDist, this.centerY_ - 12 * diagDist); + this.ctx_.fillText('75°', this.centerX_ + 44 * diagDist, this.centerY_ - 44 * diagDist); + this.ctx_.fillText('60°', this.centerX_ + 76 * diagDist, this.centerY_ - 76 * diagDist); + this.ctx_.fillText('45°', this.centerX_ + 108 * diagDist, this.centerY_ - 108 * diagDist); + this.ctx_.fillText('30°', this.centerX_ + 143 * diagDist, this.centerY_ - 143 * diagDist); + this.ctx_.fillText('15°', this.centerX_ + 175 * diagDist, this.centerY_ - 175 * diagDist); + this.ctx_.fillText('0°', this.centerX_ + 206 * diagDist, this.centerY_ - 206 * diagDist); + this.ctx_.stroke(); + } + + private labelAzimuthAxis_() { + const radius = 98 * this.distanceUnit_; + + this.ctx_.font = `${this.canvasSize_ * this.fontRatio_}px serif`; + this.ctx_.textAlign = 'center'; + this.ctx_.textBaseline = 'bottom'; + this.ctx_.fillText(' 0°', this.centerX_, this.centerY_ - radius); + this.ctx_.textBaseline = 'top'; + this.ctx_.fillText('180°', this.centerX_, this.centerY_ + radius); + this.ctx_.textAlign = 'right'; + this.ctx_.textBaseline = 'middle'; + this.ctx_.fillText('270°', this.centerX_ - radius, this.centerY_); + this.ctx_.textAlign = 'left'; + this.ctx_.fillText('90°', this.centerX_ + radius, this.centerY_); + this.ctx_.stroke(); + } +} diff --git a/src/plugins/sensor/custom-sensor-plugin.ts b/src/plugins/sensor/custom-sensor-plugin.ts index db2ee9027..c4aec1bdc 100644 --- a/src/plugins/sensor/custom-sensor-plugin.ts +++ b/src/plugins/sensor/custom-sensor-plugin.ts @@ -189,6 +189,16 @@ export class CustomSensorPlugin extends KeepTrackPlugin { typ: CruncerMessageTypes.SUNLIGHT_VIEW, }); break; + case 'colors-confidence-rmb': + case 'colors-rcs-rmb': + case 'colors-density-rmb': + case 'colors-starlink-rmb': + case 'colors-sunlight-rmb': + case 'colors-country-rmb': + case 'colors-velocity-rmb': + case 'colors-ageOfElset-rmb': + case 'colors-default-rmb': + break; default: errorManagerInstance.info(`Unknown RMB target: ${targetId}`); break; diff --git a/src/plugins/sensor/sensorManager.ts b/src/plugins/sensor/sensorManager.ts index 22200283a..7abf54cce 100644 --- a/src/plugins/sensor/sensorManager.ts +++ b/src/plugins/sensor/sensorManager.ts @@ -47,6 +47,10 @@ import { SensorSurvFence } from '../sensor-surv/sensor-surv-fence'; export class SensorManager { lastMultiSiteArray: TearrData[]; + getSensor(): DetailedSensor | null { + return this.currentSensors[0] ?? null; + } + addSecondarySensor(sensor: DetailedSensor, isReplaceSensor = false): void { // If there is no primary sensor, make this the primary sensor const primarySensor = this.currentSensors[0]; diff --git a/src/settings/settings.ts b/src/settings/settings.ts index 471eb5931..e0ab96821 100644 --- a/src/settings/settings.ts +++ b/src/settings/settings.ts @@ -79,6 +79,8 @@ export class SettingsManager { scenarioCreator: false, debrisScreening: true, videoDirector: true, + reports: true, + polarPlot: true, }; colors: ColorSchemeColorMap; diff --git a/src/settings/versionDate.js b/src/settings/versionDate.js index 13b6a27f9..1399fbf5f 100644 --- a/src/settings/versionDate.js +++ b/src/settings/versionDate.js @@ -1,2 +1,2 @@ // THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -export const VERSION_DATE = 'May 8, 2024'; +export const VERSION_DATE = 'July 19, 2024'; diff --git a/src/singletons/color-scheme-manager.ts b/src/singletons/color-scheme-manager.ts index 560ec67d6..390d092b5 100644 --- a/src/singletons/color-scheme-manager.ts +++ b/src/singletons/color-scheme-manager.ts @@ -303,9 +303,9 @@ export class ColorSchemeManager { waitForCruncher({ cruncher: keepTrackApi.getCatalogManager().satCruncher, cb: () => { - keepTrackApi.getColorSchemeManager().calculateColorBuffers(true); + keepTrackApi.getColorSchemeManager().calculateColorBuffers(); }, - validationFunc: (m: PositionCruncherOutgoingMsg) => m.satPos?.length > 0, + validationFunc: (m: PositionCruncherOutgoingMsg) => m.satInView?.length > 0, isSkipFirst: true, isRunCbOnFailure: true, maxRetries: 5, @@ -840,6 +840,18 @@ export class ColorSchemeManager { this.calculateColorBuffers(true).then(() => { this.isReady = true; }); + + // This helps keep the inview colors up to date + keepTrackApi.register({ + event: KeepTrackApiEvents.staticOffsetChange, + cbName: 'colorSchemeManager', + cb: () => { + setTimeout(() => { + this.calcColorBufsNextCruncher(); + }, 1000); + }, + }); + }, }); }