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