1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2025-05-04 10:27:44 +02:00

Merge branch 'master' into android-latest

This commit is contained in:
Martin Tůma 2025-04-22 19:22:36 +02:00
commit 5898cd0878
10 changed files with 233 additions and 269 deletions

View File

@ -1,4 +1,4 @@
version: 13.39.{build} version: 13.40.{build}
configuration: configuration:
- Release - Release

View File

@ -3,7 +3,7 @@ unix:!macx:!android {
} else { } else {
TARGET = GPXSee TARGET = GPXSee
} }
VERSION = 13.39 VERSION = 13.40
QT += core \ QT += core \
gui \ gui \

View File

@ -49,7 +49,7 @@ Unicode true
; The name of the installer ; The name of the installer
Name "GPXSee" Name "GPXSee"
; Program version ; Program version
!define VERSION "13.39" !define VERSION "13.40"
; The file to write ; The file to write
OutFile "GPXSee-${VERSION}_x64.exe" OutFile "GPXSee-${VERSION}_x64.exe"

View File

@ -1,3 +1,4 @@
#include <QtEndian>
#include <QFile> #include <QFile>
#include <QRegularExpression> #include <QRegularExpression>
#include "common/util.h" #include "common/util.h"
@ -5,13 +6,6 @@
using namespace ENC; using namespace ENC;
#define UINT16(x) \
(((quint16)*(const uchar*)(x)) \
| ((quint16)(*((const uchar*)(x) + 1)) << 8))
#define INT32(x) ((qint32)UINT32(x))
#define INT16(x) ((qint16)UINT16(x))
struct DR { struct DR {
char RecordLength[5]; char RecordLength[5];
char InterchangeLevel; char InterchangeLevel;
@ -28,52 +22,6 @@ struct DR {
char FieldTagSize; char FieldTagSize;
}; };
const QVariant *ISO8211::Field::data(const QByteArray &name, int idx) const
{
const QVector<QVariant> &v = _data.at(idx);
for (int i = 0; i < _subFields.size(); i++)
if (_subFields.at(i) == name)
return &v.at(i);
return 0;
}
bool ISO8211::Field::subfield(const char *name, int *val, int idx) const
{
bool ok;
const QVariant *v = data(name, idx);
if (!v)
return false;
*val = v->toInt(&ok);
return ok;
}
bool ISO8211::Field::subfield(const char *name, uint *val, int idx) const
{
bool ok;
const QVariant *v = data(name, idx);
if (!v)
return false;
*val = v->toUInt(&ok);
return ok;
}
bool ISO8211::Field::subfield(const char *name, QByteArray *val, int idx) const
{
const QVariant *v = data(name, idx);
if (!v)
return false;
*val = v->toByteArray();
return true;
}
ISO8211::SubFieldDefinition ISO8211::fieldType(const QString &str, int cnt) ISO8211::SubFieldDefinition ISO8211::fieldType(const QString &str, int cnt)
{ {
if (str == "A" || str == "I" || str == "R") if (str == "A" || str == "I" || str == "R")
@ -101,6 +49,7 @@ int ISO8211::readDR(QVector<FieldDefinition> &fields)
DR ddr; DR ddr;
QByteArray fieldLen, fieldPos; QByteArray fieldLen, fieldPos;
int len, lenSize, posSize, tagSize, offset; int len, lenSize, posSize, tagSize, offset;
char tag[4];
static_assert(sizeof(ddr) == 24, "Invalid DR alignment"); static_assert(sizeof(ddr) == 24, "Invalid DR alignment");
if (_file.read((char*)&ddr, sizeof(ddr)) != sizeof(ddr)) if (_file.read((char*)&ddr, sizeof(ddr)) != sizeof(ddr))
@ -115,20 +64,19 @@ int ISO8211::readDR(QVector<FieldDefinition> &fields)
if (len < 0 || offset < 0 || lenSize < 0 || posSize < 0 || tagSize < 0) if (len < 0 || offset < 0 || lenSize < 0 || posSize < 0 || tagSize < 0)
return -1; return -1;
fields.resize((offset - 1 - sizeof(DR)) / (lenSize + posSize + tagSize)); fields.resize((offset - 1 - sizeof(ddr)) / (lenSize + posSize + tagSize));
fieldLen.resize(lenSize); fieldLen.resize(lenSize);
fieldPos.resize(posSize); fieldPos.resize(posSize);
for (int i = 0; i < fields.size(); i++) { for (int i = 0; i < fields.size(); i++) {
FieldDefinition &r = fields[i]; FieldDefinition &r = fields[i];
r.tag.resize(tagSize); if (_file.read(tag, sizeof(tag)) != tagSize
if (_file.read(r.tag.data(), tagSize) != tagSize
|| _file.read(fieldLen.data(), lenSize) != lenSize || _file.read(fieldLen.data(), lenSize) != lenSize
|| _file.read(fieldPos.data(), posSize) != posSize) || _file.read(fieldPos.data(), posSize) != posSize)
return -1; return -1;
r.tag = qFromLittleEndian<quint32>(tag);
r.pos = offset + Util::str2int(fieldPos.constData(), posSize); r.pos = offset + Util::str2int(fieldPos.constData(), posSize);
r.size = Util::str2int(fieldLen.constData(), lenSize); r.size = Util::str2int(fieldLen.constData(), lenSize);
@ -141,11 +89,12 @@ int ISO8211::readDR(QVector<FieldDefinition> &fields)
bool ISO8211::readDDA(const FieldDefinition &def, SubFields &fields) bool ISO8211::readDDA(const FieldDefinition &def, SubFields &fields)
{ {
static const QRegularExpression re("(\\d*)(\\w+)\\(*(\\d*)\\)*"); static const QRegularExpression re(
"([0-9]*)(A|I|R|B|b11|b12|b14|b21|b22|b24)\\(*([0-9]*)\\)*");
QByteArray ba(def.size, Qt::Initialization::Uninitialized); QByteArray ba(def.size, Qt::Initialization::Uninitialized);
bool repeat = false; bool repeat = false;
QVector<SubFieldDefinition> defs; QVector<SubFieldDefinition> defs;
QVector<QByteArray> defTags; QVector<quint32> defTags;
if (!(_file.seek(def.pos) && _file.read(ba.data(), ba.size()) == ba.size())) if (!(_file.seek(def.pos) && _file.read(ba.data(), ba.size()) == ba.size()))
return false; return false;
@ -155,9 +104,9 @@ bool ISO8211::readDDA(const FieldDefinition &def, SubFields &fields)
repeat = true; repeat = true;
list[1].remove(0, 1); list[1].remove(0, 1);
} }
QList<QByteArray> tags(list.at(1).split('!'));
if (list.size() > 2) { if (list.size() > 2) {
QList<QByteArray> tags(list.at(1).split('!'));
QRegularExpressionMatchIterator it = re.globalMatch(list.at(2)); QRegularExpressionMatchIterator it = re.globalMatch(list.at(2));
int tag = 0; int tag = 0;
@ -187,11 +136,17 @@ bool ISO8211::readDDA(const FieldDefinition &def, SubFields &fields)
SubFieldDefinition sfd(fieldType(typeStr, size)); SubFieldDefinition sfd(fieldType(typeStr, size));
if (sfd.type() == Unknown) if (sfd.type() == Unknown)
return false; return false;
if (tag >= tags.size())
return false;
defs[tag] = sfd; defs[tag] = sfd;
defTags[tag] = tags.at(tag); defTags[tag] = (tags.at(tag).length() == 4)
? qFromLittleEndian<quint32>(tags.at(tag).constData()) : 0;
tag++; tag++;
} }
} }
if (tag != tags.size())
return false;
} }
fields = SubFields(defTags, defs, repeat); fields = SubFields(defTags, defs, repeat);
@ -217,8 +172,10 @@ bool ISO8211::readDDR()
for (int i = 0; i < fields.size(); i++) { for (int i = 0; i < fields.size(); i++) {
SubFields def; SubFields def;
if (!readDDA(fields.at(i), def)) { if (!readDDA(fields.at(i), def)) {
QByteArray tag(sizeof(quint32), Qt::Initialization::Uninitialized);
qToLittleEndian<quint32>(fields.at(i).tag, tag.data());
_errorString = QString("Error reading %1 DDA field") _errorString = QString("Error reading %1 DDA field")
.arg(QString(fields.at(i).tag)); .arg(QString(tag));
return false; return false;
} }
_map.insert(fields.at(i).tag, def); _map.insert(fields.at(i).tag, def);
@ -270,11 +227,11 @@ bool ISO8211::readUDA(quint64 pos, const FieldDefinition &def,
dp++; dp++;
break; break;
case S16: case S16:
row[i] = QVariant(INT16(dp)); row[i] = QVariant(qFromLittleEndian<qint16>(dp));
dp += 2; dp += 2;
break; break;
case S32: case S32:
row[i] = QVariant(INT32(dp)); row[i] = QVariant(qFromLittleEndian<qint32>(dp));
dp += 4; dp += 4;
break; break;
case U8: case U8:
@ -282,11 +239,11 @@ bool ISO8211::readUDA(quint64 pos, const FieldDefinition &def,
dp++; dp++;
break; break;
case U16: case U16:
row[i] = QVariant(UINT16(dp)); row[i] = QVariant(qFromLittleEndian<quint16>(dp));
dp += 2; dp += 2;
break; break;
case U32: case U32:
row[i] = QVariant(UINT32(dp)); row[i] = QVariant(qFromLittleEndian<quint32>(dp));
dp += 4; dp += 4;
break; break;
default: default:
@ -322,24 +279,26 @@ bool ISO8211::readRecord(Record &record)
FieldsMap::const_iterator it(_map.find(def.tag)); FieldsMap::const_iterator it(_map.find(def.tag));
if (it == _map.constEnd()) { if (it == _map.constEnd()) {
_errorString = QString("%1: unknown record").arg(QString(def.tag)); QByteArray tag(sizeof(quint32), Qt::Initialization::Uninitialized);
qToLittleEndian<quint32>(def.tag, tag.data());
_errorString = QString("%1: unknown record").arg(QString(tag));
return false; return false;
} }
if (!readUDA(pos, def, it->defs(), it->repeat(), data)) { if (!readUDA(pos, def, it->defs(), it->repeat(), data)) {
_errorString = QString("Error reading %1 record") QByteArray tag(sizeof(quint32), Qt::Initialization::Uninitialized);
.arg(QString(def.tag)); qToLittleEndian<quint32>(def.tag, tag.data());
_errorString = QString("Error reading %1 record").arg(QString(tag));
return false; return false;
} }
record[i] = Field(def.tag, it->tags(), data); record[i] = Field(def.tag, data);
} }
return true; return true;
} }
const ISO8211::Field *ISO8211::field(const Record &record, quint32 name)
const ISO8211::Field *ISO8211::field(const Record &record, const QByteArray &name)
{ {
for (int i = 0; i < record.size(); i++) for (int i = 0; i < record.size(); i++)
if (record.at(i).tag() == name) if (record.at(i).tag() == name)

View File

@ -4,13 +4,6 @@
#include <QFile> #include <QFile>
#include <QByteArray> #include <QByteArray>
#include <QVariant> #include <QVariant>
#include <QDebug>
#define UINT32(x) \
(((quint32)*(const uchar*)(x)) \
| ((quint32)(*((const uchar*)(x) + 1)) << 8) \
| ((quint32)(*((const uchar*)(x) + 2)) << 16) \
| ((quint32)(*((const uchar*)(x) + 3)) << 24))
namespace ENC { namespace ENC {
@ -22,23 +15,14 @@ public:
class Field class Field
{ {
public: public:
Field() {} Field() : _tag(0) {}
Field(const QByteArray &tag, const QVector<QByteArray> &subFields, Field(quint32 tag, const Data &data) : _tag(tag), _data(data) {}
const Data &data) : _tag(tag), _subFields(subFields), _data(data) {}
const QByteArray &tag() const {return _tag;} quint32 tag() const {return _tag;}
const QVector<QByteArray> &subFields() const {return _subFields;}
const Data &data() const {return _data;} const Data &data() const {return _data;}
bool subfield(const char *name, int *val, int idx = 0) const;
bool subfield(const char *name, uint *val, int idx = 0) const;
bool subfield(const char *name, QByteArray *val, int idx = 0) const;
private: private:
const QVariant *data(const QByteArray &name, int idx = 0) const; quint32 _tag;
QByteArray _tag;
QVector<QByteArray> _subFields;
Data _data; Data _data;
}; };
@ -47,17 +31,23 @@ public:
ISO8211(const QString &path) : _file(path) {} ISO8211(const QString &path) : _file(path) {}
bool readDDR(); bool readDDR();
bool readRecord(Record &record); bool readRecord(Record &record);
const QString &errorString() const {return _errorString;} const QString &errorString() const {return _errorString;}
static const Field *field(const Record &record, const QByteArray &name); static const Field *field(const Record &record, quint32 name);
static constexpr quint32 NAME(const char str[4])
{
return static_cast<quint32>(str[0])
+ (static_cast<quint32>(str[1]) << 8)
+ (static_cast<quint32>(str[2]) << 16)
+ (static_cast<quint32>(str[3]) << 24);
}
private: private:
enum FieldType {Unknown, String, Array, S8, S16, S32, U8, U16, U32}; enum FieldType {Unknown, String, Array, S8, S16, S32, U8, U16, U32};
struct FieldDefinition struct FieldDefinition
{ {
QByteArray tag; quint32 tag;
int pos; int pos;
int size; int size;
}; };
@ -81,22 +71,22 @@ private:
{ {
public: public:
SubFields() : _repeat(false) {} SubFields() : _repeat(false) {}
SubFields(const QVector<QByteArray> &tags, SubFields(const QVector<quint32> &tags,
const QVector<SubFieldDefinition> &defs, bool repeat) const QVector<SubFieldDefinition> &defs, bool repeat)
: _tags(tags), _defs(defs), _repeat(repeat) {} : _tags(tags), _defs(defs), _repeat(repeat) {}
const QVector<QByteArray> &tags() const {return _tags;} const QVector<quint32> &tags() const {return _tags;}
const QVector<SubFieldDefinition> &defs() const {return _defs;} const QVector<SubFieldDefinition> &defs() const {return _defs;}
bool repeat() const {return _repeat;} bool repeat() const {return _repeat;}
private: private:
QVector<QByteArray> _tags; QVector<quint32> _tags;
QVector<SubFieldDefinition> _defs; QVector<SubFieldDefinition> _defs;
bool _repeat; bool _repeat;
}; };
typedef QMap<QByteArray, SubFields> FieldsMap; typedef QMap<quint32, SubFields> FieldsMap;
static SubFieldDefinition fieldType(const QString &str, int cnt); static SubFieldDefinition fieldType(const QString &str, int cnt);
@ -110,14 +100,6 @@ private:
QString _errorString; QString _errorString;
}; };
#ifndef QT_NO_DEBUG
inline QDebug operator<<(QDebug dbg, const ISO8211::Field &field)
{
dbg.nospace() << "Field(" << field.tag() << ", " << field.subFields() << ")";
return dbg.space();
}
#endif // QT_NO_DEBUG
} }
#endif // ENC_ISO8211_H #endif // ENC_ISO8211_H

View File

@ -1,3 +1,4 @@
#include <QtEndian>
#include "GUI/units.h" #include "GUI/units.h"
#include "objects.h" #include "objects.h"
#include "attributes.h" #include "attributes.h"
@ -14,6 +15,15 @@ using namespace ENC;
#define PRIM_L 2 #define PRIM_L 2
#define PRIM_A 3 #define PRIM_A 3
constexpr quint32 SG2D = ISO8211::NAME("SG2D");
constexpr quint32 SG3D = ISO8211::NAME("SG3D");
constexpr quint32 FSPT = ISO8211::NAME("FSPT");
constexpr quint32 VRPT = ISO8211::NAME("VRPT");
constexpr quint32 ATTF = ISO8211::NAME("ATTF");
constexpr quint32 VRID = ISO8211::NAME("VRID");
constexpr quint32 FRID = ISO8211::NAME("FRID");
constexpr quint32 DSPM = ISO8211::NAME("DSPM");
static QMap<uint,uint> orderMapInit() static QMap<uint,uint> orderMapInit()
{ {
QMap<uint,uint> map; QMap<uint,uint> map;
@ -90,20 +100,19 @@ static uint order(uint type)
return (it == orderMap.constEnd()) ? (type>>16) + 512 : it.value(); return (it == orderMap.constEnd()) ? (type>>16) + 512 : it.value();
} }
static void warning(const ISO8211::Field &FRID, uint PRIM) static void warning(const ISO8211::Field &frid, uint prim)
{ {
uint RCID = 0xFFFFFFFF; uint rcid = frid.data().at(0).at(1).toUInt();
FRID.subfield("RCID", &RCID);
switch (PRIM) { switch (prim) {
case PRIM_P: case PRIM_P:
qWarning("%u: invalid point feature", RCID); qWarning("%u: invalid point feature", rcid);
break; break;
case PRIM_L: case PRIM_L:
qWarning("%u: invalid line feature", RCID); qWarning("%u: invalid line feature", rcid);
break; break;
case PRIM_A: case PRIM_A:
qWarning("%u: invalid area feature", RCID); qWarning("%u: invalid area feature", rcid);
break; break;
} }
} }
@ -132,7 +141,7 @@ static bool parseNAME(const ISO8211::Field *f, quint8 *type, quint32 *id,
return false; return false;
*type = (quint8)(*ba.constData()); *type = (quint8)(*ba.constData());
*id = UINT32(ba.constData() + 1); *id = qFromLittleEndian<quint32>(ba.constData() + 1);
return true; return true;
} }
@ -141,9 +150,9 @@ static const ISO8211::Field *SGXD(const ISO8211::Record &r)
{ {
const ISO8211::Field *f; const ISO8211::Field *f;
if ((f = ISO8211::field(r, "SG2D"))) if ((f = ISO8211::field(r, SG2D)))
return f; return f;
else if ((f = ISO8211::field(r, "SG3D"))) else if ((f = ISO8211::field(r, SG3D)))
return f; return f;
else else
return 0; return 0;
@ -212,12 +221,12 @@ static bool linePointCb(const MapData::Line *line, void *context)
return true; return true;
} }
static Coordinates coordinates(int x, int y, uint COMF) static Coordinates coordinates(int x, int y, uint comf)
{ {
return Coordinates(x / (double)COMF, y / (double)COMF); return Coordinates(x / (double)comf, y / (double)comf);
} }
static Coordinates point(const ISO8211::Record &r, uint COMF) static Coordinates point(const ISO8211::Record &r, uint comf)
{ {
const ISO8211::Field *f = SGXD(r); const ISO8211::Field *f = SGXD(r);
if (!f) if (!f)
@ -226,7 +235,7 @@ static Coordinates point(const ISO8211::Record &r, uint COMF)
int y = f->data().at(0).at(0).toInt(); int y = f->data().at(0).at(0).toInt();
int x = f->data().at(0).at(1).toInt(); int x = f->data().at(0).at(1).toInt();
return coordinates(x, y, COMF); return coordinates(x, y, comf);
} }
static uint depthLevel(double minDepth) static uint depthLevel(double minDepth)
@ -477,10 +486,10 @@ RectC MapData::Line::bounds() const
} }
QVector<MapData::Sounding> MapData::soundings(const ISO8211::Record &r, QVector<MapData::Sounding> MapData::soundings(const ISO8211::Record &r,
uint COMF, uint SOMF) uint comf, uint somf)
{ {
QVector<Sounding> s; QVector<Sounding> s;
const ISO8211::Field *f = ISO8211::field(r, "SG3D"); const ISO8211::Field *f = ISO8211::field(r, SG3D);
if (!f) if (!f)
return QVector<Sounding>(); return QVector<Sounding>();
@ -489,24 +498,24 @@ QVector<MapData::Sounding> MapData::soundings(const ISO8211::Record &r,
int y = f->data().at(i).at(0).toInt(); int y = f->data().at(i).at(0).toInt();
int x = f->data().at(i).at(1).toInt(); int x = f->data().at(i).at(1).toInt();
int z = f->data().at(i).at(2).toInt(); int z = f->data().at(i).at(2).toInt();
s.append(Sounding(coordinates(x, y, COMF), z / (double)SOMF)); s.append(Sounding(coordinates(x, y, comf), z / (double)somf));
} }
return s; return s;
} }
QVector<MapData::Sounding> MapData::soundingGeometry(const ISO8211::Record &r, QVector<MapData::Sounding> MapData::soundingGeometry(const ISO8211::Record &r,
const RecordMap &vi, const RecordMap &vc, uint COMF, uint SOMF) const RecordMap &vi, const RecordMap &vc, uint comf, uint somf)
{ {
quint8 type; quint8 type;
quint32 id; quint32 id;
RecordMapIterator it; RecordMapIterator it;
const ISO8211::Field *FSPT = ISO8211::field(r, "FSPT"); const ISO8211::Field *fspt = ISO8211::field(r, FSPT);
if (!FSPT || FSPT->data().at(0).size() != 4) if (!fspt || fspt->data().at(0).size() != 4)
return QVector<Sounding>(); return QVector<Sounding>();
if (!parseNAME(FSPT, &type, &id)) if (!parseNAME(fspt, &type, &id))
return QVector<Sounding>(); return QVector<Sounding>();
if (type == RCNM_VI) { if (type == RCNM_VI) {
@ -520,21 +529,21 @@ QVector<MapData::Sounding> MapData::soundingGeometry(const ISO8211::Record &r,
} else } else
return QVector<Sounding>(); return QVector<Sounding>();
return soundings(it.value(), COMF, SOMF); return soundings(it.value(), comf, somf);
} }
Coordinates MapData::pointGeometry(const ISO8211::Record &r, Coordinates MapData::pointGeometry(const ISO8211::Record &r,
const RecordMap &vi, const RecordMap &vc, uint COMF) const RecordMap &vi, const RecordMap &vc, uint comf)
{ {
quint8 type; quint8 type;
quint32 id; quint32 id;
RecordMapIterator it; RecordMapIterator it;
const ISO8211::Field *FSPT = ISO8211::field(r, "FSPT"); const ISO8211::Field *fspt = ISO8211::field(r, FSPT);
if (!FSPT || FSPT->data().at(0).size() != 4) if (!fspt || fspt->data().at(0).size() != 4)
return Coordinates(); return Coordinates();
if (!parseNAME(FSPT, &type, &id)) if (!parseNAME(fspt, &type, &id))
return Coordinates(); return Coordinates();
if (type == RCNM_VI) { if (type == RCNM_VI) {
@ -548,55 +557,55 @@ Coordinates MapData::pointGeometry(const ISO8211::Record &r,
} else } else
return Coordinates(); return Coordinates();
return point(it.value(), COMF); return point(it.value(), comf);
} }
QVector<Coordinates> MapData::lineGeometry(const ISO8211::Record &r, QVector<Coordinates> MapData::lineGeometry(const ISO8211::Record &r,
const RecordMap &vc, const RecordMap &ve, uint COMF) const RecordMap &vc, const RecordMap &ve, uint comf)
{ {
QVector<Coordinates> path; QVector<Coordinates> path;
Coordinates c[2]; Coordinates c[2];
uint ORNT; uint ornt;
quint8 type; quint8 type;
quint32 id; quint32 id;
const ISO8211::Field *FSPT = ISO8211::field(r, "FSPT"); const ISO8211::Field *fspt = ISO8211::field(r, FSPT);
if (!FSPT || FSPT->data().at(0).size() != 4) if (!fspt || fspt->data().at(0).size() != 4)
return QVector<Coordinates>(); return QVector<Coordinates>();
for (int i = 0; i < FSPT->data().size(); i++) { for (int i = 0; i < fspt->data().size(); i++) {
if (!parseNAME(FSPT, &type, &id, i) || type != RCNM_VE) if (!parseNAME(fspt, &type, &id, i) || type != RCNM_VE)
return QVector<Coordinates>(); return QVector<Coordinates>();
ORNT = FSPT->data().at(i).at(1).toUInt(); ornt = fspt->data().at(i).at(1).toUInt();
RecordMapIterator it = ve.find(id); RecordMapIterator it = ve.find(id);
if (it == ve.constEnd()) if (it == ve.constEnd())
return QVector<Coordinates>(); return QVector<Coordinates>();
const ISO8211::Record &FRID = it.value(); const ISO8211::Record &frid = it.value();
const ISO8211::Field *VRPT = ISO8211::field(FRID, "VRPT"); const ISO8211::Field *vrpt = ISO8211::field(frid, VRPT);
if (!VRPT || VRPT->data().size() != 2) if (!vrpt || vrpt->data().size() != 2)
return QVector<Coordinates>(); return QVector<Coordinates>();
for (int j = 0; j < 2; j++) { for (int j = 0; j < 2; j++) {
if (!parseNAME(VRPT, &type, &id, j) || type != RCNM_VC) if (!parseNAME(vrpt, &type, &id, j) || type != RCNM_VC)
return QVector<Coordinates>(); return QVector<Coordinates>();
RecordMapIterator jt = vc.find(id); RecordMapIterator jt = vc.find(id);
if (jt == vc.constEnd()) if (jt == vc.constEnd())
return QVector<Coordinates>(); return QVector<Coordinates>();
c[j] = point(jt.value(), COMF); c[j] = point(jt.value(), comf);
if (c[j].isNull()) if (c[j].isNull())
return QVector<Coordinates>(); return QVector<Coordinates>();
} }
const ISO8211::Field *vertexes = SGXD(FRID); const ISO8211::Field *vertexes = SGXD(frid);
if (ORNT == 2) { if (ornt == 2) {
path.append(c[1]); path.append(c[1]);
if (vertexes) { if (vertexes) {
for (int j = vertexes->data().size() - 1; j >= 0; j--) { for (int j = vertexes->data().size() - 1; j >= 0; j--) {
const QVector<QVariant> &cv = vertexes->data().at(j); const QVector<QVariant> &cv = vertexes->data().at(j);
path.append(coordinates(cv.at(1).toInt(), cv.at(0).toInt(), path.append(coordinates(cv.at(1).toInt(), cv.at(0).toInt(),
COMF)); comf));
} }
} }
path.append(c[0]); path.append(c[0]);
@ -606,7 +615,7 @@ QVector<Coordinates> MapData::lineGeometry(const ISO8211::Record &r,
for (int j = 0; j < vertexes->data().size(); j++) { for (int j = 0; j < vertexes->data().size(); j++) {
const QVector<QVariant> &cv = vertexes->data().at(j); const QVector<QVariant> &cv = vertexes->data().at(j);
path.append(coordinates(cv.at(1).toInt(), cv.at(0).toInt(), path.append(coordinates(cv.at(1).toInt(), cv.at(0).toInt(),
COMF)); comf));
} }
} }
path.append(c[1]); path.append(c[1]);
@ -617,26 +626,26 @@ QVector<Coordinates> MapData::lineGeometry(const ISO8211::Record &r,
} }
Polygon MapData::polyGeometry(const ISO8211::Record &r, const RecordMap &vc, Polygon MapData::polyGeometry(const ISO8211::Record &r, const RecordMap &vc,
const RecordMap &ve, uint COMF) const RecordMap &ve, uint comf)
{ {
Polygon path; Polygon path;
QVector<Coordinates> v; QVector<Coordinates> v;
Coordinates c[2]; Coordinates c[2];
uint ORNT, USAG; uint ornt, usag;
quint8 type; quint8 type;
quint32 id; quint32 id;
const ISO8211::Field *FSPT = ISO8211::field(r, "FSPT"); const ISO8211::Field *fspt = ISO8211::field(r, FSPT);
if (!FSPT || FSPT->data().at(0).size() != 4) if (!fspt || fspt->data().at(0).size() != 4)
return Polygon(); return Polygon();
for (int i = 0; i < FSPT->data().size(); i++) { for (int i = 0; i < fspt->data().size(); i++) {
if (!parseNAME(FSPT, &type, &id, i) || type != RCNM_VE) if (!parseNAME(fspt, &type, &id, i) || type != RCNM_VE)
return Polygon(); return Polygon();
ORNT = FSPT->data().at(i).at(1).toUInt(); ornt = fspt->data().at(i).at(1).toUInt();
USAG = FSPT->data().at(i).at(2).toUInt(); usag = fspt->data().at(i).at(2).toUInt();
if (USAG == 2 && path.isEmpty()) { if (usag == 2 && path.isEmpty()) {
path.append(v); path.append(v);
v.clear(); v.clear();
} }
@ -644,55 +653,55 @@ Polygon MapData::polyGeometry(const ISO8211::Record &r, const RecordMap &vc,
RecordMapIterator it = ve.find(id); RecordMapIterator it = ve.find(id);
if (it == ve.constEnd()) if (it == ve.constEnd())
return Polygon(); return Polygon();
const ISO8211::Record &FRID = it.value(); const ISO8211::Record &frid = it.value();
const ISO8211::Field *VRPT = ISO8211::field(FRID, "VRPT"); const ISO8211::Field *vrpt = ISO8211::field(frid, VRPT);
if (!VRPT || VRPT->data().size() != 2) if (!vrpt || vrpt->data().size() != 2)
return Polygon(); return Polygon();
for (int j = 0; j < 2; j++) { for (int j = 0; j < 2; j++) {
if (!parseNAME(VRPT, &type, &id, j) || type != RCNM_VC) if (!parseNAME(vrpt, &type, &id, j) || type != RCNM_VC)
return Polygon(); return Polygon();
RecordMapIterator jt = vc.find(id); RecordMapIterator jt = vc.find(id);
if (jt == vc.constEnd()) if (jt == vc.constEnd())
return Polygon(); return Polygon();
c[j] = point(jt.value(), COMF); c[j] = point(jt.value(), comf);
if (c[j].isNull()) if (c[j].isNull())
return Polygon(); return Polygon();
} }
const ISO8211::Field *vertexes = SGXD(FRID); const ISO8211::Field *vertexes = SGXD(frid);
if (ORNT == 2) { if (ornt == 2) {
v.append(c[1]); v.append(c[1]);
if (USAG == 3) if (usag == 3)
v.append(Coordinates()); v.append(Coordinates());
if (vertexes) { if (vertexes) {
for (int j = vertexes->data().size() - 1; j >= 0; j--) { for (int j = vertexes->data().size() - 1; j >= 0; j--) {
const QVector<QVariant> &cv = vertexes->data().at(j); const QVector<QVariant> &cv = vertexes->data().at(j);
v.append(coordinates(cv.at(1).toInt(), cv.at(0).toInt(), v.append(coordinates(cv.at(1).toInt(), cv.at(0).toInt(),
COMF)); comf));
} }
} }
if (USAG == 3) if (usag == 3)
v.append(Coordinates()); v.append(Coordinates());
v.append(c[0]); v.append(c[0]);
} else { } else {
v.append(c[0]); v.append(c[0]);
if (USAG == 3) if (usag == 3)
v.append(Coordinates()); v.append(Coordinates());
if (vertexes) { if (vertexes) {
for (int j = 0; j < vertexes->data().size(); j++) { for (int j = 0; j < vertexes->data().size(); j++) {
const QVector<QVariant> &cv = vertexes->data().at(j); const QVector<QVariant> &cv = vertexes->data().at(j);
v.append(coordinates(cv.at(1).toInt(), cv.at(0).toInt(), v.append(coordinates(cv.at(1).toInt(), cv.at(0).toInt(),
COMF)); comf));
} }
} }
if (USAG == 3) if (usag == 3)
v.append(Coordinates()); v.append(Coordinates());
v.append(c[1]); v.append(c[1]);
} }
if (USAG == 2 && v.first() == v.last()) { if (usag == 2 && v.first() == v.last()) {
path.append(v); path.append(v);
v.clear(); v.clear();
} }
@ -708,12 +717,12 @@ MapData::Attributes MapData::attributes(const ISO8211::Record &r)
{ {
Attributes attr; Attributes attr;
const ISO8211::Field *ATTF = ISO8211::field(r, "ATTF"); const ISO8211::Field *attf = ISO8211::field(r, ATTF);
if (!(ATTF && ATTF->data().at(0).size() == 2)) if (!(attf && attf->data().at(0).size() == 2))
return attr; return attr;
for (int i = 0; i < ATTF->data().size(); i++) { for (int i = 0; i < attf->data().size(); i++) {
const QVector<QVariant> &av = ATTF->data().at(i); const QVector<QVariant> &av = attf->data().at(i);
attr.insert(av.at(0).toUInt(), av.at(1).toByteArray()); attr.insert(av.at(0).toUInt(), av.at(1).toByteArray());
} }
@ -726,65 +735,74 @@ MapData::Point *MapData::pointObject(const Sounding &s)
} }
MapData::Point *MapData::pointObject(const ISO8211::Record &r, MapData::Point *MapData::pointObject(const ISO8211::Record &r,
const RecordMap &vi, const RecordMap &vc, uint COMF, uint OBJL, uint HUNI) const RecordMap &vi, const RecordMap &vc, uint comf, uint objl, uint huni)
{ {
Coordinates c(pointGeometry(r, vi, vc, COMF)); Coordinates c(pointGeometry(r, vi, vc, comf));
return (c.isNull() ? 0 : new Point(OBJL, c, attributes(r), HUNI)); return (c.isNull() ? 0 : new Point(objl, c, attributes(r), huni));
} }
MapData::Line *MapData::lineObject(const ISO8211::Record &r, MapData::Line *MapData::lineObject(const ISO8211::Record &r,
const RecordMap &vc, const RecordMap &ve, uint COMF, uint OBJL) const RecordMap &vc, const RecordMap &ve, uint comf, uint objl)
{ {
QVector<Coordinates> path(lineGeometry(r, vc, ve, COMF)); QVector<Coordinates> path(lineGeometry(r, vc, ve, comf));
return (path.isEmpty() ? 0 : new Line(OBJL, path, attributes(r))); return (path.isEmpty() ? 0 : new Line(objl, path, attributes(r)));
} }
MapData::Poly *MapData::polyObject(const ISO8211::Record &r, MapData::Poly *MapData::polyObject(const ISO8211::Record &r,
const RecordMap &vc, const RecordMap &ve, uint COMF, uint OBJL, uint HUNI) const RecordMap &vc, const RecordMap &ve, uint comf, uint objl, uint huni)
{ {
Polygon path(polyGeometry(r, vc, ve, COMF)); Polygon path(polyGeometry(r, vc, ve, comf));
return (path.isEmpty() ? 0 : new Poly(OBJL, path, attributes(r), HUNI)); return (path.isEmpty() ? 0 : new Poly(objl, path, attributes(r), huni));
} }
bool MapData::processRecord(const ISO8211::Record &record, bool MapData::processRecord(const ISO8211::Record &record,
QVector<ISO8211::Record> &fe, RecordMap &vi, RecordMap &vc, RecordMap &ve, QVector<ISO8211::Record> &fe, RecordMap &vi, RecordMap &vc, RecordMap &ve,
RecordMap &vf, uint &COMF, uint &SOMF, uint &HUNI) uint &comf, uint &huni, uint &somf)
{ {
if (record.size() < 2) if (record.size() < 2)
return false; return false;
const ISO8211::Field &f = record.at(1); const ISO8211::Field &f = record.at(1);
const QByteArray &ba = f.tag(); quint32 tag = f.tag();
if (tag == VRID) {
bool nmok, idok;
if (ba == "VRID") {
if (f.data().at(0).size() < 2) if (f.data().at(0).size() < 2)
return false; return false;
int RCNM = f.data().at(0).at(0).toInt(); int rcnm = f.data().at(0).at(0).toInt(&nmok);
uint RCID = f.data().at(0).at(1).toUInt(); uint rcid = f.data().at(0).at(1).toUInt(&idok);
if (!(nmok && idok))
return false;
switch (RCNM) { switch (rcnm) {
case RCNM_VI: case RCNM_VI:
vi.insert(RCID, record); vi.insert(rcid, record);
break; break;
case RCNM_VC: case RCNM_VC:
vc.insert(RCID, record); vc.insert(rcid, record);
break; break;
case RCNM_VE: case RCNM_VE:
ve.insert(RCID, record); ve.insert(rcid, record);
break; break;
case RCNM_VF: case RCNM_VF:
vf.insert(RCID, record); qWarning("Full topology/faces not supported");
break; return false;
default: default:
return false; return false;
} }
} else if (ba == "FRID") { } else if (tag == FRID) {
fe.append(record); fe.append(record);
} else if (ba == "DSPM") { } else if (tag == DSPM) {
if (!(f.subfield("COMF", &COMF) && f.subfield("SOMF", &SOMF))) bool cok, sok, hok;
return false;
if (!f.subfield("HUNI", &HUNI)) if (f.data().at(0).size() < 12)
return false; return false;
comf = f.data().at(0).at(10).toUInt(&cok);
somf = f.data().at(0).at(11).toUInt(&sok);
huni = f.data().at(0).at(7).toUInt(&hok);
return (cok && sok && hok);
} }
return true; return true;
@ -792,11 +810,11 @@ bool MapData::processRecord(const ISO8211::Record &record,
MapData::MapData(const QString &path) MapData::MapData(const QString &path)
{ {
RecordMap vi, vc, ve, vf; RecordMap vi, vc, ve;
QVector<ISO8211::Record> fe; QVector<ISO8211::Record> fe;
ISO8211 ddf(path); ISO8211 ddf(path);
ISO8211::Record record; ISO8211::Record record;
uint PRIM, OBJL, COMF = 1, SOMF = 1, HUNI = 1; uint prim, objl, comf = 1, somf = 1, huni = 1;
Poly *poly; Poly *poly;
Line *line; Line *line;
Point *point; Point *point;
@ -806,48 +824,48 @@ MapData::MapData(const QString &path)
if (!ddf.readDDR()) if (!ddf.readDDR())
return; return;
while (ddf.readRecord(record)) while (ddf.readRecord(record))
if (!processRecord(record, fe, vi, vc, ve, vf, COMF, SOMF, HUNI)) if (!processRecord(record, fe, vi, vc, ve, comf, somf, huni))
qWarning("Invalid S-57 record"); qWarning("Invalid S-57 record");
for (int i = 0; i < fe.size(); i++) { for (int i = 0; i < fe.size(); i++) {
const ISO8211::Record &r = fe.at(i); const ISO8211::Record &r = fe.at(i);
const ISO8211::Field &f = r.at(1); const ISO8211::Field &frid = r.at(1);
if (f.data().at(0).size() < 5) if (frid.data().at(0).size() < 5)
continue; continue;
PRIM = f.data().at(0).at(2).toUInt(); prim = frid.data().at(0).at(2).toUInt();
OBJL = f.data().at(0).at(4).toUInt(); objl = frid.data().at(0).at(4).toUInt();
switch (PRIM) { switch (prim) {
case PRIM_P: case PRIM_P:
if (OBJL == SOUNDG) { if (objl == SOUNDG) {
QVector<Sounding> s(soundingGeometry(r, vi, vc, COMF, SOMF)); QVector<Sounding> s(soundingGeometry(r, vi, vc, comf, somf));
for (int i = 0; i < s.size(); i++) { for (int i = 0; i < s.size(); i++) {
point = pointObject(s.at(i)); point = pointObject(s.at(i));
pointBounds(point->pos(), min, max); pointBounds(point->pos(), min, max);
_points.Insert(min, max, point); _points.Insert(min, max, point);
} }
} else { } else {
if ((point = pointObject(r, vi, vc, COMF, OBJL, HUNI))) { if ((point = pointObject(r, vi, vc, comf, objl, huni))) {
pointBounds(point->pos(), min, max); pointBounds(point->pos(), min, max);
_points.Insert(min, max, point); _points.Insert(min, max, point);
} else } else
warning(f, PRIM); warning(frid, prim);
} }
break; break;
case PRIM_L: case PRIM_L:
if ((line = lineObject(r, vc, ve, COMF, OBJL))) { if ((line = lineObject(r, vc, ve, comf, objl))) {
rectcBounds(line->bounds(), min, max); rectcBounds(line->bounds(), min, max);
_lines.Insert(min, max, line); _lines.Insert(min, max, line);
} else } else
warning(f, PRIM); warning(frid, prim);
break; break;
case PRIM_A: case PRIM_A:
if ((poly = polyObject(r, vc, ve, COMF, OBJL, HUNI))) { if ((poly = polyObject(r, vc, ve, comf, objl, huni))) {
rectcBounds(poly->bounds(), min, max); rectcBounds(poly->bounds(), min, max);
_areas.Insert(min, max, poly); _areas.Insert(min, max, poly);
} else } else
warning(f, PRIM); warning(frid, prim);
break; break;
} }
} }

View File

@ -32,28 +32,28 @@ private:
typedef RTree<const Line*, double, 2> LineTree; typedef RTree<const Line*, double, 2> LineTree;
typedef RTree<const Point*, double, 2> PointTree; typedef RTree<const Point*, double, 2> PointTree;
static QVector<Sounding> soundings(const ISO8211::Record &r, uint COMF, static QVector<Sounding> soundings(const ISO8211::Record &r, uint comf,
uint SOMF); uint somf);
static QVector<Sounding> soundingGeometry(const ISO8211::Record &r, static QVector<Sounding> soundingGeometry(const ISO8211::Record &r,
const RecordMap &vi, const RecordMap &vc, uint COMF, uint SOMF); const RecordMap &vi, const RecordMap &vc, uint comf, uint somf);
static Coordinates pointGeometry(const ISO8211::Record &r, static Coordinates pointGeometry(const ISO8211::Record &r,
const RecordMap &vi, const RecordMap &vc, uint COMF); const RecordMap &vi, const RecordMap &vc, uint comf);
static QVector<Coordinates> lineGeometry(const ISO8211::Record &r, static QVector<Coordinates> lineGeometry(const ISO8211::Record &r,
const RecordMap &vc, const RecordMap &ve, uint COMF); const RecordMap &vc, const RecordMap &ve, uint comf);
static Polygon polyGeometry(const ISO8211::Record &r, const RecordMap &vc, static Polygon polyGeometry(const ISO8211::Record &r, const RecordMap &vc,
const RecordMap &ve, uint COMF); const RecordMap &ve, uint comf);
static Attributes attributes(const ISO8211::Record &r); static Attributes attributes(const ISO8211::Record &r);
static Point *pointObject(const Sounding &s); static Point *pointObject(const Sounding &s);
static Point *pointObject(const ISO8211::Record &r, const RecordMap &vi, static Point *pointObject(const ISO8211::Record &r, const RecordMap &vi,
const RecordMap &vc, uint COMF, uint OBJL, uint HUNI); const RecordMap &vc, uint comf, uint objl, uint huni);
static Line *lineObject(const ISO8211::Record &r, const RecordMap &vc, static Line *lineObject(const ISO8211::Record &r, const RecordMap &vc,
const RecordMap &ve, uint COMF, uint OBJL); const RecordMap &ve, uint comf, uint objl);
static Poly *polyObject(const ISO8211::Record &r, const RecordMap &vc, static Poly *polyObject(const ISO8211::Record &r, const RecordMap &vc,
const RecordMap &ve, uint COMF, uint OBJL, uint HUNI); const RecordMap &ve, uint comf, uint objl, uint huni);
static bool processRecord(const ISO8211::Record &record, static bool processRecord(const ISO8211::Record &record,
QVector<ISO8211::Record> &fe, RecordMap &vi, RecordMap &vc, RecordMap &ve, QVector<ISO8211::Record> &fe, RecordMap &vi, RecordMap &vc, RecordMap &ve,
RecordMap &vf, uint &COMF, uint &SOMF, uint &HUNI); uint &comf, uint &somf, uint &huni);
PolygonTree _areas; PolygonTree _areas;
LineTree _lines; LineTree _lines;

View File

@ -12,6 +12,8 @@ using namespace ENC;
#define EPSILON 1e-6 #define EPSILON 1e-6
#define TILE_SIZE 512 #define TILE_SIZE 512
constexpr quint32 CATD = ISO8211::NAME("CATD");
Range ENCAtlas::zooms(IntendedUsage usage) Range ENCAtlas::zooms(IntendedUsage usage)
{ {
switch (usage) { switch (usage) {
@ -59,36 +61,27 @@ bool ENCAtlas::processRecord(const ISO8211::Record &record, QByteArray &file,
if (record.size() < 2) if (record.size() < 2)
return false; return false;
const ENC::ISO8211::Field &f = record.at(1); const ENC::ISO8211::Field &field = record.at(1);
const QByteArray &ba = f.tag();
if (ba == "CATD") { if (field.tag() == CATD) {
QByteArray FILE, IMPL; if (field.data().at(0).size() < 10)
return false;
QByteArray impl = field.data().at(0).at(5).toByteArray();
file = field.data().at(0).at(2).toByteArray();
if (!f.subfield("IMPL", &IMPL)) if (impl == "BIN" && file.endsWith("000")) {
return false; QByteArray slat = field.data().at(0).at(6).toByteArray();
if (!f.subfield("FILE", &FILE)) QByteArray wlon = field.data().at(0).at(7).toByteArray();
return false; QByteArray nlat = field.data().at(0).at(8).toByteArray();
QByteArray elon = field.data().at(0).at(9).toByteArray();
if (IMPL == "BIN" && FILE.endsWith("000")) {
QByteArray SLAT, WLON, NLAT, ELON;
if (!f.subfield("SLAT", &SLAT))
return false;
if (!f.subfield("WLON", &WLON))
return false;
if (!f.subfield("NLAT", &NLAT))
return false;
if (!f.subfield("ELON", &ELON))
return false;
bool ok1, ok2, ok3, ok4; bool ok1, ok2, ok3, ok4;
bounds = RectC(Coordinates(WLON.toDouble(&ok1), NLAT.toDouble(&ok2)), bounds = RectC(Coordinates(wlon.toDouble(&ok1), nlat.toDouble(&ok2)),
Coordinates(ELON.toDouble(&ok3), SLAT.toDouble(&ok4))); Coordinates(elon.toDouble(&ok3), slat.toDouble(&ok4)));
if (!(ok1 && ok2 && ok3 && ok4)) if (!(ok1 && ok2 && ok3 && ok4))
return false; return false;
file = FILE.replace('\\', '/'); file.replace('\\', '/');
return true; return true;
} }

View File

@ -15,6 +15,12 @@ using namespace ENC;
#define EPSILON 1e-6 #define EPSILON 1e-6
#define TILE_SIZE 512 #define TILE_SIZE 512
constexpr quint32 SG2D = ISO8211::NAME("SG2D");
constexpr quint32 SG3D = ISO8211::NAME("SG3D");
constexpr quint32 VRID = ISO8211::NAME("VRID");
constexpr quint32 DSID = ISO8211::NAME("DSID");
constexpr quint32 DSPM = ISO8211::NAME("DSPM");
static Range zooms(const RectC &bounds) static Range zooms(const RectC &bounds)
{ {
double size = qMin(bounds.width(), bounds.height()); double size = qMin(bounds.width(), bounds.height());
@ -57,9 +63,9 @@ static const ISO8211::Field *SGXD(const ISO8211::Record &r)
{ {
const ISO8211::Field *f; const ISO8211::Field *f;
if ((f = ISO8211::field(r, "SG2D"))) if ((f = ISO8211::field(r, SG2D)))
return f; return f;
else if ((f = ISO8211::field(r, "SG3D"))) else if ((f = ISO8211::field(r, SG3D)))
return f; return f;
else else
return 0; return 0;
@ -97,23 +103,26 @@ bool ENCMap::bounds(const QVector<ISO8211::Record> &gv, Rect &b)
} }
bool ENCMap::processRecord(const ISO8211::Record &record, bool ENCMap::processRecord(const ISO8211::Record &record,
QVector<ISO8211::Record> &rv, uint &COMF, QString &name) QVector<ISO8211::Record> &rv, uint &comf, QByteArray &dsnm)
{ {
if (record.size() < 2) if (record.size() < 2)
return false; return false;
const ISO8211::Field &f = record.at(1); const ISO8211::Field &f = record.at(1);
const QByteArray &ba = f.tag(); quint32 tag = f.tag();
if (ba == "VRID") { if (tag == VRID) {
rv.append(record); rv.append(record);
} else if (ba == "DSID") { } else if (tag == DSID) {
QByteArray DSNM; if (f.data().at(0).size() < 5)
if (!f.subfield("DSNM", &DSNM))
return false; return false;
name = DSNM; dsnm = f.data().at(0).at(4).toByteArray();
} else if (ba == "DSPM") { } else if (tag == DSPM) {
if (!f.subfield("COMF", &COMF)) bool ok;
if (f.data().at(0).size() < 11)
return false;
comf = f.data().at(0).at(10).toUInt(&ok);
if (!ok)
return false; return false;
} }
@ -127,14 +136,15 @@ ENCMap::ENCMap(const QString &fileName, QObject *parent)
QVector<ISO8211::Record> gv; QVector<ISO8211::Record> gv;
ISO8211 ddf(fileName); ISO8211 ddf(fileName);
ISO8211::Record record; ISO8211::Record record;
uint COMF = 1; uint comf = 1;
QByteArray dsnm;
if (!ddf.readDDR()) { if (!ddf.readDDR()) {
_errorString = ddf.errorString(); _errorString = ddf.errorString();
return; return;
} }
while (ddf.readRecord(record)) { while (ddf.readRecord(record)) {
if (!processRecord(record, gv, COMF, _name)) { if (!processRecord(record, gv, comf, dsnm)) {
_errorString = "Invalid S-57 record"; _errorString = "Invalid S-57 record";
return; return;
} }
@ -144,13 +154,15 @@ ENCMap::ENCMap(const QString &fileName, QObject *parent)
return; return;
} }
_name = dsnm;
Rect b; Rect b;
if (!bounds(gv, b)) { if (!bounds(gv, b)) {
_errorString = "Error fetching geometries bounds"; _errorString = "Error fetching geometries bounds";
return; return;
} }
Coordinates tl(b.minX() / (double)COMF, b.maxY() / (double)COMF); Coordinates tl(b.minX() / (double)comf, b.maxY() / (double)comf);
Coordinates br(b.maxX() / (double)COMF, b.minY() / (double)COMF); Coordinates br(b.maxX() / (double)comf, b.minY() / (double)comf);
_llBounds = RectC(tl, br); _llBounds = RectC(tl, br);
if (!_llBounds.isValid()) { if (!_llBounds.isValid()) {
_errorString = "Invalid geometries bounds"; _errorString = "Invalid geometries bounds";

View File

@ -97,7 +97,7 @@ private:
static bool bounds(const ENC::ISO8211::Record &record, Rect &rect); static bool bounds(const ENC::ISO8211::Record &record, Rect &rect);
static bool bounds(const QVector<ENC::ISO8211::Record> &gv, Rect &b); static bool bounds(const QVector<ENC::ISO8211::Record> &gv, Rect &b);
static bool processRecord(const ENC::ISO8211::Record &record, static bool processRecord(const ENC::ISO8211::Record &record,
QVector<ENC::ISO8211::Record> &rv, uint &COMF, QString &name); QVector<ENC::ISO8211::Record> &rv, uint &comf, QByteArray &dsnm);
QString _name; QString _name;
ENC::MapData *_data; ENC::MapData *_data;