示例#1
0
/**
 * vik_trw_layer_tpwin_set_tp:
 * @tpwin:      The Trackpoint Edit Window
 * @tpl:        The #Glist of trackpoints pointing at the current trackpoint
 * @track_name: The name of the track in which the trackpoint belongs
 * @is_route:   Is the track of the trackpoint actually a route?
 *
 * Sets the Trackpoint Edit Window to the values of the current trackpoint given in @tpl.
 *
 */
void vik_trw_layer_tpwin_set_tp ( VikTrwLayerTpwin *tpwin, GList *tpl, const gchar *track_name, gboolean is_route )
{
  static char tmp_str[64];
  static struct LatLon ll;
  VikTrackpoint *tp = VIK_TRACKPOINT(tpl->data);

  if ( tp->name )
    gtk_entry_set_text ( GTK_ENTRY(tpwin->trkpt_name), tp->name );
  else
    gtk_editable_delete_text ( GTK_EDITABLE(tpwin->trkpt_name), 0, -1 );
  gtk_widget_set_sensitive ( tpwin->trkpt_name, TRUE );

  /* Only can insert if not at the end (otherwise use extend track) */
  gtk_widget_set_sensitive ( tpwin->button_insert, (gboolean) GPOINTER_TO_INT (tpl->next) );
  gtk_widget_set_sensitive ( tpwin->button_delete, TRUE );

  /* We can only split up a track if it's not an endpoint. Makes sense to me. */
  gtk_widget_set_sensitive ( tpwin->button_split, tpl->next && tpl->prev );

  gtk_widget_set_sensitive ( tpwin->button_forward, (gboolean) GPOINTER_TO_INT (tpl->next) );
  gtk_widget_set_sensitive ( tpwin->button_back, (gboolean) GPOINTER_TO_INT (tpl->prev) );

  gtk_widget_set_sensitive ( GTK_WIDGET(tpwin->lat), TRUE );
  gtk_widget_set_sensitive ( GTK_WIDGET(tpwin->lon), TRUE );
  gtk_widget_set_sensitive ( GTK_WIDGET(tpwin->alt), TRUE );
  gtk_widget_set_sensitive ( GTK_WIDGET(tpwin->ts), tp->has_timestamp );
  gtk_widget_set_sensitive ( GTK_WIDGET(tpwin->time), tp->has_timestamp );
  // Enable adding timestamps - but not on routepoints
  if ( !tp->has_timestamp && !is_route ) {
    gtk_widget_set_sensitive ( GTK_WIDGET(tpwin->time), TRUE );
    GtkWidget *img = gtk_image_new_from_stock ( GTK_STOCK_ADD, GTK_ICON_SIZE_MENU );
    gtk_button_set_image ( GTK_BUTTON(tpwin->time), img );
  }
  else

  vik_trw_layer_tpwin_set_track_name ( tpwin, track_name );

  tpwin->sync_to_tp_block = TRUE; /* don't update while setting data. */

  vik_coord_to_latlon ( &(tp->coord), &ll );
  gtk_spin_button_set_value ( tpwin->lat, ll.lat );
  gtk_spin_button_set_value ( tpwin->lon, ll.lon );
  vik_units_height_t height_units = a_vik_get_units_height ();
  switch (height_units) {
  case VIK_UNITS_HEIGHT_METRES:
    gtk_spin_button_set_value ( tpwin->alt, tp->altitude );
    break;
  case VIK_UNITS_HEIGHT_FEET:
    gtk_spin_button_set_value ( tpwin->alt, VIK_METERS_TO_FEET(tp->altitude) );
    break;
  default:
    gtk_spin_button_set_value ( tpwin->alt, tp->altitude );
    g_critical("Houston, we've had a problem. height=%d", height_units);
  }

  tpwin_update_times ( tpwin, tp );

  tpwin->sync_to_tp_block = FALSE; // don't update while setting data.

  vik_units_speed_t speed_units = a_vik_get_units_speed ();
  vik_units_distance_t dist_units = a_vik_get_units_distance ();
  if ( tpwin->cur_tp )
  {
    switch (dist_units) {
    case VIK_UNITS_DISTANCE_KILOMETRES:
      g_snprintf ( tmp_str, sizeof(tmp_str), "%.2f m", vik_coord_diff(&(tp->coord), &(tpwin->cur_tp->coord)));
      break;
    case VIK_UNITS_DISTANCE_MILES:
    case VIK_UNITS_DISTANCE_NAUTICAL_MILES:
      g_snprintf ( tmp_str, sizeof(tmp_str), "%.2f yards", vik_coord_diff(&(tp->coord), &(tpwin->cur_tp->coord))*1.0936133);
      break;
    default:
      g_critical("Houston, we've had a problem. distance=%d", dist_units);
    }

    gtk_label_set_text ( tpwin->diff_dist, tmp_str );
    if ( tp->has_timestamp && tpwin->cur_tp->has_timestamp )
    {
      g_snprintf ( tmp_str, sizeof(tmp_str), "%ld s", tp->timestamp - tpwin->cur_tp->timestamp);
      gtk_label_set_text ( tpwin->diff_time, tmp_str );
      if ( tp->timestamp == tpwin->cur_tp->timestamp )
        gtk_label_set_text ( tpwin->diff_speed, "--" );
      else
      {
	switch (speed_units) {
	case VIK_UNITS_SPEED_KILOMETRES_PER_HOUR:
	  g_snprintf ( tmp_str, sizeof(tmp_str), "%.2f km/h", VIK_MPS_TO_KPH(vik_coord_diff(&(tp->coord), &(tpwin->cur_tp->coord)) / (ABS(tp->timestamp - tpwin->cur_tp->timestamp))) );
	  break;
	case VIK_UNITS_SPEED_MILES_PER_HOUR:
	  g_snprintf ( tmp_str, sizeof(tmp_str), "%.2f mph", VIK_MPS_TO_MPH(vik_coord_diff(&(tp->coord), &(tpwin->cur_tp->coord)) / (ABS(tp->timestamp - tpwin->cur_tp->timestamp))) );
	  break;
	case VIK_UNITS_SPEED_METRES_PER_SECOND:
	  g_snprintf ( tmp_str, sizeof(tmp_str), "%.2f m/s", vik_coord_diff(&(tp->coord), &(tpwin->cur_tp->coord)) / ABS(tp->timestamp - tpwin->cur_tp->timestamp) );
	  break;
	case VIK_UNITS_SPEED_KNOTS:
	  g_snprintf ( tmp_str, sizeof(tmp_str), "%.2f knots", VIK_MPS_TO_KNOTS(vik_coord_diff(&(tp->coord), &(tpwin->cur_tp->coord)) / (ABS(tp->timestamp - tpwin->cur_tp->timestamp))) );
	  break;
	case VIK_UNITS_SPEED_SECONDS_PER_KM:
	  g_snprintf ( tmp_str, sizeof(tmp_str), "%.2f s/km", VIK_MPS_TO_PACE_SPK(vik_coord_diff(&(tp->coord), &(tpwin->cur_tp->coord)) / (ABS(tp->timestamp - tpwin->cur_tp->timestamp))) );
	  break;
	case VIK_UNITS_SPEED_MINUTES_PER_KM:
	  g_snprintf ( tmp_str, sizeof(tmp_str), "%.2f min/km", VIK_MPS_TO_PACE_MPK(vik_coord_diff(&(tp->coord), &(tpwin->cur_tp->coord)) / (ABS(tp->timestamp - tpwin->cur_tp->timestamp))) );
	  break;
	case VIK_UNITS_SPEED_SECONDS_PER_MILE:
	  g_snprintf ( tmp_str, sizeof(tmp_str), "%.2f sec/mi", VIK_MPS_TO_PACE_SPM(vik_coord_diff(&(tp->coord), &(tpwin->cur_tp->coord)) / (ABS(tp->timestamp - tpwin->cur_tp->timestamp))) );
	  break;
	case VIK_UNITS_SPEED_MINUTES_PER_MILE:
	  g_snprintf ( tmp_str, sizeof(tmp_str), "%.2f min/mi", VIK_MPS_TO_PACE_MPM(vik_coord_diff(&(tp->coord), &(tpwin->cur_tp->coord)) / (ABS(tp->timestamp - tpwin->cur_tp->timestamp))) );
	  break;
	default:
	  g_snprintf ( tmp_str, sizeof(tmp_str), "--" );
	  g_critical("Houston, we've had a problem. speed=%d", speed_units);
	}
        gtk_label_set_text ( tpwin->diff_speed, tmp_str );
      }
    }
    else
    {
      gtk_label_set_text ( tpwin->diff_time, NULL );
      gtk_label_set_text ( tpwin->diff_speed, NULL );
    }
  }

  if ( isnan(tp->course) )
    g_snprintf ( tmp_str, sizeof(tmp_str), "--" );
  else
    g_snprintf ( tmp_str, sizeof(tmp_str), "%05.1f\302\260", tp->course );
  gtk_label_set_text ( tpwin->course, tmp_str );

  if ( isnan(tp->speed) )
    g_snprintf ( tmp_str, sizeof(tmp_str), "--" );
  else {
    switch (speed_units) {
    case VIK_UNITS_SPEED_MILES_PER_HOUR:
      g_snprintf ( tmp_str, sizeof(tmp_str), "%.2f mph", VIK_MPS_TO_MPH(tp->speed) );
      break;
    case VIK_UNITS_SPEED_METRES_PER_SECOND:
      g_snprintf ( tmp_str, sizeof(tmp_str), "%.2f m/s", tp->speed );
      break;
    case VIK_UNITS_SPEED_KNOTS:
      g_snprintf ( tmp_str, sizeof(tmp_str), "%.2f knots", VIK_MPS_TO_KNOTS(tp->speed) );
      break;
    case VIK_UNITS_SPEED_SECONDS_PER_KM:
      g_snprintf ( tmp_str, sizeof(tmp_str), "%.2f s/km", VIK_MPS_TO_PACE_SPK(tp->speed) );
      break;
    case VIK_UNITS_SPEED_MINUTES_PER_KM:
      g_snprintf ( tmp_str, sizeof(tmp_str), "%.2f min/km", VIK_MPS_TO_PACE_MPK(tp->speed) );
      break;
    case VIK_UNITS_SPEED_SECONDS_PER_MILE:
      g_snprintf ( tmp_str, sizeof(tmp_str), "%.2f s/mi", VIK_MPS_TO_PACE_SPM(tp->speed) );
      break;
    case VIK_UNITS_SPEED_MINUTES_PER_MILE:
      g_snprintf ( tmp_str, sizeof(tmp_str), "%.2f min/mi", VIK_MPS_TO_PACE_MPM(tp->speed) );
      break;
    default:
      // VIK_UNITS_SPEED_KILOMETRES_PER_HOUR:
      g_snprintf ( tmp_str, sizeof(tmp_str), "%.2f km/h", VIK_MPS_TO_KPH(tp->speed) );
      break;
    }
  }
  gtk_label_set_text ( tpwin->speed, tmp_str );

  switch (dist_units) {
  case VIK_UNITS_DISTANCE_KILOMETRES:
    g_snprintf ( tmp_str, sizeof(tmp_str), "%.5f m", tp->hdop );
    gtk_label_set_text ( tpwin->hdop, tmp_str );
    g_snprintf ( tmp_str, sizeof(tmp_str), "%.5f m", tp->pdop );
    gtk_label_set_text ( tpwin->pdop, tmp_str );
    break;
  case VIK_UNITS_DISTANCE_NAUTICAL_MILES:
  case VIK_UNITS_DISTANCE_MILES:
    g_snprintf ( tmp_str, sizeof(tmp_str), "%.5f yards", tp->hdop*1.0936133 );
    gtk_label_set_text ( tpwin->hdop, tmp_str );
    g_snprintf ( tmp_str, sizeof(tmp_str), "%.5f yards", tp->pdop*1.0936133 );
    gtk_label_set_text ( tpwin->pdop, tmp_str );
    break;
  default:
    g_critical("Houston, we've had a problem. distance=%d", dist_units);
  }

  switch (height_units) {
  case VIK_UNITS_HEIGHT_METRES:
    g_snprintf ( tmp_str, sizeof(tmp_str), "%.5f m", tp->vdop );
    break;
  case VIK_UNITS_HEIGHT_FEET:
    g_snprintf ( tmp_str, sizeof(tmp_str), "%.5f feet", VIK_METERS_TO_FEET(tp->vdop) );
    break;
  default:
    g_snprintf ( tmp_str, sizeof(tmp_str), "--" );
    g_critical("Houston, we've had a problem. height=%d", height_units);
  }
  gtk_label_set_text ( tpwin->vdop, tmp_str );

  g_snprintf ( tmp_str, sizeof(tmp_str), "%d / %d", tp->nsats, tp->fix_mode );
  gtk_label_set_text ( tpwin->sat, tmp_str );

  tpwin->cur_tp = tp;
}
示例#2
0
/**
 * vu_trackpoint_formatted_message:
 * @format_code:  String describing the message to generate
 * @trkpt:        The trackpoint for which the message is generated about
 * @trkpt_prev:   A trackpoint (presumed previous) for interpolating values with the other trackpoint (such as speed)
 * @trk:          The track in which the trackpoints reside
 *
 *  TODO: One day replace this cryptic format code with some kind of tokenizer parsing
 *    thus would make it more user friendly and maybe even GUI controlable.
 * However for now at least there is some semblance of user control
 */
gchar* vu_trackpoint_formatted_message ( gchar *format_code, VikTrackpoint *trkpt, VikTrackpoint *trkpt_prev, VikTrack *trk )
{
	if ( !trkpt )
		return NULL;

	gint len = 0;
	if ( format_code )
		len = strlen ( format_code );
	if ( len > FMT_MAX_NUMBER_CODES )
		len = FMT_MAX_NUMBER_CODES;

	gchar* values[FMT_MAX_NUMBER_CODES];
	int i;
	for ( i = 0; i < FMT_MAX_NUMBER_CODES; i++ ) {
		values[i] = '\0';
	}

	gchar *speed_units_str = NULL;
	vik_units_speed_t speed_units = a_vik_get_units_speed ();
	switch (speed_units) {
	case VIK_UNITS_SPEED_MILES_PER_HOUR:
		speed_units_str = g_strdup ( _("mph") );
		break;
	case VIK_UNITS_SPEED_METRES_PER_SECOND:
		speed_units_str = g_strdup ( _("m/s") );
		break;
	case VIK_UNITS_SPEED_KNOTS:
		speed_units_str = g_strdup ( _("knots") );
		break;
	default:
		// VIK_UNITS_SPEED_KILOMETRES_PER_HOUR:
		speed_units_str = g_strdup ( _("km/h") );
		break;
	}

	gchar *separator = g_strdup ( " | " );

	for ( i = 0; i < len; i++ ) {
		switch ( g_ascii_toupper ( format_code[i] ) ) {
		case 'G': values[i] = g_strdup ( _("GPSD") ); break; // GPS Preamble
		case 'K': values[i] = g_strdup ( _("Trkpt") ); break; // Trkpt Preamble

		case 'S': {
			gdouble speed = 0.0;
			gchar *speedtype = NULL;
			if ( isnan(trkpt->speed) && trkpt_prev ) {
				if ( trkpt->has_timestamp && trkpt_prev->has_timestamp ) {
					if ( trkpt->timestamp == trkpt_prev->timestamp ) {

						// Work out from previous trackpoint location and time difference
						speed = vik_coord_diff(&(trkpt->coord), &(trkpt_prev->coord)) / ABS(trkpt->timestamp - trkpt_prev->timestamp);

						switch (speed_units) {
						case VIK_UNITS_SPEED_KILOMETRES_PER_HOUR:
							speed = VIK_MPS_TO_KPH(speed);
							break;
						case VIK_UNITS_SPEED_MILES_PER_HOUR:
							speed = VIK_MPS_TO_MPH(speed);
							break;
						case VIK_UNITS_SPEED_KNOTS:
							speed = VIK_MPS_TO_KNOTS(speed);
							break;
						default:
							// VIK_UNITS_SPEED_METRES_PER_SECOND:
							// Already in m/s so nothing to do
							break;
						}
						speedtype = g_strdup ( "*" ); // Interpolated
					}
					else
						speedtype = g_strdup ( "**" );
				}
				else
					speedtype = g_strdup ( "**" );
			}
			else {
				speed = trkpt->speed;
				speedtype = g_strdup ( "" );
			}

			values[i] = g_strdup_printf ( _("%sSpeed%s %.1f%s"), separator, speedtype, speed, speed_units_str );
			g_free ( speedtype );
			break;
		}

		case 'A': {
			vik_units_height_t height_units = a_vik_get_units_height ();
			switch (height_units) {
			case VIK_UNITS_HEIGHT_FEET:
				values[i] = g_strdup_printf ( _("%sAlt %dfeet"), separator, (int)round(VIK_METERS_TO_FEET(trkpt->altitude)) );
				break;
			default:
				//VIK_UNITS_HEIGHT_METRES:
				values[i] = g_strdup_printf ( _("%sAlt %dm"), separator, (int)round(trkpt->altitude) );
				break;
			}
			break;
		}

		case 'C': {
			gint heading = isnan(trkpt->course) ? 0 : (gint)round(trkpt->course);
			values[i] = g_strdup_printf ( _("%sCourse %03d\302\260" ), separator, heading );
			break;
		}

		case 'P': {
			if ( trkpt_prev ) {
				gint diff = (gint) round ( vik_coord_diff ( &(trkpt->coord), &(trkpt_prev->coord) ) );

				gchar *dist_units_str = NULL;
				vik_units_distance_t dist_units = a_vik_get_units_distance ();
				// expect the difference between track points to be small hence use metres or yards
				switch (dist_units) {
				case VIK_UNITS_DISTANCE_MILES:
					dist_units_str = g_strdup ( _("yards") );
					break;
				default:
					// VIK_UNITS_DISTANCE_KILOMETRES:
					dist_units_str = g_strdup ( _("m") );
					break;
				}

				values[i] = g_strdup_printf ( _("%sDistance diff %d%s"), separator, diff, dist_units_str );

				g_free ( dist_units_str );
			}
			break;
		}

		case 'T': {
			gchar tmp[64];
			tmp[0] = '\0';
			if ( trkpt->has_timestamp ) {
				// Compact date time format
				strftime (tmp, sizeof(tmp), "%x %X", localtime(&(trkpt->timestamp)));
			}
			else
				g_snprintf (tmp, sizeof(tmp), "--");
			values[i] = g_strdup_printf ( _("%sTime %s"), separator, tmp );
			break;
		}

		case 'M': {
			if ( trkpt_prev ) {
				if ( trkpt->has_timestamp && trkpt_prev->has_timestamp ) {
					time_t t_diff = trkpt->timestamp - trkpt_prev->timestamp;
					values[i] = g_strdup_printf ( _("%sTime diff %lds"), separator, t_diff );
				}
			}
			break;
		}

		case 'X': values[i] = g_strdup_printf ( _("%sNo. of Sats %d"), separator, trkpt->nsats ); break;

		case 'D': {
			if ( trk ) {
				// Distance from start (along the track)
				gdouble distd =	vik_track_get_length_to_trackpoint (trk, trkpt);
				gchar *dist_units_str = NULL;
				vik_units_distance_t dist_units = a_vik_get_units_distance ();
				// expect the difference between track points to be small hence use metres or yards
				switch (dist_units) {
				case VIK_UNITS_DISTANCE_MILES:
					dist_units_str = g_strdup ( _("miles") );
					distd = VIK_METERS_TO_MILES(distd);
					break;
				default:
					// VIK_UNITS_DISTANCE_KILOMETRES:
					dist_units_str = g_strdup ( _("km") );
					distd = distd / 1000.0;
					break;
				}
				values[i] = g_strdup_printf ( _("%sDistance along %.2f%s"), separator, distd, dist_units_str );
				g_free ( dist_units_str );
			}
			break;
		}

		case 'L': {
			// Location (Lat/Long)
			gchar *lat = NULL, *lon = NULL;
			struct LatLon ll;
			vik_coord_to_latlon (&(trkpt->coord), &ll);
			a_coords_latlon_to_string ( &ll, &lat, &lon );
			values[i] = g_strdup_printf ( "%s%s %s", separator, lat, lon );
			g_free ( lat );
			g_free ( lon );
			break;
		}

		case 'N': // Name of track
			values[i] = g_strdup_printf ( _("%sTrack: %s"), separator, trk->name );
			break;

		case 'E': // Name of trackpoint if available
			if ( trkpt->name )
				values[i] = g_strdup_printf ( "%s%s", separator, trkpt->name );
			else
				values[i] = g_strdup ( "" );
			break;

		default:
			break;
		}
	}

	g_free ( separator );
	g_free ( speed_units_str );

	gchar *msg = g_strconcat ( values[0], values[1], values[2], values[3], values[4], values[5], values[6], values[7], values[8], NULL );

	for ( i = 0; i < FMT_MAX_NUMBER_CODES; i++ ) {
		if ( values[i] != '\0' )
			g_free ( values[i] );
	}
	
	return msg;
}
示例#3
0
/**
 * @val_analyse_track:
 * @trk: The track to be analyse
 *
 * Function to collect statistics, using the internal track functions
 */
static void val_analyse_track ( VikTrack *trk )
{
	//val_reset ( TS_TRACK );
	gdouble min_alt;
	gdouble max_alt;
	gdouble up;
	gdouble down;

	gdouble  length      = 0.0;
	gdouble  length_gaps = 0.0;
	gdouble  max_speed   = 0.0;
	gulong   trackpoints = 0;
	guint    segments    = 0;

	tracks_stats[TS_TRACKS].count++;

	trackpoints = vik_track_get_tp_count (trk);
	segments    = vik_track_get_segment_count (trk);
	length      = vik_track_get_length (trk);
	length_gaps = vik_track_get_length_including_gaps (trk);
	max_speed   = vik_track_get_max_speed (trk);

    if ( !trk->is_route ) {
		// Eddington number will be in the current Units distance preference
		gdouble e_len;
		switch (a_vik_get_units_distance ()) {
		case VIK_UNITS_DISTANCE_MILES:          e_len = VIK_METERS_TO_MILES(length); break;
		case VIK_UNITS_DISTANCE_NAUTICAL_MILES: e_len = VIK_METERS_TO_NAUTICAL_MILES(length); break;
			//VIK_UNITS_DISTANCE_KILOMETRES
		default: e_len = length/1000.0; break;
		}
		gdouble *gd = g_malloc ( sizeof(gdouble) );
		*gd = e_len;
		tracks_stats[TS_TRACKS].e_list = g_list_prepend ( tracks_stats[TS_TRACKS].e_list, gd );
	}

	int ii;
	for (ii = 0; ii < G_N_ELEMENTS(tracks_stats); ii++) {
		tracks_stats[ii].trackpoints += trackpoints;
		tracks_stats[ii].segments    += segments;
		tracks_stats[ii].length      += length;
		tracks_stats[ii].length_gaps += length_gaps;
		if ( max_speed > tracks_stats[ii].max_speed )
			tracks_stats[ii].max_speed = max_speed;
	}

	if ( vik_track_get_minmax_alt (trk, &min_alt, &max_alt) ) {
		for (ii = 0; ii < G_N_ELEMENTS(tracks_stats); ii++) {
			if ( min_alt < tracks_stats[ii].min_alt )
				tracks_stats[ii].min_alt = min_alt;
			if ( max_alt > tracks_stats[ii].max_alt )
				tracks_stats[ii].max_alt = max_alt;
		}
	}

	vik_track_get_total_elevation_gain (trk, &up, &down );

	for (ii = 0; ii < G_N_ELEMENTS(tracks_stats); ii++) {
		tracks_stats[ii].elev_gain += up;
		tracks_stats[ii].elev_loss += down;
	}

	if ( trk->trackpoints && VIK_TRACKPOINT(trk->trackpoints->data)->timestamp ) {
		time_t t1, t2;
		t1 = VIK_TRACKPOINT(g_list_first(trk->trackpoints)->data)->timestamp;
		t2 = VIK_TRACKPOINT(g_list_last(trk->trackpoints)->data)->timestamp;

		// Assume never actually have a track with a time of 0 (1st Jan 1970)
		for (ii = 0; ii < G_N_ELEMENTS(tracks_stats); ii++) {
			if ( tracks_stats[ii].start_time == 0)
				tracks_stats[ii].start_time = t1;
			if ( tracks_stats[ii].end_time == 0)
				tracks_stats[ii].end_time = t2;
		}

		// Initialize to the first value
		for (ii = 0; ii < G_N_ELEMENTS(tracks_stats); ii++) {
			if (t1 < tracks_stats[ii].start_time)
				tracks_stats[ii].start_time = t1;
			if (t2 > tracks_stats[ii].end_time)
				tracks_stats[ii].end_time = t2;
		}

		for (ii = 0; ii < G_N_ELEMENTS(tracks_stats); ii++) {
			tracks_stats[ii].duration = tracks_stats[ii].duration + (int)(t2-t1);
		}
	}
}
示例#4
0
文件: vikviewport.c 项目: gdt/viking
void vik_viewport_draw_scale ( VikViewport *vvp )
{
  g_return_if_fail ( vvp != NULL );

  if ( vvp->draw_scale ) {
    VikCoord left, right;
    gdouble unit, base, diff, old_unit, old_diff, ratio;
    gint odd, len, SCSIZE = 5, HEIGHT=10;
    PangoLayout *pl;
    gchar s[128];

    vik_viewport_screen_to_coord ( vvp, 0, vvp->height, &left );
    vik_viewport_screen_to_coord ( vvp, vvp->width/SCSIZE, vvp->height, &right );

    vik_units_distance_t dist_units = a_vik_get_units_distance ();
    switch (dist_units) {
    case VIK_UNITS_DISTANCE_KILOMETRES:
      base = vik_coord_diff ( &left, &right ); // in meters
      break;
    case VIK_UNITS_DISTANCE_MILES:
      // in 0.1 miles (copes better when zoomed in as 1 mile can be too big)
      base = VIK_METERS_TO_MILES(vik_coord_diff ( &left, &right )) * 10.0;
      break;
    default:
      base = 1; // Keep the compiler happy
      g_critical("Houston, we've had a problem. distance=%d", dist_units);
    }
    ratio = (vvp->width/SCSIZE)/base;

    unit = 1;
    diff = fabs(base-unit);
    old_unit = unit;
    old_diff = diff;
    odd = 1;
    while (diff <= old_diff) {
      old_unit = unit;
      old_diff = diff;
      unit = unit * (odd%2 ? 5 : 2);
      diff = fabs(base-unit);
      odd++;
    }
    unit = old_unit;
    len = unit * ratio;

    /* white background */
    vik_viewport_draw_line(vvp, vvp->scale_bg_gc, 
			 PAD, vvp->height-PAD, PAD + len, vvp->height-PAD);
    vik_viewport_draw_line(vvp, vvp->scale_bg_gc,
			 PAD, vvp->height-PAD, PAD, vvp->height-PAD-HEIGHT);
    vik_viewport_draw_line(vvp, vvp->scale_bg_gc,
			 PAD + len, vvp->height-PAD, PAD + len, vvp->height-PAD-HEIGHT);
    /* black scale */
    vik_viewport_draw_line(vvp, gtk_widget_get_style(GTK_WIDGET(&vvp->drawing_area))->black_gc,
			 PAD, vvp->height-PAD, PAD + len, vvp->height-PAD);
    vik_viewport_draw_line(vvp, gtk_widget_get_style(GTK_WIDGET(&vvp->drawing_area))->black_gc,
			 PAD, vvp->height-PAD, PAD, vvp->height-PAD-HEIGHT);
    vik_viewport_draw_line(vvp, gtk_widget_get_style(GTK_WIDGET(&vvp->drawing_area))->black_gc,
			 PAD + len, vvp->height-PAD, PAD + len, vvp->height-PAD-HEIGHT);
    if (odd%2) {
      int i;
      for (i=1; i<5; i++) {
        vik_viewport_draw_line(vvp, vvp->scale_bg_gc, 
			     PAD+i*len/5, vvp->height-PAD, PAD+i*len/5, vvp->height-PAD-((i==5)?(2*HEIGHT/3):(HEIGHT/2)));
        vik_viewport_draw_line(vvp, gtk_widget_get_style(GTK_WIDGET(&vvp->drawing_area))->black_gc,
			     PAD+i*len/5, vvp->height-PAD, PAD+i*len/5, vvp->height-PAD-((i==5)?(2*HEIGHT/3):(HEIGHT/2)));
      }
    } else {
      int i;
      for (i=1; i<10; i++) {
        vik_viewport_draw_line(vvp, vvp->scale_bg_gc,
  			     PAD+i*len/10, vvp->height-PAD, PAD+i*len/10, vvp->height-PAD-((i==5)?(2*HEIGHT/3):(HEIGHT/2)));
        vik_viewport_draw_line(vvp, gtk_widget_get_style(GTK_WIDGET(&vvp->drawing_area))->black_gc,
  			     PAD+i*len/10, vvp->height-PAD, PAD+i*len/10, vvp->height-PAD-((i==5)?(2*HEIGHT/3):(HEIGHT/2)));
      }
    }
    pl = gtk_widget_create_pango_layout (GTK_WIDGET(&vvp->drawing_area), NULL); 
    pango_layout_set_font_description (pl, gtk_widget_get_style(GTK_WIDGET(&vvp->drawing_area))->font_desc);

    switch (dist_units) {
    case VIK_UNITS_DISTANCE_KILOMETRES:
      if (unit >= 1000) {
	sprintf(s, "%d km", (int)unit/1000);
      } else {
	sprintf(s, "%d m", (int)unit);
      }
      break;
    case VIK_UNITS_DISTANCE_MILES:
      // Handle units in 0.1 miles
      if (unit < 10.0) {
	sprintf(s, "%0.1f miles", unit/10.0);
      }
      else if ((int)unit == 10.0) {
	sprintf(s, "1 mile");
      }
      else {
	sprintf(s, "%d miles", (int)(unit/10.0));
      }
      break;
    default:
      g_critical("Houston, we've had a problem. distance=%d", dist_units);
    }
    pango_layout_set_text(pl, s, -1);
    vik_viewport_draw_layout(vvp, gtk_widget_get_style(GTK_WIDGET(&vvp->drawing_area))->black_gc,
			   PAD + len + PAD, vvp->height - PAD - 10, pl);
    g_object_unref(pl);
    pl = NULL;
  }
}
示例#5
0
/**
 * table_output:
 *
 * Update the given widgets table with the values from the track stats
 */
static void table_output ( track_stats ts, GtkWidget *content[], gboolean extended )
{
	int cnt = 0;

	gchar tmp_buf[64];
	g_snprintf ( tmp_buf, sizeof(tmp_buf), "%d", ts.count );
	gtk_label_set_text ( GTK_LABEL(content[cnt++]), tmp_buf );

	if ( ts.count == 0 ) {
		// Blank all other fields
		g_snprintf ( tmp_buf, sizeof(tmp_buf), "--" );
		for ( cnt = 1; cnt < G_N_ELEMENTS(label_texts); cnt++ )
			gtk_label_set_text ( GTK_LABEL(content[cnt]), tmp_buf );
		return;
	}

	// Check for potential date range
	// Test if the same day by comparing the date string of the timestamp
	GDate* gdate_start = g_date_new ();
	g_date_set_time_t ( gdate_start, ts.start_time );
	gchar time_start[32];
	g_date_strftime ( time_start, sizeof(time_start), "%x", gdate_start );
	g_date_free ( gdate_start );

	GDate* gdate_end = g_date_new ();
	g_date_set_time_t ( gdate_end, ts.end_time );
	gchar time_end[32];
	g_date_strftime ( time_end, sizeof(time_end), "%x", gdate_end );
	g_date_free ( gdate_end );

	if ( ts.start_time == ts.end_time )
		g_snprintf ( tmp_buf, sizeof(tmp_buf), _("No Data") );
	else if ( strncmp(time_start, time_end, 32) )
		g_snprintf ( tmp_buf, sizeof(tmp_buf), "%s --> %s", time_start, time_end );
	else
		g_snprintf ( tmp_buf, sizeof(tmp_buf), "%s", time_start );

	gtk_label_set_text ( GTK_LABEL(content[cnt++]), tmp_buf );

	switch (a_vik_get_units_distance ()) {
	case VIK_UNITS_DISTANCE_MILES:
		g_snprintf ( tmp_buf, sizeof(tmp_buf), _("%.1f miles"), VIK_METERS_TO_MILES(ts.length) );
		break;
	case VIK_UNITS_DISTANCE_NAUTICAL_MILES:
		g_snprintf ( tmp_buf, sizeof(tmp_buf), _("%.1f NM"), VIK_METERS_TO_NAUTICAL_MILES(ts.length) );
		break;
	default:
		//VIK_UNITS_DISTANCE_KILOMETRES
		g_snprintf ( tmp_buf, sizeof(tmp_buf), _("%.1f km"), ts.length/1000.0 );
		break;
	}
	gtk_label_set_text ( GTK_LABEL(content[cnt++]), tmp_buf );

	switch (a_vik_get_units_distance ()) {
	case VIK_UNITS_DISTANCE_MILES:
		g_snprintf ( tmp_buf, sizeof(tmp_buf), _("%.2f miles"), (VIK_METERS_TO_MILES(ts.length)/ts.count) );
		break;
	case VIK_UNITS_DISTANCE_NAUTICAL_MILES:
		g_snprintf ( tmp_buf, sizeof(tmp_buf), _("%.2f NM"), (VIK_METERS_TO_NAUTICAL_MILES(ts.length)/ts.count) );
		break;
	default:
		//VIK_UNITS_DISTANCE_KILOMETRES
		g_snprintf ( tmp_buf, sizeof(tmp_buf), _("%.2f km"), ts.length/(1000.0*ts.count) );
		break;
	}
	gtk_label_set_text ( GTK_LABEL(content[cnt++]), tmp_buf );

	if ( extended ) {
		// Note that this currently is a simplified approach to calculate the Eddington number.
		// In that a per track value is used, rather than trying to work out a length per day.
		//  (i.e. doesn't combine multiple tracks for a single day or split very long tracks into days)
		tracks_stats[TS_TRACKS].e_list = g_list_sort ( tracks_stats[TS_TRACKS].e_list, rsort_by_distance );
		guint Eddington = 0;
		guint position = 0;
		for (GList *iter = g_list_first (tracks_stats[TS_TRACKS].e_list); iter != NULL; iter = g_list_next (iter)) {
			position++;
			gdouble *num = (gdouble*)iter->data;
			if ( *num > position )
				Eddington = position;
		}
		g_snprintf ( tmp_buf, sizeof(tmp_buf), ("%d"), Eddington );
		gtk_label_set_text ( GTK_LABEL(content[cnt++]), tmp_buf );
	} else
		cnt++;

	// I'm sure this could be cleaner...
	g_snprintf ( tmp_buf, sizeof(tmp_buf), "--" );
	switch (a_vik_get_units_speed()) {
	case VIK_UNITS_SPEED_MILES_PER_HOUR:
		if ( ts.max_speed > 0 )
			g_snprintf ( tmp_buf, sizeof(tmp_buf), _("%.1f mph"), (double)VIK_MPS_TO_MPH(ts.max_speed) );
		gtk_label_set_text ( GTK_LABEL(content[cnt++]), tmp_buf );
		if ( ts.duration > 0 )
			g_snprintf ( tmp_buf, sizeof(tmp_buf), ("%.1f mph"), (double)VIK_MPS_TO_MPH(ts.length/ts.duration) );
		else
			g_snprintf ( tmp_buf, sizeof(tmp_buf), "--" );
		break;
	case VIK_UNITS_SPEED_METRES_PER_SECOND:
		if ( ts.max_speed > 0 )
			g_snprintf ( tmp_buf, sizeof(tmp_buf), _("%.2f m/s"), (double)ts.max_speed );
		gtk_label_set_text ( GTK_LABEL(content[cnt++]), tmp_buf );
		if ( ts.duration > 0 )
			g_snprintf ( tmp_buf, sizeof(tmp_buf), ("%.2f m/s"), (double)(ts.length/ts.duration) );
		else
			g_snprintf ( tmp_buf, sizeof(tmp_buf), "--" );
		break;
	case VIK_UNITS_SPEED_KNOTS:
		if ( ts.max_speed > 0 )
			g_snprintf ( tmp_buf, sizeof(tmp_buf), _("%.2f knots"), (double)VIK_MPS_TO_KNOTS(ts.max_speed) );
		gtk_label_set_text ( GTK_LABEL(content[cnt++]), tmp_buf );
		if ( ts.duration > 0 )
			g_snprintf ( tmp_buf, sizeof(tmp_buf), _("%.2f knots"), (double)VIK_MPS_TO_KNOTS(ts.length/ts.duration) );
		else
			g_snprintf ( tmp_buf, sizeof(tmp_buf), "--" );
		break;
	case VIK_UNITS_SPEED_SECONDS_PER_KM:
		if ( ts.max_speed > 0 )
			g_snprintf ( tmp_buf, sizeof(tmp_buf), _("%d s/km"), (int)VIK_MPS_TO_PACE_SPK(ts.max_speed) );
		gtk_label_set_text ( GTK_LABEL(content[cnt++]), tmp_buf );
		if ( ts.duration > 0 )
			g_snprintf ( tmp_buf, sizeof(tmp_buf), _("%d s/km"), (int)VIK_MPS_TO_PACE_SPK(ts.length/ts.duration) );
		else
			g_snprintf ( tmp_buf, sizeof(tmp_buf), "--" );
		break;

	case VIK_UNITS_SPEED_MINUTES_PER_KM:
		if ( ts.max_speed > 0 )
			g_snprintf ( tmp_buf, sizeof(tmp_buf), _("%.1f min/km"), (double)VIK_MPS_TO_PACE_MPK(ts.max_speed) );
		gtk_label_set_text ( GTK_LABEL(content[cnt++]), tmp_buf );
		if ( ts.duration > 0 )
			g_snprintf ( tmp_buf, sizeof(tmp_buf), _("%.1f min/km"), (double)VIK_MPS_TO_PACE_MPK(ts.length/ts.duration) );
		else
			g_snprintf ( tmp_buf, sizeof(tmp_buf), "--" );
		break;

	case VIK_UNITS_SPEED_SECONDS_PER_MILE:
		if ( ts.max_speed > 0 )
			g_snprintf ( tmp_buf, sizeof(tmp_buf), _("%d sec/mi"), (int)VIK_MPS_TO_PACE_SPM(ts.max_speed) );
		gtk_label_set_text ( GTK_LABEL(content[cnt++]), tmp_buf );
		if ( ts.duration > 0 )
			g_snprintf ( tmp_buf, sizeof(tmp_buf), _("%d sec/mi"), (int)VIK_MPS_TO_PACE_SPM(ts.length/ts.duration) );
		else
			g_snprintf ( tmp_buf, sizeof(tmp_buf), "--" );
		break;

	case VIK_UNITS_SPEED_MINUTES_PER_MILE:
		if ( ts.max_speed > 0 )
			g_snprintf ( tmp_buf, sizeof(tmp_buf), _("%.1f min/mi"), (double)VIK_MPS_TO_PACE_MPM(ts.max_speed) );
		gtk_label_set_text ( GTK_LABEL(content[cnt++]), tmp_buf );
		if ( ts.duration > 0 )
			g_snprintf ( tmp_buf, sizeof(tmp_buf), _("%.1f min/mi"), (double)VIK_MPS_TO_PACE_MPM(ts.length/ts.duration) );
		else
			g_snprintf ( tmp_buf, sizeof(tmp_buf), "--" );
		break;

	default:
		//VIK_UNITS_SPEED_KILOMETRES_PER_HOUR:
		if ( ts.max_speed > 0 )
			g_snprintf ( tmp_buf, sizeof(tmp_buf), _("%.2f km/h"), (double)VIK_MPS_TO_KPH(ts.max_speed) );
		gtk_label_set_text ( GTK_LABEL(content[cnt++]), tmp_buf );
		if ( ts.duration > 0 )
			g_snprintf ( tmp_buf, sizeof(tmp_buf), _("%.2f km/h"), (double)VIK_MPS_TO_KPH(ts.length/ts.duration) );
		else
			g_snprintf ( tmp_buf, sizeof(tmp_buf), "--" );
		break;
	}
	gtk_label_set_text ( GTK_LABEL(content[cnt++]), tmp_buf );

	switch ( a_vik_get_units_height() ) {
		// Note always round off height value output since sub unit accuracy is overkill
	case VIK_UNITS_HEIGHT_FEET:
		if ( ts.min_alt != VIK_VAL_MIN_ALT )
			g_snprintf ( tmp_buf, sizeof(tmp_buf), _("%d feet"), (int)round(VIK_METERS_TO_FEET(ts.min_alt)) );
		else
			g_snprintf ( tmp_buf, sizeof(tmp_buf), "--" );
		gtk_label_set_text ( GTK_LABEL(content[cnt++]), tmp_buf );

		if ( ts.max_alt != VIK_VAL_MAX_ALT )
			g_snprintf ( tmp_buf, sizeof(tmp_buf), _("%d feet"), (int)round(VIK_METERS_TO_FEET(ts.max_alt)) );
		else
			g_snprintf ( tmp_buf, sizeof(tmp_buf), "--" );
		gtk_label_set_text ( GTK_LABEL(content[cnt++]), tmp_buf );

		g_snprintf ( tmp_buf, sizeof(tmp_buf), _("%d feet / %d feet"), (int)round(VIK_METERS_TO_FEET(ts.elev_gain)), (int)round(VIK_METERS_TO_FEET(ts.elev_loss)) );
		gtk_label_set_text ( GTK_LABEL(content[cnt++]), tmp_buf );
		g_snprintf ( tmp_buf, sizeof(tmp_buf), _("%d feet / %d feet"), (int)round(VIK_METERS_TO_FEET(ts.elev_gain/ts.count)), (int)round(VIK_METERS_TO_FEET(ts.elev_loss/ts.count)) );
		break;
	default:
		//VIK_UNITS_HEIGHT_METRES
		if ( ts.min_alt != VIK_VAL_MIN_ALT )
			g_snprintf ( tmp_buf, sizeof(tmp_buf), _("%d m"), (int)round(ts.min_alt) );
		else
			g_snprintf ( tmp_buf, sizeof(tmp_buf), "--" );
		gtk_label_set_text ( GTK_LABEL(content[cnt++]), tmp_buf );

		if ( ts.max_alt != VIK_VAL_MAX_ALT )
			g_snprintf ( tmp_buf, sizeof(tmp_buf), _("%d m"), (int)round(ts.max_alt) );
		else
			g_snprintf ( tmp_buf, sizeof(tmp_buf), "--" );
		gtk_label_set_text ( GTK_LABEL(content[cnt++]), tmp_buf );

		g_snprintf ( tmp_buf, sizeof(tmp_buf), _("%d m / %d m"), (int)round(ts.elev_gain), (int)round(ts.elev_loss) );
		gtk_label_set_text ( GTK_LABEL(content[cnt++]), tmp_buf );
		g_snprintf ( tmp_buf, sizeof(tmp_buf), _("%d m / %d m"), (int)round(ts.elev_gain/ts.count), (int)round(ts.elev_loss/ts.count) );
		break;
	}
	gtk_label_set_text ( GTK_LABEL(content[cnt++]), tmp_buf );

	gint hours;
	gint minutes;
	gint days;
	// Total Duration
	days    = (gint)(ts.duration / (60*60*24));
	hours   = (gint)floor((ts.duration - (days*60*60*24)) / (60*60));
	minutes = (gint)((ts.duration - (days*60*60*24) - (hours*60*60)) / 60);
	g_snprintf ( tmp_buf, sizeof(tmp_buf), _("%d:%02d:%02d days:hrs:mins"), days, hours, minutes );
	gtk_label_set_text ( GTK_LABEL(content[cnt++]), tmp_buf );

	// Average Duration
	gint avg_dur = ts.duration / ts.count;
	hours   = (gint)floor(avg_dur / (60*60));
	minutes = (gint)((avg_dur - (hours*60*60)) / 60);
	g_snprintf ( tmp_buf, sizeof(tmp_buf), _("%d:%02d hrs:mins"), hours, minutes );
	gtk_label_set_text ( GTK_LABEL(content[cnt++]), tmp_buf );
}