📄 gpslib.cpp
字号:
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <qmessagebox.h>
#include "gpslib.h"
int verbose; // defining instance
// WHY THE BIZARRE STYLE OF DECLARATIONS IN THIS FILE?
// Because it was originally a DLL for Visual Basic and works.
// Minimum changes only have been made, but changes there are.
// Following functions implement various globals and other things
// When processing a logfile, scale parameters to fit
struct vals{
double LongMax, LongMin, LatMax, LatMin;
// No idea what MinTime & MaxTime were ever supposed to do!
// long MinTime, MaxTime;
// getline uses these globals
double lat, longit;
double utctime; // This is typically measured to hundredths of a second ...
}rdvals, wvals; // rdvals used when reading, wvals when writing
// wvals is not currently (may never be) used
FILE *logfp; // Used when reading
int openlogfile(const char *cp, bool forwriting){
if(logfp)
fclose(logfp);
logfp = fopen(cp, forwriting ? "ab" : "rb");
return logfp != 0;
printf("Logfile opened for reading\n");
}
// write a newline-terminatd string to the logfile if open
void putlogfpstring(const char *cp){
if(logfp)fprintf(logfp, "%s\n", cp);
}
int closelogfile(){
if(logfp){
fclose(logfp);
logfp = 0;
return 1;
}
return 0;
}
int getline();
int getscale(double *minlat, double *maxlat, double *minlong, double *maxlong){
if(logfp == 0)
return 0;
int first = 1;
while(getline()){
if(first){
rdvals.LatMax = rdvals.LatMin = rdvals.lat;
rdvals.LongMax = rdvals.LongMin = rdvals.longit;
// rdvals.MinTime = rdvals.MaxTime = rdvals.ms;
first = 0;
}else{
// if(rdvals.ms < rdvals.MinTime) rdvals.MinTime = rdvals.ms;
// if(rdvals.ms > rdvals.MaxTime) rdvals.MaxTime = rdvals.ms;
if(rdvals.lat < rdvals.LatMin) rdvals.LatMin = rdvals.lat;
if(rdvals.lat > rdvals.LatMax) rdvals.LatMax = rdvals.lat;
if(rdvals.longit < rdvals.LongMin) rdvals.LongMin = rdvals.longit;
if(rdvals.longit > rdvals.LongMax) rdvals.LongMax = rdvals.longit;
}
//printf ("Lat (deg) = %f, Long (deg) = %f\n", lat, longit);
// getchar();
}
*minlat = rdvals.LatMin;
*maxlat = rdvals.LatMax;
*minlong = rdvals.LongMin;
*maxlong = rdvals.LongMax;
rewind(logfp);
return 1;
}
int convert(const char *, vals *);
int getline(){
char rbuff[512];
long count=0;
int rval;
loop:
if ((rval = (fgets(rbuff, sizeof(rbuff), logfp) != 0)) != 0){
count++;
if(!isdigit(rbuff[0]))
goto loop;
convert(rbuff, &rdvals);
}
return rval;
}
// convert n chars to int
int rdint(const char *&cpr, int ndigs){
int result = 0;
while(ndigs-- && *cpr){
result = result*10 + *cpr++-'0';
}
return result;
}
// convert xx[x]nn.nnn to fractional degrees
double getlatlong(const char *&cpr, int ndigs){
int ipart = rdint(cpr, ndigs);
double fracdegs = strtod((char *)cpr, (char **)&cpr);
fracdegs = fracdegs/60+ipart;
// Strtod absorbs a trailing 'E' (sigh)
char c = cpr[-1];
if(c && tolower(c) == 'e')
cpr--;
return fracdegs;
}
double getlatitude(const char *&cpr){
double res = getlatlong(cpr, 2);
switch(tolower(*cpr++)){
case 'n': break;
case 's': res = -res; break;
default: return 1000;
}
return res;
}
double getlongitude(const char *&cpr){
double res = getlatlong(cpr, 3);
switch(tolower(*cpr++)){
case 'e': break;
case 'w': res = -res; break;
default: return 1000;
}
return res;
}
// convert
int convert(const char *rbuff, vals *vp){
const ncommas = 13;
const char *fields[ncommas];
fields[0] = rbuff;
for(int i = 1; i < ncommas; i++){
const char *cp = strchr(fields[i-1], ',');
if(cp == 0){
fprintf(stderr, "Convert: too few commas in %s", rbuff);
return 0;
}
fields[i] = cp+1;
// *cp = 0;
// printf("Field %d = %s\n", i, fields[i-1]);
}
// Now validate that it's all sensible characters
for(const char *cp = rbuff; *cp; cp++){
if(iscntrl(*cp) && *cp != '\r' && *cp != '\n'){
printf("convert: bad character 0x%x(%c) in %s\n", *cp, *cp, rbuff);
return 0;
}
}
// printf("read log line %s\n", rbuff);
/*
const char *thisf = fields[0]+8;
// collect hundredths of seconds
vp->ms = *thisf-- -'0';
vp->ms += (*thisf-- -'0')* 10;
thisf--;
vp->ms += (*thisf-- -'0')* 100;
vp->ms += (*thisf-- -'0')* 1000;
vp->ms += (*thisf-- -'0')* 6000l;
vp->ms += (*thisf-- -'0')* 60000l;
vp->ms += (*thisf-- -'0')* 360000l;
vp->ms += (*thisf-- -'0')*3600000l;
// long secs = vp->ms/100;
// printf("Seconds = %ld (%.2ld:%.2ld:%.2ld) ", ms, secs / 3600, secs % 3600 / 60, secs %60);
*/
const char *thisf = fields[0];
vp->utctime = rdint(thisf, 2)*60l*60l;
vp->utctime += rdint(thisf, 2)*60;
vp->utctime += strtod(thisf, 0);
thisf = fields[1];
vp->lat = getlatlong(thisf, 2);
if(*(fields[2]) == 'S'){
vp->lat = -vp->lat;
}
thisf = fields[3];
vp->longit = getlatlong(thisf, 3);
if(*(fields[4]) == 'W'){
vp->longit = -vp->longit;
}
return 1;
}
int getlogstr(char *latp){
char rbuff[512];
loop:
if (fgets(rbuff, sizeof(rbuff), logfp)){
if(!isdigit(rbuff[0]))
goto loop;
strcpy(latp, rbuff);
return strlen(rbuff);
}
return 0;
}
int rcvplotstr(const String &plotstr, double &latit, double &longit, double &utctime){
if(verbose)printf("Read GPS input %s\n", plotstr.cstring());
if(plotstr.left(7) != "$GPGGA,"){
return 0;
}
const char *cp = plotstr.cstring()+7;
if(verbose) printf("Received valid GPGGA string: %s\n", cp);
putlogfpstring(cp);
if(!convert(cp, &rdvals)){
printf("Couldn't convert GPGGA string: %s\n", cp);
return 0;
}
latit = rdvals.lat;
longit = rdvals.longit;
utctime = rdvals.utctime;
return 1;
}
int getlogll(double &latit, double &longit, double &utctime){
int rval = getline();
if(rval){
latit = rdvals.lat;
longit = rdvals.longit;
utctime = rdvals.utctime;
}else{
rewind(logfp);
}
return rval;
}
char ngrletters[] = "ABCDEFGHJKLMNOPQRSTUVWXYZ";
int glet2int(char c){
char *lp = strchr(ngrletters, toupper(c));
if(lp == 0)
return -1;
return int(lp-ngrletters);
}
FILE *lmfp;
int openlandmarkfile(const char *cp){
if(lmfp) fclose(lmfp);
lmfp = fopen(cp, "r");
return lmfp != 0;
}
int closelandmarkfile(){
if(!lmfp) return 0;
fclose(lmfp);
return 1;
}
int cvtngrstr(const char *ngrstr, long *eastres, long *northres, double *latres, double *longres){
const char *cp = ngrstr;
return _cvtngrstr(cp, eastres, northres, latres, longres);
}
int _cvtngrstr(const char * &cp, long *eastres, long *northres, double *latres, double *longres){
// Stuff that VB should have
// presume ngr
long north, east;
int lval = glet2int(*cp++);
if(lval < 0) return 0;
// flip to give useful base
lval = 21-lval;
if(lval < 0) return 0;
east = (4-lval%5)*500000l;
north = lval/5*500000l;
// printf("East %ld, north %ld\n", east, north);
if((lval = glet2int(*cp++)) < 0) return 0;
east += (lval%5)*100000l;
north += (4-lval/5)*100000l;
// printf("East %ld, north %ld\n", east, north);
if(*cp == ' ')cp++;
// allowable format is now nnn nnn, nnnn nnnn, nnnnnn, nnnnnnnn
// not strictly checked though
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -