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

Compare commits

..

No commits in common. "372f2966bb574ed1ccc3c23027f58288efddf6c0" and "91376fd6099cce5f79bd4a997f51abd8366dae80" have entirely different histories.

7 changed files with 209 additions and 230 deletions

View File

@ -1,4 +1,3 @@
#include <QtEndian>
#include <QFile>
#include <QRegularExpression>
#include "common/util.h"
@ -6,6 +5,13 @@
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 {
char RecordLength[5];
char InterchangeLevel;
@ -23,18 +29,18 @@ struct DR {
};
const QVariant *ISO8211::Field::data(quint32 name, int idx) const
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)
for (int i = 0; i < _subFields.size(); i++)
if (_subFields.at(i) == name)
return &v.at(i);
return 0;
}
bool ISO8211::Field::subfield(quint32 name, int *val, int idx) const
bool ISO8211::Field::subfield(const char *name, int *val, int idx) const
{
bool ok;
@ -46,7 +52,7 @@ bool ISO8211::Field::subfield(quint32 name, int *val, int idx) const
return ok;
}
bool ISO8211::Field::subfield(quint32 name, uint *val, int idx) const
bool ISO8211::Field::subfield(const char *name, uint *val, int idx) const
{
bool ok;
@ -58,7 +64,7 @@ bool ISO8211::Field::subfield(quint32 name, uint *val, int idx) const
return ok;
}
bool ISO8211::Field::subfield(quint32 name, QByteArray *val, int idx) const
bool ISO8211::Field::subfield(const char *name, QByteArray *val, int idx) const
{
const QVariant *v = data(name, idx);
if (!v)
@ -95,7 +101,6 @@ int ISO8211::readDR(QVector<FieldDefinition> &fields)
DR ddr;
QByteArray fieldLen, fieldPos;
int len, lenSize, posSize, tagSize, offset;
char tag[4];
static_assert(sizeof(ddr) == 24, "Invalid DR alignment");
if (_file.read((char*)&ddr, sizeof(ddr)) != sizeof(ddr))
@ -110,19 +115,20 @@ int ISO8211::readDR(QVector<FieldDefinition> &fields)
if (len < 0 || offset < 0 || lenSize < 0 || posSize < 0 || tagSize < 0)
return -1;
fields.resize((offset - 1 - sizeof(ddr)) / (lenSize + posSize + tagSize));
fields.resize((offset - 1 - sizeof(DR)) / (lenSize + posSize + tagSize));
fieldLen.resize(lenSize);
fieldPos.resize(posSize);
for (int i = 0; i < fields.size(); i++) {
FieldDefinition &r = fields[i];
if (_file.read(tag, sizeof(tag)) != tagSize
r.tag.resize(tagSize);
if (_file.read(r.tag.data(), tagSize) != tagSize
|| _file.read(fieldLen.data(), lenSize) != lenSize
|| _file.read(fieldPos.data(), posSize) != posSize)
return -1;
r.tag = qFromLittleEndian<quint32>(tag);
r.pos = offset + Util::str2int(fieldPos.constData(), posSize);
r.size = Util::str2int(fieldLen.constData(), lenSize);
@ -135,12 +141,11 @@ int ISO8211::readDR(QVector<FieldDefinition> &fields)
bool ISO8211::readDDA(const FieldDefinition &def, SubFields &fields)
{
static const QRegularExpression re(
"([0-9]*)(A|I|R|B|b11|b12|b14|b21|b22|b24)\\(*([0-9]*)\\)*");
static const QRegularExpression re("(\\d*)(\\w+)\\(*(\\d*)\\)*");
QByteArray ba(def.size, Qt::Initialization::Uninitialized);
bool repeat = false;
QVector<SubFieldDefinition> defs;
QVector<quint32> defTags;
QVector<QByteArray> defTags;
if (!(_file.seek(def.pos) && _file.read(ba.data(), ba.size()) == ba.size()))
return false;
@ -150,9 +155,9 @@ bool ISO8211::readDDA(const FieldDefinition &def, SubFields &fields)
repeat = true;
list[1].remove(0, 1);
}
QList<QByteArray> tags(list.at(1).split('!'));
if (list.size() > 2) {
QList<QByteArray> tags(list.at(1).split('!'));
QRegularExpressionMatchIterator it = re.globalMatch(list.at(2));
int tag = 0;
@ -185,8 +190,7 @@ bool ISO8211::readDDA(const FieldDefinition &def, SubFields &fields)
if (tag >= tags.size())
return false;
defs[tag] = sfd;
defTags[tag] = (tags.at(tag).length() == 4)
? qFromLittleEndian<quint32>(tags.at(tag).constData()) : 0;
defTags[tag] = tags.at(tag);
tag++;
}
}
@ -218,10 +222,8 @@ bool ISO8211::readDDR()
for (int i = 0; i < fields.size(); i++) {
SubFields 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")
.arg(QString(tag));
.arg(QString(fields.at(i).tag));
return false;
}
_map.insert(fields.at(i).tag, def);
@ -273,11 +275,11 @@ bool ISO8211::readUDA(quint64 pos, const FieldDefinition &def,
dp++;
break;
case S16:
row[i] = QVariant(qFromLittleEndian<qint16>(dp));
row[i] = QVariant(INT16(dp));
dp += 2;
break;
case S32:
row[i] = QVariant(qFromLittleEndian<qint32>(dp));
row[i] = QVariant(INT32(dp));
dp += 4;
break;
case U8:
@ -285,11 +287,11 @@ bool ISO8211::readUDA(quint64 pos, const FieldDefinition &def,
dp++;
break;
case U16:
row[i] = QVariant(qFromLittleEndian<quint16>(dp));
row[i] = QVariant(UINT16(dp));
dp += 2;
break;
case U32:
row[i] = QVariant(qFromLittleEndian<quint32>(dp));
row[i] = QVariant(UINT32(dp));
dp += 4;
break;
default:
@ -325,16 +327,13 @@ bool ISO8211::readRecord(Record &record)
FieldsMap::const_iterator it(_map.find(def.tag));
if (it == _map.constEnd()) {
QByteArray tag(sizeof(quint32), Qt::Initialization::Uninitialized);
qToLittleEndian<quint32>(def.tag, tag.data());
_errorString = QString("%1: unknown record").arg(QString(tag));
_errorString = QString("%1: unknown record").arg(QString(def.tag));
return false;
}
if (!readUDA(pos, def, it->defs(), it->repeat(), data)) {
QByteArray tag(sizeof(quint32), Qt::Initialization::Uninitialized);
qToLittleEndian<quint32>(def.tag, tag.data());
_errorString = QString("Error reading %1 record").arg(QString(tag));
_errorString = QString("Error reading %1 record")
.arg(QString(def.tag));
return false;
}
@ -344,7 +343,8 @@ bool ISO8211::readRecord(Record &record)
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++)
if (record.at(i).tag() == name)

View File

@ -4,6 +4,13 @@
#include <QFile>
#include <QByteArray>
#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 {
@ -15,22 +22,23 @@ public:
class Field
{
public:
Field() : _subFields(0) {}
Field(quint32 tag, const QVector<quint32> &subFields, const Data &data)
: _tag(tag), _subFields(&subFields), _data(data) {}
Field() {}
Field(const QByteArray &tag, const QVector<QByteArray> &subFields,
const Data &data) : _tag(tag), _subFields(subFields), _data(data) {}
quint32 tag() const {return _tag;}
const QByteArray &tag() const {return _tag;}
const QVector<QByteArray> &subFields() const {return _subFields;}
const Data &data() const {return _data;}
bool subfield(quint32 name, int *val, int idx = 0) const;
bool subfield(quint32 name, uint *val, int idx = 0) const;
bool subfield(quint32 name, QByteArray *val, int idx = 0) const;
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:
const QVariant *data(quint32 name, int idx = 0) const;
const QVariant *data(const QByteArray &name, int idx = 0) const;
quint32 _tag;
const QVector<quint32> *_subFields;
QByteArray _tag;
QVector<QByteArray> _subFields;
Data _data;
};
@ -42,21 +50,14 @@ public:
const QString &errorString() const {return _errorString;}
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);
}
static const Field *field(const Record &record, const QByteArray &name);
private:
enum FieldType {Unknown, String, Array, S8, S16, S32, U8, U16, U32};
struct FieldDefinition
{
quint32 tag;
QByteArray tag;
int pos;
int size;
};
@ -80,22 +81,22 @@ private:
{
public:
SubFields() : _repeat(false) {}
SubFields(const QVector<quint32> &tags,
SubFields(const QVector<QByteArray> &tags,
const QVector<SubFieldDefinition> &defs, bool repeat)
: _tags(tags), _defs(defs), _repeat(repeat) {}
const QVector<quint32> &tags() const {return _tags;}
const QVector<QByteArray> &tags() const {return _tags;}
const QVector<SubFieldDefinition> &defs() const {return _defs;}
bool repeat() const {return _repeat;}
private:
QVector<quint32> _tags;
QVector<QByteArray> _tags;
QVector<SubFieldDefinition> _defs;
bool _repeat;
};
typedef QMap<quint32, SubFields> FieldsMap;
typedef QMap<QByteArray, SubFields> FieldsMap;
static SubFieldDefinition fieldType(const QString &str, int cnt);
@ -109,6 +110,14 @@ private:
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

View File

@ -1,4 +1,3 @@
#include <QtEndian>
#include "GUI/units.h"
#include "objects.h"
#include "attributes.h"
@ -15,19 +14,6 @@ using namespace ENC;
#define PRIM_L 2
#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()
{
QMap<uint,uint> map;
@ -104,20 +90,20 @@ static uint order(uint type)
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;
frid.subfield(RCID, &rcid);
uint RCID = 0xFFFFFFFF;
FRID.subfield("RCID", &RCID);
switch (prim) {
switch (PRIM) {
case PRIM_P:
qWarning("%u: invalid point feature", rcid);
qWarning("%u: invalid point feature", RCID);
break;
case PRIM_L:
qWarning("%u: invalid line feature", rcid);
qWarning("%u: invalid line feature", RCID);
break;
case PRIM_A:
qWarning("%u: invalid area feature", rcid);
qWarning("%u: invalid area feature", RCID);
break;
}
}
@ -146,7 +132,7 @@ static bool parseNAME(const ISO8211::Field *f, quint8 *type, quint32 *id,
return false;
*type = (quint8)(*ba.constData());
*id = qFromLittleEndian<quint32>(ba.constData() + 1);
*id = UINT32(ba.constData() + 1);
return true;
}
@ -155,9 +141,9 @@ static const ISO8211::Field *SGXD(const ISO8211::Record &r)
{
const ISO8211::Field *f;
if ((f = ISO8211::field(r, SG2D)))
if ((f = ISO8211::field(r, "SG2D")))
return f;
else if ((f = ISO8211::field(r, SG3D)))
else if ((f = ISO8211::field(r, "SG3D")))
return f;
else
return 0;
@ -226,12 +212,12 @@ static bool linePointCb(const MapData::Line *line, void *context)
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);
if (!f)
@ -240,7 +226,7 @@ static Coordinates point(const ISO8211::Record &r, uint comf)
int y = f->data().at(0).at(0).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)
@ -491,10 +477,10 @@ RectC MapData::Line::bounds() const
}
QVector<MapData::Sounding> MapData::soundings(const ISO8211::Record &r,
uint comf, uint somf)
uint COMF, uint SOMF)
{
QVector<Sounding> s;
const ISO8211::Field *f = ISO8211::field(r, SG3D);
const ISO8211::Field *f = ISO8211::field(r, "SG3D");
if (!f)
return QVector<Sounding>();
@ -503,24 +489,24 @@ QVector<MapData::Sounding> MapData::soundings(const ISO8211::Record &r,
int y = f->data().at(i).at(0).toInt();
int x = f->data().at(i).at(1).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;
}
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;
quint32 id;
RecordMapIterator it;
const ISO8211::Field *fspt = ISO8211::field(r, FSPT);
if (!fspt || fspt->data().at(0).size() != 4)
const ISO8211::Field *FSPT = ISO8211::field(r, "FSPT");
if (!FSPT || FSPT->data().at(0).size() != 4)
return QVector<Sounding>();
if (!parseNAME(fspt, &type, &id))
if (!parseNAME(FSPT, &type, &id))
return QVector<Sounding>();
if (type == RCNM_VI) {
@ -534,21 +520,21 @@ QVector<MapData::Sounding> MapData::soundingGeometry(const ISO8211::Record &r,
} else
return QVector<Sounding>();
return soundings(it.value(), comf, somf);
return soundings(it.value(), COMF, SOMF);
}
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;
quint32 id;
RecordMapIterator it;
const ISO8211::Field *fspt = ISO8211::field(r, FSPT);
if (!fspt || fspt->data().at(0).size() != 4)
const ISO8211::Field *FSPT = ISO8211::field(r, "FSPT");
if (!FSPT || FSPT->data().at(0).size() != 4)
return Coordinates();
if (!parseNAME(fspt, &type, &id))
if (!parseNAME(FSPT, &type, &id))
return Coordinates();
if (type == RCNM_VI) {
@ -562,55 +548,55 @@ Coordinates MapData::pointGeometry(const ISO8211::Record &r,
} else
return Coordinates();
return point(it.value(), comf);
return point(it.value(), COMF);
}
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;
Coordinates c[2];
uint ornt;
uint ORNT;
quint8 type;
quint32 id;
const ISO8211::Field *fspt = ISO8211::field(r, FSPT);
if (!fspt || fspt->data().at(0).size() != 4)
const ISO8211::Field *FSPT = ISO8211::field(r, "FSPT");
if (!FSPT || FSPT->data().at(0).size() != 4)
return QVector<Coordinates>();
for (int i = 0; i < fspt->data().size(); i++) {
if (!parseNAME(fspt, &type, &id, i) || type != RCNM_VE)
for (int i = 0; i < FSPT->data().size(); i++) {
if (!parseNAME(FSPT, &type, &id, i) || type != RCNM_VE)
return QVector<Coordinates>();
ornt = fspt->data().at(i).at(1).toUInt();
ORNT = FSPT->data().at(i).at(1).toUInt();
RecordMapIterator it = ve.find(id);
if (it == ve.constEnd())
return QVector<Coordinates>();
const ISO8211::Record &frid = it.value();
const ISO8211::Field *vrpt = ISO8211::field(frid, VRPT);
if (!vrpt || vrpt->data().size() != 2)
const ISO8211::Record &FRID = it.value();
const ISO8211::Field *VRPT = ISO8211::field(FRID, "VRPT");
if (!VRPT || VRPT->data().size() != 2)
return QVector<Coordinates>();
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>();
RecordMapIterator jt = vc.find(id);
if (jt == vc.constEnd())
return QVector<Coordinates>();
c[j] = point(jt.value(), comf);
c[j] = point(jt.value(), COMF);
if (c[j].isNull())
return QVector<Coordinates>();
}
const ISO8211::Field *vertexes = SGXD(frid);
if (ornt == 2) {
const ISO8211::Field *vertexes = SGXD(FRID);
if (ORNT == 2) {
path.append(c[1]);
if (vertexes) {
for (int j = vertexes->data().size() - 1; j >= 0; j--) {
const QVector<QVariant> &cv = vertexes->data().at(j);
path.append(coordinates(cv.at(1).toInt(), cv.at(0).toInt(),
comf));
COMF));
}
}
path.append(c[0]);
@ -620,7 +606,7 @@ QVector<Coordinates> MapData::lineGeometry(const ISO8211::Record &r,
for (int j = 0; j < vertexes->data().size(); j++) {
const QVector<QVariant> &cv = vertexes->data().at(j);
path.append(coordinates(cv.at(1).toInt(), cv.at(0).toInt(),
comf));
COMF));
}
}
path.append(c[1]);
@ -631,26 +617,26 @@ QVector<Coordinates> MapData::lineGeometry(const ISO8211::Record &r,
}
Polygon MapData::polyGeometry(const ISO8211::Record &r, const RecordMap &vc,
const RecordMap &ve, uint comf)
const RecordMap &ve, uint COMF)
{
Polygon path;
QVector<Coordinates> v;
Coordinates c[2];
uint ornt, usag;
uint ORNT, USAG;
quint8 type;
quint32 id;
const ISO8211::Field *fspt = ISO8211::field(r, FSPT);
if (!fspt || fspt->data().at(0).size() != 4)
const ISO8211::Field *FSPT = ISO8211::field(r, "FSPT");
if (!FSPT || FSPT->data().at(0).size() != 4)
return Polygon();
for (int i = 0; i < fspt->data().size(); i++) {
if (!parseNAME(fspt, &type, &id, i) || type != RCNM_VE)
for (int i = 0; i < FSPT->data().size(); i++) {
if (!parseNAME(FSPT, &type, &id, i) || type != RCNM_VE)
return Polygon();
ornt = fspt->data().at(i).at(1).toUInt();
usag = fspt->data().at(i).at(2).toUInt();
ORNT = FSPT->data().at(i).at(1).toUInt();
USAG = FSPT->data().at(i).at(2).toUInt();
if (usag == 2 && path.isEmpty()) {
if (USAG == 2 && path.isEmpty()) {
path.append(v);
v.clear();
}
@ -658,55 +644,55 @@ Polygon MapData::polyGeometry(const ISO8211::Record &r, const RecordMap &vc,
RecordMapIterator it = ve.find(id);
if (it == ve.constEnd())
return Polygon();
const ISO8211::Record &frid = it.value();
const ISO8211::Field *vrpt = ISO8211::field(frid, VRPT);
if (!vrpt || vrpt->data().size() != 2)
const ISO8211::Record &FRID = it.value();
const ISO8211::Field *VRPT = ISO8211::field(FRID, "VRPT");
if (!VRPT || VRPT->data().size() != 2)
return Polygon();
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();
RecordMapIterator jt = vc.find(id);
if (jt == vc.constEnd())
return Polygon();
c[j] = point(jt.value(), comf);
c[j] = point(jt.value(), COMF);
if (c[j].isNull())
return Polygon();
}
const ISO8211::Field *vertexes = SGXD(frid);
if (ornt == 2) {
const ISO8211::Field *vertexes = SGXD(FRID);
if (ORNT == 2) {
v.append(c[1]);
if (usag == 3)
if (USAG == 3)
v.append(Coordinates());
if (vertexes) {
for (int j = vertexes->data().size() - 1; j >= 0; j--) {
const QVector<QVariant> &cv = vertexes->data().at(j);
v.append(coordinates(cv.at(1).toInt(), cv.at(0).toInt(),
comf));
COMF));
}
}
if (usag == 3)
if (USAG == 3)
v.append(Coordinates());
v.append(c[0]);
} else {
v.append(c[0]);
if (usag == 3)
if (USAG == 3)
v.append(Coordinates());
if (vertexes) {
for (int j = 0; j < vertexes->data().size(); j++) {
const QVector<QVariant> &cv = vertexes->data().at(j);
v.append(coordinates(cv.at(1).toInt(), cv.at(0).toInt(),
comf));
COMF));
}
}
if (usag == 3)
if (USAG == 3)
v.append(Coordinates());
v.append(c[1]);
}
if (usag == 2 && v.first() == v.last()) {
if (USAG == 2 && v.first() == v.last()) {
path.append(v);
v.clear();
}
@ -722,12 +708,12 @@ MapData::Attributes MapData::attributes(const ISO8211::Record &r)
{
Attributes attr;
const ISO8211::Field *attf = ISO8211::field(r, ATTF);
if (!(attf && attf->data().at(0).size() == 2))
const ISO8211::Field *ATTF = ISO8211::field(r, "ATTF");
if (!(ATTF && ATTF->data().at(0).size() == 2))
return attr;
for (int i = 0; i < attf->data().size(); i++) {
const QVector<QVariant> &av = attf->data().at(i);
for (int i = 0; i < ATTF->data().size(); i++) {
const QVector<QVariant> &av = ATTF->data().at(i);
attr.insert(av.at(0).toUInt(), av.at(1).toByteArray());
}
@ -740,64 +726,64 @@ MapData::Point *MapData::pointObject(const Sounding &s)
}
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));
return (c.isNull() ? 0 : new Point(objl, c, attributes(r), huni));
Coordinates c(pointGeometry(r, vi, vc, COMF));
return (c.isNull() ? 0 : new Point(OBJL, c, attributes(r), HUNI));
}
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));
return (path.isEmpty() ? 0 : new Line(objl, path, attributes(r)));
QVector<Coordinates> path(lineGeometry(r, vc, ve, COMF));
return (path.isEmpty() ? 0 : new Line(OBJL, path, attributes(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));
return (path.isEmpty() ? 0 : new Poly(objl, path, attributes(r), huni));
Polygon path(polyGeometry(r, vc, ve, COMF));
return (path.isEmpty() ? 0 : new Poly(OBJL, path, attributes(r), HUNI));
}
bool MapData::processRecord(const ISO8211::Record &record,
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)
return false;
const ISO8211::Field &f = record.at(1);
quint32 tag = f.tag();
const QByteArray &ba = f.tag();
if (tag == VRID) {
if (ba == "VRID") {
if (f.data().at(0).size() < 2)
return false;
int rcnm = f.data().at(0).at(0).toInt();
uint rcid = f.data().at(0).at(1).toUInt();
int RCNM = f.data().at(0).at(0).toInt();
uint RCID = f.data().at(0).at(1).toUInt();
switch (rcnm) {
switch (RCNM) {
case RCNM_VI:
vi.insert(rcid, record);
vi.insert(RCID, record);
break;
case RCNM_VC:
vc.insert(rcid, record);
vc.insert(RCID, record);
break;
case RCNM_VE:
ve.insert(rcid, record);
ve.insert(RCID, record);
break;
case RCNM_VF:
vf.insert(rcid, record);
vf.insert(RCID, record);
break;
default:
return false;
}
} else if (tag == FRID) {
} else if (ba == "FRID") {
fe.append(record);
} else if (tag == DSPM) {
if (!(f.subfield(COMF, &comf) && f.subfield(SOMF, &somf)))
} else if (ba == "DSPM") {
if (!(f.subfield("COMF", &COMF) && f.subfield("SOMF", &SOMF)))
return false;
if (!f.subfield(HUNI, &huni))
if (!f.subfield("HUNI", &HUNI))
return false;
}
@ -810,7 +796,7 @@ MapData::MapData(const QString &path)
QVector<ISO8211::Record> fe;
ISO8211 ddf(path);
ISO8211::Record record;
uint prim, objl, comf = 1, somf = 1, huni = 1;
uint PRIM, OBJL, COMF = 1, SOMF = 1, HUNI = 1;
Poly *poly;
Line *line;
Point *point;
@ -820,7 +806,7 @@ MapData::MapData(const QString &path)
if (!ddf.readDDR())
return;
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");
for (int i = 0; i < fe.size(); i++) {
@ -829,39 +815,39 @@ MapData::MapData(const QString &path)
if (f.data().at(0).size() < 5)
continue;
prim = f.data().at(0).at(2).toUInt();
objl = f.data().at(0).at(4).toUInt();
PRIM = f.data().at(0).at(2).toUInt();
OBJL = f.data().at(0).at(4).toUInt();
switch (prim) {
switch (PRIM) {
case PRIM_P:
if (objl == SOUNDG) {
QVector<Sounding> s(soundingGeometry(r, vi, vc, comf, somf));
if (OBJL == SOUNDG) {
QVector<Sounding> s(soundingGeometry(r, vi, vc, COMF, SOMF));
for (int i = 0; i < s.size(); i++) {
point = pointObject(s.at(i));
pointBounds(point->pos(), min, max);
_points.Insert(min, max, point);
}
} else {
if ((point = pointObject(r, vi, vc, comf, objl, huni))) {
if ((point = pointObject(r, vi, vc, COMF, OBJL, HUNI))) {
pointBounds(point->pos(), min, max);
_points.Insert(min, max, point);
} else
warning(f, prim);
warning(f, PRIM);
}
break;
case PRIM_L:
if ((line = lineObject(r, vc, ve, comf, objl))) {
if ((line = lineObject(r, vc, ve, COMF, OBJL))) {
rectcBounds(line->bounds(), min, max);
_lines.Insert(min, max, line);
} else
warning(f, prim);
warning(f, PRIM);
break;
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);
_areas.Insert(min, max, poly);
} else
warning(f, prim);
warning(f, PRIM);
break;
}
}

View File

@ -32,28 +32,28 @@ private:
typedef RTree<const Line*, double, 2> LineTree;
typedef RTree<const Point*, double, 2> PointTree;
static QVector<Sounding> soundings(const ISO8211::Record &r, uint comf,
uint somf);
static QVector<Sounding> soundings(const ISO8211::Record &r, uint COMF,
uint SOMF);
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,
const RecordMap &vi, const RecordMap &vc, uint comf);
const RecordMap &vi, const RecordMap &vc, uint COMF);
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,
const RecordMap &ve, uint comf);
const RecordMap &ve, uint COMF);
static Attributes attributes(const ISO8211::Record &r);
static Point *pointObject(const Sounding &s);
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,
const RecordMap &ve, uint comf, uint objl);
const RecordMap &ve, uint COMF, uint OBJL);
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,
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;
LineTree _lines;

View File

@ -12,14 +12,6 @@ using namespace ENC;
#define EPSILON 1e-6
#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)
{
switch (usage) {
@ -68,34 +60,35 @@ bool ENCAtlas::processRecord(const ISO8211::Record &record, QByteArray &file,
return false;
const ENC::ISO8211::Field &f = record.at(1);
const QByteArray &ba = f.tag();
if (f.tag() == CATD) {
QByteArray impl;
if (ba == "CATD") {
QByteArray FILE, IMPL;
if (!f.subfield(IMPL, &impl))
if (!f.subfield("IMPL", &IMPL))
return false;
if (!f.subfield(F1LE, &file))
if (!f.subfield("FILE", &FILE))
return false;
if (impl == "BIN" && file.endsWith("000")) {
QByteArray slat, wlon, nlat, elon;
if (IMPL == "BIN" && FILE.endsWith("000")) {
QByteArray SLAT, WLON, NLAT, ELON;
if (!f.subfield(SLAT, &slat))
if (!f.subfield("SLAT", &SLAT))
return false;
if (!f.subfield(WLON, &wlon))
if (!f.subfield("WLON", &WLON))
return false;
if (!f.subfield(NLAT, &nlat))
if (!f.subfield("NLAT", &NLAT))
return false;
if (!f.subfield(ELON, &elon))
if (!f.subfield("ELON", &ELON))
return false;
bool ok1, ok2, ok3, ok4;
bounds = RectC(Coordinates(wlon.toDouble(&ok1), nlat.toDouble(&ok2)),
Coordinates(elon.toDouble(&ok3), slat.toDouble(&ok4)));
bounds = RectC(Coordinates(WLON.toDouble(&ok1), NLAT.toDouble(&ok2)),
Coordinates(ELON.toDouble(&ok3), SLAT.toDouble(&ok4)));
if (!(ok1 && ok2 && ok3 && ok4))
return false;
file.replace('\\', '/');
file = FILE.replace('\\', '/');
return true;
}

View File

@ -15,14 +15,6 @@ using namespace ENC;
#define EPSILON 1e-6
#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)
{
double size = qMin(bounds.width(), bounds.height());
@ -65,9 +57,9 @@ static const ISO8211::Field *SGXD(const ISO8211::Record &r)
{
const ISO8211::Field *f;
if ((f = ISO8211::field(r, SG2D)))
if ((f = ISO8211::field(r, "SG2D")))
return f;
else if ((f = ISO8211::field(r, SG3D)))
else if ((f = ISO8211::field(r, "SG3D")))
return f;
else
return 0;
@ -105,21 +97,23 @@ bool ENCMap::bounds(const QVector<ISO8211::Record> &gv, Rect &b)
}
bool ENCMap::processRecord(const ISO8211::Record &record,
QVector<ISO8211::Record> &rv, uint &comf, QByteArray &dsnm)
QVector<ISO8211::Record> &rv, uint &COMF, QString &name)
{
if (record.size() < 2)
return false;
const ISO8211::Field &f = record.at(1);
quint32 tag = f.tag();
const QByteArray &ba = f.tag();
if (tag == VRID) {
if (ba == "VRID") {
rv.append(record);
} else if (tag == DSID) {
if (!f.subfield(DSNM, &dsnm))
} else if (ba == "DSID") {
QByteArray DSNM;
if (!f.subfield("DSNM", &DSNM))
return false;
} else if (tag == DSPM) {
if (!f.subfield(COMF, &comf))
name = DSNM;
} else if (ba == "DSPM") {
if (!f.subfield("COMF", &COMF))
return false;
}
@ -133,15 +127,14 @@ ENCMap::ENCMap(const QString &fileName, QObject *parent)
QVector<ISO8211::Record> gv;
ISO8211 ddf(fileName);
ISO8211::Record record;
uint comf = 1;
QByteArray dsnm;
uint COMF = 1;
if (!ddf.readDDR()) {
_errorString = ddf.errorString();
return;
}
while (ddf.readRecord(record)) {
if (!processRecord(record, gv, comf, dsnm)) {
if (!processRecord(record, gv, COMF, _name)) {
_errorString = "Invalid S-57 record";
return;
}
@ -151,15 +144,13 @@ ENCMap::ENCMap(const QString &fileName, QObject *parent)
return;
}
_name = dsnm;
Rect b;
if (!bounds(gv, b)) {
_errorString = "Error fetching geometries bounds";
return;
}
Coordinates tl(b.minX() / (double)comf, b.maxY() / (double)comf);
Coordinates br(b.maxX() / (double)comf, b.minY() / (double)comf);
Coordinates tl(b.minX() / (double)COMF, b.maxY() / (double)COMF);
Coordinates br(b.maxX() / (double)COMF, b.minY() / (double)COMF);
_llBounds = RectC(tl, br);
if (!_llBounds.isValid()) {
_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 QVector<ENC::ISO8211::Record> &gv, Rect &b);
static bool processRecord(const ENC::ISO8211::Record &record,
QVector<ENC::ISO8211::Record> &rv, uint &comf, QByteArray &dsnm);
QVector<ENC::ISO8211::Record> &rv, uint &COMF, QString &name);
QString _name;
ENC::MapData *_data;