00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "garmin.h"
00013 #include "nmeagen.h"
00014 #include "exifgen.h"
00015
00016 #include <math.h>
00017 #include <stdio.h>
00018 #include <string.h>
00019
00020 void exif_init_meta(struct meta_GPSInfo_t *meta) {
00021 meta->GPSLatitudeRef= 'N';
00022 meta->GPSLatitude_deg_nom= __cpu_to_be32((int) 0);
00023 meta->GPSLatitude_deg_denom= __cpu_to_be32((int) 1);
00024 meta->GPSLatitude_min_nom= __cpu_to_be32((int) 0);
00025 meta->GPSLatitude_min_denom= __cpu_to_be32((int) EXIF_GPS_MIN_DENOM);
00026 meta->GPSLongitudeRef= 'W';
00027 meta->GPSLongitude_deg_nom= __cpu_to_be32((int) 0);
00028 meta->GPSLongitude_deg_denom=__cpu_to_be32((int) 1);
00029 meta->GPSLongitude_min_nom= __cpu_to_be32((int) 0);
00030 meta->GPSLongitude_min_denom=__cpu_to_be32((int) EXIF_GPS_MIN_DENOM);
00031 meta->GPSAltitudeRef= 0;
00032 meta->GPSAltitude_nom= __cpu_to_be32((int) 0);
00033 meta->GPSAltitude_denom= __cpu_to_be32((int) EXIF_GPS_METERS_DENOM);
00034 meta->GPSTimeStamp_hrs_nom= __cpu_to_be32((int) 0);
00035 meta->GPSTimeStamp_hrs_denom=__cpu_to_be32((int) 1);
00036 meta->GPSTimeStamp_min_nom= __cpu_to_be32((int) 0);
00037 meta->GPSTimeStamp_min_denom=__cpu_to_be32((int) 1);
00038 meta->GPSTimeStamp_sec_nom= __cpu_to_be32((int) 0);
00039 meta->GPSMeasureMode= '0';
00040 meta->GPSTimeStamp_sec_denom=__cpu_to_be32((int) EXIF_GPS_TIMESEC_DENOM);
00041
00042
00043 }
00044
00045 void exif_getutc(D800_Pvt_Data_Type *pvt, struct meta_GPSInfo_t *meta) {
00046 int tmp = 0, dtmp=0;
00047 int frac_sec;
00048
00049
00050
00051
00052
00053
00054
00055 tmp = (pvt->tow + 0.5/EXIF_GPS_TIMESEC_DENOM);
00056 frac_sec = ((pvt->tow + 0.5/EXIF_GPS_TIMESEC_DENOM) - tmp)*EXIF_GPS_TIMESEC_DENOM +0.5;
00057
00058 dtmp = pvt->wn_days;
00059
00060
00061
00062
00063
00064
00065 if (tmp >= 604800)
00066 {
00067 dtmp += 7;
00068 tmp = 0;
00069 }
00070
00071
00072
00073
00074
00075
00076
00077 tmp -= pvt->leap_scnds;
00078 if (tmp < 0)
00079 {
00080 tmp+= 604800;
00081 dtmp -= 7;
00082 }
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 dtmp += (tmp / 86400);
00094 tmp %= 86400;
00095
00096 int h, m, s;
00097 h = tmp / 3600;
00098 m = (tmp - h*3600) / 60;
00099 s = ((tmp - h*3600 - m*60) * EXIF_GPS_TIMESEC_DENOM)+frac_sec;
00100
00101 meta->GPSTimeStamp_hrs_nom= __cpu_to_be32((int) h);
00102 meta->GPSTimeStamp_min_nom= __cpu_to_be32((int) m);
00103 meta->GPSTimeStamp_sec_nom= __cpu_to_be32((int) s);
00104
00105
00106 unsigned long jd = dtmp + 2447892;
00107 unsigned long w, x, a, b, c, d, e, f;
00108 unsigned long day, month, year;
00109
00110 w = (unsigned long)((jd - 1867216.25)/36524.25);
00111 x = w/4;
00112 a = jd + 1 + w - x;
00113 b = a + 1524;
00114 c = (unsigned long)((b - 122.1)/365.25);
00115 d = (unsigned long)(365.25 * c);
00116 e = (unsigned long)((b-d)/30.6001);
00117 f = (unsigned long)(30.6001 * e);
00118
00119 day = b - d - f;
00120 month = e - 1;
00121 if (month > 12) month -= 12;
00122 year = c - 4716;
00123 if (month == 1 || month == 2) year++;
00124
00125 sprintf(meta->GPSDateStamp, "%04ld:%02ld:%02ld", year, month,day);
00126 }
00127
00128
00129 int exif_gen(D800_Pvt_Data_Type *pvt, cpo_sat_data *sat, struct meta_GPSInfo_t *meta) {
00130 int deg,m_scaled;
00131 exif_getutc( pvt, meta);
00132 meta->GPSMeasureMode= (pvt->fix >= 4)?'3':'2';
00134 m_scaled=rad2deg(pvt->lat)*60*EXIF_GPS_MIN_DENOM +0.5;
00135 meta->GPSLatitudeRef= (m_scaled >=0)?'N':'S';
00136 if (m_scaled<0) m_scaled=-m_scaled;
00137 deg = m_scaled/(60*EXIF_GPS_MIN_DENOM);
00138 m_scaled -= deg*(60*EXIF_GPS_MIN_DENOM);
00139 meta->GPSLatitude_deg_nom= __cpu_to_be32(deg);
00140 meta->GPSLatitude_min_nom= __cpu_to_be32(m_scaled);
00142 m_scaled=rad2deg(pvt->lon)*60*EXIF_GPS_MIN_DENOM +0.5;
00143 meta->GPSLongitudeRef= (m_scaled >=0)?'E':'W';
00144 if (m_scaled<0) m_scaled=-m_scaled;
00145 deg = m_scaled/(60*EXIF_GPS_MIN_DENOM);
00146 m_scaled -= deg*(60*EXIF_GPS_MIN_DENOM);
00147 meta->GPSLongitude_deg_nom= __cpu_to_be32(deg);
00148 meta->GPSLongitude_min_nom= __cpu_to_be32(m_scaled);
00150 m_scaled= (pvt->msl_hght + pvt->alt)*EXIF_GPS_METERS_DENOM +0.5;
00151 meta->GPSAltitudeRef= (m_scaled >=0)? 0 : 1;
00152 if (m_scaled<0) m_scaled=-m_scaled;
00153 meta->GPSAltitude_nom= __cpu_to_be32(m_scaled);
00154 return 0;
00155 }
00156