--- CloudCompare-2.9.1/libs/qCC_io/ShpFilter.cpp 2017-11-03 12:30:42.000000000 +0100
+++ ./ShpFilter.cpp 2018-02-23 14:19:46.837624000 +0100
@@ -72,6 +72,34 @@
SHP_MULTI_PATCH = 31
};
+//DGM: by default qToLittleEndian and qFromLittleEndian only works for integer types!
+double swapD(double in)
+{
+ //! Change the endianness (see https://stackoverflow.com/questions/41012414/convert-double-value-from-little-endian-to-big-endian)
+ std::array<char, sizeof(double)> p;
+ memcpy(&p[0], &in, sizeof(double));
+ std::reverse(p.begin(), p.end());
+ memcpy(&in, &p[0], sizeof(double));
+ return in;
+}
+
+double qFromLittleEndianD(double in)
+{
+#if Q_BYTE_ORDER == Q_BIG_ENDIAN
+ return swapD(in);
+#endif
+ return in;
+}
+
+double qToLittleEndianD(double in)
+{
+#if Q_BYTE_ORDER == Q_BIG_ENDIAN
+ return swapD(in);
+#endif
+ return in;
+}
+
+
//! Shape File Save dialog
class SaveSHPFileDialog : public QDialog, public Ui::SaveSHPFileDlg
{
@@ -271,10 +299,10 @@
{
//The Bounding Box for the PolyLine stored in the order Xmin, Ymin, Xmax, Ymax
//DGM: ignored
- //double xMin = qFromLittleEndian<double>(*reinterpret_cast<double*>(header ));
- //double xMax = qFromLittleEndian<double>(*reinterpret_cast<double*>(header+ 8));
- //double yMin = qFromLittleEndian<double>(*reinterpret_cast<double*>(header+16));
- //double yMax = qFromLittleEndian<double>(*reinterpret_cast<double*>(header+24));
+ //double xMin = qFromLittleEndianD(*reinterpret_cast<double*>(header ));
+ //double xMax = qFromLittleEndianD(*reinterpret_cast<double*>(header+ 8));
+ //double yMin = qFromLittleEndianD(*reinterpret_cast<double*>(header+16));
+ //double yMax = qFromLittleEndianD(*reinterpret_cast<double*>(header+24));
}
//Byte 32: NumParts (The number of parts in the PolyLine)
@@ -321,8 +349,8 @@
//check for errors
if (file.error() != QFile::NoError)
return CC_FERR_READING;
- double x = qFromLittleEndian<double>(*reinterpret_cast<double*>(header));
- double y = qFromLittleEndian<double>(*reinterpret_cast<double*>(header + 8));
+ double x = qFromLittleEndianD(*reinterpret_cast<double*>(header));
+ double y = qFromLittleEndianD(*reinterpret_cast<double*>(header + 8));
points[i].x = static_cast<PointCoordinateType>(x + PShift.x);
points[i].y = static_cast<PointCoordinateType>(y + PShift.y);
points[i].z = 0;
@@ -337,8 +365,8 @@
{
file.read(header, 16);
//DGM: ignored
- //double zMin = qFromLittleEndian<double>(*reinterpret_cast<double*>(header ));
- //double zMax = qFromLittleEndian<double>(*reinterpret_cast<double*>(header+8));
+ //double zMin = qFromLittleEndianD(*reinterpret_cast<double*>(header ));
+ //double zMax = qFromLittleEndianD(*reinterpret_cast<double*>(header+8));
}
//Z coordinates (an array of length NumPoints)
@@ -349,7 +377,7 @@
//check for errors
if (file.error() != QFile::NoError)
return CC_FERR_READING;
- double z = qFromLittleEndian<double>(*reinterpret_cast<double*>(header));
+ double z = qFromLittleEndianD(*reinterpret_cast<double*>(header));
points[i].z = static_cast<PointCoordinateType>(z + PShift.z);
}
}
@@ -365,8 +393,8 @@
//check for errors
if (file.error() != QFile::NoError)
return CC_FERR_READING;
- double mMin = qFromLittleEndian<double>(*reinterpret_cast<double*>(header));
- double mMax = qFromLittleEndian<double>(*reinterpret_cast<double*>(header + 8));
+ double mMin = qFromLittleEndianD(*reinterpret_cast<double*>(header));
+ double mMax = qFromLittleEndianD(*reinterpret_cast<double*>(header + 8));
if (mMin != ESRI_NO_DATA && mMax != ESRI_NO_DATA)
{
@@ -391,7 +419,7 @@
//check for errors
if (file.error() != QFile::NoError)
return CC_FERR_READING;
- double m = qFromLittleEndian<double>(*reinterpret_cast<double*>(header));
+ double m = qFromLittleEndianD(*reinterpret_cast<double*>(header));
scalarValues[i] = (m == ESRI_NO_DATA ? NAN_VALUE : static_cast<ScalarType>(m));
}
}
@@ -509,10 +537,10 @@
//Byte 4: Box
{
- double xMin = qToLittleEndian<double>(bbMing.u[X]);
- double xMax = qToLittleEndian<double>(bbMaxg.u[X]);
- double yMin = qToLittleEndian<double>(bbMing.u[Y]);
- double yMax = qToLittleEndian<double>(bbMaxg.u[Y]);
+ double xMin = qToLittleEndianD(bbMing.u[X]);
+ double xMax = qToLittleEndianD(bbMaxg.u[X]);
+ double yMin = qToLittleEndianD(bbMing.u[Y]);
+ double yMax = qToLittleEndianD(bbMaxg.u[Y]);
//The Bounding Box for the PolyLine stored in the order Xmin, Ymin, Xmax, Ymax
/*Byte 4*/file.write((const char*)&xMin, 8);
/*Byte 12*/file.write((const char*)&yMin, 8);
@@ -595,8 +623,8 @@
const CCVector3* P = vertices->getPoint(ii % realNumPoints); //warning: handle loop if polyline is closed
CCVector3d Pg = poly->toGlobal3d(*P);
- double x = qToLittleEndian<double>(Pg.u[X]);
- double y = qToLittleEndian<double>(Pg.u[Y]);
+ double x = qToLittleEndianD(Pg.u[X]);
+ double y = qToLittleEndianD(Pg.u[Y]);
/*Byte 0*/file.write((const char*)&x, 8);
/*Byte 8*/file.write((const char*)&y, 8);
bytesWritten += 16;
@@ -608,8 +636,8 @@
{
//Z boundaries
{
- double zMin = qToLittleEndian<double>(bbMing.u[Z]);
- double zMax = qToLittleEndian<double>(bbMaxg.u[Z]);
+ double zMin = qToLittleEndianD(bbMing.u[Z]);
+ double zMax = qToLittleEndianD(bbMaxg.u[Z]);
file.write((const char*)&zMin, 8);
file.write((const char*)&zMax, 8);
bytesWritten += 16;
@@ -622,7 +650,7 @@
int32_t ii = (inverseOrder ? numPoints - 1 - i : i);
const CCVector3* P = vertices->getPoint(ii % realNumPoints); //warning: handle loop if polyline is closed
CCVector3d Pg = poly->toGlobal3d(*P);
- double z = qToLittleEndian<double>(Pg.u[Z]);
+ double z = qToLittleEndianD(Pg.u[Z]);
file.write((const char*)&z, 8);
bytesWritten += 8;
}
@@ -651,8 +679,8 @@
}
}
}
- mMin = qToLittleEndian<double>(mMin);
- mMax = qToLittleEndian<double>(mMax);
+ mMin = qToLittleEndianD(mMin);
+ mMax = qToLittleEndianD(mMax);
file.write((const char*)&mMin, 8);
file.write((const char*)&mMax, 8);
bytesWritten += 16;
@@ -660,13 +688,13 @@
//M values (for each part - just one here)
{
- double scalar = qToLittleEndian<double>(ESRI_NO_DATA);
+ double scalar = qToLittleEndianD(ESRI_NO_DATA);
for (int32_t i = 0; i < numPoints; ++i)
{
if (hasSF)
{
scalar = static_cast<double>(vertices->getPointScalarValue(i % realNumPoints)); //warning: handle loop if polyline is closed
- scalar = qToLittleEndian<double>(scalar);
+ scalar = qToLittleEndianD(scalar);
}
file.write((const char*)&scalar, 8);
bytesWritten += 8;
@@ -686,10 +714,10 @@
{
//The Bounding Box for the Cloud stored in the order Xmin, Ymin, Xmax, Ymax
//DGM: ignored
- //double xMin = qFromLittleEndian<double>(*reinterpret_cast<double*>(header ));
- //double xMax = qFromLittleEndian<double>(*reinterpret_cast<double*>(header+ 8));
- //double yMin = qFromLittleEndian<double>(*reinterpret_cast<double*>(header+16));
- //double yMax = qFromLittleEndian<double>(*reinterpret_cast<double*>(header+24));
+ //double xMin = qFromLittleEndianD(*reinterpret_cast<double*>(header ));
+ //double xMax = qFromLittleEndianD(*reinterpret_cast<double*>(header+ 8));
+ //double yMin = qFromLittleEndianD(*reinterpret_cast<double*>(header+16));
+ //double yMax = qFromLittleEndianD(*reinterpret_cast<double*>(header+24));
}
//Byte 32: NumPoints (The total number of points)
@@ -708,8 +736,8 @@
for (int32_t i = 0; i < numPoints; ++i)
{
file.read(header, 16);
- double x = qFromLittleEndian<double>(*reinterpret_cast<double*>(header));
- double y = qFromLittleEndian<double>(*reinterpret_cast<double*>(header + 8));
+ double x = qFromLittleEndianD(*reinterpret_cast<double*>(header));
+ double y = qFromLittleEndianD(*reinterpret_cast<double*>(header + 8));
CCVector3 P(static_cast<PointCoordinateType>(x + PShift.x),
static_cast<PointCoordinateType>(y + PShift.y),
0);
@@ -724,8 +752,8 @@
{
file.read(header, 16);
//DGM: ignored
- //double zMin = qFromLittleEndian<double>(*reinterpret_cast<double*>(header ));
- //double zMax = qFromLittleEndian<double>(*reinterpret_cast<double*>(header+8));
+ //double zMin = qFromLittleEndianD(*reinterpret_cast<double*>(header ));
+ //double zMax = qFromLittleEndianD(*reinterpret_cast<double*>(header+8));
}
//Z coordinates (an array of length NumPoints)
@@ -733,7 +761,7 @@
for (int32_t i = 0; i < numPoints; ++i)
{
file.read(header, 8);
- double z = qFromLittleEndian<double>(*reinterpret_cast<double*>(header));
+ double z = qFromLittleEndianD(*reinterpret_cast<double*>(header));
const CCVector3* P = cloud->getPoint(i);
const_cast<CCVector3*>(P)->z = static_cast<PointCoordinateType>(z + PShift.z);
}
@@ -749,8 +777,8 @@
ccScalarField* sf = 0;
{
file.read(header, 16);
- double mMin = qFromLittleEndian<double>(*reinterpret_cast<double*>(header));
- double mMax = qFromLittleEndian<double>(*reinterpret_cast<double*>(header + 8));
+ double mMin = qFromLittleEndianD(*reinterpret_cast<double*>(header));
+ double mMax = qFromLittleEndianD(*reinterpret_cast<double*>(header + 8));
if (mMin != ESRI_NO_DATA && mMax != ESRI_NO_DATA)
{
@@ -770,7 +798,7 @@
for (int32_t i = 0; i < numPoints; ++i)
{
file.read(header, 8);
- double m = qFromLittleEndian<double>(*reinterpret_cast<double*>(header));
+ double m = qFromLittleEndianD(*reinterpret_cast<double*>(header));
ScalarType s = m == ESRI_NO_DATA ? NAN_VALUE : static_cast<ScalarType>(m);
sf->addElement(s);
}
@@ -809,10 +837,10 @@
//Byte 4: Box
{
- double xMin = qToLittleEndian<double>(bbMing.x);
- double xMax = qToLittleEndian<double>(bbMaxg.x);
- double yMin = qToLittleEndian<double>(bbMing.y);
- double yMax = qToLittleEndian<double>(bbMaxg.y);
+ double xMin = qToLittleEndianD(bbMing.x);
+ double xMax = qToLittleEndianD(bbMaxg.x);
+ double yMin = qToLittleEndianD(bbMing.y);
+ double yMax = qToLittleEndianD(bbMaxg.y);
//The Bounding Box for the Cloud stored in the order Xmin, Ymin, Xmax, Ymax
/*Byte 4*/file.write((const char*)&xMin, 8);
/*Byte 12*/file.write((const char*)&yMin, 8);
@@ -836,8 +864,8 @@
const CCVector3* P = cloud->getPoint(i);
CCVector3d Pg = cloud->toGlobal3d(*P);
- double x = qToLittleEndian<double>(Pg.x);
- double y = qToLittleEndian<double>(Pg.y);
+ double x = qToLittleEndianD(Pg.x);
+ double y = qToLittleEndianD(Pg.y);
/*Byte 0*/file.write((const char*)&x, 8);
/*Byte 8*/file.write((const char*)&y, 8);
bytesWritten += 16;
@@ -846,8 +874,8 @@
//Z boundaries
{
- double zMin = qToLittleEndian<double>(bbMing.z);
- double zMax = qToLittleEndian<double>(bbMaxg.z);
+ double zMin = qToLittleEndianD(bbMing.z);
+ double zMax = qToLittleEndianD(bbMaxg.z);
file.write((const char*)&zMin, 8);
file.write((const char*)&zMax, 8);
bytesWritten += 16;
@@ -859,7 +887,7 @@
{
const CCVector3* P = cloud->getPoint(i);
CCVector3d Pg = cloud->toGlobal3d(*P);
- double z = qToLittleEndian<double>(Pg.z);
+ double z = qToLittleEndianD(Pg.z);
file.write((const char*)&z, 8);
bytesWritten += 8;
}
@@ -888,8 +916,8 @@
}
}
}
- mMin = qToLittleEndian<double>(mMin);
- mMax = qToLittleEndian<double>(mMax);
+ mMin = qToLittleEndianD(mMin);
+ mMax = qToLittleEndianD(mMax);
file.write((const char*)&mMin, 8);
file.write((const char*)&mMax, 8);
bytesWritten += 16;
@@ -897,13 +925,13 @@
//M values
{
- double scalar = qToLittleEndian<double>(ESRI_NO_DATA);
+ double scalar = qToLittleEndianD(ESRI_NO_DATA);
for (int32_t i = 0; i < numPoints; ++i)
{
if (hasSF)
{
scalar = static_cast<double>(cloud->getPointScalarValue(i));
- scalar = qToLittleEndian<double>(scalar);
+ scalar = qToLittleEndianD(scalar);
}
file.write((const char*)&scalar, 8);
bytesWritten += 8;
@@ -918,8 +946,8 @@
char buffer[16];
file.read(buffer, 16);
- double x = qFromLittleEndian<double>(*reinterpret_cast<double*>(buffer));
- double y = qFromLittleEndian<double>(*reinterpret_cast<double*>(buffer + 8));
+ double x = qFromLittleEndianD(*reinterpret_cast<double*>(buffer));
+ double y = qFromLittleEndianD(*reinterpret_cast<double*>(buffer + 8));
CCVector3 P(static_cast<PointCoordinateType>(x + PShift.x),
static_cast<PointCoordinateType>(y + PShift.y),
0);
@@ -930,7 +958,7 @@
//Z coordinate
{
file.read(buffer, 8);
- double z = qFromLittleEndian<double>(*reinterpret_cast<double*>(buffer));
+ double z = qFromLittleEndianD(*reinterpret_cast<double*>(buffer));
P.z = static_cast<PointCoordinateType>(z + PShift.z);
}
}
@@ -957,7 +985,7 @@
//Measure
{
file.read(buffer, 8);
- double m = qFromLittleEndian<double>(*reinterpret_cast<double*>(buffer));
+ double m = qFromLittleEndianD(*reinterpret_cast<double*>(buffer));
if (m != ESRI_NO_DATA)
{
s = static_cast<ScalarType>(m);
@@ -1144,10 +1172,10 @@
_header += 4;
//X and Y bounaries
- double xMin = qToLittleEndian<double>(bbMinCorner.u[X]);
- double xMax = qToLittleEndian<double>(bbMaxCorner.u[X]);
- double yMin = qToLittleEndian<double>(bbMinCorner.u[Y]);
- double yMax = qToLittleEndian<double>(bbMaxCorner.u[Y]);
+ double xMin = qToLittleEndianD(bbMinCorner.u[X]);
+ double xMax = qToLittleEndianD(bbMaxCorner.u[X]);
+ double yMin = qToLittleEndianD(bbMinCorner.u[Y]);
+ double yMax = qToLittleEndianD(bbMaxCorner.u[Y]);
//Byte 36: box X min
memcpy(_header, (const char*)&xMin, 8);
_header += 8;
@@ -1163,8 +1191,8 @@
//Z bounaries
//Unused, with value 0.0, if not Measured or Z type
- double zMin = outputShapeType < SHP_POINT_Z ? 0.0 : qToLittleEndian<double>(bbMinCorner.u[Z]);
- double zMax = outputShapeType < SHP_POINT_Z ? 0.0 : qToLittleEndian<double>(bbMaxCorner.u[Z]);
+ double zMin = outputShapeType < SHP_POINT_Z ? 0.0 : qToLittleEndianD(bbMinCorner.u[Z]);
+ double zMax = outputShapeType < SHP_POINT_Z ? 0.0 : qToLittleEndianD(bbMaxCorner.u[Z]);
//Byte 68: box Z min
memcpy(_header, (const char*)&zMin, 8);
_header += 8;
@@ -1447,25 +1475,25 @@
//X and Y bounaries
//Byte 36: box X min
- double xMin = qFromLittleEndian<double>(*reinterpret_cast<const double*>(_header));
+ double xMin = qFromLittleEndianD(*reinterpret_cast<const double*>(_header));
_header += 8;
//Byte 44: box Y min
- double yMin = qFromLittleEndian<double>(*reinterpret_cast<const double*>(_header));
+ double yMin = qFromLittleEndianD(*reinterpret_cast<const double*>(_header));
_header += 8;
//Byte 52: box X max
- //double xMax = qFromLittleEndian<double>(*reinterpret_cast<const double*>(_header));
+ //double xMax = qFromLittleEndianD(*reinterpret_cast<const double*>(_header));
_header += 8;
//Byte 60: box Y max
- //double yMax = qFromLittleEndian<double>(*reinterpret_cast<const double*>(_header));
+ //double yMax = qFromLittleEndianD(*reinterpret_cast<const double*>(_header));
_header += 8;
//Z bounaries
//Unused, with value 0.0, if not Measured or Z type
//Byte 68: box Z min
- double zMin = qFromLittleEndian<double>(*reinterpret_cast<const double*>(_header));
+ double zMin = qFromLittleEndianD(*reinterpret_cast<const double*>(_header));
_header += 8;
//Byte 76: box Z max
- //double zMax = qFromLittleEndian<double>(*reinterpret_cast<const double*>(_header));
+ //double zMax = qFromLittleEndianD(*reinterpret_cast<const double*>(_header));
_header += 8;
if (std::isnan(zMin))
@@ -1482,10 +1510,10 @@
//M bounaries (M = measures)
//Byte 84: M min
- //double mMin = qFromLittleEndian<double>(*reinterpret_cast<const double*>(_header));
+ //double mMin = qFromLittleEndianD(*reinterpret_cast<const double*>(_header));
_header += 8;
//Byte 92: M max
- //double mMax = qFromLittleEndian<double>(*reinterpret_cast<const double*>(_header));
+ //double mMax = qFromLittleEndianD(*reinterpret_cast<const double*>(_header));
_header += 8;
}
assert(fileLength >= 100);