mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-14 16:01:30 -06:00
367 lines
13 KiB
C++
367 lines
13 KiB
C++
/*****************************************************************************************
|
|
* *
|
|
* OpenSpace *
|
|
* *
|
|
* Copyright (c) 2014-2023 *
|
|
* *
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
|
* software and associated documentation files (the "Software"), to deal in the Software *
|
|
* without restriction, including without limitation the rights to use, copy, modify, *
|
|
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
|
* permit persons to whom the Software is furnished to do so, subject to the following *
|
|
* conditions: *
|
|
* *
|
|
* The above copyright notice and this permission notice shall be included in all copies *
|
|
* or substantial portions of the Software. *
|
|
* *
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
|
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
|
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
|
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
|
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
|
****************************************************************************************/
|
|
|
|
#ifndef __OPENSPACE_MODULE_GLOBEBROWSING___TIMEQUANTIZER___H__
|
|
#define __OPENSPACE_MODULE_GLOBEBROWSING___TIMEQUANTIZER___H__
|
|
|
|
#include <openspace/util/timerange.h>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
namespace openspace { class Time; }
|
|
|
|
namespace openspace::globebrowsing {
|
|
|
|
/* RangedTime class is used to define an acceptable time range. Functionality includes
|
|
* checking if a given date/time is within that range, or clamping a date to enforce
|
|
* this range.
|
|
*/
|
|
class RangedTime {
|
|
public:
|
|
RangedTime() {}
|
|
|
|
/*
|
|
* Constructor that accepts an ISO8601 date/time string (YYYY-MM-DDTHH:mm:ss) for an
|
|
* allowable time range defined by start and end values.
|
|
*
|
|
* \param start The date/time start of the time range.
|
|
* \param end The date/time ending of the time range.
|
|
*/
|
|
RangedTime(std::string start, std::string end);
|
|
|
|
/*
|
|
* Checks if a date/time value falls within the start/end range defined in this
|
|
* instance of the class.
|
|
*
|
|
* \param checkTime The time to test if it falls within the range
|
|
*
|
|
* \returns true if the input date/time falls between the start and end date/times
|
|
*/
|
|
bool includes(const Time& checkTime) const;
|
|
|
|
/*
|
|
* Enforces the start/end range on a given date/time string by clamping the value
|
|
*
|
|
* \param checkTime An ISO8601 date/time string to clamp if falls outside of range
|
|
*
|
|
* \returns clamped value of input parameter, will be equal to the start value if
|
|
* less than start, equal to end if greater than end, or equal to input
|
|
* parameter if falls in-between
|
|
*/
|
|
const char* clamp(const char* checkTime);
|
|
|
|
/*
|
|
* Get the start date/time of the time range
|
|
*
|
|
* \returns The ISO8601 date/time string that defines the start of the range
|
|
*/
|
|
std::string_view start() const;
|
|
|
|
/*
|
|
* Get the end date/time of the time range
|
|
*
|
|
* \returns The ISO8601 date/time string that defines the end of the range
|
|
*/
|
|
std::string_view end() const;
|
|
|
|
/*
|
|
* Set the start date/time of the time range
|
|
*
|
|
* \param The ISO8601 date/time string that defines the start of the range
|
|
*/
|
|
void setStart(const std::string start);
|
|
|
|
/*
|
|
* Set the end date/time of the time range
|
|
*
|
|
* \param The ISO8601 date/time string that defines the end of the range
|
|
*/
|
|
void setEnd(const std::string start);
|
|
|
|
private:
|
|
std::string _start;
|
|
std::string _end;
|
|
double _startJ2000;
|
|
double _endJ2000;
|
|
};
|
|
|
|
/* DateTime class is used to manage a date/time value and provide methods for increment/
|
|
* decrementing the value, which gets complicated because of the varying days of the
|
|
* different months, leap years, etc.
|
|
* This class exists to handle date/time values within a "people-friendly" calendar
|
|
* schedule. For example, a temporal data set that's updated on the 10th of every month
|
|
* will sometimes be updated in 28 days, other times in 31 days. The intent of the class
|
|
* is to handle all of the "special cases" where simply using J2000 seconds won't work.
|
|
*/
|
|
class DateTime {
|
|
public:
|
|
DateTime() = default;
|
|
/*
|
|
* Constructor that initializes with date/time string
|
|
*
|
|
* \params initDateTime the ISO8601 date/time string (YYYY-MM-DDTHH:mm:ss)
|
|
*/
|
|
DateTime(std::string_view initDateTime);
|
|
|
|
/*
|
|
* Set the date/time value
|
|
*
|
|
* \params input the ISO8601 date/time string (YYYY-MM-DDTHH:mm:ss) to set
|
|
*/
|
|
void setTime(std::string_view input);
|
|
|
|
/*
|
|
* Get the date/time value in ISO8601 format
|
|
*
|
|
* \returns the date/time value string
|
|
*/
|
|
std::string ISO8601() const;
|
|
|
|
/*
|
|
* Get the J2000 seconds equivalent of the object's date/time, using
|
|
* the loaded SPICE kernel
|
|
*
|
|
* \returns J2000 seconds of date/time
|
|
*/
|
|
double J2000() const;
|
|
|
|
/*
|
|
* Get the year of the object's date/time (YYYY format)
|
|
* \returns integer value of the year
|
|
*/
|
|
int year() const;
|
|
|
|
/*
|
|
* Get the month of the object's date/time (1 - 12)
|
|
* \returns integer value of the month
|
|
*/
|
|
int month() const;
|
|
|
|
/*
|
|
* Get the day-of-month of the object's date/time (1 - 31)
|
|
* \returns integer value of the day
|
|
*/
|
|
int day() const;
|
|
|
|
/*
|
|
* Get the hour of the object's date/time
|
|
* \returns integer value of the hour (0 - 23)
|
|
*/
|
|
int hour() const;
|
|
|
|
/*
|
|
* Get the minute of the object's date/time
|
|
* \returns integer value of the minutes
|
|
*/
|
|
int minute() const;
|
|
|
|
/*
|
|
* Get the seconds of the object's date/time
|
|
* \returns integer value of the seconds
|
|
*/
|
|
int second() const;
|
|
|
|
/*
|
|
* Set the year of the object's date/time
|
|
* \param y integer value of the year
|
|
*/
|
|
void setYear(int y);
|
|
|
|
/*
|
|
* Set the month of the object's date/time (1 - 12)
|
|
* \param m integer value of the year
|
|
*/
|
|
void setMonth(int m);
|
|
|
|
/*
|
|
* Set the day-of-month of the object's date/time (1 - 31)
|
|
* \param d integer value of the day
|
|
*/
|
|
void setDay(int d);
|
|
|
|
/*
|
|
* Set the hour of the object's date/time (0 - 23)
|
|
* \param h integer value of the hour
|
|
*/
|
|
void setHour(int h);
|
|
|
|
/*
|
|
* Set the minute of the object's date/time
|
|
* \param m integer value of the minute
|
|
*/
|
|
void setMinute(int m);
|
|
|
|
/*
|
|
* Set the seconds of the object's date/time
|
|
* \param s integer value of the seconds
|
|
*/
|
|
void setSecond(int s);
|
|
|
|
/*
|
|
* Increment operation for the date/time
|
|
*
|
|
* \param value integer value for number of units in an operation
|
|
* \param unit single char that specifies the unit of increment. Allowable units are:
|
|
* (y)ear, (M)onth, (d)ay, (h)our, (m)inute, (s)econd
|
|
* \param error The difference in J2000 seconds from current date/time to target
|
|
* (a positive value means target is in the future)
|
|
* \param resolution The J2000 seconds of the interval defined by the value & unit
|
|
*
|
|
* \returns The number of increments that were performed in order to get as close as
|
|
* possible to the target, where each increment is defined by the value &
|
|
* unit (and approximated but not fixed by the resolution param)
|
|
*/
|
|
int increment(int value, char unit, double error, double resolution);
|
|
|
|
/*
|
|
* Decrement operation for the date/time
|
|
*
|
|
* \param value integer value for number of units in an operation
|
|
* \param unit single char that specifies the unit of decrement. Allowable units are:
|
|
* (y)ear, (M)onth, (d)ay, (h)our, (m)inute, (s)econd
|
|
* \param error The difference in J2000 seconds from current date/time to target
|
|
* (a positive value means target is in the future)
|
|
* \param resolution The J2000 seconds of the interval defined by the value & unit
|
|
*
|
|
* \returns The number of decrements that were performed in order to get as close as
|
|
* possible to the target, where each decrement is defined by the value &
|
|
* unit (and approximated but not fixed by the resolution param)
|
|
*/
|
|
int decrement(int value, char unit, double error, double resolution);
|
|
|
|
/*
|
|
* Single increment operation for the date/time
|
|
*
|
|
* \param value integer value for number of units in an operation
|
|
* \param unit single char that specifies the unit of increment. Allowable units are:
|
|
* (y)ear, (M)onth, (d)ay, (h)our, (m)inute, (s)econd
|
|
*/
|
|
void incrementOnce(int value, char unit);
|
|
|
|
/*
|
|
* Single decrement operation for the date/time
|
|
*
|
|
* \param value integer value for number of units in an operation
|
|
* \param unit single char that specifies the unit of decrement. Allowable units are:
|
|
* (y)ear, (M)onth, (d)ay, (h)our, (m)inute, (s)econd
|
|
*/
|
|
void decrementOnce(int value, char unit);
|
|
|
|
private:
|
|
int _year = 2000;
|
|
int _month = 1;
|
|
int _day = 1;
|
|
int _hour = 0;
|
|
int _minute = 0;
|
|
int _second = 0;
|
|
};
|
|
|
|
/**
|
|
* Used to quantize time to discrete values.
|
|
*/
|
|
class TimeQuantizer {
|
|
public:
|
|
TimeQuantizer() = default;
|
|
/*
|
|
* Constructor that initializes with formatted strings for start & ends date/times,
|
|
* and a time resolution within that range
|
|
*
|
|
* \params start the ISO8601 date/time string (YYYY-MM-DDTHH:mm:ss) for start
|
|
* \params end the ISO8601 date/time string (YYYY-MM-DDTHH:mm:ss) for end
|
|
* \params resolution the formatted resolution, which consists of an integer & unit
|
|
* character. The acceptable unit characters are:
|
|
* (y)ear Example: '1y' = 1 year. No range limitations
|
|
* (M)onth Example: '4M' = 4 months. Allowable values: 1, 2, 3, 4, 6
|
|
* (d)ay Example: '10d' = 10 days. Allowable values: 1 - 28
|
|
* (h)our Example: '12h' = 12 hours. Allowable values: 1, 2, 3, 4, 6, 12
|
|
* (m)inute Example: '15m' = 15 minutes. Allowable values: 0, 15, 30
|
|
*/
|
|
TimeQuantizer(std::string start, std::string end, const std::string& resolution);
|
|
|
|
/*
|
|
* Set the time range start & end date/time range.
|
|
*
|
|
* \param start The ISO8601 date/time string for start of the time range
|
|
* \param end The ISO8601 date/time string for end of the time range.
|
|
*/
|
|
void setStartEndRange(const std::string& start, const std::string& end);
|
|
|
|
/*
|
|
* Set the time resolution
|
|
*
|
|
* \param resolutionString String that defines the resolution within the time range.
|
|
* see comment header for constructor for the allowable
|
|
* values and ranges.
|
|
*/
|
|
void setResolution(const std::string& resolutionString);
|
|
|
|
/**
|
|
* Takes a time resulition string and parses it into a double
|
|
* value representing the time resolution as seconds.
|
|
*
|
|
* Example: parseTimeResolutionStr("1d");
|
|
*
|
|
* \param resolutionStr with the format {number}{unit} where supported units are:
|
|
* (s)econds, (m)inutes, (h)ours, (d)ays, (y)ears
|
|
* \return the time resolution in seconds
|
|
*/
|
|
double parseTimeResolutionStr(const std::string& resolutionStr);
|
|
|
|
/**
|
|
* Quantizes a OpenSpace Time into descrete values. If the provided Time \p t is
|
|
* outside the time range, it will be clamped to the the time range.
|
|
*
|
|
* \param t Time instance, which will be quantized
|
|
* \param clamp Whether or not time should be clamped if not t is in the time range
|
|
* \return wether or not time was quantized
|
|
*/
|
|
bool quantize(Time& t, bool clamp);
|
|
|
|
/**
|
|
* Returns a list of quantized Time strings that represent all the valid quantized
|
|
* time%s between \p start and \p end.
|
|
*
|
|
* \param start The start time for the time range quantization
|
|
* \param end The end time for the time range quantization
|
|
* \return A list of quantized times between \p start and \end
|
|
*/
|
|
std::vector<std::string> quantized(Time& start, Time& end);
|
|
|
|
private:
|
|
void verifyStartTimeRestrictions();
|
|
void verifyResolutionRestrictions(const int value, const char unit);
|
|
void doFirstApproximation(DateTime& q, DateTime& unQ, double value, char unit);
|
|
double computeSecondsFromResolution(const int valueIn, const char unit);
|
|
double _resolution = 0.0;
|
|
double _resolutionValue = 0.0;
|
|
char _resolutionUnit = 'd';
|
|
DateTime _dt;
|
|
DateTime _start;
|
|
RangedTime _timerange;
|
|
};
|
|
|
|
} // namespace openspace::globebrowsing
|
|
|
|
#endif // __OPENSPACE_MODULE_GLOBEBROWSING___TIMEQUANTIZER___H__
|