+static const char kml_header_start[] =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ "<kml xmlns=\"http://www.opengis.net/kml/2.2\">\n"
+ "<Document>\n"
+ " <name>%s</name>\n"
+ " <description>\n";
+static const char kml_header_end[] =
+ " </description>\n"
+ " <open>0</open>\n";
+
+static const char kml_style_start[] =
+ " <Style id=\"ao-flightstate-%s\">\n"
+ " <LineStyle><color>%s</color><width>4</width></LineStyle>\n"
+ " <BalloonStyle>\n"
+ " <text>\n";
+static const char kml_style_end[] =
+ " </text>\n"
+ " </BalloonStyle>\n"
+ " </Style>\n";
+
+static const char kml_placemark_start[] =
+ " <Placemark>\n"
+ " <name>%s</name>\n"
+ " <styleUrl>#ao-flightstate-%s</styleUrl>\n"
+ " <LineString>\n"
+ " <tessellate>1</tessellate>\n"
+ " <altitudeMode>absolute</altitudeMode>\n"
+ " <coordinates>\n";
+
+static const char kml_coord_fmt[] =
+ " %12.7f, %12.7f, %12.7f <!-- alt %12.7f time %12.7f sats %d -->\n";
+
+static const char kml_placemark_end[] =
+ " </coordinates>\n"
+ " </LineString>\n"
+ " </Placemark>\n";
+
+static const char kml_footer[] =
+ " </coordinates>\n"
+ " </LineString>\n"
+ " </Placemark>\n"
+ "</Document>\n"
+ "</kml>\n";
+
+static unsigned
+gps_daytime(struct cc_gpselt *gps)
+{
+ return ((gps->hour * 60 +
+ gps->minute) * 60 +
+ gps->second) * 1000;
+}
+
+int
+daytime_hour(unsigned daytime)
+{
+ return daytime / 1000 / 60 / 60;
+}
+
+int
+daytime_minute(unsigned daytime)
+{
+ return (daytime / 1000 / 60) % 60;
+}
+
+int
+daytime_second(unsigned daytime)
+{
+ return (daytime / 1000) % 60;
+}
+
+int
+daytime_millisecond(unsigned daytime)
+{
+ return daytime % 1000;
+}
+
+static unsigned
+compute_daytime_ms(double time, struct cc_gpsdata *gps)
+{
+ int i;
+ unsigned gps_start_daytime, gps_stop_daytime;
+
+ if (time <= gps->data[0].time) {
+ gps_stop_daytime = gps_daytime(&gps->data[0]);
+ return gps_stop_daytime - (gps->data[0].time - time) * 10;
+ }
+ for (i = 0; i < gps->num - 1; i++)
+ if (time > gps->data[i].time)
+ break;
+ gps_start_daytime = gps_daytime(&gps->data[i]);
+ if (i == gps->num - 1) {
+ return gps_start_daytime + (time - gps->data[i].time) * 10;
+ } else {
+ unsigned gps_period_daytime;
+ double gps_period_time;
+ double time_since_start;
+
+ gps_stop_daytime = gps_daytime(&gps->data[i + 1]);
+
+ /* range of gps daytime values */
+ gps_period_daytime = gps_stop_daytime - gps_start_daytime;
+
+ /* range of gps time values */
+ gps_period_time = gps->data[i+1].time - gps->data[i].time;
+
+ /* sample time after first gps time */
+ time_since_start = time - gps->data[i].time;
+
+ return gps_start_daytime +
+ gps_period_daytime * time_since_start / gps_period_time;
+ }
+}
+