Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add decimals keyword to gps text + move RAW keyword check #1039

Merged
merged 3 commits into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
170 changes: 72 additions & 98 deletions src/modules/qt/filter_gpstext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,168 +191,142 @@ static void gps_point_to_output(mlt_filter filter,
crt_point = pdata->gps_points_p[i_now];
}

//check for the generic "decimals" extra-keyword and if present read a single digit after it (+whitespace)
char *ptr = NULL;
int use_decimals = -1;
if ((ptr = strstr(keyword, "decimals"))) {
ptr += strlen("decimals");
while (ptr && isspace(*ptr))
ptr++;
if (ptr && isdigit(*ptr))
use_decimals = *ptr - '0';
}
//check for generic "RAW" extra keyword
bool use_raw = 0;
if (strstr(keyword, "RAW"))
use_raw = 1;

/* for every keyword: we first check if the "RAW" keyword is used and if so, we print the value read from file (or --)
then we check if there's a format keyword and apply the necessary conversion/format.
The format must appear after the main keyword, RAW and format order is not important (strstr is used)
*/
if (!strncmp(keyword, "gps_lat", strlen("gps_lat")) && crt_point.lat != GPS_UNINIT) {
if (strstr(keyword, "RAW")) {
if (raw.lat == GPS_UNINIT)
return;
snprintf(gps_text, 10, "%3.6f", raw.lat);
} else {
snprintf(gps_text, 10, "%3.6f", crt_point.lat);
}
double val = use_raw ? raw.lat : crt_point.lat;
if (val == GPS_UNINIT)
return;
snprintf(gps_text, 15, "%3.*f", (use_decimals == -1 ? 6 : use_decimals), val);
} else if (!strncmp(keyword, "gps_lon", strlen("gps_lon")) && crt_point.lon != GPS_UNINIT) {
if (strstr(keyword, "RAW")) {
if (raw.lon == GPS_UNINIT)
return;
snprintf(gps_text, 10, "%3.6f", swap_180_if_needed(raw.lon));
} else {
snprintf(gps_text, 10, "%3.6f", swap_180_if_needed(crt_point.lon));
}
double val = swap_180_if_needed(use_raw ? raw.lon : crt_point.lon);
if (val == GPS_UNINIT)
return;
snprintf(gps_text, 15, "%3.*f", (use_decimals == -1 ? 6 : use_decimals), val);
} else if (!strncmp(keyword, "gps_elev", strlen("gps_elev")) && crt_point.ele != GPS_UNINIT) {
if (strlen(keyword) > strlen("gps_elev"))
format = keyword + strlen("gps_elev");
double val;
if (strstr(keyword, "RAW")) {
if (raw.ele == GPS_UNINIT)
return;
val = convert_distance_to_format(raw.ele, format);
} else {
val = convert_distance_to_format(crt_point.ele, format);
}
snprintf(gps_text, 10, "%.*f", decimals_needed(val), val);
double val = convert_distance_to_format((use_raw ? raw.ele : crt_point.ele), format);
if (val == GPS_UNINIT)
return;
snprintf(gps_text, 15, "%.*f", decimals_needed(val, use_decimals), val);
} else if (!strncmp(keyword, "gps_speed", strlen("gps_speed"))
&& crt_point.speed != GPS_UNINIT) {
if (strlen(keyword) > strlen("gps_speed"))
format = keyword + strlen("gps_speed");
double val = 0;
if (strstr(keyword, "RAW")) {
if (raw.speed == GPS_UNINIT)
return;
val = raw.speed;
} else {
val = crt_point.speed;
if (strstr(keyword, "vertical"))
val = crt_point.speed_vertical;
else if (strstr(keyword, "3d"))
val = crt_point.speed_3d;
}
double val = use_raw ? raw.speed : crt_point.speed;
if (!use_raw && strstr(keyword, "vertical"))
val = crt_point.speed_vertical;
else if (!use_raw && strstr(keyword, "3d"))
val = crt_point.speed_3d;
if (val == GPS_UNINIT)
return;
val = convert_speed_to_format(val, format);
snprintf(gps_text, 10, "%.*f", decimals_needed(val), val);
snprintf(gps_text, 15, "%.*f", decimals_needed(val, use_decimals), val);
} else if (!strncmp(keyword, "gps_hr", strlen("gps_hr")) && crt_point.hr != GPS_UNINIT) {
if (strstr(keyword, "RAW")) {
if (raw.hr == GPS_UNINIT)
return;
snprintf(gps_text, 10, "%.0f", raw.hr);
} else {
snprintf(gps_text, 10, "%.0f", crt_point.hr);
}
double val = use_raw ? raw.hr : crt_point.hr;
if (val == GPS_UNINIT)
return;
snprintf(gps_text, 15, "%.*f", (use_decimals == -1 ? 0 : use_decimals), val);
} else if (!strncmp(keyword, "gps_bearing", strlen("gps_bearing"))
&& crt_point.bearing != GPS_UNINIT) {
if (strstr(keyword, "RAW")) {
if (raw.bearing == GPS_UNINIT)
return;
snprintf(gps_text, 10, "%.0f", raw.bearing);
} else {
snprintf(gps_text, 10, "%.0f", crt_point.bearing);
}
double val = use_raw ? raw.bearing : crt_point.bearing;
if (val == GPS_UNINIT)
return;
snprintf(gps_text, 15, "%.*f", (use_decimals == -1 ? 0 : use_decimals), val);
} else if (!strncmp(keyword, "gps_compass", strlen("gps_compass"))
&& crt_point.bearing != GPS_UNINIT) {
if (strstr(keyword, "RAW")) {
if (raw.bearing == GPS_UNINIT)
return;
snprintf(gps_text, 4, "%s", bearing_to_compass(raw.bearing));
} else {
snprintf(gps_text, 4, "%s", bearing_to_compass(crt_point.bearing));
}
const char *val = (const char *) (bearing_to_compass(use_raw ? raw.bearing
: crt_point.bearing));
snprintf(gps_text, 4, "%s", val);
} else if (!strncmp(keyword, "gps_cadence", strlen("gps_cadence"))
&& crt_point.cad != GPS_UNINIT) {
if (strstr(keyword, "RAW")) {
if (raw.cad == GPS_UNINIT)
return;
snprintf(gps_text, 10, "%.0f", raw.cad);
} else {
snprintf(gps_text, 10, "%.0f", crt_point.cad);
}
double val = use_raw ? raw.cad : crt_point.cad;
if (val == GPS_UNINIT)
return;
snprintf(gps_text, 15, "%.*f", (use_decimals == -1 ? 0 : use_decimals), crt_point.cad);
} else if (!strncmp(keyword, "gps_temperature", strlen("gps_temperature"))
&& crt_point.atemp != GPS_UNINIT) {
double atemp;
if (strstr(keyword, "RAW")) {
if (raw.atemp == GPS_UNINIT)
return;
atemp = raw.atemp;
} else {
atemp = crt_point.atemp;
}
double val = use_raw ? raw.atemp : crt_point.atemp;
if (val == GPS_UNINIT)
return;
if (strstr(keyword, "F"))
atemp = atemp * 1.8 + 32;
val = val * 1.8 + 32;
else if (strstr(keyword, "K"))
atemp = atemp + 273.15;
snprintf(gps_text, 10, "%.*f", decimals_needed_maxone(atemp), atemp);
val = val + 273.15;
snprintf(gps_text, 15, "%.*f", (use_decimals == -1 ? 0 : use_decimals), val);
} else if (!strncmp(keyword, "gps_power", strlen("gps_power"))
&& crt_point.power != GPS_UNINIT) {
if (strstr(keyword, "RAW")) {
if (raw.power == GPS_UNINIT)
return;
snprintf(gps_text, 10, "%.0f", raw.power);
} else {
snprintf(gps_text, 10, "%.0f", crt_point.power);
}
double val = use_raw ? raw.power : crt_point.power;
if (val == GPS_UNINIT)
return;
snprintf(gps_text, 15, "%.*f", (use_decimals == -1 ? 0 : use_decimals), val);
} else if (!strncmp(keyword, "gps_vdist_up", strlen("gps_vdist_up"))
&& crt_point.elev_up != GPS_UNINIT) {
if (strlen(keyword) > strlen("gps_vdist_up"))
format = keyword + strlen("gps_vdist_up");
double val = convert_distance_to_format(fabs(crt_point.elev_up), format);
snprintf(gps_text, 10, "%.*f", decimals_needed(val), val);
snprintf(gps_text, 15, "%.*f", decimals_needed(val, use_decimals), val);
} else if (!strncmp(keyword, "gps_vdist_down", strlen("gps_vdist_down"))
&& crt_point.elev_down != GPS_UNINIT) {
if (strlen(keyword) > strlen("gps_vdist_down"))
format = keyword + strlen("gps_vdist_down");
double val = convert_distance_to_format(fabs(crt_point.elev_down), format);
snprintf(gps_text, 10, "%.*f", decimals_needed(val), val);
snprintf(gps_text, 15, "%.*f", decimals_needed(val, use_decimals), val);
} else if (!strncmp(keyword, "gps_dist_uphill", strlen("gps_dist_uphill"))
&& crt_point.dist_up != GPS_UNINIT) {
if (strlen(keyword) > strlen("gps_dist_uphill"))
format = keyword + strlen("gps_dist_uphill");
double val = convert_distance_to_format(crt_point.dist_up, format);
snprintf(gps_text, 10, "%.*f", decimals_needed(val), val);
snprintf(gps_text, 15, "%.*f", decimals_needed(val, use_decimals), val);
} else if (!strncmp(keyword, "gps_dist_downhill", strlen("gps_dist_downhill"))
&& crt_point.dist_down != GPS_UNINIT) {
if (strlen(keyword) > strlen("gps_dist_downhill"))
format = keyword + strlen("gps_dist_downhill");
double val = convert_distance_to_format(crt_point.dist_down, format);
snprintf(gps_text, 10, "%.*f", decimals_needed(val), val);
snprintf(gps_text, 15, "%.*f", decimals_needed(val, use_decimals), val);
} else if (!strncmp(keyword, "gps_dist_flat", strlen("gps_dist_flat"))
&& crt_point.dist_flat != GPS_UNINIT) {
if (strlen(keyword) > strlen("gps_dist_flat"))
format = keyword + strlen("gps_dist_flat");
double val = convert_distance_to_format(crt_point.dist_flat, format);
snprintf(gps_text, 10, "%.*f", decimals_needed(val), val);
snprintf(gps_text, 15, "%.*f", decimals_needed(val, use_decimals), val);
}
//NOTE: gps_dist must be below gps_dist_up/down/flat or it'll match them
else if (!strncmp(keyword, "gps_dist", strlen("gps_dist"))
&& crt_point.total_dist != GPS_UNINIT) {
if (strlen(keyword) > strlen("gps_dist"))
format = keyword + strlen("gps_dist");
double val;
if (strstr(keyword, "RAW")) {
if (raw.total_dist == GPS_UNINIT)
return;
val = convert_distance_to_format(raw.total_dist, format);
} else {
val = convert_distance_to_format(crt_point.total_dist, format);
}
snprintf(gps_text, 10, "%.*f", decimals_needed(val), val);
double val = convert_distance_to_format((use_raw ? raw.total_dist : crt_point.total_dist),
format);
if (val == GPS_UNINIT)
return;
snprintf(gps_text, 15, "%.*f", decimals_needed(val, use_decimals), val);
} else if (!strncmp(keyword, "gps_grade_percentage", strlen("gps_grade_percentage"))
&& crt_point.grade_p != GPS_UNINIT) {
double val = crt_point.grade_p;
snprintf(gps_text, 10, "%+.*f", decimals_needed_maxone(val), val);
snprintf(gps_text, 15, "%+.*f", (use_decimals == -1 ? 0 : use_decimals), val);
} else if (!strncmp(keyword, "gps_grade_degrees", strlen("gps_grade_degrees"))
&& crt_point.grade_p != GPS_UNINIT) {
double val = to_deg(atan(crt_point.grade_p / 100.0));
snprintf(gps_text, 10, "%+.*f", decimals_needed_maxone(val), val);
snprintf(gps_text, 15, "%+.*f", (use_decimals == -1 ? 0 : use_decimals), val);
} else if (!strncmp(keyword, "gps_datetime_now", strlen("gps_datetime_now"))
&& raw.time != GPS_UNINIT) {
int64_t val = 0;
Expand Down
2 changes: 2 additions & 0 deletions src/modules/qt/filter_gpstext.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ parameters:
An extra word "RAW" (uppercase!) can be added to the keyword to display the
unchanged value from the file. If a keyword can't produce valid data it will
print "--".
Keywords returning numeric values can use the extra word "decimals" to forcefully
set a specific number of decimals (0-9). Example: #gps_speed decimals 3#.
Time-based keywords can include a strftime format string to customize the
output and a number (representing seconds) preceeded by '+' or '-' which will
offset the actual time. For example, "#gps_datetime_now %I:%M:%S %p +3600#" shows
Expand Down
28 changes: 14 additions & 14 deletions src/modules/qt/gps_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@
//shifts all (longitude) values from near 180 to 0
double get_180_swapped(double lon)
{
// mlt_log_info(NULL, "get_180_swapped(%f) -> %f\n", lon, lon + ( lon>0 ? -180 : 180));
if (lon == GPS_UNINIT)
return lon;
return lon + (lon > 0 ? -180 : 180);
}

Expand Down Expand Up @@ -332,31 +333,25 @@ int binary_search_gps(gps_private_data gdata, int64_t video_time, bool force_res

/** Returns a nicer number of decimal values for floats
* [ 1.23m | 12.3m | 123m ]
* - argument use_decimals defaults to -1 (in .h)
*/
int decimals_needed(double x)
int decimals_needed(double x, int use_decimals)
{
if (use_decimals != -1)
return use_decimals;

if (fabs(x) < 10)
return 2;
if (fabs(x) < 100)
return 1;
return 0;
}

/** Returns a nicer number of decimal values for floats, max 1 digit after .
* [ 1.2% | 12% ]
*/
int decimals_needed_maxone(double x)
{
if (fabs(x) < 10)
return 1;
return 0;
}

/** Converts the distance (stored in meters) to the unit requested in extended keyword
*/
double convert_distance_to_format(double x, const char *format)
{
if (format == NULL)
if (format == NULL || x == GPS_UNINIT)
return x;

if (strstr(format, "km") || strstr(format, "kilometer"))
Expand All @@ -374,7 +369,9 @@ double convert_distance_to_format(double x, const char *format)
*/
double convert_speed_to_format(double x, const char *format)
{
//order is important as short keywords will match anywhere (ms in kms and mi in min[utes])
if (x == GPS_UNINIT)
return x;
//order is important as short keywords will match anywhere (ms in kms and mi in mi[nutes])
if (format == NULL || strstr(format, "kms") || strstr(format, "km/s")
|| strstr(format, "kilometer"))
return x * 3.6; //default km/h
Expand All @@ -399,6 +396,9 @@ double convert_speed_to_format(double x, const char *format)
*/
const char *bearing_to_compass(double x)
{
if (x == GPS_UNINIT)
return "--";

if (x <= 22.5 || x >= 360 - 22.5)
return "N";
else if (x < 45 + 22.5)
Expand Down
3 changes: 1 addition & 2 deletions src/modules/qt/gps_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,7 @@ void get_last_gps_time(gps_private_data gdata);
double get_avg_gps_time_ms(gps_private_data gdata);
int get_max_gps_diff_ms(gps_private_data gdata);
int binary_search_gps(gps_private_data gdata, int64_t video_time, bool force_result = false);
int decimals_needed(double x);
int decimals_needed_maxone(double x);
int decimals_needed(double x, int use_decimals = -1);
double convert_distance_to_format(double x, const char *format);
double convert_speed_to_format(double x, const char *format);
const char *bearing_to_compass(double x);
Expand Down