00001
00002
00003
00004
00005
00006
00007 #include "CurveConnectAs.h"
00008 #include "Document.h"
00009 #include "EngaugeAssert.h"
00010 #include "ExportFileRelations.h"
00011 #include "ExportLayoutFunctions.h"
00012 #include "ExportOrdinalsSmooth.h"
00013 #include "ExportOrdinalsStraight.h"
00014 #include "FormatCoordsUnits.h"
00015 #include "Logger.h"
00016 #include <qdebug.h>
00017 #include <qmath.h>
00018 #include <QTextStream>
00019 #include <QVector>
00020 #include "Spline.h"
00021 #include "SplinePair.h"
00022 #include "Transformation.h"
00023 #include <vector>
00024
00025 using namespace std;
00026
00027 const int COLUMNS_PER_CURVE = 2;
00028
00029 ExportFileRelations::ExportFileRelations()
00030 {
00031 }
00032
00033 void ExportFileRelations::exportAllPerLineXThetaValuesMerged (const DocumentModelExportFormat &modelExportOverride,
00034 const Document &document,
00035 const MainWindowModel &modelMainWindow,
00036 const QStringList &curvesIncluded,
00037 const QString &delimiter,
00038 const Transformation &transformation,
00039 QTextStream &str) const
00040 {
00041 LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::exportAllPerLineXThetaValuesMerged";
00042
00043 int curveCount = curvesIncluded.count();
00044 int maxColumnSize = maxColumnSizeAllocation (modelExportOverride,
00045 document,
00046 transformation,
00047 curvesIncluded);
00048
00049
00050 if (maxColumnSize > 0) {
00051
00052 QVector<QVector<QString*> > xThetaYRadiusValues (COLUMNS_PER_CURVE * curveCount, QVector<QString*> (maxColumnSize));
00053 initializeXThetaYRadiusValues (curvesIncluded,
00054 xThetaYRadiusValues);
00055 loadXThetaYRadiusValues (modelExportOverride,
00056 document,
00057 modelMainWindow,
00058 curvesIncluded,
00059 transformation,
00060 xThetaYRadiusValues);
00061 outputXThetaYRadiusValues (modelExportOverride,
00062 curvesIncluded,
00063 xThetaYRadiusValues,
00064 delimiter,
00065 str);
00066 destroy2DArray (xThetaYRadiusValues);
00067 }
00068 }
00069
00070 void ExportFileRelations::exportOnePerLineXThetaValuesMerged (const DocumentModelExportFormat &modelExportOverride,
00071 const Document &document,
00072 const MainWindowModel &modelMainWindow,
00073 const QStringList &curvesIncluded,
00074 const QString &delimiter,
00075 const Transformation &transformation,
00076 QTextStream &str) const
00077 {
00078 LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::exportOnePerLineXThetaValuesMerged";
00079
00080 QStringList::const_iterator itr;
00081 for (itr = curvesIncluded.begin(); itr != curvesIncluded.end(); itr++) {
00082
00083 QString curveIncluded = *itr;
00084
00085 exportAllPerLineXThetaValuesMerged (modelExportOverride,
00086 document,
00087 modelMainWindow,
00088 QStringList (curveIncluded),
00089 delimiter,
00090 transformation,
00091 str);
00092 }
00093 }
00094
00095 void ExportFileRelations::exportToFile (const DocumentModelExportFormat &modelExportOverride,
00096 const Document &document,
00097 const MainWindowModel &modelMainWindow,
00098 const Transformation &transformation,
00099 QTextStream &str) const
00100 {
00101 LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::exportToFile";
00102
00103
00104 QStringList curvesIncluded = curvesToInclude (modelExportOverride,
00105 document,
00106 document.curvesGraphsNames(),
00107 CONNECT_AS_RELATION_SMOOTH,
00108 CONNECT_AS_RELATION_STRAIGHT);
00109
00110
00111 const QString delimiter = exportDelimiterToText (modelExportOverride.delimiter());
00112
00113
00114 if (modelExportOverride.layoutFunctions() == EXPORT_LAYOUT_ALL_PER_LINE) {
00115 exportAllPerLineXThetaValuesMerged (modelExportOverride,
00116 document,
00117 modelMainWindow,
00118 curvesIncluded,
00119 delimiter,
00120 transformation,
00121 str);
00122 } else {
00123 exportOnePerLineXThetaValuesMerged (modelExportOverride,
00124 document,
00125 modelMainWindow,
00126 curvesIncluded,
00127 delimiter,
00128 transformation,
00129 str);
00130 }
00131 }
00132
00133 void ExportFileRelations::initializeXThetaYRadiusValues (const QStringList &curvesIncluded,
00134 QVector<QVector<QString*> > &xThetaYRadiusValues) const
00135 {
00136 LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::initializeXThetaYRadiusValues";
00137
00138
00139 int curveCount = curvesIncluded.count();
00140 int xThetaCount = xThetaYRadiusValues [0].count();
00141 for (int row = 0; row < xThetaCount; row++) {
00142 for (int col = 0; col < COLUMNS_PER_CURVE * curveCount; col++) {
00143 xThetaYRadiusValues [col] [row] = new QString;
00144 }
00145 }
00146 }
00147
00148 QPointF ExportFileRelations::linearlyInterpolate (const Points &points,
00149 double ordinal,
00150 const Transformation &transformation) const
00151 {
00152 LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::linearlyInterpolate";
00153
00154 double xTheta = 0, yRadius = 0;
00155 double ordinalBefore = 0;
00156 QPointF posGraphBefore;
00157 bool foundIt = false;
00158 for (int ip = 0; ip < points.count(); ip++) {
00159
00160 const Point &point = points.at (ip);
00161 QPointF posGraph;
00162 transformation.transformScreenToRawGraph (point.posScreen(),
00163 posGraph);
00164
00165 if (ordinal <= point.ordinal()) {
00166
00167 foundIt = true;
00168 if (ip == 0) {
00169
00170
00171 xTheta = posGraph.x();
00172 yRadius = posGraph.y();
00173
00174 } else {
00175
00176
00177
00178 double s = (ordinal - ordinalBefore) / (point.ordinal() - ordinalBefore);
00179 xTheta = (1.0 - s) * posGraphBefore.x() + s * posGraph.x();
00180 yRadius = (1.0 - s) * posGraphBefore.y() + s * posGraph.y();
00181 }
00182
00183 break;
00184 }
00185
00186 ordinalBefore = point.ordinal();
00187 posGraphBefore = posGraph;
00188 }
00189
00190 if (!foundIt) {
00191
00192
00193 xTheta = posGraphBefore.x();
00194 yRadius = posGraphBefore.y();
00195
00196 }
00197
00198 return QPointF (xTheta,
00199 yRadius);
00200 }
00201
00202 void ExportFileRelations::loadXThetaYRadiusValues (const DocumentModelExportFormat &modelExportOverride,
00203 const Document &document,
00204 const MainWindowModel &modelMainWindow,
00205 const QStringList &curvesIncluded,
00206 const Transformation &transformation,
00207 QVector<QVector<QString*> > &xThetaYRadiusValues) const
00208 {
00209 LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::loadXThetaYRadiusValues";
00210
00211
00212 for (int ic = 0; ic < curvesIncluded.count(); ic++) {
00213
00214 int colXTheta = 2 * ic;
00215 int colYRadius = 2 * ic + 1;
00216
00217 const QString curveName = curvesIncluded.at (ic);
00218
00219 const Curve *curve = document.curveForCurveName (curveName);
00220 const Points points = curve->points ();
00221
00222 if (modelExportOverride.pointsSelectionRelations() == EXPORT_POINTS_SELECTION_RELATIONS_RAW) {
00223
00224
00225 loadXThetaYRadiusValuesForCurveRaw (document.modelCoords(),
00226 modelMainWindow,
00227 points,
00228 xThetaYRadiusValues [colXTheta],
00229 xThetaYRadiusValues [colYRadius],
00230 transformation);
00231 } else {
00232
00233 const LineStyle &lineStyle = document.modelCurveStyles().lineStyle(curveName);
00234
00235
00236 ExportValuesOrdinal ordinals = ordinalsAtIntervals (modelExportOverride.pointsIntervalRelations(),
00237 modelExportOverride.pointsIntervalUnitsRelations(),
00238 lineStyle.curveConnectAs(),
00239 transformation,
00240 points);
00241
00242 if (curve->curveStyle().lineStyle().curveConnectAs() == CONNECT_AS_RELATION_SMOOTH) {
00243
00244 loadXThetaYRadiusValuesForCurveInterpolatedSmooth (document.modelCoords(),
00245 modelMainWindow,
00246 points,
00247 ordinals,
00248 xThetaYRadiusValues [colXTheta],
00249 xThetaYRadiusValues [colYRadius],
00250 transformation);
00251
00252 } else {
00253
00254 loadXThetaYRadiusValuesForCurveInterpolatedStraight (document.modelCoords(),
00255 modelMainWindow,
00256 points,
00257 ordinals,
00258 xThetaYRadiusValues [colXTheta],
00259 xThetaYRadiusValues [colYRadius],
00260 transformation);
00261 }
00262 }
00263 }
00264 }
00265
00266 void ExportFileRelations::loadXThetaYRadiusValuesForCurveInterpolatedSmooth (const DocumentModelCoords &modelCoords,
00267 const MainWindowModel &modelMainWindow,
00268 const Points &points,
00269 const ExportValuesOrdinal &ordinals,
00270 QVector<QString*> &xThetaValues,
00271 QVector<QString*> &yRadiusValues,
00272 const Transformation &transformation) const
00273 {
00274 LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::loadXThetaYRadiusValuesForCurveInterpolatedSmooth";
00275
00276 vector<double> t;
00277 vector<SplinePair> xy;
00278 ExportOrdinalsSmooth ordinalsSmooth;
00279
00280 ordinalsSmooth.loadSplinePairsWithTransformation (points,
00281 transformation,
00282 t,
00283 xy);
00284
00285
00286 Spline spline (t,
00287 xy);
00288
00289 FormatCoordsUnits format;
00290
00291
00292 for (int row = 0; row < ordinals.count(); row++) {
00293
00294 double ordinal = ordinals.at (row);
00295 SplinePair splinePairFound = spline.interpolateCoeff(ordinal);
00296 double xTheta = splinePairFound.x ();
00297 double yRadius = splinePairFound.y ();
00298
00299
00300 format.unformattedToFormatted (xTheta,
00301 yRadius,
00302 modelCoords,
00303 modelMainWindow,
00304 *(xThetaValues [row]),
00305 *(yRadiusValues [row]),
00306 transformation);
00307 }
00308 }
00309
00310 void ExportFileRelations::loadXThetaYRadiusValuesForCurveInterpolatedStraight (const DocumentModelCoords &modelCoords,
00311 const MainWindowModel &modelMainWindow,
00312 const Points &points,
00313 const ExportValuesOrdinal &ordinals,
00314 QVector<QString*> &xThetaValues,
00315 QVector<QString*> &yRadiusValues,
00316 const Transformation &transformation) const
00317 {
00318 LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::loadXThetaYRadiusValuesForCurveInterpolatedStraight";
00319
00320 FormatCoordsUnits format;
00321
00322
00323 for (int row = 0; row < ordinals.count(); row++) {
00324
00325 double ordinal = ordinals.at (row);
00326
00327 QPointF pointInterpolated = linearlyInterpolate (points,
00328 ordinal,
00329 transformation);
00330
00331
00332 format.unformattedToFormatted (pointInterpolated.x(),
00333 pointInterpolated.y(),
00334 modelCoords,
00335 modelMainWindow,
00336 *(xThetaValues [row]),
00337 *(yRadiusValues [row]),
00338 transformation);
00339 }
00340 }
00341
00342 void ExportFileRelations::loadXThetaYRadiusValuesForCurveRaw (const DocumentModelCoords &modelCoords,
00343 const MainWindowModel &modelMainWindow,
00344 const Points &points,
00345 QVector<QString*> &xThetaValues,
00346 QVector<QString*> &yRadiusValues,
00347 const Transformation &transformation) const
00348 {
00349 LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::loadXThetaYRadiusValuesForCurveRaw";
00350
00351 FormatCoordsUnits format;
00352
00353 for (int pt = 0; pt < points.count(); pt++) {
00354
00355 const Point &point = points.at (pt);
00356
00357 QPointF posGraph;
00358 transformation.transformScreenToRawGraph (point.posScreen(),
00359 posGraph);
00360
00361
00362 format.unformattedToFormatted (posGraph.x(),
00363 posGraph.y(),
00364 modelCoords,
00365 modelMainWindow,
00366 *(xThetaValues [pt]),
00367 *(yRadiusValues [pt]),
00368 transformation);
00369 }
00370 }
00371
00372 int ExportFileRelations::maxColumnSizeAllocation (const DocumentModelExportFormat &modelExport,
00373 const Document &document,
00374 const Transformation &transformation,
00375 const QStringList &curvesIncluded) const
00376 {
00377 LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::maxColumnSizeAllocation";
00378
00379 int maxColumnSize = 0;
00380
00381
00382 for (int ic = 0; ic < curvesIncluded.count(); ic++) {
00383
00384 const QString curveName = curvesIncluded.at (ic);
00385
00386 const Curve *curve = document.curveForCurveName (curveName);
00387 const Points points = curve->points ();
00388
00389 if (modelExport.pointsSelectionRelations() == EXPORT_POINTS_SELECTION_RELATIONS_RAW) {
00390
00391
00392 maxColumnSize = qMax (maxColumnSize,
00393 points.count());
00394
00395 } else {
00396
00397 const LineStyle &lineStyle = document.modelCurveStyles().lineStyle(curveName);
00398
00399
00400 ExportValuesOrdinal ordinals = ordinalsAtIntervals (modelExport.pointsIntervalRelations(),
00401 modelExport.pointsIntervalUnitsRelations(),
00402 lineStyle.curveConnectAs(),
00403 transformation,
00404 points);
00405
00406 maxColumnSize = qMax (maxColumnSize,
00407 ordinals.count());
00408 }
00409 }
00410
00411 return maxColumnSize;
00412 }
00413
00414 ExportValuesOrdinal ExportFileRelations::ordinalsAtIntervals (double pointsIntervalRelations,
00415 ExportPointsIntervalUnits pointsIntervalUnits,
00416 CurveConnectAs curveConnectAs,
00417 const Transformation &transformation,
00418 const Points &points) const
00419 {
00420 LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::ordinalsAtIntervals";
00421
00422 if (pointsIntervalUnits == EXPORT_POINTS_INTERVAL_UNITS_GRAPH) {
00423 if (curveConnectAs == CONNECT_AS_RELATION_SMOOTH) {
00424
00425 return ordinalsAtIntervalsSmoothGraph (pointsIntervalRelations,
00426 transformation,
00427 points);
00428
00429 } else {
00430
00431 return ordinalsAtIntervalsStraightGraph (pointsIntervalRelations,
00432 transformation,
00433 points);
00434
00435 }
00436 } else {
00437
00438 if (curveConnectAs == CONNECT_AS_RELATION_SMOOTH) {
00439
00440 return ordinalsAtIntervalsSmoothScreen (pointsIntervalRelations,
00441 points);
00442
00443 } else {
00444
00445 return ordinalsAtIntervalsStraightScreen (pointsIntervalRelations,
00446 points);
00447
00448 }
00449 }
00450 }
00451
00452 ExportValuesOrdinal ExportFileRelations::ordinalsAtIntervalsSmoothGraph (double pointsIntervalRelations,
00453 const Transformation &transformation,
00454 const Points &points) const
00455 {
00456 LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::ordinalsAtIntervalsSmoothGraph";
00457
00458 ExportValuesOrdinal ordinals;
00459
00460
00461 if ((pointsIntervalRelations > 0) &&
00462 (points.count() > 0)) {
00463
00464 vector<double> t;
00465 vector<SplinePair> xy;
00466 ExportOrdinalsSmooth ordinalsSmooth;
00467
00468 ordinalsSmooth.loadSplinePairsWithTransformation (points,
00469 transformation,
00470 t,
00471 xy);
00472
00473 ordinals = ordinalsSmooth.ordinalsAtIntervalsGraph (t,
00474 xy,
00475 pointsIntervalRelations);
00476 }
00477
00478 return ordinals;
00479 }
00480
00481 ExportValuesOrdinal ExportFileRelations::ordinalsAtIntervalsSmoothScreen (double pointsIntervalRelations,
00482 const Points &points) const
00483 {
00484 LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::ordinalsAtIntervalsSmoothScreen"
00485 << " pointCount=" << points.count();
00486
00487
00488 ExportValuesOrdinal ordinals;
00489
00490
00491 if ((pointsIntervalRelations > 0) &&
00492 (points.count() > 0)) {
00493
00494 vector<double> t;
00495 vector<SplinePair> xy;
00496 ExportOrdinalsSmooth ordinalsSmooth;
00497
00498 ordinalsSmooth.loadSplinePairsWithoutTransformation (points,
00499 t,
00500 xy);
00501
00502 ordinals = ordinalsSmooth.ordinalsAtIntervalsGraph (t,
00503 xy,
00504 pointsIntervalRelations);
00505 }
00506
00507 return ordinals;
00508 }
00509
00510 ExportValuesOrdinal ExportFileRelations::ordinalsAtIntervalsStraightGraph (double pointsIntervalRelations,
00511 const Transformation &transformation,
00512 const Points &points) const
00513 {
00514 LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::ordinalsAtIntervalsStraightGraph";
00515
00516 ExportValuesOrdinal ordinals;
00517
00518
00519 if ((pointsIntervalRelations > 0) &&
00520 (points.count() > 0)) {
00521
00522 ExportOrdinalsStraight ordinalsStraight;
00523
00524 ordinals = ordinalsStraight.ordinalsAtIntervalsGraphWithTransformation (points,
00525 transformation,
00526 pointsIntervalRelations);
00527 }
00528
00529 return ordinals;
00530 }
00531
00532 ExportValuesOrdinal ExportFileRelations::ordinalsAtIntervalsStraightScreen (double pointsIntervalRelations,
00533 const Points &points) const
00534 {
00535 LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::ordinalsAtIntervalsStraightScreen"
00536 << " pointCount=" << points.count();
00537
00538
00539 ExportValuesOrdinal ordinals;
00540
00541
00542 if ((pointsIntervalRelations > 0) &&
00543 (points.count() > 0)) {
00544
00545 ExportOrdinalsStraight ordinalsStraight;
00546
00547 ordinals = ordinalsStraight.ordinalsAtIntervalsGraphWithoutTransformation (points,
00548 pointsIntervalRelations);
00549 }
00550
00551 return ordinals;
00552 }
00553
00554 void ExportFileRelations::outputXThetaYRadiusValues (const DocumentModelExportFormat &modelExportOverride,
00555 const QStringList &curvesIncluded,
00556 QVector<QVector<QString*> > &xThetaYRadiusValues,
00557 const QString &delimiter,
00558 QTextStream &str) const
00559 {
00560 LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::outputXThetaYRadiusValues";
00561
00562
00563 if (modelExportOverride.header() != EXPORT_HEADER_NONE) {
00564 if (modelExportOverride.header() == EXPORT_HEADER_GNUPLOT) {
00565 str << curveSeparator(str.string());
00566 str << gnuplotComment();
00567 }
00568 QString delimiterForRow;
00569 QStringList::const_iterator itr;
00570 for (itr = curvesIncluded.begin(); itr != curvesIncluded.end(); itr++) {
00571 QString curveName = *itr;
00572 str << delimiterForRow << modelExportOverride.xLabel();
00573 delimiterForRow = delimiter;
00574 str << delimiterForRow << curveName;
00575 }
00576 str << "\n";
00577 }
00578
00579 for (int row = 0; row < xThetaYRadiusValues [0].count(); row++) {
00580
00581 QString delimiterForRow;
00582 for (int col = 0; col < xThetaYRadiusValues.count(); col++) {
00583
00584 str << delimiterForRow << *(xThetaYRadiusValues [col] [row]);
00585 delimiterForRow = delimiter;
00586 }
00587
00588 str << "\n";
00589 }
00590 }