Public Member Functions | Protected Member Functions
CoordReader Class Reference

Brief description of class still missing. More...

#include <CoordReader.h>

Inheritance diagram for CoordReader:
QGpCoreTools::ArgumentStdinReader

List of all members.

Public Member Functions

 CoordReader ()
bool hasInput () const
bool setOptions (int &argc, char **argv)
bool terminate ()
 ~CoordReader ()

Protected Member Functions

virtual bool parse (QTextStream &s)

Detailed Description

Brief description of class still missing.

Full description of class still missing


Constructor & Destructor Documentation

Description of constructor still missing

References TRACE.

    : ArgumentStdinReader()
{
  TRACE;
  _mode=None;
  _averageCount=0;
  _kml=0;
  _utmZone=0;
  _distanceStddev=0.01; // 1 cm
  _priorPrecision=5.0;  // 2 m
}

References TRACE.

{
  TRACE;
  delete _utmZone;
}

Member Function Documentation

bool CoordReader::hasInput ( ) const

References TRACE.

Referenced by main().

{
  TRACE;
  switch(_mode) {
  case Distance:
  case DistanceLookup:
  case DistanceGeo:
  case Azimuth:
  case AzimuthGeo:
  case FromGeo:
  case ToGeo:
  case FromDMS:
  case ToDMS:
  case FromDM:
  case ToDM:
  case ToUTM:
  case FromUTM:
  case ToKML:
    break;
  case FromKML:
  case GenerateCircle:
    return false;
  case Translate:
  case Rotate:
  case Localize:
  case Average:
  case Lookup:
  case TriangulateDistance:
  case TriangulateAzimuth:
  case FromDistances:
  case None:
    break;
  }
  return true;
}
bool CoordReader::parse ( QTextStream &  s) [protected, virtual]

Implements QGpCoreTools::ArgumentStdinReader.

References TapePositioningSystem::Triangulator::addDistance(), QGpCoreTools::GoogleEarthKML::Folder::addPlacemark(), QGpCoreTools::Point2D::azimuthTo(), QGpCoreTools::Angle::cos(), QGpCoreTools::LineParser::count(), QGpCoreTools::Point2D::degreesToDM(), QGpCoreTools::Point2D::degreesToDMS(), QGpCoreTools::Point::distanceTo(), QGpCoreTools::Point2D::DMSToDegrees(), QGpCoreTools::Point2D::DMToDegrees(), QGpCoreTools::GoogleEarthKML::document(), QGpCoreTools::endl(), QGpCoreTools::NamedPoint::fromString(), QGpCoreTools::Point::fromString(), QGpCoreTools::Point2D::geographicalAzimuthTo(), QGpCoreTools::Point2D::geographicalDistanceTo(), QGpCoreTools::Point2D::geographicalToRectangular(), QGpCoreTools::Point2D::geographicalToUtm(), QGpCoreTools::GoogleEarthKML::Document::mainFolder(), QGpCoreTools::NamedPoint::name(), QGpCoreTools::Point2D::rectangularToGeographical(), QGpCoreTools::Point2D::rotate(), QGpCoreTools::GoogleEarthKML::Placemark::setCoordinates(), QGpCoreTools::Angle::setDegreeAzimuth(), QGpCoreTools::NamedPoint::setName(), QGpCoreTools::GoogleEarthKML::Placemark::setName(), QGpCoreTools::Point2D::setX(), QGpCoreTools::Point2D::setY(), QGpCoreTools::Angle::sin(), sOut(), QGpCoreTools::LineParser::toDouble(), QGpCoreTools::LineParser::toString(), QGpCoreTools::NamedPoint::toString(), QGpCoreTools::tr(), TRACE, QGpCoreTools::Point::translate(), QGpCoreTools::Point2D::utmToGeographical(), QGpCoreTools::Point2D::utmZoneIndex(), QGpCoreTools::Point2D::x(), and QGpCoreTools::Point2D::y().

{
  TRACE;
  QTextStream sOut(stdout);

  QString buf;
  bool ok=true;
  while(!s.atEnd()) {
    buf=s.readLine();
    if(!buf.isEmpty() && buf[0]!='\n' && buf[0]!='#') {
      switch(_mode) {
      case Distance: {
          LineParser par(buf);
          if(par.count()==6) {
            Point p1(par.toDouble(0,ok), par.toDouble(1,ok), par.toDouble(2,ok));
            Point p2(par.toDouble(3,ok), par.toDouble(4,ok), par.toDouble(5,ok));
            sOut << p1.distanceTo(p2) << endl;
          } else {
            Point p1(par.toDouble(0,ok), par.toDouble(1,ok));
            Point p2(par.toDouble(2,ok), par.toDouble(3,ok));
            sOut << p1.distanceTo(p2) << endl;
          }
        }
        break;
      case DistanceLookup: {
          LineParser par(buf);
          QString name1=par.toString(0,ok);
          QString name2=par.toString(1,ok);
          QMap<QString, Point>::iterator it1=_refPoints.find(name1);
          if(it1==_refPoints.end()) {
            sOut << tr("Error unknown point name: %1").arg(name1) << endl;
            return true;
          }
          QMap<QString, Point>::iterator it2=_refPoints.find(name2);
          if(it2==_refPoints.end()) {
            sOut << tr("Error unknown point name: %1").arg(name2) << endl;
            return true;
          }
          Point p1=it1.value();
          Point p2=it2.value();
          double calcDist=p1.distanceTo(p2);
          if(par.count()==3) {
            double refDist=par.toDouble(2,ok);
            sOut << QString("%1 %2 %3 %4 %5 %6").arg(name1).arg(name2)
                    .arg(calcDist, 0, 'f', 2)
                    .arg(refDist, 0, 'f', 2)
                    .arg(refDist-calcDist, 0, 'f', 2)
                    .arg(100.0*(refDist-calcDist)/refDist, 0, 'f', 1) << endl;
          } else {
            sOut << QString("%1 %2 %3").arg(name1).arg(name2).arg(calcDist, 0, 'f', 2) << endl;
          }
        }
        break;
      case DistanceGeo: {
          LineParser par(buf);
          if(par.count()==6) {
            Point p1(par.toDouble(0,ok), par.toDouble(1,ok), par.toDouble(2,ok));
            Point p2(par.toDouble(3,ok), par.toDouble(4,ok), par.toDouble(5,ok));
            sOut << p1.geographicalDistanceTo(p2) << endl;
          } else {
            Point p1(par.toDouble(0,ok), par.toDouble(1,ok));
            Point p2(par.toDouble(2,ok), par.toDouble(3,ok));
            sOut << p1.geographicalDistanceTo(p2) << endl;
          }
        }
        break;
      case Azimuth: {
          LineParser par(buf);
          double az;
          if(par.count()==6) {
            Point p1(par.toDouble(0,ok), par.toDouble(1,ok), par.toDouble(2,ok));
            Point p2(par.toDouble(3,ok), par.toDouble(4,ok), par.toDouble(5,ok));
            az=p1.azimuthTo(p2);
          } else {
            Point p1(par.toDouble(0,ok), par.toDouble(1,ok));
            Point p2(par.toDouble(2,ok), par.toDouble(3,ok));
            az=p1.azimuthTo(p2);
          }
          sOut << Angle::mathToGeographic(az) << endl;
        }
        break;
      case AzimuthGeo: {
          LineParser par(buf);
          double az;
          if(par.count()==6) {
            Point p1(par.toDouble(0,ok), par.toDouble(1,ok), par.toDouble(2,ok));
            Point p2(par.toDouble(3,ok), par.toDouble(4,ok), par.toDouble(5,ok));
            az=p1.geographicalAzimuthTo(p2);
          } else {
            Point p1(par.toDouble(0,ok), par.toDouble(1,ok));
            Point p2(par.toDouble(2,ok), par.toDouble(3,ok));
            az=p1.geographicalAzimuthTo(p2);
          }
          sOut << Angle::radiansToDegrees(az) << endl;
        }
        break;
      case FromGeo: {
          NamedPoint longLat;
          ok=longLat.fromString(buf);
          if(!ok) {
            App::stream() << tr("Error parsing input: %1").arg(buf) << endl;
            return false;
          }
          longLat.geographicalToRectangular(_geoReference);
          sOut << " " << longLat.toString(20) << endl;
        }
        break;
      case ToGeo: {
          NamedPoint longLat;
          ok=longLat.fromString(buf);
          if(!ok) {
            App::stream() << tr("Error parsing input") << endl;
            return false;
          }
          longLat.rectangularToGeographical(_geoReference);
          sOut << longLat.toString(20) << endl;
        }
        break;
      case FromDMS: {
          NamedPoint longLat;
          ok=longLat.fromString(buf);
          if(!ok) {
            App::stream() << tr("Error parsing input: %1").arg(buf) << endl;
            return false;
          }
          longLat.DMSToDegrees();
          sOut << " " << longLat.toString(20) << endl;
        }
        break;
      case ToDMS: {
          NamedPoint longLat;
          ok=longLat.fromString(buf);
          if(!ok) {
            App::stream() << tr("Error parsing input") << endl;
            return false;
          }
          longLat.degreesToDMS();
          sOut << longLat.toString(20) << endl;
        }
        break;
      case FromDM: {
          NamedPoint longLat;
          ok=longLat.fromString(buf);
          if(!ok) {
            App::stream() << tr("Error parsing input: %1").arg(buf) << endl;
            return false;
          }
          longLat.DMToDegrees();
          sOut << " " << longLat.toString(20) << endl;
        }
        break;
      case ToDM: {
          NamedPoint longLat;
          ok=longLat.fromString(buf);
          if(!ok) {
            App::stream() << tr("Error parsing input") << endl;
            return false;
          }
          longLat.degreesToDM();
          sOut << longLat.toString(20) << endl;
        }
        break;
      case ToUTM: {
          NamedPoint longLat;
          ok=longLat.fromString(buf);
          if(!ok) {
            App::stream() << tr("Error parsing input") << endl;
            return false;
          }
          QPoint utmZone;
          if(_utmZone) {
            utmZone=*_utmZone;
          } else {
            utmZone=longLat.utmZoneIndex();
          }
          longLat.geographicalToUtm(&utmZone);
          sOut << Point2D::utmZone(utmZone) << " " << longLat.toString(20) << endl;
        }
        break;
      case FromUTM: {
          LineParser par(buf);
          bool ok=true;
          QString utmZoneName=par.toString(0, ok);
          if(!ok) {
            App::stream() << tr("Error parsing input, cannot read first column.") << endl;
            return false;
          }
          bool zoneOk;
          QPoint utmZone=Point2D::utmZone(utmZoneName, &zoneOk);
          QString pointString;
          if(zoneOk) {
            pointString=par.toString(1, par.count(), ok);
            if(!ok) {
              App::stream() << tr("Error parsing input, missong point coordinates.") << endl;
              return false;
            }
          } else {
            pointString=buf;
          }
          NamedPoint utmCoord;
          ok=utmCoord.fromString(pointString);
          if(!ok) {
            App::stream() << tr("Error parsing input") << endl;
            return false;
          }
          if(zoneOk) {
            utmCoord.utmToGeographical(utmZone);
          } else if(_utmZone){
            utmCoord.utmToGeographical(*_utmZone);
          } else {
            App::stream() << tr("Missing specification of UTM zone (stdin or argument, see -help)") << endl;
            return false;
          }
          sOut << utmCoord.toString(20) << endl;
        }
        break;
      case ToKML: {
          NamedPoint longLat;
          ok=longLat.fromString(buf);
          if(!ok) {
            App::stream() << tr("Error parsing input") << endl;
            return false;
          }
          GoogleEarthKML::Document& doc=_kml->document();
          GoogleEarthKML::Folder * f=doc.mainFolder();
          GoogleEarthKML::Placemark * p=new GoogleEarthKML::Placemark;
          p->setName(longLat.name());
          p->setCoordinates(longLat);
          f->addPlacemark(p);
        }
        break;
      case FromKML:
      case GenerateCircle:
        ASSERT(false);
        break;
      case Translate: {
          NamedPoint p;
          ok=p.fromString(buf);
          if(!ok) {
            App::stream() << tr("Error parsing input") << endl;
            return false;
          }
          p.translate(_translateVector);
          sOut << p.toString(20) << endl;
        }
        break;
      case Rotate: {
          NamedPoint p;
          ok=p.fromString(buf);
          if(!ok) {
            App::stream() << tr("Error parsing input") << endl;
            return false;
          }
          p.rotate(_angle);
          sOut << p.toString(20) << endl;
        }
        break;
      case Localize: {
          NamedPoint v, p;
          ok=v.fromString(buf);
          if(!ok) {
            App::stream() << tr("Error parsing input") << endl;
            return false;
          }
          Angle a;
          a.setDegreeAzimuth(v.y());
          p.setX(_cartReference.x()+v.x()*a.cos());
          p.setY(_cartReference.y()+v.x()*a.sin());
          p.setName(v.name());
          sOut << p.toString(20) << endl;
        }
        break;
      case Average: {
          Point p;
          ok=p.fromString(buf);
          if(!ok) {
            App::stream() << tr("Error parsing input") << endl;
            return false;
          }
          _average+=p;
          _averageCount++;
        }
        break;
      case Lookup: {
          QMap<QString, Point>::iterator it=_refPoints.find(buf);
          if(it==_refPoints.end()) {
            sOut << tr("Error unknown point name: %1").arg(buf) << endl;
            return false;
          }
          sOut << it.value().toString(20) << " " << it.key() << endl;
        }
        break;
      case TriangulateDistance: {
          LineParser par(buf);
          if(par.count()==2) {
            QString name=par.toString(0,ok);
            if(!ok) {
              App::stream() << tr("Error parsing input, missing reference point name.") << endl;
              return false;
            }
            QMap<QString, Point>::iterator it=_refPoints.find(name);
            if(it==_refPoints.end()) {
              App::stream() << tr("Error unknown point name: %1").arg(name) << endl;
              return false;
            }
            _circles.append(Circle(it.value().x(), it.value().y(), par.toDouble(1,ok)));
            if(!ok) {
              App::stream() << tr("Error parsing input, missing distance for point %1.").arg(name) << endl;
              return false;
            }
          } else {
            App::stream() << tr("Error parsing input, NAME DISTANCE expected") << endl;
            return false;
          }
        }
        break;
      case TriangulateAzimuth: {
          LineParser par(buf);
          if(par.count()==2) {
            QString name=par.toString(0,ok);
            if(!ok) {
              App::stream() << tr("Error parsing input, missing reference point name.") << endl;
              return false;
            }
            QMap<QString, Point>::iterator it=_refPoints.find(name);
            if(it==_refPoints.end()) {
              App::stream() << tr("Error unknown point name: %1").arg(name) << endl;
              return false;
            }
            double az=par.toDouble(1,ok)*M_PI/180.0;
            _lines.append(Line2D(it.value().x(), it.value().y(), az));
            if(!ok) {
              App::stream() << tr("Error parsing input, missing azimuth for point %1.").arg(name) << endl;
              return false;
            }
          } else {
            App::stream() << tr("Error parsing input, NAME AZIMUTH expected") << endl;
            return false;
          }
        }
        break;
      case FromDistances: {
          LineParser par(buf);
          if(par.count()==3) {
            QString name1=par.toString(0,ok);
            if(!ok) {
              App::stream() << tr("Error parsing input, missing first point name.") << endl;
              return false;
            }
            QString name2=par.toString(1,ok);
            if(!ok) {
              App::stream() << tr("Error parsing input, missing second point name.") << endl;
              return false;
            }
            double d=par.toDouble(2,ok);
            if(!ok) {
              App::stream() << tr("Error parsing input, missing distance for couple %1-%2.").arg(name1).arg(name2) << endl;
              return false;
            }
            if(name1==name2) {
              App::stream() << tr("Error parsing input, name of points must differ within the same couple ('%1').").arg(name1) << endl;
              return false;
            }
            _fromDistanceFactory.addDistance(name1, name2, d);
          } else {
            App::stream() << tr("Error parsing input, NAME1 NAME2 DISTANCE expected") << endl;
            return false;
          }
        }
        break;
      case None:
        App::stream() << tr("gpcoord: no operation defined, see -h") << endl;
        return false;
      }
    }
  }
  return true;
}
bool CoordReader::setOptions ( int &  argc,
char **  argv 
)

References QGpCoreTools::Angle::cos(), QGpCoreTools::LineParser::count(), QGpCoreTools::GoogleEarthKML::document(), QGpCoreTools::endl(), QGpCoreTools::GoogleEarthKML::Document::mainFolder(), QGpCoreTools::Angle::setDegreeAzimuth(), QGpCoreTools::Angle::setDegrees(), QGpCoreTools::NamedPoint::setName(), QGpCoreTools::GoogleEarthKML::Folder::setName(), QGpCoreTools::GoogleEarthKML::Document::setName(), QGpCoreTools::LineParser::setString(), QGpCoreTools::Point2D::setX(), QGpCoreTools::Point2D::setY(), QGpCoreTools::Angle::sin(), sOut(), QGpCoreTools::LineParser::toDouble(), QGpCoreTools::LineParser::toString(), QGpCoreTools::NamedPoint::toString(), QGpCoreTools::tr(), and TRACE.

Referenced by main().

{
  TRACE;
  QString coordFile;
  int i, j=1;
  for(i=1; i<argc; i++) {
    QByteArray arg=argv[i];
    if(arg[0]=='-') {
      if(arg=="-distance") {
        _mode=Distance;
      } else if(arg=="-distance-lookup") {
        _mode=DistanceLookup;
        CoreApplication::checkOptionArg(i, argc, argv);
        coordFile=argv[i];
      } else if(arg=="-distance-geo") {
        _mode=DistanceGeo;
      } else if(arg=="-azimuth") {
        _mode=Azimuth;
      } else if(arg=="-azimuth-geo") {
        _mode=AzimuthGeo;
      } else if(arg=="-from-dms") {
        _mode=FromDMS;
      } else if(arg=="-to-dms") {
        _mode=ToDMS;
      } else if(arg=="-from-dm") {
        _mode=FromDM;
      } else if(arg=="-to-dm") {
        _mode=ToDM;
      } else if(arg=="-from-geo") {
        _mode=FromGeo;
      } else if(arg=="-to-geo") {
        _mode=ToGeo;
      } else if(arg=="-to-utm") {
        if(CoreApplication::checkOptionArg(i, argc, argv, false)) {
          bool ok;
          delete _utmZone;
          _utmZone=new QPoint(Point2D::utmZone(argv[i], &ok));
          if(!ok) {
            App::stream() << tr("gpcoord: bad utm zone, %1").arg(argv[i]) << endl;
            return false;
          }
        }
        _mode=ToUTM;
      } else if(arg=="-from-utm") {
        if(CoreApplication::checkOptionArg(i, argc, argv, false)) {
          bool ok;
          delete _utmZone;
          _utmZone=new QPoint(Point2D::utmZone(argv[i], &ok));
          if(!ok) {
            App::stream() << tr("gpcoord: bad utm zone, %1").arg(argv[i]) << endl;
            return false;
          }
        }
        _mode=FromUTM;
      } else if(arg=="-to-kml") {
        CoreApplication::checkOptionArg(i, argc, argv);
        _kmlFileName=argv[i];
        _mode=ToKML;
        delete _kml;
        _kml=new GoogleEarthKML;
        GoogleEarthKML::Document& doc=_kml->document();
        QFileInfo fi(_kmlFileName);
        doc.setName(fi.baseName());
        GoogleEarthKML::Folder * f=doc.mainFolder();
        f->setName(fi.baseName());
      } else if(arg=="-from-kml") {
        CoreApplication::checkOptionArg(i, argc, argv);
        _kmlFileName=argv[i];
        _mode=FromKML;
      } else if(arg=="-reference") {
        CoreApplication::checkOptionArg(i, argc, argv);
        _geoReference.setX(atof(argv[i]));
        CoreApplication::checkOptionArg(i, argc, argv);
        _geoReference.setY(atof(argv[i]));
      } else if(arg=="-translate") {
        _mode=Translate;
        CoreApplication::checkOptionArg(i, argc, argv);
        _translateVector.setX(atof(argv[i]));
        CoreApplication::checkOptionArg(i, argc, argv);
        _translateVector.setY(atof(argv[i]));
      } else if(arg=="-rotate") {
        CoreApplication::checkOptionArg(i, argc, argv);
        _mode=Rotate;
        // Input is counted clockwize while Angle uses math angles
        _angle.setDegrees(-atof(argv[i]));
      } else if(arg=="-average") {
        _mode=Average;
      } else if(arg=="-localize") {
        _mode=Localize;
        CoreApplication::checkOptionArg(i, argc, argv);
        _cartReference.setX(atof(argv[i]));
        CoreApplication::checkOptionArg(i, argc, argv);
        _cartReference.setY(atof(argv[i]));
      } else if(arg=="-lookup") {
        _mode=Lookup;
        CoreApplication::checkOptionArg(i, argc, argv);
        coordFile=argv[i];
      } else if(arg=="-trig-dist") {
        _mode=TriangulateDistance;
        CoreApplication::checkOptionArg(i, argc, argv);
        coordFile=argv[i];
      } else if(arg=="-trig-az") {
        _mode=TriangulateAzimuth;
        CoreApplication::checkOptionArg(i, argc, argv);
        coordFile=argv[i];
      } else if(arg=="-circle") {
        _mode=GenerateCircle;
        CoreApplication::checkOptionArg(i, argc, argv);
        double radius=atof(argv[i]);
        CoreApplication::checkOptionArg(i, argc, argv);
        int n=atoi(argv[i]);
        int i0=0;
        if(CoreApplication::checkOptionArg(i, argc, argv, false)) {
          i0=atoi(argv[i]);
        }
        QTextStream sOut(stdout);
        Angle a;
        NamedPoint p;
        p.setName(QString("S%1").arg(i0, 3, 10, QChar('0')));
        sOut << p.toString(20) << endl;
        for(int i=0; i<n; i++) {
          a.setDegreeAzimuth(i*360.0/n);
          p.setX(radius*a.cos());
          p.setY(radius*a.sin());
          p.setName(QString("S%1").arg(i0+i+1, 3, 10, QChar('0')));
          sOut << p.toString(20) << endl;
        }
      } else if(arg=="-from-distances") {
        _mode=FromDistances;
      } else if(arg=="-stddev") {
        CoreApplication::checkOptionArg(i, argc, argv);
        _distanceStddev=atof(argv[i]);
      } else if(arg=="-origin") {
        CoreApplication::checkOptionArg(i, argc, argv);
        _origin=argv[i];
      } else if(arg=="-north") {
        CoreApplication::checkOptionArg(i, argc, argv);
        _north=argv[i];
      } else if(arg=="-eastward") {
        CoreApplication::checkOptionArg(i, argc, argv);
        _eastward=argv[i];
      } else if(arg=="-prior-positions") {
        CoreApplication::checkOptionArg(i, argc, argv);
        coordFile=argv[i];
      } else if(arg=="-prior-precision") {
        CoreApplication::checkOptionArg(i, argc, argv);
        _priorPrecision=atof(argv[i]);
      } else {
        App::stream() << tr("gpcoord: bad option %1, see -help").arg(argv[i]) << endl;
        return false;
      }
    } else {
      argv[j++]=argv[i];
    }
  }
  if(j < argc) {
    argv[j]=0;
    argc=j;
  }
  if(!coordFile.isEmpty()) {
    QFile fCoord(coordFile);
    if(!fCoord.open(QIODevice::ReadOnly) ) {
      App::stream() << tr("gpcoord: cannot read file %1.").arg(coordFile) << endl;
      return false;
    }
    QTextStream sCoord(&fCoord);
    LineParser p;
    bool ok=true;
    int iLine=0;
    while( ! sCoord.atEnd()) {
      QString l=sCoord.readLine();
      iLine++;
      if(!l.isEmpty() && l[0]!='#') {
        p.setString(l);
        double x, y, z;
        QString name;
        x=p.toDouble(0, ok);
        y=p.toDouble(1, ok);
        if(p.count()==4) {
          z=p.toDouble(2, ok);
          name=p.toString(3, ok);
        } else {
          z=0.0;
          name=p.toString(2, ok);
        }
        if(!ok) {
          App::stream() << tr("gpcoord: error reading file %1 at line %2").arg(coordFile).arg(iLine) << endl;
          return false;
        }
        _refPoints.insert(name, Point(x, y, z));
      }
    }
  }
  if(_mode==FromDistances) {
    if(_origin.isEmpty()) {
      App::stream() << tr("gpcoord: missing option '-origin'") << endl;
      return false;
    }
    if(_north.isEmpty()) {
      App::stream() << tr("gpcoord: missing option '-north'") << endl;
      return false;
    }
    if(_eastward.isEmpty()) {
      App::stream() << tr("gpcoord: missing option '-eastward'") << endl;
      return false;
    }
    if(_origin==_north) {
      App::stream() << tr("gpcoord: origin and north cannot refer to the same point") << endl;
      return false;
    }
    if(_origin==_eastward) {
      App::stream() << tr("gpcoord: origin and eastward cannot refer to the same point") << endl;
      return false;
    }
    if(_north==_eastward) {
      App::stream() << tr("gpcoord: north and eastward cannot refer to the same point") << endl;
      return false;
    }
  }
  return true;
}

References TapePositioningSystem::Triangulator::aggregate(), TapePositioningSystem::Triangulator::covariance(), QGpCoreTools::GoogleEarthKML::document(), QGpCoreTools::endl(), QGpCoreTools::Covariance::mean(), TapePositioningSystem::Node::name(), TapePositioningSystem::Triangulator::node(), TapePositioningSystem::Triangulator::nodes(), QGpCoreTools::GoogleEarthKML::Document::points(), QGpCoreTools::GoogleEarthKML::save(), TapePositioningSystem::Triangulator::setCoordinates(), TapePositioningSystem::Triangulator::setPriorCoordinates(), TapePositioningSystem::Triangulator::solutions(), sOut(), QGpCoreTools::sqrt(), QGpCoreTools::Covariance::stddev2D(), str, QGpCoreTools::Ellipse::toString(), QGpCoreTools::Point::toString(), QGpCoreTools::tr(), QGpCoreTools::Point2D::x(), QGpCoreTools::XMLHeader::xml_restoreFile(), and QGpCoreTools::Point2D::y().

Referenced by main().

{
  QTextStream sOut(stdout);
  switch(_mode) {
  case Distance:
  case DistanceLookup:
  case DistanceGeo:
  case Azimuth:
  case AzimuthGeo:
  case FromGeo:
  case ToGeo:
  case FromDMS:
  case ToDMS:
  case FromDM:
  case ToDM:
  case ToUTM:
  case FromUTM:
  case Translate:
  case Rotate:
  case Localize:
  case Lookup:
  case GenerateCircle:
  case None:
    break;
  case TriangulateDistance:
    if(_circles.count()==2) {
      QVector<Point2D> p=_circles.first().intersect(_circles.last());
      for(QVector<Point2D>::iterator it=p.begin(); it!=p.end(); it++) {
        sOut << it->x() << " " << it->y() << endl;
      }
    } else if(_circles.count()>=3) {
      bool ok;
      int n=0;
      Point2D pAver(0, 0), pDev(0, 0);
      for(int i=0; i<_circles.count(); i++) {
        for(int j=i+1; j<_circles.count(); j++) {
          // Used to discriminate between the classical
          // two solutions of the intersection of two circles.
          int disc;
          if(j+1<_circles.count()) {
            disc=j+1;
          } else if(i+1<j) {
            disc=i+1;
          } else {
            disc=i-1;
          }
          Point2D p=_circles.at(i).intersect(_circles.at(j), ok, _circles.at(disc));
          if(ok) {
            pAver+=p;
            pDev+=p*p;
            n++;
          }
        }
      }
      if(n>0) {
        pAver/=n;
        pDev/=n;
        pDev-=pAver * pAver;
      } else {
        App::stream() << tr("No intersection") << endl;
        return false;
      }
      sOut << pAver.x() << " " << pAver.y() << " "
           << sqrt(pDev.x()) << " " << sqrt(pDev.y()) << endl;
    } else {
      App::stream() << tr("At least two distances are required to triangulate.") << endl;
      return false;
    }
    break;
  case TriangulateAzimuth:
    if(_lines.count()>=2) {
      bool ok;
      int n=0;
      Point2D pAver(0, 0), pDev(0, 0);
      for(int i=0; i<_lines.count(); i++) {
        for(int j=i+1; j<_lines.count(); j++) {
          Point2D p=_lines.at(i).intersect(_lines.at(j), ok);
          if(ok) {
            pAver+=p;
            pDev+=p*p;
            n++;
          }
        }
      }
      if(n>0) {
        pAver/=n;
        pDev/=n;
        pDev-=pAver * pAver;
      } else {
        App::stream() << tr("No intersection") << endl;
        return false;
      }
      sOut << pAver.x() << " " << pAver.y() << " "
           << sqrt(pDev.x()) << " " << sqrt(pDev.y()) << endl;
    } else {
      App::stream() << tr("At least two azimuth are required to triangulate.") << endl;
      return false;
    }
    break;
  case Average:
    if(_averageCount>0) {
      _average/=(double)_averageCount;
      sOut << _average.toString(20) << endl;
    } else {
      App::stream() << tr("No point available to calculate average") << endl;
      return false;
    }
    break;
  case ToKML:
    _kml->save(_kmlFileName);
    delete _kml;
    break;
  case FromKML: {
      GoogleEarthKML kml;
      XMLHeader hdr(&kml);
      if(hdr.xml_restoreFile(_kmlFileName, 0, XMLClass::XmlFile)!=XMLClass::NoError) {
        App::stream() << tr("Error while reading file %1").arg(_kmlFileName) << endl;
        return false;
      }
      QList<NamedPoint> list=kml.document().points();
      QString str;
      for(QList<NamedPoint>::iterator it=list.begin(); it!=list.end(); it++) {
        sOut << (*it).toString(20) << endl;
      }
    }
    break;
  case FromDistances: {
      Node * origin=_fromDistanceFactory.node(_origin);
      if(!origin) {
        App::stream() << tr("gpcoord: origin node '%1' does not exist").arg(_origin) << endl;
        return false;
      }
      Node * north=_fromDistanceFactory.node(_north);
      if(!north) {
        App::stream() << tr("gpcoord: north node '%1' does not exist").arg(_north) << endl;
        return false;
      }
      Node * eastward=_fromDistanceFactory.node(_eastward);
      if(!eastward) {
        App::stream() << tr("gpcoord: eastward node '%1' does not exist").arg(_eastward) << endl;
        return false;
      }
      _fromDistanceFactory.aggregate(_distanceStddev);
      _fromDistanceFactory.setCoordinates(origin, north, eastward);
      if(!_refPoints.isEmpty() ) {
        _fromDistanceFactory.setPriorCoordinates(_refPoints, _priorPrecision);
      }
      QList<Node *> nodes=_fromDistanceFactory.nodes();
      for(QList<Node *>::iterator it=nodes.begin(); it!=nodes.end(); it++) {
        Node * n=*it;
        QSet<Point2D> coordinates=_fromDistanceFactory.solutions(n->name());
        for(QSet<Point2D>::iterator its=coordinates.begin(); its!=coordinates.end(); its++) {
          sOut << "RAW " << its->toString() << " 0 " << n->name() << endl;
        }
        Covariance cov=_fromDistanceFactory.covariance(n->name());
        sOut << "ELLIPSE " << cov.stddev2D().toString() << endl;
        sOut << "MEAN " << cov.mean(0) << " " << cov.mean(1) << " 0 " <<  n->name() << endl;
      }
    }
    break;
  }
  return true;
}

The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines