Skip to content

Commit e2eb9a2

Browse files
authored
Fix #1178 background image scaling in gpsgraphic filter (#1179)
* Fix for #1178 tranform latitude for gpsgraphic, as the tile server usually use a different coordinate represenation EPSG 3857, which leads to misscaling without transformation, especially on large areas. Transformation is done during loading of the file and interpolation, so hopefully not affecting speed of filter * Fix for #1178 - Fixed now dot text - Fixed grid text - Removed unused var - method to calculate back to gps coordinates from projected coordinate
1 parent 94f78e3 commit e2eb9a2

File tree

6 files changed

+55
-31
lines changed

6 files changed

+55
-31
lines changed

src/modules/qt/filter_gpsgraphic.cpp

Lines changed: 13 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -130,20 +130,20 @@ double get_by_src(mlt_filter filter,
130130
if (pdata->graph_data_source == gspg_location_src) {
131131
if (get_type == -1) {
132132
if (subtype == gpsg_latitude_id)
133-
return pdata->minmax.min_lat;
133+
return pdata->minmax.min_lat_projected;
134134
else if (subtype == gpsg_longitude_id)
135135
return pdata->minmax.min_lon;
136136
} else if (get_type == 1) {
137137
if (subtype == gpsg_latitude_id)
138-
return pdata->minmax.max_lat;
138+
return pdata->minmax.max_lat_projected;
139139
else if (subtype == gpsg_longitude_id)
140140
return pdata->minmax.max_lon;
141141
} else if (get_type == 0) {
142142
if (subtype == gpsg_latitude_id) {
143143
if (gps_p == NULL)
144-
return pdata->gps_points_p[i_gps].lat;
144+
return pdata->gps_points_p[i_gps].lat_projected;
145145
else if (gps_p != NULL)
146-
return gps_p->lat;
146+
return gps_p->lat_projected;
147147
} else if (subtype == gpsg_longitude_id) {
148148
if (gps_p == NULL)
149149
return pdata->gps_points_p[i_gps].lon;
@@ -485,33 +485,20 @@ static void find_minmax_of_data(mlt_filter filter)
485485
assign_if_smaller(crt->grade_p, pdata->minmax.min_grade_p);
486486
assign_if_bigger(crt->grade_p, pdata->minmax.max_grade_p);
487487
}
488+
pdata->minmax.min_lat_projected = project_latitude(pdata->minmax.min_lat);
489+
pdata->minmax.max_lat_projected = project_latitude(pdata->minmax.max_lat);
488490
#undef assign_if_smaller
489491
#undef assign_if_bigger
490492

491-
//compute the map aspect ratio using real distances (used to correctly overlay background image over gps track)
493+
//compute the gps track aspect ratio (from coords)
492494
double map_aspect_ratio = 1;
493-
double map_width = distance_haversine_2p(pdata->minmax.min_lat,
494-
pdata->minmax.min_lon,
495-
pdata->minmax.min_lat,
496-
pdata->minmax.max_lon);
497-
double map_height = distance_haversine_2p(pdata->minmax.min_lat,
498-
pdata->minmax.min_lon,
499-
pdata->minmax.max_lat,
500-
pdata->minmax.min_lon);
501-
if (map_width && map_height)
495+
double map_width = pdata->minmax.max_lon - pdata->minmax.min_lon;
496+
double map_height = pdata->minmax.max_lat_projected - pdata->minmax.min_lat_projected;
497+
if (map_width && map_height) {
502498
map_aspect_ratio = map_width / map_height;
503-
pdata->map_aspect_ratio_from_distance = map_aspect_ratio;
504-
mlt_properties_set_double(MLT_FILTER_PROPERTIES(filter),
505-
"map_original_aspect_ratio",
506-
map_aspect_ratio);
507-
508-
// //compute the gps track aspect ratio (from coords) // the other one seems better almost every time
509-
// map_aspect_ratio = 1;
510-
// map_width = pdata->minmax.max_lon - pdata->minmax.min_lon;
511-
// map_height = pdata->minmax.max_lat - pdata->minmax.min_lat;
512-
// if (map_width && map_height)
513-
// map_aspect_ratio = map_width / map_height;
514-
// mlt_properties_set_double(MLT_FILTER_PROPERTIES( filter ), "map_original_aspect_ratio", map_aspect_ratio);
499+
pdata->map_aspect_ratio_from_distance = map_aspect_ratio;
500+
}
501+
mlt_properties_set_double(MLT_FILTER_PROPERTIES( filter ), "map_original_aspect_ratio", map_aspect_ratio);
515502

516503
char middle_point[255];
517504
double middle_lat = (pdata->minmax.min_lat + pdata->minmax.max_lat) / 2;

src/modules/qt/filter_gpsgraphic.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,14 @@ struct s_crops
1717

1818
struct s_gps_data_bounds
1919
{
20-
double min_lat, max_lat, min_lon, max_lon;
20+
double min_lat, min_lat_projected, max_lat, max_lat_projected, min_lon, max_lon;
2121
double min_ele, max_ele, min_speed, max_speed;
2222
double min_hr, max_hr, min_grade_p, max_grade_p;
2323

2424
void set_defaults()
2525
{
26-
min_lat = 90, min_lon = 180, max_lat = -90, max_lon = -180;
26+
min_lat = 90, min_lat_projected = project_latitude(90), min_lon = 180,
27+
max_lat = -90, max_lat_projected = project_latitude(-90), max_lon = -180;
2728
min_ele = 99999, max_ele = -99999, min_speed = 99999, max_speed = -99999;
2829
min_hr = 99999, max_hr = 0, min_grade_p = 99999, max_grade_p = -99999;
2930
}

src/modules/qt/filter_gpstext.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ static void gps_point_to_output(mlt_filter filter,
172172
gps_point_raw raw = pdata->gps_points_r[i_now];
173173
if (pdata->last_smooth_lvl == 0) {
174174
crt_point.lat = raw.lat;
175+
crt_point.lat_projected = raw.lat_projected;
175176
crt_point.lon = raw.lon;
176177
crt_point.speed = raw.speed;
177178
crt_point.total_dist = raw.total_dist;

src/modules/qt/gps_drawing.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,10 @@ void draw_legend_grid(mlt_filter filter, mlt_frame frame, QPainter &p, s_base_cr
145145
get_max_bysrc(filter),
146146
used_crops.bot,
147147
used_crops.top);
148+
if (pdata->graph_data_source == gspg_location_src)
149+
{
150+
crt_val = unproject_latitude(crt_val);
151+
}
148152
crt_val = convert_bysrc_to_format(filter, crt_val);
149153
p.drawText(path_grid_lines.currentPosition().x() + 3,
150154
path_grid_lines.currentPosition().y() - 3,
@@ -456,6 +460,10 @@ void draw_main_line_graph(mlt_filter filter, mlt_frame frame, QPainter &p, s_bas
456460
p.setFont(font);
457461
p.setPen(Qt::white);
458462

463+
if (pdata->graph_data_source == gspg_location_src)
464+
{
465+
now_val = unproject_latitude(now_val);
466+
}
459467
now_val = convert_bysrc_to_format(filter, now_val);
460468
QString now_text = QString::number(now_val, 'f', decimals_needed_bysrc(filter, now_val));
461469
if (pdata->graph_data_source == gspg_location_src) {

src/modules/qt/gps_parser.cpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,18 @@
2727
#define _s (const char *)
2828
#define _qxml_getthestring(s) qUtf8Printable((s).toString())
2929

30+
// Maps are usually in ESPG3857 format, not in GPS format EPSG4326 / WG84. We have to project
31+
// the latitude, otherwise big maps have wrong aspect ratio
32+
double project_latitude(double lat)
33+
{
34+
return log(tan(((90 + (double)lat) * MATH_PI) / 360)) / (MATH_PI / 180);
35+
}
36+
37+
double unproject_latitude(double lat_projected)
38+
{
39+
return (atan(pow(exp(1), lat_projected * (MATH_PI / 180)))*360) / MATH_PI - 90;
40+
}
41+
3042
//shifts all (longitude) values from near 180 to 0
3143
double get_180_swapped(double lon)
3244
{
@@ -740,6 +752,7 @@ gps_point_proc weighted_middle_point_proc(gps_point_proc *p1,
740752
gps_point_proc crt_point = uninit_gps_proc_point;
741753
crt_point.lat
742754
= weighted_middle_double(p1->lat, p1->time, p2->lat, p2->time, new_t, max_gps_diff_ms);
755+
crt_point.lat_projected = project_latitude(crt_point.lat);
743756
crt_point.lon
744757
= weighted_middle_double(p1->lon, p1->time, p2->lon, p2->time, new_t, max_gps_diff_ms);
745758
crt_point.speed
@@ -960,6 +973,7 @@ void process_gps_smoothing(gps_private_data gdata, char do_processing)
960973
//these are not interpolated but as long as we're iterating we can copy them now
961974
gp_p[i].time = gp_r[i].time;
962975
gp_p[i].lat = gp_r[i].lat;
976+
gp_p[i].lat_projected = gp_r[i].lat_projected;
963977
gp_p[i].lon = gp_r[i].lon;
964978
}
965979
}
@@ -972,6 +986,7 @@ void process_gps_smoothing(gps_private_data gdata, char do_processing)
972986
if (req_smooth == 1) {
973987
//copy raw lat/lon to calc lat/lon and interpolate 1 location if necessary
974988
gps_points_p[i].lat = gps_points_r[i].lat;
989+
gps_points_p[i].lat_projected = gps_points_r[i].lat_projected;
975990
gps_points_p[i].lon = gps_points_r[i].lon;
976991

977992
//this can happen often if location and altitude are stored at different time intervals (every 3s vs every 10s)
@@ -989,6 +1004,7 @@ void process_gps_smoothing(gps_private_data gdata, char do_processing)
9891004
gps_points_r[i + 1].time,
9901005
gps_points_r[i].time,
9911006
max_gps_diff_ms);
1007+
gps_points_p[i].lat_projected = project_latitude(gps_points_p[i].lat);
9921008
gps_points_p[i].lon = weighted_middle_double(gps_points_r[i - 1].lon,
9931009
gps_points_r[i - 1].time,
9941010
gps_points_r[i + 1].lon,
@@ -1013,9 +1029,11 @@ void process_gps_smoothing(gps_private_data gdata, char do_processing)
10131029
}
10141030
if (nr_div != 0) {
10151031
gps_points_p[i].lat = lat_sum / nr_div;
1032+
gps_points_p[i].lat_projected = project_latitude(gps_points_p[i].lat);
10161033
gps_points_p[i].lon = lon_sum / nr_div;
10171034
} else {
10181035
gps_points_p[i].lat = gps_points_r[i].lat;
1036+
gps_points_p[i].lat_projected = gps_points_r[i].lat;
10191037
gps_points_p[i].lon = gps_points_r[i].lon;
10201038
}
10211039
//mlt_log_info(filter, "i=%d, lat_sum=%f, lon_sum=%f, nr_div=%d, time=%d", i, lat_sum, lon_sum, nr_div, gps_points[i].time);
@@ -1060,7 +1078,10 @@ void qxml_parse_gpx(QXmlStreamReader &reader, gps_point_ll **gps_list, int *coun
10601078

10611079
QXmlStreamAttributes attributes = reader.attributes();
10621080
if (attributes.hasAttribute("lat"))
1081+
{
10631082
crt_point.lat = attributes.value("lat").toDouble();
1083+
crt_point.lat_projected = project_latitude( crt_point.lat);
1084+
}
10641085
if (attributes.hasAttribute("lon"))
10651086
crt_point.lon = attributes.value("lon").toDouble();
10661087

@@ -1215,8 +1236,10 @@ void qxml_parse_tcx(QXmlStreamReader &reader, gps_point_ll **gps_list, int *coun
12151236
qUtf8Printable(reader.readElementText()));
12161237
else if (reader.name() == QStringLiteral("Position")) {
12171238
reader.readNextStartElement();
1218-
if (reader.name() == QStringLiteral("LatitudeDegrees"))
1239+
if (reader.name() == QStringLiteral("LatitudeDegrees")) {
12191240
crt_point.lat = reader.readElementText().toDouble();
1241+
crt_point.lat_projected = project_latitude(crt_point.lat);
1242+
}
12201243
reader.readNextStartElement();
12211244
if (reader.name() == QStringLiteral("LongitudeDegrees"))
12221245
crt_point.lon = reader.readElementText().toDouble();

src/modules/qt/gps_parser.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828

2929
typedef struct
3030
{
31-
double lat, lon, speed, total_dist, ele, hr, bearing, cad, atemp, power;
31+
double lat, lon, lat_projected, speed, total_dist, ele, hr, bearing, cad, atemp, power;
3232
int64_t time; //epoch milliseconds
3333
} gps_point_raw;
3434

@@ -40,7 +40,7 @@ typedef struct gps_point_raw_list
4040

4141
typedef struct
4242
{
43-
double lat, lon, speed, speed_vertical, speed_3d, total_dist, ele, hr, bearing, cad, atemp,
43+
double lat, lon, lat_projected, speed, speed_vertical, speed_3d, total_dist, ele, hr, bearing, cad, atemp,
4444
power;
4545
int64_t time;
4646
double d_elev, elev_up, elev_down, dist_up, dist_down, dist_flat, grade_p;
@@ -49,6 +49,7 @@ typedef struct
4949
//0 is a valid value for many fields, use GPS_UNINIT (-9999) to differentiate missing values
5050
static const gps_point_raw uninit_gps_raw_point = {.lat = GPS_UNINIT,
5151
.lon = GPS_UNINIT,
52+
.lat_projected = GPS_UNINIT,
5253
.speed = GPS_UNINIT,
5354
.total_dist = GPS_UNINIT,
5455
.ele = GPS_UNINIT,
@@ -61,6 +62,7 @@ static const gps_point_raw uninit_gps_raw_point = {.lat = GPS_UNINIT,
6162

6263
static const gps_point_proc uninit_gps_proc_point = {.lat = GPS_UNINIT,
6364
.lon = GPS_UNINIT,
65+
.lat_projected = GPS_UNINIT,
6466
.speed = GPS_UNINIT,
6567
.speed_vertical = GPS_UNINIT,
6668
.speed_3d = GPS_UNINIT,
@@ -123,6 +125,8 @@ double convert_speed_to_format(double x, const char *format);
123125
const char *bearing_to_compass(double x);
124126
void recalculate_gps_data(gps_private_data gdata);
125127
void process_gps_smoothing(gps_private_data gdata, char do_processing);
128+
double project_latitude(double lat);
129+
double unproject_latitude(double lat_projected);
126130

127131
double weighted_middle_double(
128132
double v1, int64_t t1, double v2, int64_t t2, int64_t new_t, int max_gps_diff_ms);

0 commit comments

Comments
 (0)