Logo Search packages:      
Sourcecode: viking version File versions  Download package

degrees_converters.c

/*
 * viking -- GPS Data and Topo Analyzer, Explorer, and Manager
 *
 * Copyright (C) 2006-2007, Guilhem Bonnefille <guilhem.bonnefille@gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

#include <math.h>
#include <glib.h>
#include <stdio.h>
#include <string.h>

/**
 * @param pos_c char for positive value
 * @param neg_c char for negative value
 */
static gchar *convert_dec_to_ddd(gdouble dec, gchar pos_c, gchar neg_c)
{
  gchar sign_c = ' ';
  gdouble val_d;
  gchar *result = NULL;

  if ( dec > 0 )
    sign_c = pos_c;
  else if ( dec < 0 )
    sign_c = neg_c;
  else /* Nul value */
    sign_c = ' ';

  /* Degree */
  val_d = fabs(dec);

  /* Format */
  /* TODO : replace "°" as UTF-8 */
  result = g_strdup_printf ( "%c%f°", sign_c, val_d );
  return result;
}

gchar *convert_lat_dec_to_ddd(gdouble lat)
{
  return convert_dec_to_ddd(lat, 'N', 'S');
}

gchar *convert_lon_dec_to_ddd(gdouble lon)
{
  return convert_dec_to_ddd(lon, 'E', 'W');
}

/**
 * @param pos_c char for positive value
 * @param neg_c char for negative value
 */
static gchar *convert_dec_to_dmm(gdouble dec, gchar pos_c, gchar neg_c)
{
  gdouble tmp;
  gchar sign_c = ' ';
  gint val_d;
  gdouble val_m;
  gchar *result = NULL;

  if ( dec > 0 )
    sign_c = pos_c;
  else if ( dec < 0 )
    sign_c = neg_c;
  else /* Nul value */
    sign_c = ' ';

  /* Degree */
  tmp = fabs(dec);
  val_d = (gint)tmp;

  /* Minutes */
  val_m = (tmp - val_d) * 60;

  /* Format */
  /* TODO : replace "°" as UTF-8 */
  result = g_strdup_printf ( "%c%d°%f'",
                             sign_c, val_d, val_m );
  return result;
}

gchar *convert_lat_dec_to_dmm(gdouble lat)
{
  return convert_dec_to_dmm(lat, 'N', 'S');
}

gchar *convert_lon_dec_to_dmm(gdouble lon)
{
  return convert_dec_to_dmm(lon, 'E', 'W');
}

/**
 * @param pos_c char for positive value
 * @param neg_c char for negative value
 */
static gchar *convert_dec_to_dms(gdouble dec, gchar pos_c, gchar neg_c)
{
  gdouble tmp;
  gchar sign_c = ' ';
  gint val_d, val_m;
  gdouble val_s;
  gchar *result = NULL;

  if ( dec > 0 )
    sign_c = pos_c;
  else if ( dec < 0 )
    sign_c = neg_c;
  else /* Nul value */
    sign_c = ' ';

  /* Degree */
  tmp = fabs(dec);
  val_d = (gint)tmp;

  /* Minutes */
  tmp = (tmp - val_d) * 60;
  val_m = (gint)tmp;

  /* Minutes */
  val_s = (tmp - val_m) * 60;

  /* Format */
  /* TODO : replace "°" as UTF-8 */
  result = g_strdup_printf ( "%c%d°%d'%f\"",
                             sign_c, val_d, val_m, val_s );
  return result;
}

gchar *convert_lat_dec_to_dms(gdouble lat)
{
  return convert_dec_to_dms(lat, 'N', 'S');
}

gchar *convert_lon_dec_to_dms(gdouble lon)
{
  return convert_dec_to_dms(lon, 'E', 'W');
}

gdouble convert_dms_to_dec(const gchar *dms)
{
      gdouble d = 0.0; /* Degree */
      gdouble m = 0.0; /* Minutes */
      gdouble s = 0.0; /* Seconds */
      gint neg = FALSE;
      gdouble result;
      
      if (dms != NULL) {
            int nbFloat = 0;
            const gchar *ptr, *endptr;

            // Compute the sign
            // It is negative if:
            // - the '-' sign occurs
            // - it is a west longitude or south latitude
            if (strpbrk (dms, "-wWsS") != NULL)
                neg = TRUE;

            // Peek the différent components
            endptr = dms;
            do {
                  gdouble value;
                  ptr = strpbrk (endptr, "0123456789,.");
                  if (ptr != NULL) {
                        value = g_strtod(ptr, &endptr);
                        nbFloat++;
                  switch(nbFloat) {
                        case 1:
                              d = value;
                              break;
                        case 2:
                              m = value;
                              break;
                        case 3:
                              s = value;
                              break;
                  }
                  }
            } while (ptr != NULL && endptr != NULL);
      }
      
      // Compute the result
      result = d + m/60 + s/3600;
      
      if (neg) result = - result;
      
      return result;
}

Generated by  Doxygen 1.6.0   Back to index