31#include <wx/datetime.h>
34#include <wx/translation.h>
37#include "navutil_base.h"
39#include "navutil_base.h"
42extern int g_iSDMMFormat;
43extern int g_iSpeedFormat;
44extern int g_iDistanceFormat;
46wxString toSDMM(
int NEflag,
double a,
bool hi_precision) {
69 }
else if (NEflag == 2) {
79 switch (g_iSDMMFormat) {
82 if (hi_precision) mpy = mpy * 1000;
84 m = (long)wxRound((a - (
double)d) * mpy);
86 if (!NEflag || NEflag < 1 || NEflag > 2)
89 s.Printf(_T (
"%d%c %02ld.%04ld'" ), d, 0x00B0, m / 10000, m % 10000);
91 s.Printf(_T (
"%d%c %02ld.%01ld'" ), d, 0x00B0, m / 10, m % 10);
95 s.Printf(_T (
"%02d%c %02ld.%04ld' %c" ), d, 0x00B0, m / 10000,
98 s.Printf(_T (
"%03d%c %02ld.%04ld' %c" ), d, 0x00B0, m / 10000,
100 else if (NEflag == 1)
101 s.Printf(_T (
"%02d%c %02ld.%01ld' %c" ), d, 0x00B0, m / 10, (m % 10), c);
103 s.Printf(_T (
"%03d%c %02ld.%01ld' %c" ), d, 0x00B0, m / 10, (m % 10), c);
108 s.Printf(_T (
"%03.6f" ),
113 s.Printf(_T (
"%03.4f" ), ang);
116 m = (long)((a - (
double)d) * 60);
118 if (hi_precision) mpy = mpy * 100;
119 long sec = (long)((a - (
double)d - (((double)m) / 60)) * 3600 * mpy);
121 if (!NEflag || NEflag < 1 || NEflag > 2)
124 s.Printf(_T (
"%d%c %ld'%ld.%ld\"" ), d, 0x00B0, m, sec / 1000,
127 s.Printf(_T (
"%d%c %ld'%ld.%ld\"" ), d, 0x00B0, m, sec / 10, sec % 10);
131 s.Printf(_T (
"%02d%c %02ld' %02ld.%03ld\" %c" ), d, 0x00B0, m,
132 sec / 1000, sec % 1000, c);
134 s.Printf(_T (
"%03d%c %02ld' %02ld.%03ld\" %c" ), d, 0x00B0, m,
135 sec / 1000, sec % 1000, c);
136 else if (NEflag == 1)
137 s.Printf(_T (
"%02d%c %02ld' %02ld.%ld\" %c" ), d, 0x00B0, m, sec / 10,
140 s.Printf(_T (
"%03d%c %02ld' %02ld.%ld\" %c" ), d, 0x00B0, m, sec / 10,
151double toUsrSpeed(
double kts_speed,
int unit) {
153 if (
unit == -1)
unit = g_iSpeedFormat;
159 ret = kts_speed * 1.15078;
162 ret = kts_speed * 1.852;
165 ret = kts_speed * 0.514444444;
174double toUsrDistance(
double nm_distance,
int unit) {
176 if (
unit == -1)
unit = g_iDistanceFormat;
182 ret = nm_distance * 1.15078;
185 ret = nm_distance * 1.852;
188 ret = nm_distance * 1852;
191 ret = nm_distance * 6076.12;
194 ret = nm_distance * 1012.68591;
197 ret = nm_distance * 72913.4;
200 ret = nm_distance * 185200;
210wxString getUsrDistanceUnit(
int unit) {
212 if (
unit == -1)
unit = g_iDistanceFormat;
246wxString getUsrSpeedUnit(
int unit) {
248 if (
unit == -1)
unit = g_iSpeedFormat;
266wxString FormatDistanceAdaptive(
double distance) {
268 int unit = g_iDistanceFormat;
269 double usrDistance = toUsrDistance(distance,
unit);
270 if (usrDistance < 0.1 &&
271 (
unit == DISTANCE_KM ||
unit == DISTANCE_MI ||
unit == DISTANCE_NMI)) {
272 unit = (
unit == DISTANCE_MI) ? DISTANCE_FT : DISTANCE_M;
273 usrDistance = toUsrDistance(distance,
unit);
276 if (usrDistance < 5.0) {
277 format = _T(
"%1.2f ");
278 }
else if (usrDistance < 100.0) {
279 format = _T(
"%2.1f ");
280 }
else if (usrDistance < 1000.0) {
281 format = _T(
"%3.0f ");
283 format = _T(
"%4.0f ");
285 result << wxString::Format(format, usrDistance) << getUsrDistanceUnit(
unit);
292double fromUsrSpeed(
double usr_speed,
int unit,
int default_val) {
301 ret = usr_speed / 1.15078;
304 ret = usr_speed / 1.852;
307 ret = usr_speed / 0.514444444;
316double fromUsrDistance(
double usr_distance,
int unit,
int default_val) {
324 ret = usr_distance / 1.15078;
327 ret = usr_distance / 1.852;
330 ret = usr_distance / 1852;
333 ret = usr_distance / 6076.12;
342double vGetLengthOfNormal(pVector2D a, pVector2D b, pVector2D n) {
351 c.x = b->x * (vDotProduct(a, b) / vDotProduct(b, b));
352 c.y = b->y * (vDotProduct(a, b) / vDotProduct(b, b));
356 vSubtractVectors(a, &c, &vNormal);
362 return (vVectorMagnitude(&vNormal));
365double vDotProduct(pVector2D v0, pVector2D v1) {
369 (v0 == NULL || v1 == NULL) ? 0.0 : (v0->x * v1->x) + (v0->y * v1->y);
374pVector2D vAddVectors(pVector2D v0, pVector2D v1, pVector2D v) {
375 if (v0 == NULL || v1 == NULL)
378 v->x = v0->x + v1->x;
379 v->y = v0->y + v1->y;
384pVector2D vSubtractVectors(pVector2D v0, pVector2D v1, pVector2D v) {
385 if (v0 == NULL || v1 == NULL)
388 v->x = v0->x - v1->x;
389 v->y = v0->y - v1->y;
394double vVectorSquared(pVector2D v0) {
400 dS = ((v0->x * v0->x) + (v0->y * v0->y));
404double vVectorMagnitude(pVector2D v0) {
410 dMagnitude = sqrt(vVectorSquared(v0));
427const wxChar *ParseGPXDateTime(wxDateTime &dt,
const wxChar *datetime) {
428 long sign, hrs_west, mins_west;
432 while (isspace(*datetime)) datetime++;
435 if (*datetime == wxT(
'-')) datetime++;
438 if ((end = dt.ParseFormat(datetime, wxT(
"%Y-%m-%dT%T"))) != NULL) {
440 if (*end == 0)
return NULL;
446 else if (*end == wxT(
'Z')) {
452 else if (*end == wxT(
'+') || *end == wxT(
'-')) {
454 if (*end == wxT(
'+'))
461 if (isdigit(*end) && isdigit(*(end + 1)) && *(end + 2) == wxT(
':')) {
463 wxString(end).ToLong(&hrs_west);
464 if (hrs_west > 12)
return NULL;
468 if (isdigit(*end) && isdigit(*(end + 1))) {
472 mins[1] = *(end + 1);
474 wxString(mins).ToLong(&mins_west);
475 if (mins_west > 59)
return NULL;
478 dt -= sign * wxTimeSpan(hrs_west, mins_west, 0, 0);
495wxString formatTimeDelta(wxTimeSpan span) {
497 int days = span.GetDays();
498 span -= wxTimeSpan::Days(days);
499 int hours = span.GetHours();
500 span -= wxTimeSpan::Hours(hours);
501 double minutes = (double)span.GetSeconds().ToLong() / 60.0;
502 span -= wxTimeSpan::Minutes(span.GetMinutes());
503 int seconds = (double)span.GetSeconds().ToLong();
506 (days ? wxString::Format(_(
"%dd "), days) : _T(
"")) +
508 ? wxString::Format(_(
"%2dH %2dM"), hours, (int)round(minutes))
509 : wxString::Format(_(
"%2dM %2dS"), (int)floor(minutes), seconds));
514wxString formatTimeDelta(wxDateTime startTime, wxDateTime endTime) {
516 if (startTime.IsValid() && endTime.IsValid()) {
517 wxTimeSpan span = endTime - startTime;
518 return formatTimeDelta(span);
524wxString formatTimeDelta(wxLongLong secs) {
527 wxTimeSpan span(0, 0, secs);
528 return formatTimeDelta(span);
532wxString GpxDocument::GetUUID(
void) {
537 int time_hi_and_version;
538 int clock_seq_hi_and_rsv;
544 uuid.time_low = GetRandomNumber(
547 uuid.time_mid = GetRandomNumber(0, 65535);
548 uuid.time_hi_and_version = GetRandomNumber(0, 65535);
549 uuid.clock_seq_hi_and_rsv = GetRandomNumber(0, 255);
550 uuid.clock_seq_low = GetRandomNumber(0, 255);
551 uuid.node_hi = GetRandomNumber(0, 65535);
552 uuid.node_low = GetRandomNumber(0, 2147483647);
556 uuid.clock_seq_hi_and_rsv = (uuid.clock_seq_hi_and_rsv & 0x3F) | 0x80;
560 uuid.time_hi_and_version = (uuid.time_hi_and_version & 0x0fff) | 0x4000;
562 str.Printf(_T(
"%08x-%04x-%04x-%02x%02x-%04x%08x"), uuid.time_low,
563 uuid.time_mid, uuid.time_hi_and_version, uuid.clock_seq_hi_and_rsv,
564 uuid.clock_seq_low, uuid.node_hi, uuid.node_low);
569int GpxDocument::GetRandomNumber(
int range_min,
int range_max) {
570 long u = (long)wxRound(
571 ((
double)rand() / ((
double)(RAND_MAX) + 1) * (range_max - range_min)) +
598double fromDMM(wxString sdms) {
602 double stk[32], sign = 1;
607 replhelper = wxString::FromUTF8(
"´·");
608 sdms.Replace(replhelper, _T(
"."));
610 wxString::FromUTF8(
"\"·");
611 sdms.Replace(replhelper, _T(
"."));
612 replhelper = wxString::FromUTF8(
"·");
613 sdms.Replace(replhelper, _T(
"."));
616 wxString::FromUTF8(
"s. š.");
618 sdms.Replace(replhelper, _T(
"N"));
619 replhelper = wxString::FromUTF8(
"j. š.");
620 sdms.Replace(replhelper, _T(
"S"));
621 sdms.Replace(_T(
"v. d."), _T(
"E"));
622 sdms.Replace(_T(
"z. d."), _T(
"W"));
627 if (sdms.Contains(_T(
"N")) || sdms.Contains(_T(
"S")) ||
628 sdms.Contains(_T(
"E")) || sdms.Contains(_T(
"W")))
629 sdms.Replace(_T(
"-"), _T(
" "));
631 wcsncpy(buf, sdms.wc_str(wxConvUTF8), 63);
633 len = wxMin(wcslen(buf),
sizeof(narrowbuf) - 1);
636 for (i = 0; i < len; i++) {
638 if ((c >=
'0' && c <=
'9') || c ==
'-' || c ==
'.' || c ==
'+') {
646 if ((c | 32) ==
'w' || (c | 32) ==
's')
652 stk[0] = stk[1] = stk[2] = 0;
653 for (i = 0; i < len; i++) {
654 while (i < len && narrowbuf[i] == 0) i++;
656 stk[top++] = atof(narrowbuf + i);
657 i += strlen(narrowbuf + i);
661 return sign * (stk[0] + (stk[1] + stk[2] / 60) / 60);