1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2025-04-19 19:59:11 +02:00

Compare commits

..

3 Commits

7 changed files with 230 additions and 209 deletions

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;
@ -29,18 +23,18 @@ struct DR {
}; };
const QVariant *ISO8211::Field::data(const QByteArray &name, int idx) const const QVariant *ISO8211::Field::data(quint32 name, int idx) const
{ {
const QVector<QVariant> &v = _data.at(idx); const QVector<QVariant> &v = _data.at(idx);
for (int i = 0; i < _subFields.size(); i++) for (int i = 0; i < _subFields->size(); i++)
if (_subFields.at(i) == name) if (_subFields->at(i) == name)
return &v.at(i); return &v.at(i);
return 0; return 0;
} }
bool ISO8211::Field::subfield(const char *name, int *val, int idx) const bool ISO8211::Field::subfield(quint32 name, int *val, int idx) const
{ {
bool ok; bool ok;
@ -52,7 +46,7 @@ bool ISO8211::Field::subfield(const char *name, int *val, int idx) const
return ok; return ok;
} }
bool ISO8211::Field::subfield(const char *name, uint *val, int idx) const bool ISO8211::Field::subfield(quint32 name, uint *val, int idx) const
{ {
bool ok; bool ok;
@ -64,7 +58,7 @@ bool ISO8211::Field::subfield(const char *name, uint *val, int idx) const
return ok; return ok;
} }
bool ISO8211::Field::subfield(const char *name, QByteArray *val, int idx) const bool ISO8211::Field::subfield(quint32 name, QByteArray *val, int idx) const
{ {
const QVariant *v = data(name, idx); const QVariant *v = data(name, idx);
if (!v) if (!v)
@ -101,6 +95,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 +110,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 +135,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 +150,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;
@ -190,7 +185,8 @@ bool ISO8211::readDDA(const FieldDefinition &def, SubFields &fields)
if (tag >= tags.size()) if (tag >= tags.size())
return false; 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++;
} }
} }
@ -222,8 +218,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);
@ -275,11 +273,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:
@ -287,11 +285,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:
@ -327,13 +325,16 @@ 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;
} }
@ -343,8 +344,7 @@ bool ISO8211::readRecord(Record &record)
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,22 @@ public:
class Field class Field
{ {
public: public:
Field() {} Field() : _subFields(0) {}
Field(const QByteArray &tag, const QVector<QByteArray> &subFields, Field(quint32 tag, const QVector<quint32> &subFields, const Data &data)
const Data &data) : _tag(tag), _subFields(subFields), _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(quint32 name, int *val, int idx = 0) const;
bool subfield(const char *name, uint *val, int idx = 0) const; bool subfield(quint32 name, uint *val, int idx = 0) const;
bool subfield(const char *name, QByteArray *val, int idx = 0) const; bool subfield(quint32 name, QByteArray *val, int idx = 0) const;
private: private:
const QVariant *data(const QByteArray &name, int idx = 0) const; const QVariant *data(quint32 name, int idx = 0) const;
QByteArray _tag; quint32 _tag;
QVector<QByteArray> _subFields; const QVector<quint32> *_subFields;
Data _data; Data _data;
}; };
@ -50,14 +42,21 @@ public:
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 +80,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 +109,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,19 @@ using namespace ENC;
#define PRIM_L 2 #define PRIM_L 2
#define PRIM_A 3 #define PRIM_A 3
constexpr quint32 RCID = ISO8211::NAME("RCID");
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");
constexpr quint32 COMF = ISO8211::NAME("COMF");
constexpr quint32 SOMF = ISO8211::NAME("SOMF");
constexpr quint32 HUNI = ISO8211::NAME("HUNI");
static QMap<uint,uint> orderMapInit() static QMap<uint,uint> orderMapInit()
{ {
QMap<uint,uint> map; QMap<uint,uint> map;
@ -90,20 +104,20 @@ 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 = 0xFFFFFFFF;
FRID.subfield("RCID", &RCID); 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 +146,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 +155,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 +226,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 +240,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 +491,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 +503,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 +534,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 +562,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 +620,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 +631,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 +658,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 +722,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,64 +740,64 @@ 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) RecordMap &vf, uint &comf, uint &somf, uint &huni)
{ {
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) {
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();
uint RCID = f.data().at(0).at(1).toUInt(); uint rcid = f.data().at(0).at(1).toUInt();
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); vf.insert(rcid, record);
break; break;
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))) if (!(f.subfield(COMF, &comf) && f.subfield(SOMF, &somf)))
return false; return false;
if (!f.subfield("HUNI", &HUNI)) if (!f.subfield(HUNI, &huni))
return false; return false;
} }
@ -796,7 +810,7 @@ MapData::MapData(const QString &path)
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,7 +820,7 @@ 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, vf, 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++) {
@ -815,39 +829,39 @@ MapData::MapData(const QString &path)
if (f.data().at(0).size() < 5) if (f.data().at(0).size() < 5)
continue; continue;
PRIM = f.data().at(0).at(2).toUInt(); prim = f.data().at(0).at(2).toUInt();
OBJL = f.data().at(0).at(4).toUInt(); objl = f.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(f, 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(f, 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(f, 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); RecordMap &vf, uint &comf, uint &somf, uint &huni);
PolygonTree _areas; PolygonTree _areas;
LineTree _lines; LineTree _lines;

View File

@ -12,6 +12,14 @@ 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");
constexpr quint32 IMPL = ISO8211::NAME("IMPL");
constexpr quint32 F1LE = ISO8211::NAME("FILE");
constexpr quint32 SLAT = ISO8211::NAME("SLAT");
constexpr quint32 WLON = ISO8211::NAME("WLON");
constexpr quint32 NLAT = ISO8211::NAME("NLAT");
constexpr quint32 ELON = ISO8211::NAME("ELON");
Range ENCAtlas::zooms(IntendedUsage usage) Range ENCAtlas::zooms(IntendedUsage usage)
{ {
switch (usage) { switch (usage) {
@ -60,35 +68,34 @@ bool ENCAtlas::processRecord(const ISO8211::Record &record, QByteArray &file,
return false; return false;
const ENC::ISO8211::Field &f = record.at(1); const ENC::ISO8211::Field &f = record.at(1);
const QByteArray &ba = f.tag();
if (ba == "CATD") { if (f.tag() == CATD) {
QByteArray FILE, IMPL; QByteArray impl;
if (!f.subfield("IMPL", &IMPL)) if (!f.subfield(IMPL, &impl))
return false; return false;
if (!f.subfield("FILE", &FILE)) if (!f.subfield(F1LE, &file))
return false; return false;
if (IMPL == "BIN" && FILE.endsWith("000")) { if (impl == "BIN" && file.endsWith("000")) {
QByteArray SLAT, WLON, NLAT, ELON; QByteArray slat, wlon, nlat, elon;
if (!f.subfield("SLAT", &SLAT)) if (!f.subfield(SLAT, &slat))
return false; return false;
if (!f.subfield("WLON", &WLON)) if (!f.subfield(WLON, &wlon))
return false; return false;
if (!f.subfield("NLAT", &NLAT)) if (!f.subfield(NLAT, &nlat))
return false; return false;
if (!f.subfield("ELON", &ELON)) if (!f.subfield(ELON, &elon))
return false; 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,14 @@ 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 DSNM = ISO8211::NAME("DSNM");
constexpr quint32 DSPM = ISO8211::NAME("DSPM");
constexpr quint32 COMF = ISO8211::NAME("COMF");
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 +65,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 +105,21 @@ 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.subfield(DSNM, &dsnm))
if (!f.subfield("DSNM", &DSNM))
return false; return false;
name = DSNM; } else if (tag == DSPM) {
} else if (ba == "DSPM") { if (!f.subfield(COMF, &comf))
if (!f.subfield("COMF", &COMF))
return false; return false;
} }
@ -127,14 +133,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 +151,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;