⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 track.cpp

📁 给予QT的qps开源最新源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
   qpegps is a program for displaying a map centered at the current longitude/
   latitude as read from a gps receiver.

   Copyright (C) 2002 Ralf Haselmeier <Ralf.Haselmeier@gmx.de>

   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., 675 Mass Ave, Cambridge, MA 02139, USA.

 */

#include "track.h"

#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include "convert.h"

// write config file
#define WRITE_CONFIG	application->writeConfig()

// ----- NON-MEMBER FUNCTIONS -----

/*
 * move to next comma separated field
 */
char * nextfield(const char * s)
{
   char * r = strchr(s, ',');
   return ( ( r ) ? (r + 1) : NULL );
}

/*
 * calculate NMEA checksum
 */
void checksumNMEA(QString * ns)
{
   const char * n = ns->latin1();
   unsigned checksum = n[1];
   QString nend;

   for ( unsigned int i = 2; i < strlen(n); ++i ) {
      checksum ^= (unsigned int)n[i];
   }
   nend.sprintf("*%02x\r\n", checksum);
   ns->append(nend);
}

/*
 * convert (char*) "hh:mm:ss" to (double) hhmmss
 */
double tmstr2double(const char * str)
{
   int h, m, s;
   sscanf(str, "%d:%d:%d", &h, &m, &s);
   return (double)(3600 * h + 60 * m + s);
}

/*
 * convert (double) hhmmss to (char*) "hh:mm:ss"
 */
void tmdouble2str(double tm, char * str) {
   int h = (int)(tm) / 3600;
   int m = (int)(tm) / 60 - 60 * h;
   int s = (int)(tm) % 60;
   sprintf(str, "%02d:%02d:%02d", h, m, s);
}

// ----- METHODS -----

/*********************************************************************
 * TRACKPOINT constructor - create trackpoint from various formats
 *********************************************************************/

TrackPoint::TrackPoint(QString * nmea)
{
   const char * str = nmea->latin1();
   switch ( *str )
   {
      case '$':
         {
            // assuming NMEA GPGGA messages
            double lon, lat, hdop;
            char lonsign, latsign, *s = (char *)str;
            int status, sats;

            s = nextfield(s);	time = atof(s);
            s = nextfield(s);	lat = atof(s);
            s = nextfield(s);	latsign = *s;
            s = nextfield(s);	lon = atof(s);
            s = nextfield(s);	lonsign = *s;
            s = nextfield(s);	status = atoi(s);
            s = nextfield(s); sats = atoi(s);
            s = nextfield(s); hdop = atof(s);
            s = nextfield(s); altitude = atof(s);

            pos.lat = floor(lat / 100)
               + (lat - floor(lat / 100) * 100) / 60;
            pos.lon = floor(lon / 100)
               + (lon - floor(lon / 100) * 100) / 60;
            if ( latsign == 'S' ) {
               pos.lat *= -1.0;
            }
            if ( lonsign == 'W' ) {
               pos.lon *= -1.0;
            }
            break;
         }
      case 'T':
         {
            // assuming PCX5 format
            char tm[20], dt[20];
            sscanf(str, "T %lf %lf %s %s %lf", &pos.lat, &pos.lon,
                  dt, tm, &altitude);
            time = tmstr2double(tm);
            break;
         }
      case ' ':
      case '-':
      case '0':
      case '1':
      case '2':
      case '3':
      case '4':
      case '5':
      case '6':
      case '7':
      case '8':
      case '9':
         {
            // assuming gpsdrive format
            char t[5][20];
            sscanf(str, "%lf %lf %lf %s %s %s %s %s",
                  &pos.lat, &pos.lon, &altitude,
                  t[0], t[1], t[2], t[3], t[4]);
            for ( int i = 0; i < 5; ++i ) {
               if ( strchr(t[i], ':') ) {
                  // looking for time
                  time = tmstr2double(t[i]);
               }
            }
            break;
         }
      default:
         qWarning(tr("unknown trackpoint format"));
         break;
   }
}

/*
 * create trackpoint from real values
 */
TrackPoint::TrackPoint(QString tim, double lat, double lon, double alt)
{
   time = tmstr2double((char *)tim.latin1());
   pos.lat = lat;
   pos.lon = lon;
   altitude = alt;
}

/*
 * create NMEA GGA message from the trackpoint
 */
QString TrackPoint::toNMEA()
{
   // latitude
   double lat = fabs(pos.lat);
   char tsign = ( pos.lat > 0 ) ? 'N' : 'S';
   double tdeg = floor(lat);
   double tmin = (lat-tdeg)*60.0;

   // longitude
   double lon = fabs(pos.lon);
   char nsign = ( pos.lon > 0 ) ? 'E' : 'W';
   double ndeg = floor(lon);
   double nmin = (lon - ndeg) * 60.0;

   QString nmea;
   nmea.sprintf(
         "$GPGGA,%010.3f,%02d%07.4f,%c,%02d%07.4f,%c,1,0,0,%d,M,,,,0000",
         time, (int)tdeg, tmin, tsign,
         (int)ndeg, nmin, nsign, (int)altitude);
   checksumNMEA(&nmea);

   return nmea;
}

/*
 * create Garmin PCX5 message for the trackpoint
 */
QString TrackPoint::toPCX5()
{
   char tm[20];
   tmdouble2str(time, tm);

   // TODO: date
   QString pcx;
   pcx.sprintf(
         "T %+09.6f %+09.6f %s %s %4d\n",
         pos.lat, pos.lon, "00-JAN-00", tm, (int)altitude);

   return pcx;
}

/*
 * create gpsdrive trackpoint
 */
QString TrackPoint::toDrive()
{
   char tm[20];
   tmdouble2str(time,tm);

   // TODO: date
   QString drive;
   drive.sprintf(
         "%9.6f %9.6f %4d %s\n",
         pos.lat, pos.lon, (int)altitude, tm);

   return drive;
}


/*
 * return distance from given point in a strange metric (degree based)
 */
double TrackPoint::dist(Position & p)
{
   return fabs(pos.lat - p.lat)
      + fabs(pos.lon - p.lon);
}

/*
 * return time difference from given point in seconds
 */
double TrackPoint::timediff(const QString & tim)
{
//   int h, m, s;
//   sscanf(tim.latin1(), "%d:%d:%d", &h, &m, &s);
   return fabs(time - tmstr2double(tim));
}

/*********************************************************************
 * TRACK constructor - set default values, create widgets
 *********************************************************************/

void Track::placeSelected(int ind)	
{
   if ( ind ) {
      Place *place = places->at(ind);
      commMLE->setText(place->comment);
   }
}

void Track::delPlace()
{
   int ind = mapLatLonCB->currentItem();
   if (ind) {
      mapLatLonCB->removeItem(ind);
      commMLE->setText("");
      mapLatLonCB->setCurrentItem(0);

      places->remove(ind);
      places->writePlaces(trackOptions.trackPathStr + "/places.txt");

      if (placesOptions->showPlaces)
	  	   emit waypointsChanged();
   }
}

void	Track::updateConfig() 
{
   tLE->setText(trackOptions.trackPathStr);
   dLE->setText(QString::number(trackOptions.updt_freq));
   lMenuB->select(trackOptions.track_thick - 1);
   placesTB->setChecked(placesOptions->showPlaces);
   textSizeSB->setValue(placesOptions->placesTextSize);
   // update Places
   updatePlaces();
   // update track lists
   updateFileList();
}

Track::Track(Qpegps * appl, PlacesOptions *placesOpts, 
             QWidget * parent, const char * name, WFlags f)
   : QScrollView(parent, name, f), placesOptions(placesOpts), 
   application(appl), wDo(false), rDo(false)
{
   logdir = new QDir();
   logdir->setNameFilter("[^.]*");

   setHScrollBarMode(AlwaysOff);
   setVScrollBarMode(Auto);
   QVBox * mainBox = new QVBox(this);
   addChild(mainBox);

   setResizePolicy(AutoOneFit);

   QHBox * hBox = new QHBox(mainBox);
   QVGroupBox * PlaceGB = new QVGroupBox(tr("Places"), hBox);
   hBox = new QHBox(PlaceGB);
   mapLatLonCB = new QComboBox(hBox);
   connect( mapLatLonCB, SIGNAL(activated(int)),
         this, SLOT(placeSelected(int)) );
   QPushButton * QDelButt = new QPushButton("Delete", hBox);
   connect(QDelButt, SIGNAL(pressed()), SLOT(delPlace()));

   hBox = new QHBox(PlaceGB);

   commMLE = new QMultiLineEdit(hBox);
   commMLE->setWordWrap(QMultiLineEdit::WidgetWidth);
   commMLE->setWrapPolicy(QMultiLineEdit::Anywhere);
   commMLE->setReadOnly(TRUE);
   commMLE->setFixedVisibleLines(2);

   // Show places
   hBox = new QHBox(PlaceGB);
   placesTB = new QCheckBox(hBox);
   placesTB->setText(tr("Show places"));
   placesTB->setChecked(placesOptions->showPlaces);
   QLabel * textSizeL = new QLabel(tr("Text Size"), hBox);
   textSizeL->setAlignment(AlignRight | AlignVCenter);
   textSizeSB = new QSpinBox(4, 30, 1, hBox, "Text Size");
   textSizeSB->setValue(placesOptions->placesTextSize);

   connect(placesTB, SIGNAL(toggled(bool)), 
         SLOT(setShowPlacesTB(bool)));
   connect( textSizeSB , SIGNAL(valueChanged(int)),
         SLOT(setPlacesTextSize(int)) );

   (void)new QLabel(
         tr(	" - TRACKLOG is saved when unchecking write checkbox\n"
            " - (re)select map to display track in Info"), mainBox);

   // create field for track directory
   QHBox * tBox = new QHBox(mainBox);
//   tBox->setMargin(2);
   (void)new QLabel(tr("Track dir: "), tBox);
   tLE = new QLineEdit(tBox);
   QPushButton * tButton = new QPushButton(tr("search"), tBox);
   tLE->setText(trackOptions.trackPathStr);
   connect(tButton, SIGNAL(pressed()), SLOT(setTrackPath()));
   connect(tLE, SIGNAL(returnPressed()), SLOT(tLEChanged()));

   // create checkboxes and comboboxes for tracklog files
   QHBox * wBox = new QHBox(mainBox);
//   wBox->setMargin(2);
   QCheckBox * wCB = new QCheckBox(wBox);
//   wBox->setMargin(2);
   (void)new QLabel(tr("write "), wBox);
   wLog = new QComboBox(true, wBox, tr("write_log_filename"));
   connect(wCB, SIGNAL(toggled(bool)), SLOT(setWriteCB(bool)));

   QHBox * rBox = new QHBox(mainBox);
//   rBox->setMargin(2);
   QCheckBox * rCB = new QCheckBox(rBox);
   (void)new QLabel(tr("read  "), rBox);
   rLog = new QComboBox(true, rBox, tr("read_log_filename"));
   connect(rCB, SIGNAL(toggled(bool)), SLOT(setReadCB(bool)));
   connect(rLog, SIGNAL(activated(const QString &)),
         SLOT(setReadName(const QString &)));

   updateFileList();

   // minimal time difference between 2 positions
   QHBox * dBox = new QHBox(mainBox);
//   dBox->setMargin(2);
   (void)new QLabel(tr("min time difference [s]    "), dBox);
   dLE = new QLineEdit(dBox);
   QString buf;
   buf.sprintf("%d", trackOptions.updt_freq);
   dLE->setText(buf);
   connect(dLE, SIGNAL(returnPressed()), SLOT(dLEChanged()));

#ifndef DESKTOP
   // track line thickness
   QStringList thickList;
   thickList << "1" << "2" << "3" << "4" << "5";
   QHBox * lBox = new QHBox(mainBox);
//   lBox->setMargin(2);
   (void)new QLabel(tr("line thickness"), lBox);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -