Engauge Digitizer 2
Loading...
Searching...
No Matches
ExportFileRelations.cpp
Go to the documentation of this file.
1/******************************************************************************************************
2 * (C) 2014 markummitchell@github.com. This file is part of Engauge Digitizer, which is released *
3 * under GNU General Public License version 2 (GPLv2) or (at your option) any later version. See file *
4 * LICENSE or go to gnu.org/licenses for details. Distribution requires prior written permission. *
5 ******************************************************************************************************/
6
7#include "CurveConnectAs.h"
8#include "Document.h"
10#include "EngaugeAssert.h"
11#include "ExportFileRelations.h"
15#include "FormatCoordsUnits.h"
16#include "Logger.h"
17#include <qdebug.h>
18#include <qmath.h>
19#include <QTextStream>
20#include <QVector>
21#include "Spline.h"
22#include "SplinePair.h"
23#include "Transformation.h"
24#include <vector>
25
26using namespace std;
27
28const int COLUMNS_PER_CURVE = 2;
29
33
34void ExportFileRelations::exportAllPerLineXThetaValuesMerged (const DocumentModelExportFormat &modelExportOverride,
35 const Document &document,
36 const MainWindowModel &modelMainWindow,
37 const QStringList &curvesIncluded,
38 const QString &delimiter,
39 const Transformation &transformation,
40 bool isLogXTheta,
41 bool isLogYRadius,
42 QTextStream &str,
43 unsigned int &numWritesSoFar) const
44{
45 LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::exportAllPerLineXThetaValuesMerged";
46
47 int maxColumnSize = maxColumnSizeAllocation (modelExportOverride,
48 document,
49 transformation,
50 isLogXTheta,
51 isLogYRadius,
52 curvesIncluded);
53
54 // Skip if every curve was a function
55 if (maxColumnSize > 0) {
56
58
59 exportAllPerLineXThetaValuesMergedMultiplePass (maxColumnSize,
60 modelExportOverride,
61 document,
62 modelMainWindow,
63 curvesIncluded,
64 delimiter,
65 transformation,
66 isLogXTheta,
67 isLogYRadius,
68 str,
69 numWritesSoFar);
70
71 } else {
72
73 exportAllPerLineXThetaValuesMergedOnePass (maxColumnSize,
74 modelExportOverride,
75 document,
76 modelMainWindow,
77 curvesIncluded,
78 delimiter,
79 transformation,
80 isLogXTheta,
81 isLogYRadius,
82 str,
83 numWritesSoFar);
84 }
85 }
86}
87
88void ExportFileRelations::exportAllPerLineXThetaValuesMergedMultiplePass (int maxColumnSize,
89 const DocumentModelExportFormat &modelExportOverride,
90 const Document &document,
91 const MainWindowModel &modelMainWindow,
92 const QStringList &curvesIncluded,
93 const QString &delimiter,
94 const Transformation &transformation,
95 bool isLogXTheta,
96 bool isLogYRadius,
97 QTextStream &str,
98 unsigned int &numWritesSoFar) const
99{
100 // For interpolation of relations in general a single set of x/theta values cannot be created that work for every
101 // relation curve, since one curve may have M y/radius values for a specific x/radius while another curve has
102 // N y/radius values for that same x/radius value. So we export each curve into memory separately and then merge
103 // the results. Why? Since the methods called from this method all assume a single set of x/theta values can be
104 // used for all curves
105
106 const int CURVE_COUNT_PER_PASS = 1;
107
108 int curveCount = curvesIncluded.count ();
109
110 QVector<QVector<QString*> > xThetaYRadiusValuesAll (COLUMNS_PER_CURVE * curveCount, QVector<QString*> (maxColumnSize));
111
112 initializeXThetaYRadiusValues (curvesIncluded,
113 xThetaYRadiusValuesAll);
114
115 // One pass per curve
116 int colX = 0, colY = colX + 1;
117 for (int c = 0; c < curvesIncluded.count (); c++) {
118 QString curve = curvesIncluded [c];
119
120 QStringList curvesIncludedInPass;
121 curvesIncludedInPass << curve;
122 ENGAUGE_ASSERT (curvesIncludedInPass.count () == CURVE_COUNT_PER_PASS);
123
124 QVector<QVector<QString*> > xThetaYRadiusValuesOne (COLUMNS_PER_CURVE * CURVE_COUNT_PER_PASS, QVector<QString*> (maxColumnSize));
125
126 initializeXThetaYRadiusValues (curvesIncludedInPass,
127 xThetaYRadiusValuesOne);
128 loadXThetaYRadiusValues (modelExportOverride,
129 document,
130 modelMainWindow,
131 curvesIncludedInPass,
132 transformation,
133 isLogXTheta,
134 isLogYRadius,
135 xThetaYRadiusValuesOne);
136
137 // Merge one curve array into all curves array
138 for (int row = 0; row < maxColumnSize; row++) {
139 *(xThetaYRadiusValuesAll [colX] [row]) = *(xThetaYRadiusValuesOne [0] [row]);
140 *(xThetaYRadiusValuesAll [colY] [row]) = *(xThetaYRadiusValuesOne [1] [row]);
141 }
142
143 destroy2DArray (xThetaYRadiusValuesOne);
144
145 colX += 2;
146 colY += 2;
147 }
148
149 outputXThetaYRadiusValues (modelExportOverride,
150 curvesIncluded,
151 xThetaYRadiusValuesAll,
152 delimiter,
153 str,
154 numWritesSoFar);
155 destroy2DArray (xThetaYRadiusValuesAll);
156}
157
158void ExportFileRelations::exportAllPerLineXThetaValuesMergedOnePass (int maxColumnSize,
159 const DocumentModelExportFormat &modelExportOverride,
160 const Document &document,
161 const MainWindowModel &modelMainWindow,
162 const QStringList &curvesIncluded,
163 const QString &delimiter,
164 const Transformation &transformation,
165 bool isLogXTheta,
166 bool isLogYRadius,
167 QTextStream &str,
168 unsigned int &numWritesSoFar) const
169{
170 int curveCount = curvesIncluded.count ();
171
172 QVector<QVector<QString*> > xThetaYRadiusValues (COLUMNS_PER_CURVE * curveCount, QVector<QString*> (maxColumnSize));
173 initializeXThetaYRadiusValues (curvesIncluded,
174 xThetaYRadiusValues);
175 loadXThetaYRadiusValues (modelExportOverride,
176 document,
177 modelMainWindow,
178 curvesIncluded,
179 transformation,
180 isLogXTheta,
181 isLogYRadius,
182 xThetaYRadiusValues);
183 outputXThetaYRadiusValues (modelExportOverride,
184 curvesIncluded,
185 xThetaYRadiusValues,
186 delimiter,
187 str,
188 numWritesSoFar);
189 destroy2DArray (xThetaYRadiusValues);
190}
191
192void ExportFileRelations::exportOnePerLineXThetaValuesMerged (const DocumentModelExportFormat &modelExportOverride,
193 const Document &document,
194 const MainWindowModel &modelMainWindow,
195 const QStringList &curvesIncluded,
196 const QString &delimiter,
197 const Transformation &transformation,
198 bool isLogXTheta,
199 bool isLogYRadius,
200 QTextStream &str,
201 unsigned int &numWritesSoFar) const
202{
203 LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::exportOnePerLineXThetaValuesMerged";
204
205 QStringList::const_iterator itr;
206 for (itr = curvesIncluded.begin(); itr != curvesIncluded.end(); itr++) {
207
208 QString curveIncluded = *itr;
209
210 exportAllPerLineXThetaValuesMerged (modelExportOverride,
211 document,
212 modelMainWindow,
213 QStringList (curveIncluded),
214 delimiter,
215 transformation,
216 isLogXTheta,
217 isLogYRadius,
218 str,
219 numWritesSoFar);
220 }
221}
222
224 const Document &document,
225 const MainWindowModel &modelMainWindow,
226 const Transformation &transformation,
227 QTextStream &str,
228 unsigned int &numWritesSoFar) const
229{
230 LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::exportToFile";
231
232 // Log coordinates must be temporarily transformed to linear coordinates
233 bool isLogXTheta = (document.modelCoords().coordScaleXTheta() == COORD_SCALE_LOG);
234 bool isLogYRadius = (document.modelCoords().coordScaleYRadius() == COORD_SCALE_LOG);
235
236 // Identify curves to be included
237 QStringList curvesIncluded = curvesToInclude (modelExportOverride,
238 document,
239 document.curvesGraphsNames(),
242
243 // Delimiter
244 const QString delimiter = exportDelimiterToText (modelExportOverride.delimiter(),
245 modelExportOverride.header() == EXPORT_HEADER_GNUPLOT);
246
247 // Export in one of two layouts
248 if (modelExportOverride.layoutFunctions() == EXPORT_LAYOUT_ALL_PER_LINE) {
249 exportAllPerLineXThetaValuesMerged (modelExportOverride,
250 document,
251 modelMainWindow,
252 curvesIncluded,
253 delimiter,
254 transformation,
255 isLogXTheta,
256 isLogYRadius,
257 str,
258 numWritesSoFar);
259 } else {
260 exportOnePerLineXThetaValuesMerged (modelExportOverride,
261 document,
262 modelMainWindow,
263 curvesIncluded,
264 delimiter,
265 transformation,
266 isLogXTheta,
267 isLogYRadius,
268 str,
269 numWritesSoFar);
270 }
271}
272
273void ExportFileRelations::initializeXThetaYRadiusValues (const QStringList &curvesIncluded,
274 QVector<QVector<QString*> > &xThetaYRadiusValues) const
275{
276 LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::initializeXThetaYRadiusValues";
277
278 // Initialize every entry with empty string
279 int curveCount = curvesIncluded.count();
280 int xThetaCount = xThetaYRadiusValues [0].count();
281 for (int row = 0; row < xThetaCount; row++) {
282 for (int col = 0; col < COLUMNS_PER_CURVE * curveCount; col++) {
283 xThetaYRadiusValues [col] [row] = new QString;
284 }
285 }
286}
287
288QPointF ExportFileRelations::linearlyInterpolate (const Points &points,
289 double ordinal,
290 const Transformation &transformation) const
291{
292 // LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::linearlyInterpolate";
293
294 double xTheta = 0, yRadius = 0;
295 double ordinalBefore = 0; // Not set until ip=1
296 QPointF posGraphBefore; // Not set until ip=1
297 bool foundIt = false;
298 for (int ip = 0; ip < points.count(); ip++) {
299
300 const Point &point = points.at (ip);
301 QPointF posGraph;
302 transformation.transformScreenToRawGraph (point.posScreen(),
303 posGraph);
304
305 if (ordinal <= point.ordinal()) {
306
307 foundIt = true;
308 if (ip == 0) {
309
310 // Use first point
311 xTheta = posGraph.x();
312 yRadius = posGraph.y();
313
314 } else {
315
316 // Between posGraphBefore and posGraph. Note that if posGraph.x()=posGraphBefore.x() then
317 // previous iteration of loop would have been used for interpolation, and then the loop was exited
318 double s = (ordinal - ordinalBefore) / (point.ordinal() - ordinalBefore);
319 xTheta = (1.0 - s) * posGraphBefore.x() + s * posGraph.x();
320 yRadius = (1.0 - s) * posGraphBefore.y() + s * posGraph.y();
321 }
322
323 break;
324 }
325
326 ordinalBefore = point.ordinal();
327 posGraphBefore = posGraph;
328 }
329
330 if (!foundIt) {
331
332 // Use last point
333 xTheta = posGraphBefore.x();
334 yRadius = posGraphBefore.y();
335
336 }
337
338 return QPointF (xTheta,
339 yRadius);
340}
341
342void ExportFileRelations::loadXThetaYRadiusValues (const DocumentModelExportFormat &modelExportOverride,
343 const Document &document,
344 const MainWindowModel &modelMainWindow,
345 const QStringList &curvesIncluded,
346 const Transformation &transformation,
347 bool isLogXTheta,
348 bool isLogYRadius,
349 QVector<QVector<QString*> > &xThetaYRadiusValues) const
350{
351 LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::loadXThetaYRadiusValues";
352
353 // The curve processing logic here is mirrored in maxColumnSizeAllocation so the array allocations are in sync
354 for (int ic = 0; ic < curvesIncluded.count(); ic++) {
355
356 int colXTheta = 2 * ic;
357 int colYRadius = 2 * ic + 1;
358
359 const QString curveName = curvesIncluded.at (ic);
360
361 const Curve *curve = document.curveForCurveName (curveName);
362 const Points points = curve->points ();
363
365
366 // No interpolation. Raw points
367 loadXThetaYRadiusValuesForCurveRaw (document.modelCoords(),
368 document.modelGeneral(),
369 modelMainWindow,
370 points,
371 xThetaYRadiusValues [colXTheta],
372 xThetaYRadiusValues [colYRadius],
373 transformation);
374 } else {
375
376 const LineStyle &lineStyle = document.modelCurveStyles().lineStyle(curveName);
377
378 // Interpolation. Points are taken approximately every every modelExport.pointsIntervalRelations
379 ExportValuesOrdinal ordinals = ordinalsAtIntervals (modelExportOverride.pointsIntervalRelations(),
380 modelExportOverride.pointsIntervalUnitsRelations(),
381 lineStyle.curveConnectAs(),
382 transformation,
383 isLogXTheta,
384 isLogYRadius,
385 points);
386
388
389 loadXThetaYRadiusValuesForCurveInterpolatedSmooth (document.modelCoords(),
390 document.modelGeneral(),
391 modelMainWindow,
392 points,
393 ordinals,
394 xThetaYRadiusValues [colXTheta],
395 xThetaYRadiusValues [colYRadius],
396 transformation,
397 isLogXTheta,
398 isLogYRadius);
399
400 } else {
401
402 loadXThetaYRadiusValuesForCurveInterpolatedStraight (document.modelCoords(),
403 document.modelGeneral(),
404 modelMainWindow,
405 points,
406 ordinals,
407 xThetaYRadiusValues [colXTheta],
408 xThetaYRadiusValues [colYRadius],
409 transformation);
410 }
411 }
412 }
413}
414
415void ExportFileRelations::loadXThetaYRadiusValuesForCurveInterpolatedSmooth (const DocumentModelCoords &modelCoords,
416 const DocumentModelGeneral &modelGeneral,
417 const MainWindowModel &modelMainWindow,
418 const Points &points,
419 const ExportValuesOrdinal &ordinals,
420 QVector<QString*> &xThetaValues,
421 QVector<QString*> &yRadiusValues,
422 const Transformation &transformation,
423 bool isLogXTheta,
424 bool isLogYRadius) const
425{
426 LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::loadXThetaYRadiusValuesForCurveInterpolatedSmooth";
427
428 vector<double> t;
429 vector<SplinePair> xy;
430 ExportOrdinalsSmooth ordinalsSmooth;
431
432 ordinalsSmooth.loadSplinePairsWithTransformation (points,
433 transformation,
434 isLogXTheta,
435 isLogYRadius,
436 t,
437 xy);
438
439 // Spline class requires at least one point
440 if (xy.size() > 0) {
441
442 // Fit a spline
443 Spline spline (t,
444 xy);
445
446 FormatCoordsUnits format;
447
448 // Extract the points
449 for (int row = 0; row < ordinals.count(); row++) {
450
451 double ordinal = ordinals.at (row);
452 SplinePair splinePairFound = spline.interpolateCoeff(ordinal);
453 double xTheta = splinePairFound.x ();
454 double yRadius = splinePairFound.y ();
455
456 // Save values for this row into xThetaValues and yRadiusValues, after appropriate formatting
457 format.unformattedToFormatted (xTheta,
458 yRadius,
459 modelCoords,
460 modelGeneral,
461 modelMainWindow,
462 *(xThetaValues [row]),
463 *(yRadiusValues [row]),
464 transformation);
465 }
466 }
467}
468
469void ExportFileRelations::loadXThetaYRadiusValuesForCurveInterpolatedStraight (const DocumentModelCoords &modelCoords,
470 const DocumentModelGeneral &modelGeneral,
471 const MainWindowModel &modelMainWindow,
472 const Points &points,
473 const ExportValuesOrdinal &ordinals,
474 QVector<QString*> &xThetaValues,
475 QVector<QString*> &yRadiusValues,
476 const Transformation &transformation) const
477{
478 LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::loadXThetaYRadiusValuesForCurveInterpolatedStraight";
479
480 FormatCoordsUnits format;
481
482 // Get value at desired points
483 for (int row = 0; row < ordinals.count(); row++) {
484
485 double ordinal = ordinals.at (row);
486
487 QPointF pointInterpolated = linearlyInterpolate (points,
488 ordinal,
489 transformation);
490
491 // Save values for this row into xThetaValues and yRadiusValues, after appropriate formatting
492 format.unformattedToFormatted (pointInterpolated.x(),
493 pointInterpolated.y(),
494 modelCoords,
495 modelGeneral,
496 modelMainWindow,
497 *(xThetaValues [row]),
498 *(yRadiusValues [row]),
499 transformation);
500 }
501}
502
503void ExportFileRelations::loadXThetaYRadiusValuesForCurveRaw (const DocumentModelCoords &modelCoords,
504 const DocumentModelGeneral &modelGeneral,
505 const MainWindowModel &modelMainWindow,
506 const Points &points,
507 QVector<QString*> &xThetaValues,
508 QVector<QString*> &yRadiusValues,
509 const Transformation &transformation) const
510{
511 LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::loadXThetaYRadiusValuesForCurveRaw";
512
513 FormatCoordsUnits format;
514
515 for (int pt = 0; pt < points.count(); pt++) {
516
517 const Point &point = points.at (pt);
518
519 QPointF posGraph;
520 transformation.transformScreenToRawGraph (point.posScreen(),
521 posGraph);
522
523 // Save values for this row into xThetaValues and yRadiusValues, after appropriate formatting
524 format.unformattedToFormatted (posGraph.x(),
525 posGraph.y(),
526 modelCoords,
527 modelGeneral,
528 modelMainWindow,
529 *(xThetaValues [pt]),
530 *(yRadiusValues [pt]),
531 transformation);
532 }
533}
534
535int ExportFileRelations::maxColumnSizeAllocation (const DocumentModelExportFormat &modelExport,
536 const Document &document,
537 const Transformation &transformation,
538 bool isLogXTheta,
539 bool isLogYRadius,
540 const QStringList &curvesIncluded) const
541{
542 LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::maxColumnSizeAllocation";
543
544 int maxColumnSize = 0;
545
546 // The curve processing logic here is mirrored in loadXThetaYRadiusValues so the array allocations are in sync
547 for (int ic = 0; ic < curvesIncluded.count(); ic++) {
548
549 const QString curveName = curvesIncluded.at (ic);
550
551 const Curve *curve = document.curveForCurveName (curveName);
552 const Points points = curve->points ();
553
555
556 // No interpolation. Raw points
557 maxColumnSize = qMax (maxColumnSize,
558 points.count());
559
560 } else {
561
562 const LineStyle &lineStyle = document.modelCurveStyles().lineStyle(curveName);
563
564
565 // Interpolation. Points are taken approximately every every modelExport.pointsIntervalRelations
566 ExportValuesOrdinal ordinals = ordinalsAtIntervals (modelExport.pointsIntervalRelations(),
567 modelExport.pointsIntervalUnitsRelations(),
568 lineStyle.curveConnectAs(),
569 transformation,
570 isLogXTheta,
571 isLogYRadius,
572 points);
573
574 maxColumnSize = qMax (maxColumnSize,
575 ordinals.count());
576 }
577 }
578
579 return maxColumnSize;
580}
581
582ExportValuesOrdinal ExportFileRelations::ordinalsAtIntervals (double pointsIntervalRelations,
583 ExportPointsIntervalUnits pointsIntervalUnits,
584 CurveConnectAs curveConnectAs,
585 const Transformation &transformation,
586 bool isLogXTheta,
587 bool isLogYRadius,
588 const Points &points) const
589{
590 LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::ordinalsAtIntervals";
591
592 if (pointsIntervalUnits == EXPORT_POINTS_INTERVAL_UNITS_GRAPH) {
593 if (curveConnectAs == CONNECT_AS_RELATION_SMOOTH) {
594
595 return ordinalsAtIntervalsSmoothGraph (pointsIntervalRelations,
596 transformation,
597 isLogXTheta,
598 isLogYRadius,
599 points);
600
601 } else {
602
603 return ordinalsAtIntervalsStraightGraph (pointsIntervalRelations,
604 transformation,
605 points);
606
607 }
608 } else {
609
610 if (curveConnectAs == CONNECT_AS_RELATION_SMOOTH) {
611
612 return ordinalsAtIntervalsSmoothScreen (pointsIntervalRelations,
613 points);
614
615 } else {
616
617 return ordinalsAtIntervalsStraightScreen (pointsIntervalRelations,
618 points);
619
620 }
621 }
622}
623
624ExportValuesOrdinal ExportFileRelations::ordinalsAtIntervalsSmoothGraph (double pointsIntervalRelations,
625 const Transformation &transformation,
626 bool isLogXTheta,
627 bool isLogYRadius,
628 const Points &points) const
629{
630 LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::ordinalsAtIntervalsSmoothGraph";
631
632 ExportValuesOrdinal ordinals;
633
634 // Prevent infinite loop when there are no points or will be too many points
635 if ((pointsIntervalRelations > 0) &&
636 (points.count() > 0)) {
637
638 vector<double> t;
639 vector<SplinePair> xy;
640 ExportOrdinalsSmooth ordinalsSmooth;
641
642 ordinalsSmooth.loadSplinePairsWithTransformation (points,
643 transformation,
644 isLogXTheta,
645 isLogYRadius,
646 t,
647 xy);
648
649 ordinals = ordinalsSmooth.ordinalsAtIntervalsGraph (t,
650 xy,
651 pointsIntervalRelations);
652 }
653
654 return ordinals;
655}
656
657ExportValuesOrdinal ExportFileRelations::ordinalsAtIntervalsSmoothScreen (double pointsIntervalRelations,
658 const Points &points) const
659{
660 LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::ordinalsAtIntervalsSmoothScreen"
661 << " pointCount=" << points.count();
662
663 // Results
664 ExportValuesOrdinal ordinals;
665
666 // Prevent infinite loop when there are no points or will be too many points
667 if ((pointsIntervalRelations > 0) &&
668 (points.count() > 0)) {
669
670 vector<double> t;
671 vector<SplinePair> xy;
672 ExportOrdinalsSmooth ordinalsSmooth;
673
674 ordinalsSmooth.loadSplinePairsWithoutTransformation (points,
675 t,
676 xy);
677
678 ordinals = ordinalsSmooth.ordinalsAtIntervalsGraph (t,
679 xy,
680 pointsIntervalRelations);
681 }
682
683 return ordinals;
684}
685
686ExportValuesOrdinal ExportFileRelations::ordinalsAtIntervalsStraightGraph (double pointsIntervalRelations,
687 const Transformation &transformation,
688 const Points &points) const
689{
690 LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::ordinalsAtIntervalsStraightGraph";
691
692 ExportValuesOrdinal ordinals;
693
694 // Prevent infinite loop when there are no points or will be too many points
695 if ((pointsIntervalRelations > 0) &&
696 (points.count() > 0)) {
697
698 ExportOrdinalsStraight ordinalsStraight;
699
700 ordinals = ordinalsStraight.ordinalsAtIntervalsGraphWithTransformation (points,
701 transformation,
702 pointsIntervalRelations);
703 }
704
705 return ordinals;
706}
707
708ExportValuesOrdinal ExportFileRelations::ordinalsAtIntervalsStraightScreen (double pointsIntervalRelations,
709 const Points &points) const
710{
711 LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::ordinalsAtIntervalsStraightScreen"
712 << " pointCount=" << points.count();
713
714 // Results
715 ExportValuesOrdinal ordinals;
716
717 // Prevent infinite loop when there are no points or will be too many points
718 if ((pointsIntervalRelations > 0) &&
719 (points.count() > 0)) {
720
721 ExportOrdinalsStraight ordinalsStraight;
722
723 ordinals = ordinalsStraight.ordinalsAtIntervalsGraphWithoutTransformation (points,
724 pointsIntervalRelations);
725 }
726
727 return ordinals;
728}
729
730void ExportFileRelations::outputXThetaYRadiusValues (const DocumentModelExportFormat &modelExportOverride,
731 const QStringList &curvesIncluded,
732 QVector<QVector<QString*> > &xThetaYRadiusValues,
733 const QString &delimiter,
734 QTextStream &str,
735 unsigned int &numWritesSoFar) const
736{
737 LOG4CPP_INFO_S ((*mainCat)) << "ExportFileRelations::outputXThetaYRadiusValues";
738
739 // Header
740 if (modelExportOverride.header() != EXPORT_HEADER_NONE) {
741 insertLineSeparator (numWritesSoFar == 0,
742 modelExportOverride.header (),
743 str);
744 if (modelExportOverride.header() == EXPORT_HEADER_GNUPLOT) {
745 str << gnuplotComment();
746 }
747 QString delimiterForRow;
748 QStringList::const_iterator itr;
749 for (itr = curvesIncluded.begin(); itr != curvesIncluded.end(); itr++) {
750 QString curveName = *itr;
751 str << delimiterForRow << modelExportOverride.xLabel();
752 delimiterForRow = delimiter;
753 str << delimiterForRow << curveName;
754 }
755 str << "\n";
756 }
757
758 // Table body
759 for (int row = 0; row < xThetaYRadiusValues [0].count(); row++) {
760
761 QString delimiterForRow;
762 for (int col = 0; col < xThetaYRadiusValues.count(); col++) {
763
764 QString xThetaString = *(xThetaYRadiusValues [col] [row]);
765 str << delimiterForRow << wrapInDoubleQuotesIfNeeded (modelExportOverride,
766 xThetaString);
767 delimiterForRow = delimiter;
768 }
769
770 str << "\n";
771 }
772
773 ++numWritesSoFar;
774}
@ COORD_SCALE_LOG
Definition CoordScale.h:14
CurveConnectAs
@ CONNECT_AS_RELATION_STRAIGHT
@ CONNECT_AS_RELATION_SMOOTH
#define ENGAUGE_ASSERT(cond)
Drop in replacement for Q_ASSERT if defined(QT_NO_DEBUG) && !defined(QT_FORCE_ASSERTS) define ENGAUGE...
QString exportDelimiterToText(ExportDelimiter exportDelimiter, bool isGnuplotDelimiter)
const int COLUMNS_PER_CURVE
@ EXPORT_HEADER_NONE
@ EXPORT_HEADER_GNUPLOT
@ EXPORT_LAYOUT_ALL_PER_LINE
@ EXPORT_POINTS_INTERVAL_UNITS_GRAPH
@ EXPORT_POINTS_SELECTION_RELATIONS_INTERPOLATE
@ EXPORT_POINTS_SELECTION_RELATIONS_RAW
QList< double > ExportValuesOrdinal
log4cpp::Category * mainCat
Definition Logger.cpp:14
QList< Point > Points
Definition Points.h:13
LineStyle lineStyle() const
Get method for LineStyle.
const LineStyle lineStyle(const QString &curveName) const
Get method for copying one line style in one step.
CurveStyle curveStyle() const
Return the curve style.
Definition Curve.cpp:149
const Points points() const
Return a shallow copy of the Points.
Definition Curve.cpp:451
Model for DlgSettingsCoords and CmdSettingsCoords.
Model for DlgSettingsExportFormat and CmdSettingsExportFormat.
ExportHeader header() const
Get method for header.
ExportPointsSelectionRelations pointsSelectionRelations() const
Get method for point selection for relations.
double pointsIntervalRelations() const
Get method for relations interval for relations.
QString xLabel() const
Get method for x label.
ExportPointsIntervalUnits pointsIntervalUnitsRelations() const
Get method for points interval units for relations.
ExportDelimiter delimiter() const
Get method for delimiter.
ExportLayoutFunctions layoutFunctions() const
Get method for functions layout.
Model for DlgSettingsGeneral and CmdSettingsGeneral.
Storage of one imported image and the data attached to that image.
Definition Document.h:42
DocumentModelGeneral modelGeneral() const
Get method for DocumentModelGeneral.
Definition Document.cpp:723
QStringList curvesGraphsNames() const
See CurvesGraphs::curvesGraphsNames.
Definition Document.cpp:349
DocumentModelCoords modelCoords() const
Get method for DocumentModelCoords.
Definition Document.cpp:695
CurveStyles modelCurveStyles() const
Get method for CurveStyles.
Definition Document.cpp:702
const Curve * curveForCurveName(const QString &curveName) const
See CurvesGraphs::curveForCurveNames, although this also works for AXIS_CURVE_NAME.
Definition Document.cpp:335
void destroy2DArray(QVector< QVector< QString * > > &array) const
Deallocate memory for array.
QString wrapInDoubleQuotesIfNeeded(const DocumentModelExportFormat &modelExportOverride, const QString &valueString) const
RFC 4180 says if values are delimited by a comma AND a value has commas in it (for locale like Englis...
QString gnuplotComment() const
Gnuplot comment delimiter.
QStringList curvesToInclude(const DocumentModelExportFormat &modelExportOverride, const Document &document, const QStringList &curvesGraphsNames, CurveConnectAs curveConnectAs1, CurveConnectAs curveConnectAs2) const
Identify curves to include in export. The specified DocumentModelExportFormat overrides same data in ...
void insertLineSeparator(bool isFirst, ExportHeader exportHeader, QTextStream &str) const
Insert line(s) between successive sets of curves.
ExportFileRelations()
Single constructor.
void exportToFile(const DocumentModelExportFormat &modelExportOverride, const Document &document, const MainWindowModel &modelMainWindow, const Transformation &transformation, QTextStream &str, unsigned int &numWritesSoFar) const
Export Document points according to the settings.
void loadSplinePairsWithTransformation(const Points &points, const Transformation &transformation, bool isLogXTheta, bool isLogYRadius, std::vector< double > &t, std::vector< SplinePair > &xy) const
Load t (=ordinal) and xy (=screen position) spline pairs, converting screen coordinates to graph coor...
ExportValuesOrdinal ordinalsAtIntervalsGraph(const std::vector< double > &t, const std::vector< SplinePair > &xy, double pointsInterval) const
Perform the interpolation on the arrays loaded by the other methods.
void loadSplinePairsWithoutTransformation(const Points &points, std::vector< double > &t, std::vector< SplinePair > &xy) const
Load t (=ordinal) and xy (=screen position) spline pairs, without any conversion to graph coordinates...
ExportValuesOrdinal ordinalsAtIntervalsGraphWithoutTransformation(const Points &points, double pointsInterval) const
Compute ordinals, without any conversion to graph coordinates.
ExportValuesOrdinal ordinalsAtIntervalsGraphWithTransformation(const Points &points, const Transformation &transformation, double pointsInterval) const
Compute ordinals, converting screen coordinates to graph coordinates.
void unformattedToFormatted(double xThetaUnformatted, double yRadiusUnformatted, const DocumentModelCoords &modelCoords, const DocumentModelGeneral &modelGeneral, const MainWindowModel &mainWindowModel, QString &xThetaFormatted, QString &yRadiusFormatted, const Transformation &transformation) const
Convert unformatted numeric value to formatted string. Transformation is used to determine best resol...
CurveConnectAs curveConnectAs() const
Get method for connect type.
Definition LineStyle.cpp:63
Model for DlgSettingsMainWindow.
QPointF posScreen() const
Accessor for screen position.
Definition Point.cpp:404
double ordinal(ApplyHasCheck applyHasCheck=KEEP_HAS_CHECK) const
Get method for ordinal. Skip check if copying one instance to another.
Definition Point.cpp:386
double y() const
Get method for y.
double x() const
Get method for x.
Affine transformation between screen and graph coordinates, based on digitized axis points.
void transformScreenToRawGraph(const QPointF &coordScreen, QPointF &coordGraph) const
Transform from cartesian pixel screen coordinates to cartesian/polar graph coordinates.
#define LOG4CPP_INFO_S(logger)
Definition convenience.h:18