1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-11-24 11:45:53 +01:00

Fixed broken tile/subdivs/polygon bounds/coordinates

+ do the coordinates left shift in a C++ standard defined way
This commit is contained in:
Martin Tůma 2020-02-15 11:46:16 +01:00
parent ce043ef8fa
commit 42e4b0769f
3 changed files with 40 additions and 27 deletions

View File

@ -3,14 +3,16 @@
#include <QtGlobal> #include <QtGlobal>
#define LS(val, bits) ((qint32)(((quint32)(val))<<(bits)))
inline double toWGS32(qint32 v) inline double toWGS32(qint32 v)
{ {
return (double)(((double)v / (double)(1U<<31)) * (double)180); return ((double)v / (double)(1U<<31)) * 180.0;
} }
inline double toWGS24(qint32 v) inline double toWGS24(qint32 v)
{ {
return toWGS32(v<<8); return toWGS32(LS(v, 8));
} }
#endif // GARMIN_H #endif // GARMIN_H

View File

@ -154,8 +154,8 @@ bool RGNFile::polyObjects(Handle &hdl, const SubDiv *subdiv,
? ((quint32)(type & 0x7F)) << 8 : ((quint32)(type & 0x3F)) << 8; ? ((quint32)(type & 0x7F)) << 8 : ((quint32)(type & 0x3F)) << 8;
QPoint pos(subdiv->lon() + ((qint32)lon<<(24-subdiv->bits())), QPoint pos(subdiv->lon() + LS(lon, 24-subdiv->bits()),
subdiv->lat() + ((qint32)lat<<(24-subdiv->bits()))); subdiv->lat() + LS(lat, 24-subdiv->bits()));
Coordinates c(toWGS24(pos.x()), toWGS24(pos.y())); Coordinates c(toWGS24(pos.x()), toWGS24(pos.y()));
poly.boundingRect = RectC(c, c); poly.boundingRect = RectC(c, c);
poly.points.append(QPointF(c.lon(), c.lat())); poly.points.append(QPointF(c.lon(), c.lat()));
@ -164,8 +164,10 @@ bool RGNFile::polyObjects(Handle &hdl, const SubDiv *subdiv,
DeltaStream stream(*this, hdl, len, bitstreamInfo, labelPtr & 0x400000, DeltaStream stream(*this, hdl, len, bitstreamInfo, labelPtr & 0x400000,
false); false);
while (stream.readNext(lonDelta, latDelta)) { while (stream.readNext(lonDelta, latDelta)) {
pos.rx() += lonDelta<<(24-subdiv->bits()); pos.rx() += LS(lonDelta, (24-subdiv->bits()));
pos.ry() += latDelta<<(24-subdiv->bits()); if (pos.rx() >= 0x800000 && subdiv->lon() >= 0)
pos.rx() = 0x7fffff;
pos.ry() += LS(latDelta, (24-subdiv->bits()));
Coordinates c(toWGS24(pos.x()), toWGS24(pos.y())); Coordinates c(toWGS24(pos.x()), toWGS24(pos.y()));
poly.points.append(QPointF(c.lon(), c.lat())); poly.points.append(QPointF(c.lon(), c.lat()));
@ -219,8 +221,8 @@ bool RGNFile::extPolyObjects(Handle &hdl, const SubDiv *subdiv, quint32 shift,
labelPtr = 0; labelPtr = 0;
if (!_huffmanTable.isNull()) { if (!_huffmanTable.isNull()) {
pos = QPoint((subdiv->lon()<<8) + ((qint32)lon<<(32-subdiv->bits())), pos = QPoint(LS(subdiv->lon(), 8) + LS(lon, 32-subdiv->bits()),
(subdiv->lat()<<8) + ((qint32)lat<<(32-subdiv->bits()))); LS(subdiv->lat(), 8) + LS(lat, (32-subdiv->bits())));
qint32 lonDelta, latDelta; qint32 lonDelta, latDelta;
HuffmanStream stream(*this, hdl, len, _huffmanTable, HuffmanStream stream(*this, hdl, len, _huffmanTable,
@ -229,16 +231,18 @@ bool RGNFile::extPolyObjects(Handle &hdl, const SubDiv *subdiv, quint32 shift,
if (shift) { if (shift) {
if (!stream.readOffset(lonDelta, latDelta)) if (!stream.readOffset(lonDelta, latDelta))
return false; return false;
pos = QPoint(pos.x() | lonDelta<<(32-subdiv->bits()-shift), pos = QPoint(pos.x() | LS(lonDelta, 32-subdiv->bits()-shift),
pos.y() | latDelta<<(32-subdiv->bits()-shift)); pos.y() | LS(latDelta, 32-subdiv->bits()-shift));
} }
Coordinates c(toWGS32(pos.x()), toWGS32(pos.y())); Coordinates c(toWGS32(pos.x()), toWGS32(pos.y()));
poly.boundingRect = RectC(c, c); poly.boundingRect = RectC(c, c);
poly.points.append(QPointF(c.lon(), c.lat())); poly.points.append(QPointF(c.lon(), c.lat()));
while (stream.readNext(lonDelta, latDelta)) { while (stream.readNext(lonDelta, latDelta)) {
pos.rx() += lonDelta<<(32-subdiv->bits()-shift); pos.rx() += LS(lonDelta, 32-subdiv->bits()-shift);
pos.ry() += latDelta<<(32-subdiv->bits()-shift); if (pos.rx() < 0 && subdiv->lon() >= 0)
pos.rx() = 0x7fffffff;
pos.ry() += LS(latDelta, 32-subdiv->bits()-shift);
Coordinates c(toWGS32(pos.x()), toWGS32(pos.y())); Coordinates c(toWGS32(pos.x()), toWGS32(pos.y()));
poly.points.append(QPointF(c.lon(), c.lat())); poly.points.append(QPointF(c.lon(), c.lat()));
@ -248,8 +252,8 @@ bool RGNFile::extPolyObjects(Handle &hdl, const SubDiv *subdiv, quint32 shift,
if (!(stream.atEnd() && stream.flush())) if (!(stream.atEnd() && stream.flush()))
return false; return false;
} else { } else {
pos = QPoint(subdiv->lon() + ((qint32)lon<<(24-subdiv->bits())), pos = QPoint(subdiv->lon() + LS(lon, 24-subdiv->bits()),
subdiv->lat() + ((qint32)lat<<(24-subdiv->bits()))); subdiv->lat() + LS(lat, 24-subdiv->bits()));
Coordinates c(toWGS24(pos.x()), toWGS24(pos.y())); Coordinates c(toWGS24(pos.x()), toWGS24(pos.y()));
poly.boundingRect = RectC(c, c); poly.boundingRect = RectC(c, c);
poly.points.append(QPointF(c.lon(), c.lat())); poly.points.append(QPointF(c.lon(), c.lat()));
@ -262,8 +266,10 @@ bool RGNFile::extPolyObjects(Handle &hdl, const SubDiv *subdiv, quint32 shift,
DeltaStream stream(*this, hdl, len - 1, bitstreamInfo, false, true); DeltaStream stream(*this, hdl, len - 1, bitstreamInfo, false, true);
while (stream.readNext(lonDelta, latDelta)) { while (stream.readNext(lonDelta, latDelta)) {
pos.rx() += lonDelta<<(24-subdiv->bits()); pos.rx() += LS(lonDelta, 24-subdiv->bits());
pos.ry() += latDelta<<(24-subdiv->bits()); if (pos.rx() >= 0x800000 && subdiv->lon() >= 0)
pos.rx() = 0x7fffff;
pos.ry() += LS(latDelta, 24-subdiv->bits());
Coordinates c(toWGS24(pos.x()), toWGS24(pos.y())); Coordinates c(toWGS24(pos.x()), toWGS24(pos.y()));
poly.points.append(QPointF(c.lon(), c.lat())); poly.points.append(QPointF(c.lon(), c.lat()));
@ -319,8 +325,8 @@ bool RGNFile::pointObjects(Handle &hdl, const SubDiv *subdiv,
point.type = (quint16)type<<8 | subtype; point.type = (quint16)type<<8 | subtype;
qint32 lonOffset = lon<<(24-subdiv->bits()); qint32 lonOffset = LS(lon, 24-subdiv->bits());
qint32 latOffset = lat<<(24-subdiv->bits()); qint32 latOffset = LS(lat, 24-subdiv->bits());
point.coordinates = Coordinates(toWGS24(subdiv->lon() + lonOffset), point.coordinates = Coordinates(toWGS24(subdiv->lon() + lonOffset),
toWGS24(subdiv->lat() + latOffset)); toWGS24(subdiv->lat() + latOffset));
@ -361,8 +367,8 @@ bool RGNFile::extPointObjects(Handle &hdl, const SubDiv *subdiv, LBLFile *lbl,
point.type = 0x10000 | (((quint32)type)<<8) | (subtype & 0x1F); point.type = 0x10000 | (((quint32)type)<<8) | (subtype & 0x1F);
qint32 lonOffset = lon<<(24-subdiv->bits()); qint32 lonOffset = LS(lon, 24-subdiv->bits());
qint32 latOffset = lat<<(24-subdiv->bits()); qint32 latOffset = LS(lat, 24-subdiv->bits());
point.coordinates = Coordinates(toWGS24(subdiv->lon() + lonOffset), point.coordinates = Coordinates(toWGS24(subdiv->lon() + lonOffset),
toWGS24(subdiv->lat() + latOffset)); toWGS24(subdiv->lat() + latOffset));
labelPtr = 0; labelPtr = 0;

View File

@ -3,6 +3,11 @@
#include "trefile.h" #include "trefile.h"
static inline double RB(qint32 val)
{
return (val == -0x800000 || val == 0x800000) ? 180.0 : toWGS24(val);
}
static void demangle(quint8 *data, quint32 size, quint32 key) static void demangle(quint8 *data, quint32 size, quint32 key)
{ {
static const unsigned char shuf[] = { static const unsigned char shuf[] = {
@ -53,7 +58,8 @@ bool TREFile::init(bool baseMap)
&& readInt24(hdl, east) && readInt24(hdl, south) && readInt24(hdl, west))) && readInt24(hdl, east) && readInt24(hdl, south) && readInt24(hdl, west)))
return false; return false;
_bounds = RectC(Coordinates(toWGS24(west), toWGS24(north)), _bounds = RectC(Coordinates(toWGS24(west), toWGS24(north)),
Coordinates(toWGS24(east), toWGS24(south))); Coordinates(RB(east), toWGS24(south)));
Q_ASSERT(_bounds.left() <= _bounds.right());
// Levels & subdivs info // Levels & subdivs info
quint32 levelsOffset, levelsSize, subdivSize; quint32 levelsOffset, levelsSize, subdivSize;
@ -149,17 +155,16 @@ bool TREFile::load(int idx)
s->setEnd(offset); s->setEnd(offset);
width &= 0x7FFF; width &= 0x7FFF;
width <<= (24 - _levels.at(idx).bits); width = LS(width, 24 - _levels.at(idx).bits);
height <<= (24 - _levels.at(idx).bits); height = LS(height, 24 - _levels.at(idx).bits);
s = new SubDiv(offset, lon, lat, _levels.at(idx).bits, objects); s = new SubDiv(offset, lon, lat, _levels.at(idx).bits, objects);
sl.append(s); sl.append(s);
double min[2], max[2]; double min[2], max[2];
RectC bounds(Coordinates(toWGS24(lon - width), RectC bounds(Coordinates(toWGS24(lon - width), toWGS24(lat + height)),
toWGS24(lat + height + 1)), Coordinates(toWGS24(lon + width + 1), Coordinates(RB(lon + width), toWGS24(lat - height)));
toWGS24(lat - height))); Q_ASSERT(bounds.left() <= bounds.right());
min[0] = bounds.left(); min[0] = bounds.left();
min[1] = bounds.bottom(); min[1] = bounds.bottom();