Compare commits
15 Commits
Author | SHA1 | Date | |
---|---|---|---|
0531389cd8 | |||
a281a68cbd | |||
2e7f8dc341 | |||
1304fd5c3c | |||
d310399b4f | |||
845a4b2921 | |||
00fff55cd3 | |||
722f3acb1e | |||
b38cf31920 | |||
2884c39367 | |||
1124a1adb4 | |||
8c67df7bbd | |||
d1e632523a | |||
2549ca2c90 | |||
abd01933ab |
@ -1,4 +1,4 @@
|
|||||||
version: 13.8.{build}
|
version: 13.9.{build}
|
||||||
|
|
||||||
configuration:
|
configuration:
|
||||||
- Release
|
- Release
|
||||||
@ -8,10 +8,13 @@ image:
|
|||||||
|
|
||||||
environment:
|
environment:
|
||||||
NSISDIR: C:\Program Files (x86)\NSIS
|
NSISDIR: C:\Program Files (x86)\NSIS
|
||||||
OPENSSLDIR: C:\OpenSSL-v111-Win64\bin
|
|
||||||
matrix:
|
matrix:
|
||||||
- QTDIR: C:\Qt\5.15\msvc2019_64
|
- QTDIR: C:\Qt\5.15\msvc2019_64
|
||||||
|
OPENSSLDIR: C:\OpenSSL-v111-Win64\bin
|
||||||
|
OPENSSLVERSION: 1_1
|
||||||
- QTDIR: C:\Qt\6.5\msvc2019_64
|
- QTDIR: C:\Qt\6.5\msvc2019_64
|
||||||
|
OPENSSLDIR: C:\OpenSSL-v30-Win64\bin
|
||||||
|
OPENSSLVERSION: 3
|
||||||
NSISDEF: /DQT6
|
NSISDEF: /DQT6
|
||||||
|
|
||||||
install:
|
install:
|
||||||
@ -34,8 +37,8 @@ build_script:
|
|||||||
xcopy lang\*.qm installer\translations\ /sy
|
xcopy lang\*.qm installer\translations\ /sy
|
||||||
xcopy icons\symbols installer\symbols /i
|
xcopy icons\symbols installer\symbols /i
|
||||||
copy licence.txt installer
|
copy licence.txt installer
|
||||||
copy %OPENSSLDIR%\libcrypto-1_1-x64.dll installer
|
copy %OPENSSLDIR%\libcrypto-%OPENSSLVERSION%-x64.dll installer
|
||||||
copy %OPENSSLDIR%\libssl-1_1-x64.dll installer
|
copy %OPENSSLDIR%\libssl-%OPENSSLVERSION%-x64.dll installer
|
||||||
|
|
||||||
makensis.exe %NSISDEF% installer\gpxsee64.nsi
|
makensis.exe %NSISDEF% installer\gpxsee64.nsi
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@ unix:!macx:!android {
|
|||||||
} else {
|
} else {
|
||||||
TARGET = GPXSee
|
TARGET = GPXSee
|
||||||
}
|
}
|
||||||
VERSION = 13.8
|
VERSION = 13.9
|
||||||
|
|
||||||
|
|
||||||
QT += core \
|
QT += core \
|
||||||
@ -134,6 +134,7 @@ HEADERS += src/common/config.h \
|
|||||||
src/map/encmap.h \
|
src/map/encmap.h \
|
||||||
src/map/ENC/iso8211.h \
|
src/map/ENC/iso8211.h \
|
||||||
src/map/gemfmap.h \
|
src/map/gemfmap.h \
|
||||||
|
src/map/gmifile.h \
|
||||||
src/map/oruxmap.h \
|
src/map/oruxmap.h \
|
||||||
src/map/osmdroidmap.h \
|
src/map/osmdroidmap.h \
|
||||||
src/map/proj/polyconic.h \
|
src/map/proj/polyconic.h \
|
||||||
@ -347,6 +348,7 @@ SOURCES += src/main.cpp \
|
|||||||
src/map/encmap.cpp \
|
src/map/encmap.cpp \
|
||||||
src/map/ENC/iso8211.cpp \
|
src/map/ENC/iso8211.cpp \
|
||||||
src/map/gemfmap.cpp \
|
src/map/gemfmap.cpp \
|
||||||
|
src/map/gmifile.cpp \
|
||||||
src/map/oruxmap.cpp \
|
src/map/oruxmap.cpp \
|
||||||
src/map/osmdroidmap.cpp \
|
src/map/osmdroidmap.cpp \
|
||||||
src/map/proj/polyconic.cpp \
|
src/map/proj/polyconic.cpp \
|
||||||
|
@ -188,6 +188,7 @@
|
|||||||
<file alias="radar.png">icons/map/marine/radar.png</file>
|
<file alias="radar.png">icons/map/marine/radar.png</file>
|
||||||
<file alias="radar-transponder.png">icons/map/marine/radar-transponder.png</file>
|
<file alias="radar-transponder.png">icons/map/marine/radar-transponder.png</file>
|
||||||
<file alias="silo.png">icons/map/marine/silo.png</file>
|
<file alias="silo.png">icons/map/marine/silo.png</file>
|
||||||
|
<file alias="tank.png">icons/map/marine/tank.png</file>
|
||||||
<file alias="turning-basin.png">icons/map/marine/turning-basin.png</file>
|
<file alias="turning-basin.png">icons/map/marine/turning-basin.png</file>
|
||||||
<file alias="entry-prohibited-line.png">icons/map/marine/entry-prohibited-line.png</file>
|
<file alias="entry-prohibited-line.png">icons/map/marine/entry-prohibited-line.png</file>
|
||||||
<file alias="safety-zone-line.png">icons/map/marine/safety-zone-line.png</file>
|
<file alias="safety-zone-line.png">icons/map/marine/safety-zone-line.png</file>
|
||||||
|
Before Width: | Height: | Size: 235 B After Width: | Height: | Size: 170 B |
Before Width: | Height: | Size: 260 B After Width: | Height: | Size: 205 B |
Before Width: | Height: | Size: 218 B After Width: | Height: | Size: 221 B |
BIN
icons/map/marine/tank.png
Normal file
After Width: | Height: | Size: 230 B |
@ -1648,7 +1648,7 @@
|
|||||||
<key>UTTypeIdentifier</key>
|
<key>UTTypeIdentifier</key>
|
||||||
<string>int.iho.s57-catalogue</string>
|
<string>int.iho.s57-catalogue</string>
|
||||||
<key>UTTypeReferenceURL</key>
|
<key>UTTypeReferenceURL</key>
|
||||||
<string>https://iho.int/uploads/user/pubs/standards/s-57/31Main.pdf</string>
|
<string>https://iho.int/uploads/user/pubs/standards/s-57/20ApB1.pdf</string>
|
||||||
<key>UTTypeDescription</key>
|
<key>UTTypeDescription</key>
|
||||||
<string>IHO S-57 Electronic Navigation Catalogue</string>
|
<string>IHO S-57 Electronic Navigation Catalogue</string>
|
||||||
<key>UTTypeConformsTo</key>
|
<key>UTTypeConformsTo</key>
|
||||||
|
@ -37,7 +37,7 @@ Unicode true
|
|||||||
; The name of the installer
|
; The name of the installer
|
||||||
Name "GPXSee"
|
Name "GPXSee"
|
||||||
; Program version
|
; Program version
|
||||||
!define VERSION "13.8"
|
!define VERSION "13.9"
|
||||||
|
|
||||||
; The file to write
|
; The file to write
|
||||||
OutFile "GPXSee-${VERSION}_x64.exe"
|
OutFile "GPXSee-${VERSION}_x64.exe"
|
||||||
@ -302,8 +302,13 @@ Section "OpenSSL" SEC_OPENSSL
|
|||||||
|
|
||||||
SectionIn RO
|
SectionIn RO
|
||||||
|
|
||||||
|
!ifdef QT6
|
||||||
|
File "libcrypto-3-x64.dll"
|
||||||
|
File "libssl-3-x64.dll"
|
||||||
|
!else
|
||||||
File "libcrypto-1_1-x64.dll"
|
File "libcrypto-1_1-x64.dll"
|
||||||
File "libssl-1_1-x64.dll"
|
File "libssl-1_1-x64.dll"
|
||||||
|
!endif
|
||||||
|
|
||||||
SectionEnd
|
SectionEnd
|
||||||
|
|
||||||
|
@ -1750,7 +1750,7 @@ bool GUI::loadMapNode(const TreeNode<Map*> &node, MapAction *&action,
|
|||||||
|
|
||||||
bool GUI::loadMap(const QString &fileName, MapAction *&action, int &showError)
|
bool GUI::loadMap(const QString &fileName, MapAction *&action, int &showError)
|
||||||
{
|
{
|
||||||
TreeNode<Map*> maps(MapList::loadMaps(fileName));
|
TreeNode<Map*> maps(MapList::loadMaps(fileName, _mapView->inputProjection()));
|
||||||
QList<QAction*> existingActions(_mapsActionGroup->actions());
|
QList<QAction*> existingActions(_mapsActionGroup->actions());
|
||||||
|
|
||||||
return loadMapNode(maps, action, existingActions, showError);
|
return loadMapNode(maps, action, existingActions, showError);
|
||||||
@ -1854,7 +1854,7 @@ void GUI::loadMapDir()
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
QFileInfo fi(dir);
|
QFileInfo fi(dir);
|
||||||
TreeNode<Map*> maps(MapList::loadMaps(dir));
|
TreeNode<Map*> maps(MapList::loadMaps(dir, _mapView->inputProjection()));
|
||||||
QList<QAction*> existingActions(_mapsActionGroup->actions());
|
QList<QAction*> existingActions(_mapsActionGroup->actions());
|
||||||
QList<MapAction*> actions;
|
QList<MapAction*> actions;
|
||||||
QMenu *menu = new QMenu(maps.name());
|
QMenu *menu = new QMenu(maps.name());
|
||||||
@ -2985,7 +2985,7 @@ void GUI::loadInitialMaps(const QString &selected)
|
|||||||
if (mapDir.isNull())
|
if (mapDir.isNull())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
TreeNode<Map*> maps(MapList::loadMaps(mapDir));
|
TreeNode<Map*> maps(MapList::loadMaps(mapDir, _mapView->inputProjection()));
|
||||||
createMapNodeMenu(createMapActionsNode(maps), _mapMenu, _mapsEnd);
|
createMapNodeMenu(createMapActionsNode(maps), _mapMenu, _mapsEnd);
|
||||||
|
|
||||||
// Select the active map according to the user settings
|
// Select the active map according to the user settings
|
||||||
|
@ -81,15 +81,15 @@ ToolTip MapItem::info() const
|
|||||||
return tt;
|
return tt;
|
||||||
}
|
}
|
||||||
|
|
||||||
MapItem::MapItem(MapAction *action, Map *map, const Projection &proj,
|
MapItem::MapItem(MapAction *action, Map *map, GraphicsItem *parent)
|
||||||
GraphicsItem *parent) : PlaneItem(parent)
|
: PlaneItem(parent)
|
||||||
{
|
{
|
||||||
Map *src = action->data().value<Map*>();
|
Map *src = action->data().value<Map*>();
|
||||||
Q_ASSERT(map->isReady());
|
Q_ASSERT(map->isReady());
|
||||||
|
|
||||||
_name = src->name();
|
_name = src->name();
|
||||||
_fileName = src->path();
|
_fileName = src->path();
|
||||||
_bounds = src->llBounds(proj);
|
_bounds = src->llBounds();
|
||||||
|
|
||||||
connect(this, &MapItem::triggered, action, &MapAction::trigger);
|
connect(this, &MapItem::triggered, action, &MapAction::trigger);
|
||||||
|
|
||||||
|
@ -11,8 +11,7 @@ class MapItem : public QObject, public PlaneItem
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MapItem(MapAction *action, Map *map, const Projection &proj,
|
MapItem(MapAction *action, Map *map, GraphicsItem *parent = 0);
|
||||||
GraphicsItem *parent = 0);
|
|
||||||
|
|
||||||
QPainterPath shape() const {return _painterPath;}
|
QPainterPath shape() const {return _painterPath;}
|
||||||
QRectF boundingRect() const {return _painterPath.boundingRect();}
|
QRectF boundingRect() const {return _painterPath.boundingRect();}
|
||||||
|
@ -250,7 +250,7 @@ void MapView::addWaypoints(const QVector<Waypoint> &waypoints)
|
|||||||
|
|
||||||
MapItem *MapView::addMap(MapAction *map)
|
MapItem *MapView::addMap(MapAction *map)
|
||||||
{
|
{
|
||||||
MapItem *mi = new MapItem(map, _map, _inputProjection);
|
MapItem *mi = new MapItem(map, _map);
|
||||||
mi->setColor(_palette.nextColor());
|
mi->setColor(_palette.nextColor());
|
||||||
mi->setWidth(_areaWidth);
|
mi->setWidth(_areaWidth);
|
||||||
mi->setPenStyle(_areaStyle);
|
mi->setPenStyle(_areaStyle);
|
||||||
@ -331,7 +331,7 @@ int MapView::fitMapZoom() const
|
|||||||
RectC br = _tr | _rr | _wr | _ar;
|
RectC br = _tr | _rr | _wr | _ar;
|
||||||
|
|
||||||
return _map->zoomFit(viewport()->size() - QSize(2*MARGIN, 2*MARGIN),
|
return _map->zoomFit(viewport()->size() - QSize(2*MARGIN, 2*MARGIN),
|
||||||
br.isNull() ? _map->llBounds(_inputProjection) : br);
|
br.isNull() ? _map->llBounds() : br);
|
||||||
}
|
}
|
||||||
|
|
||||||
QPointF MapView::contentCenter() const
|
QPointF MapView::contentCenter() const
|
||||||
|
@ -98,6 +98,7 @@ public:
|
|||||||
void fitContentToSize();
|
void fitContentToSize();
|
||||||
|
|
||||||
RectC boundingRect() const;
|
RectC boundingRect() const;
|
||||||
|
const Projection &inputProjection() const {return _inputProjection;}
|
||||||
|
|
||||||
#ifdef Q_OS_ANDROID
|
#ifdef Q_OS_ANDROID
|
||||||
signals:
|
signals:
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#define CATTRK 54
|
#define CATTRK 54
|
||||||
#define CATREA 56
|
#define CATREA 56
|
||||||
#define CATSIT 61
|
#define CATSIT 61
|
||||||
|
#define CATSIL 63
|
||||||
#define CATSCF 65
|
#define CATSCF 65
|
||||||
#define CATWAT 69
|
#define CATWAT 69
|
||||||
#define CATWRK 71
|
#define CATWRK 71
|
||||||
|
@ -28,12 +28,23 @@ 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 ISO8211::Field::subfield(const char *name, int *val, int idx) const
|
||||||
{
|
{
|
||||||
const QVariant *v;
|
|
||||||
bool ok;
|
bool ok;
|
||||||
|
|
||||||
v = data().field(name, idx);
|
const QVariant *v = data(name, idx);
|
||||||
if (!v)
|
if (!v)
|
||||||
return false;
|
return false;
|
||||||
*val = v->toInt(&ok);
|
*val = v->toInt(&ok);
|
||||||
@ -43,10 +54,9 @@ bool ISO8211::Field::subfield(const char *name, int *val, int idx) const
|
|||||||
|
|
||||||
bool ISO8211::Field::subfield(const char *name, uint *val, int idx) const
|
bool ISO8211::Field::subfield(const char *name, uint *val, int idx) const
|
||||||
{
|
{
|
||||||
const QVariant *v;
|
|
||||||
bool ok;
|
bool ok;
|
||||||
|
|
||||||
v = data().field(name, idx);
|
const QVariant *v = data(name, idx);
|
||||||
if (!v)
|
if (!v)
|
||||||
return false;
|
return false;
|
||||||
*val = v->toUInt(&ok);
|
*val = v->toUInt(&ok);
|
||||||
@ -56,9 +66,7 @@ bool ISO8211::Field::subfield(const char *name, uint *val, int idx) const
|
|||||||
|
|
||||||
bool ISO8211::Field::subfield(const char *name, QByteArray *val, int idx) const
|
bool ISO8211::Field::subfield(const char *name, QByteArray *val, int idx) const
|
||||||
{
|
{
|
||||||
const QVariant *v;
|
const QVariant *v = data(name, idx);
|
||||||
|
|
||||||
v = data().field(name, idx);
|
|
||||||
if (!v)
|
if (!v)
|
||||||
return false;
|
return false;
|
||||||
*val = v->toByteArray();
|
*val = v->toByteArray();
|
||||||
@ -66,25 +74,24 @@ bool ISO8211::Field::subfield(const char *name, QByteArray *val, int idx) const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ISO8211::SubFieldDefinition ISO8211::fieldType(const QString &str, int cnt,
|
ISO8211::SubFieldDefinition ISO8211::fieldType(const QString &str, int cnt)
|
||||||
const QByteArray &tag)
|
|
||||||
{
|
{
|
||||||
if (str == "A" || str == "I" || str == "R")
|
if (str == "A" || str == "I" || str == "R")
|
||||||
return SubFieldDefinition(tag, String, cnt);
|
return SubFieldDefinition(String, cnt);
|
||||||
else if (str == "B")
|
else if (str == "B")
|
||||||
return SubFieldDefinition(tag, Array, cnt / 8);
|
return SubFieldDefinition(Array, cnt / 8);
|
||||||
else if (str == "b11")
|
else if (str == "b11")
|
||||||
return SubFieldDefinition(tag, U8, 1);
|
return SubFieldDefinition(U8, 1);
|
||||||
else if (str == "b12")
|
else if (str == "b12")
|
||||||
return SubFieldDefinition(tag, U16, 2);
|
return SubFieldDefinition(U16, 2);
|
||||||
else if (str == "b14")
|
else if (str == "b14")
|
||||||
return SubFieldDefinition(tag, U32, 4);
|
return SubFieldDefinition(U32, 4);
|
||||||
else if (str == "b21")
|
else if (str == "b21")
|
||||||
return SubFieldDefinition(tag, S8, 1);
|
return SubFieldDefinition(S8, 1);
|
||||||
else if (str == "b22")
|
else if (str == "b22")
|
||||||
return SubFieldDefinition(tag, S16, 2);
|
return SubFieldDefinition(S16, 2);
|
||||||
else if (str == "b24")
|
else if (str == "b24")
|
||||||
return SubFieldDefinition(tag, S32, 4);
|
return SubFieldDefinition(S32, 4);
|
||||||
else
|
else
|
||||||
return SubFieldDefinition();
|
return SubFieldDefinition();
|
||||||
}
|
}
|
||||||
@ -138,6 +145,7 @@ bool ISO8211::readDDA(const FieldDefinition &def, SubFields &fields)
|
|||||||
QByteArray ba;
|
QByteArray ba;
|
||||||
bool repeat = false;
|
bool repeat = false;
|
||||||
QVector<SubFieldDefinition> defs;
|
QVector<SubFieldDefinition> defs;
|
||||||
|
QVector<QByteArray> defTags;
|
||||||
|
|
||||||
ba.resize(def.size);
|
ba.resize(def.size);
|
||||||
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()))
|
||||||
@ -155,6 +163,7 @@ bool ISO8211::readDDA(const FieldDefinition &def, SubFields &fields)
|
|||||||
int tag = 0;
|
int tag = 0;
|
||||||
|
|
||||||
defs.resize(tags.size());
|
defs.resize(tags.size());
|
||||||
|
defTags.resize(tags.size());
|
||||||
|
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
QRegularExpressionMatch match = it.next();
|
QRegularExpressionMatch match = it.next();
|
||||||
@ -176,16 +185,17 @@ bool ISO8211::readDDA(const FieldDefinition &def, SubFields &fields)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (uint i = 0; i < cnt; i++) {
|
for (uint i = 0; i < cnt; i++) {
|
||||||
SubFieldDefinition sfd(fieldType(typeStr, size, tags.at(tag)));
|
SubFieldDefinition sfd(fieldType(typeStr, size));
|
||||||
if (sfd.type() == Unknown)
|
if (sfd.type() == Unknown)
|
||||||
return false;
|
return false;
|
||||||
defs[tag] = sfd;
|
defs[tag] = sfd;
|
||||||
|
defTags[tag] = tags.at(tag);
|
||||||
tag++;
|
tag++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fields = SubFields(defs, repeat);
|
fields = SubFields(defTags, defs, repeat);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -223,7 +233,8 @@ bool ISO8211::readDDR()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ISO8211::readUDA(quint64 pos, const FieldDefinition &def, Data &data)
|
bool ISO8211::readUDA(quint64 pos, const FieldDefinition &def,
|
||||||
|
const QVector<SubFieldDefinition> &fields, bool repeat, Data &data)
|
||||||
{
|
{
|
||||||
QByteArray ba;
|
QByteArray ba;
|
||||||
|
|
||||||
@ -238,10 +249,10 @@ bool ISO8211::readUDA(quint64 pos, const FieldDefinition &def, Data &data)
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
QVector<QVariant> row;
|
QVector<QVariant> row;
|
||||||
row.resize(data.fields()->size());
|
row.resize(fields.size());
|
||||||
|
|
||||||
for (int i = 0; i < data.fields()->size(); i++) {
|
for (int i = 0; i < fields.size(); i++) {
|
||||||
const SubFieldDefinition &f = data.fields()->at(i);
|
const SubFieldDefinition &f = fields.at(i);
|
||||||
|
|
||||||
switch (f.type()) {
|
switch (f.type()) {
|
||||||
case String:
|
case String:
|
||||||
@ -287,7 +298,7 @@ bool ISO8211::readUDA(quint64 pos, const FieldDefinition &def, Data &data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
data.append(row);
|
data.append(row);
|
||||||
} while (data.fields()->repeat() && dp < ep);
|
} while (repeat && dp < ep);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -299,9 +310,9 @@ bool ISO8211::readRecord(Record &record)
|
|||||||
|
|
||||||
QVector<FieldDefinition> fields;
|
QVector<FieldDefinition> fields;
|
||||||
qint64 pos = _file.pos();
|
qint64 pos = _file.pos();
|
||||||
int len = readDR(fields);
|
|
||||||
|
|
||||||
if (len < 0) {
|
|
||||||
|
if (readDR(fields) < 0) {
|
||||||
_errorString = "Error reading DR";
|
_errorString = "Error reading DR";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -310,6 +321,7 @@ bool ISO8211::readRecord(Record &record)
|
|||||||
|
|
||||||
for (int i = 0; i < fields.size(); i++) {
|
for (int i = 0; i < fields.size(); i++) {
|
||||||
const FieldDefinition &def = fields.at(i);
|
const FieldDefinition &def = fields.at(i);
|
||||||
|
Data data;
|
||||||
|
|
||||||
FieldsMap::const_iterator it = _map.find(def.tag);
|
FieldsMap::const_iterator it = _map.find(def.tag);
|
||||||
if (it == _map.constEnd()) {
|
if (it == _map.constEnd()) {
|
||||||
@ -317,15 +329,13 @@ bool ISO8211::readRecord(Record &record)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Data data(&it.value());
|
if (!readUDA(pos, def, it->defs(), it->repeat(), data)) {
|
||||||
|
|
||||||
if (!readUDA(pos, def, data)) {
|
|
||||||
_errorString = QString("Error reading %1 record")
|
_errorString = QString("Error reading %1 record")
|
||||||
.arg(QString(def.tag));
|
.arg(QString(def.tag));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
record[i] = Field(def.tag, data);
|
record[i] = Field(def.tag, it->tags(), data);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -17,87 +17,17 @@ namespace ENC {
|
|||||||
class ISO8211
|
class ISO8211
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum FieldType {Unknown, String, Array, S8, S16, S32, U8, U16, U32};
|
typedef QVector<QVector<QVariant> > Data;
|
||||||
|
|
||||||
struct FieldDefinition
|
|
||||||
{
|
|
||||||
QByteArray tag;
|
|
||||||
int pos;
|
|
||||||
int size;
|
|
||||||
};
|
|
||||||
|
|
||||||
class SubFieldDefinition
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SubFieldDefinition() : _type(Unknown), _size(0) {}
|
|
||||||
SubFieldDefinition(const QByteArray &tag, FieldType type, int size)
|
|
||||||
: _tag(tag), _type(type), _size(size) {}
|
|
||||||
|
|
||||||
const QByteArray &tag() const {return _tag;}
|
|
||||||
FieldType type() const {return _type;}
|
|
||||||
int size() const {return _size;}
|
|
||||||
|
|
||||||
private:
|
|
||||||
QByteArray _tag;
|
|
||||||
FieldType _type;
|
|
||||||
int _size;
|
|
||||||
};
|
|
||||||
|
|
||||||
class SubFields
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SubFields() : _repeat(false) {}
|
|
||||||
SubFields(const QVector<SubFieldDefinition> &defs, bool repeat)
|
|
||||||
: _defs(defs), _repeat(repeat) {}
|
|
||||||
|
|
||||||
int size() const {return _defs.size();}
|
|
||||||
const SubFieldDefinition &at(int i) const {return _defs.at(i);}
|
|
||||||
|
|
||||||
bool repeat() const {return _repeat;}
|
|
||||||
|
|
||||||
private:
|
|
||||||
QVector<SubFieldDefinition> _defs;
|
|
||||||
bool _repeat;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Data
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Data() : _fields(0) {}
|
|
||||||
Data(const SubFields *fields) : _fields(fields) {}
|
|
||||||
|
|
||||||
int size() const {return _data.size();}
|
|
||||||
const QVector<QVariant> &at(int i) const {return _data.at(i);}
|
|
||||||
|
|
||||||
const SubFields *fields() const {return _fields;}
|
|
||||||
const QVariant *field(const QByteArray &name, int idx = 0) const
|
|
||||||
{
|
|
||||||
const QVector<QVariant> &v = _data.at(idx);
|
|
||||||
|
|
||||||
for (int i = 0; i < _fields->size(); i++)
|
|
||||||
if (_fields->at(i).tag() == name)
|
|
||||||
return &v.at(i);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend class ISO8211;
|
|
||||||
|
|
||||||
void append(QVector<QVariant> &row) {_data.append(row);}
|
|
||||||
|
|
||||||
QVector<QVector<QVariant> > _data;
|
|
||||||
const SubFields *_fields;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Field
|
class Field
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Field() {}
|
Field() {}
|
||||||
Field(const QByteArray &tag, const Data &data)
|
Field(const QByteArray &tag, const QVector<QByteArray> &subFields,
|
||||||
: _tag(tag), _data(data) {}
|
const Data &data) : _tag(tag), _subFields(subFields), _data(data) {}
|
||||||
|
|
||||||
const QByteArray &tag() const {return _tag;}
|
const QByteArray &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, int *val, int idx = 0) const;
|
||||||
@ -105,7 +35,10 @@ public:
|
|||||||
bool subfield(const char *name, QByteArray *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;
|
||||||
|
|
||||||
QByteArray _tag;
|
QByteArray _tag;
|
||||||
|
QVector<QByteArray> _subFields;
|
||||||
Data _data;
|
Data _data;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -120,14 +53,57 @@ public:
|
|||||||
static const Field *field(const Record &record, const QByteArray &name);
|
static const Field *field(const Record &record, const QByteArray &name);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
enum FieldType {Unknown, String, Array, S8, S16, S32, U8, U16, U32};
|
||||||
|
|
||||||
|
struct FieldDefinition
|
||||||
|
{
|
||||||
|
QByteArray tag;
|
||||||
|
int pos;
|
||||||
|
int size;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SubFieldDefinition
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SubFieldDefinition() : _type(Unknown), _size(0) {}
|
||||||
|
SubFieldDefinition(FieldType type, int size)
|
||||||
|
: _type(type), _size(size) {}
|
||||||
|
|
||||||
|
FieldType type() const {return _type;}
|
||||||
|
int size() const {return _size;}
|
||||||
|
|
||||||
|
private:
|
||||||
|
FieldType _type;
|
||||||
|
int _size;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SubFields
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SubFields() : _repeat(false) {}
|
||||||
|
SubFields(const QVector<QByteArray> &tags,
|
||||||
|
const QVector<SubFieldDefinition> &defs, bool repeat)
|
||||||
|
: _tags(tags), _defs(defs), _repeat(repeat) {}
|
||||||
|
|
||||||
|
const QVector<QByteArray> &tags() const {return _tags;}
|
||||||
|
const QVector<SubFieldDefinition> &defs() const {return _defs;}
|
||||||
|
|
||||||
|
bool repeat() const {return _repeat;}
|
||||||
|
|
||||||
|
private:
|
||||||
|
QVector<QByteArray> _tags;
|
||||||
|
QVector<SubFieldDefinition> _defs;
|
||||||
|
bool _repeat;
|
||||||
|
};
|
||||||
|
|
||||||
typedef QMap<QByteArray, SubFields> FieldsMap;
|
typedef QMap<QByteArray, SubFields> FieldsMap;
|
||||||
|
|
||||||
static SubFieldDefinition fieldType(const QString &str, int cnt,
|
static SubFieldDefinition fieldType(const QString &str, int cnt);
|
||||||
const QByteArray &tag);
|
|
||||||
|
|
||||||
int readDR(QVector<FieldDefinition> &fields);
|
int readDR(QVector<FieldDefinition> &fields);
|
||||||
bool readDDA(const FieldDefinition &def, SubFields &fields);
|
bool readDDA(const FieldDefinition &def, SubFields &fields);
|
||||||
bool readUDA(quint64 pos, const FieldDefinition &def, Data &data);
|
bool readUDA(quint64 pos, const FieldDefinition &def,
|
||||||
|
const QVector<SubFieldDefinition> &fields, bool repeat, Data &data);
|
||||||
|
|
||||||
QFile _file;
|
QFile _file;
|
||||||
FieldsMap _map;
|
FieldsMap _map;
|
||||||
@ -135,22 +111,9 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
#ifndef QT_NO_DEBUG
|
#ifndef QT_NO_DEBUG
|
||||||
inline QDebug operator<<(QDebug dbg, const ISO8211::FieldDefinition &def)
|
|
||||||
{
|
|
||||||
dbg.nospace() << "FieldDefinition(" << def.tag << ", " << def.size << ")";
|
|
||||||
return dbg.space();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline QDebug operator<<(QDebug dbg, const ISO8211::SubFieldDefinition &def)
|
|
||||||
{
|
|
||||||
dbg.nospace() << "SubField(" << def.tag() << ", " << def.type() << ", "
|
|
||||||
<< def.size() << ")";
|
|
||||||
return dbg.space();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline QDebug operator<<(QDebug dbg, const ISO8211::Field &field)
|
inline QDebug operator<<(QDebug dbg, const ISO8211::Field &field)
|
||||||
{
|
{
|
||||||
dbg.nospace() << "Field(" << field.tag() << ")";
|
dbg.nospace() << "Field(" << field.tag() << ", " << field.subFields() << ")";
|
||||||
return dbg.space();
|
return dbg.space();
|
||||||
}
|
}
|
||||||
#endif // QT_NO_DEBUG
|
#endif // QT_NO_DEBUG
|
||||||
|
@ -560,7 +560,8 @@ MapData::Attr MapData::pointAttr(const ISO8211::Record &r, uint OBJL)
|
|||||||
|| (OBJL == SISTAT && key == CATSIT)
|
|| (OBJL == SISTAT && key == CATSIT)
|
||||||
|| (OBJL == I_SISTAT && key == I_CATSIT)
|
|| (OBJL == I_SISTAT && key == I_CATSIT)
|
||||||
|| (OBJL == RDOCAL && key == TRAFIC)
|
|| (OBJL == RDOCAL && key == TRAFIC)
|
||||||
|| (OBJL == I_RDOCAL && key == TRAFIC))
|
|| (OBJL == I_RDOCAL && key == TRAFIC)
|
||||||
|
|| (OBJL == SILTNK && key == CATSIL))
|
||||||
subtype = av.at(1).toByteArray().toUInt();
|
subtype = av.at(1).toByteArray().toUInt();
|
||||||
else if (OBJL == I_DISMAR && key == CATDIS)
|
else if (OBJL == I_DISMAR && key == CATDIS)
|
||||||
subtype |= av.at(1).toByteArray().toUInt();
|
subtype |= av.at(1).toByteArray().toUInt();
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#define CANALS 23
|
#define CANALS 23
|
||||||
#define CGUSTA 29
|
#define CGUSTA 29
|
||||||
#define COALNE 30
|
#define COALNE 30
|
||||||
|
#define CONZNE 31
|
||||||
#define CONVYR 34
|
#define CONVYR 34
|
||||||
#define CRANES 35
|
#define CRANES 35
|
||||||
#define CURENT 36
|
#define CURENT 36
|
||||||
|
@ -104,6 +104,8 @@ void Style::polygonStyle()
|
|||||||
_polygons[SUBTYPE(MARKUL, 3)] = Polygon(QImage(":/marine/fishing-farm-line.png"));
|
_polygons[SUBTYPE(MARKUL, 3)] = Polygon(QImage(":/marine/fishing-farm-line.png"));
|
||||||
_polygons[SUBTYPE(I_BERTHS, 6)] = Polygon(Qt::NoBrush, QPen(QColor("#eb49eb"),
|
_polygons[SUBTYPE(I_BERTHS, 6)] = Polygon(Qt::NoBrush, QPen(QColor("#eb49eb"),
|
||||||
1, Qt::DashLine));
|
1, Qt::DashLine));
|
||||||
|
_polygons[TYPE(CONZNE)] = Polygon(Qt::NoBrush, QPen(QColor("#eb49eb"), 1,
|
||||||
|
Qt::DashDotLine));
|
||||||
|
|
||||||
_drawOrder
|
_drawOrder
|
||||||
<< TYPE(M_COVR) << TYPE(LNDARE) << SUBTYPE(DEPARE, 0)
|
<< TYPE(M_COVR) << TYPE(LNDARE) << SUBTYPE(DEPARE, 0)
|
||||||
@ -122,7 +124,7 @@ void Style::polygonStyle()
|
|||||||
<< SUBTYPE(RESARE, 9) << SUBTYPE(RESARE, 2) << SUBTYPE(I_RESARE, 2)
|
<< SUBTYPE(RESARE, 9) << SUBTYPE(RESARE, 2) << SUBTYPE(I_RESARE, 2)
|
||||||
<< SUBTYPE(RESARE, 17) << SUBTYPE(I_RESARE, 17) << SUBTYPE(RESARE, 12)
|
<< SUBTYPE(RESARE, 17) << SUBTYPE(I_RESARE, 17) << SUBTYPE(RESARE, 12)
|
||||||
<< SUBTYPE(I_RESARE, 12) << SUBTYPE(RESARE, 1) << TYPE(CBLARE)
|
<< SUBTYPE(I_RESARE, 12) << SUBTYPE(RESARE, 1) << TYPE(CBLARE)
|
||||||
<< TYPE(PIPARE) << TYPE(PRCARE) << SUBTYPE(MARKUL, 3);
|
<< TYPE(PIPARE) << TYPE(PRCARE) << SUBTYPE(MARKUL, 3) << TYPE(CONZNE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Style::lineStyle()
|
void Style::lineStyle()
|
||||||
@ -254,7 +256,11 @@ void Style::pointStyle()
|
|||||||
_points[TYPE(RDOSTA)] = Point(QImage(":/marine/radio.png"));
|
_points[TYPE(RDOSTA)] = Point(QImage(":/marine/radio.png"));
|
||||||
_points[TYPE(RADSTA)] = Point(QImage(":/marine/radar.png"));
|
_points[TYPE(RADSTA)] = Point(QImage(":/marine/radar.png"));
|
||||||
_points[TYPE(RTPBCN)] = Point(QImage(":/marine/radar-transponder.png"));
|
_points[TYPE(RTPBCN)] = Point(QImage(":/marine/radar-transponder.png"));
|
||||||
_points[TYPE(SILTNK)] = Point(QImage(":/marine/silo.png"));
|
_points[SUBTYPE(SILTNK, 0)] = Point(QImage(":/marine/silo.png"));
|
||||||
|
_points[SUBTYPE(SILTNK, 1)] = Point(QImage(":/marine/silo.png"));
|
||||||
|
_points[SUBTYPE(SILTNK, 2)] = Point(QImage(":/marine/tank.png"));
|
||||||
|
_points[SUBTYPE(SILTNK, 3)] = Point(QImage(":/marine/silo.png"));
|
||||||
|
_points[SUBTYPE(SILTNK, 4)] = Point(QImage(":/marine/silo.png"));
|
||||||
_points[TYPE(I_TRNBSN)] = Point(QImage(":/marine/turning-basin.png"));
|
_points[TYPE(I_TRNBSN)] = Point(QImage(":/marine/turning-basin.png"));
|
||||||
_points[TYPE(I_TRNBSN)].setTextColor(QColor("#eb49eb"));
|
_points[TYPE(I_TRNBSN)].setTextColor(QColor("#eb49eb"));
|
||||||
_points[TYPE(I_WTWGAG)] = Point(QImage(":/marine/gauge.png"), Small);
|
_points[TYPE(I_WTWGAG)] = Point(QImage(":/marine/gauge.png"), Small);
|
||||||
|
@ -405,8 +405,10 @@ void AQMMap::drawTile(QPainter *painter, QPixmap &pixmap, QPointF &tp)
|
|||||||
painter->drawPixmap(tp, pixmap);
|
painter->drawPixmap(tp, pixmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map *AQMMap::create(const QString &path, bool *isDir)
|
Map *AQMMap::create(const QString &path, const Projection &proj, bool *isDir)
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(proj);
|
||||||
|
|
||||||
if (isDir)
|
if (isDir)
|
||||||
*isDir = false;
|
*isDir = false;
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ public:
|
|||||||
QString name() const {return _name;}
|
QString name() const {return _name;}
|
||||||
|
|
||||||
QRectF bounds();
|
QRectF bounds();
|
||||||
RectC llBounds(const Projection &) {return _bounds;}
|
RectC llBounds() {return _bounds;}
|
||||||
qreal resolution(const QRectF &rect);
|
qreal resolution(const QRectF &rect);
|
||||||
|
|
||||||
int zoom() const {return _zoom;}
|
int zoom() const {return _zoom;}
|
||||||
@ -38,7 +38,7 @@ public:
|
|||||||
bool isValid() const {return _valid;}
|
bool isValid() const {return _valid;}
|
||||||
QString errorString() const {return _errorString;}
|
QString errorString() const {return _errorString;}
|
||||||
|
|
||||||
static Map *create(const QString &path, bool *isDir);
|
static Map *create(const QString &path, const Projection &proj, bool *isDir);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct File {
|
struct File {
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
#include "atlas.h"
|
#include "atlas.h"
|
||||||
|
|
||||||
|
|
||||||
#define ZOOM_THRESHOLD 0.9
|
#define ZOOM_THRESHOLD 0.8
|
||||||
|
|
||||||
#define TL(m) ((m)->xy2pp((m)->bounds().topLeft()))
|
#define TL(m) ((m)->xy2pp((m)->bounds().topLeft()))
|
||||||
#define BR(m) ((m)->xy2pp((m)->bounds().bottomRight()))
|
#define BR(m) ((m)->xy2pp((m)->bounds().bottomRight()))
|
||||||
@ -27,6 +27,34 @@ static bool yCmp(OziMap *m1, OziMap *m2)
|
|||||||
return TL(m1).y() > TL(m2).y();
|
return TL(m1).y() > TL(m2).y();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static QString calibrationFile(const QString &path)
|
||||||
|
{
|
||||||
|
QDir dir(path);
|
||||||
|
QFileInfoList files = dir.entryInfoList(QDir::Files);
|
||||||
|
|
||||||
|
for (int i = 0; i < files.size(); i++) {
|
||||||
|
const QFileInfo &fi = files.at(i);
|
||||||
|
QString suffix(fi.suffix().toLower());
|
||||||
|
|
||||||
|
if (suffix == "map" || suffix == "gmi")
|
||||||
|
return fi.absoluteFilePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
static QString tbaFile(const QStringList &files)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < files.size(); i++) {
|
||||||
|
QFileInfo fi(files.at(i));
|
||||||
|
|
||||||
|
if (fi.path() == "." && fi.suffix().toLower() == "tba")
|
||||||
|
return files.at(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
void Atlas::computeZooms()
|
void Atlas::computeZooms()
|
||||||
{
|
{
|
||||||
std::sort(_maps.begin(), _maps.end(), resCmp);
|
std::sort(_maps.begin(), _maps.end(), resCmp);
|
||||||
@ -72,8 +100,9 @@ void Atlas::computeBounds()
|
|||||||
QRectF(offsets.at(i), _maps.at(i)->bounds().size()));
|
QRectF(offsets.at(i), _maps.at(i)->bounds().size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
Atlas::Atlas(const QString &fileName, bool TAR, QObject *parent)
|
Atlas::Atlas(const QString &fileName, bool TAR, const Projection &proj,
|
||||||
: Map(fileName, parent), _zoom(0), _mapIndex(-1), _valid(false)
|
QObject *parent) : Map(fileName, parent), _zoom(0), _mapIndex(-1),
|
||||||
|
_valid(false)
|
||||||
{
|
{
|
||||||
QFileInfo fi(fileName);
|
QFileInfo fi(fileName);
|
||||||
QByteArray ba;
|
QByteArray ba;
|
||||||
@ -86,7 +115,11 @@ Atlas::Atlas(const QString &fileName, bool TAR, QObject *parent)
|
|||||||
_errorString = "Error reading tar file";
|
_errorString = "Error reading tar file";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QString tbaFileName = fi.completeBaseName() + ".tba";
|
QString tbaFileName(tbaFile(tar.files()));
|
||||||
|
if (tbaFileName.isNull()) {
|
||||||
|
_errorString = "No tba file found";
|
||||||
|
return;
|
||||||
|
}
|
||||||
ba = tar.file(tbaFileName);
|
ba = tar.file(tbaFileName);
|
||||||
} else {
|
} else {
|
||||||
QFile tbaFile(fileName);
|
QFile tbaFile(fileName);
|
||||||
@ -97,7 +130,7 @@ Atlas::Atlas(const QString &fileName, bool TAR, QObject *parent)
|
|||||||
ba = tbaFile.readAll();
|
ba = tbaFile.readAll();
|
||||||
}
|
}
|
||||||
if (!ba.startsWith("Atlas 1.0")) {
|
if (!ba.startsWith("Atlas 1.0")) {
|
||||||
_errorString = "Missing or invalid tba file";
|
_errorString = "Invalid tba file";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,38 +141,41 @@ Atlas::Atlas(const QString &fileName, bool TAR, QObject *parent)
|
|||||||
QFileInfoList maps = zdir.entryInfoList(QDir::Dirs
|
QFileInfoList maps = zdir.entryInfoList(QDir::Dirs
|
||||||
| QDir::NoDotAndDotDot);
|
| QDir::NoDotAndDotDot);
|
||||||
for (int i = 0; i < maps.count(); i++) {
|
for (int i = 0; i < maps.count(); i++) {
|
||||||
QString mapFile = maps.at(i).absoluteFilePath() + "/"
|
|
||||||
+ maps.at(i).fileName() + ".map";
|
|
||||||
|
|
||||||
OziMap *map;
|
OziMap *map;
|
||||||
if (tar.isOpen())
|
if (TAR)
|
||||||
map = new OziMap(mapFile, tar, this);
|
map = new OziMap(maps.at(i).absoluteFilePath(), tar, proj, this);
|
||||||
else
|
else {
|
||||||
map = new OziMap(mapFile, TAR, this);
|
QString cf(calibrationFile(maps.at(i).absoluteFilePath()));
|
||||||
|
if (cf.isNull()) {
|
||||||
|
_errorString = "No calibration file found";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
map = new OziMap(cf, proj, this);
|
||||||
|
}
|
||||||
|
|
||||||
if (map->isValid())
|
if (map->isValid())
|
||||||
_maps.append(map);
|
_maps.append(map);
|
||||||
else {
|
else {
|
||||||
_errorString = QString("Error loading map: %1: %2")
|
qWarning("%s: %s", qPrintable(map->path()),
|
||||||
.arg(mapFile, map->errorString());
|
qPrintable(map->errorString()));
|
||||||
return;
|
delete map;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_maps.isEmpty()) {
|
if (_maps.isEmpty()) {
|
||||||
_errorString = "No maps found in atlas";
|
_errorString = "No usable map found in atlas";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_valid = true;
|
_valid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
RectC Atlas::llBounds(const Projection &proj)
|
RectC Atlas::llBounds()
|
||||||
{
|
{
|
||||||
RectC bounds;
|
RectC bounds;
|
||||||
|
|
||||||
for (int i = 0; i < _maps.size(); i++)
|
for (int i = 0; i < _maps.size(); i++)
|
||||||
bounds |= _maps.at(i)->llBounds(proj);
|
bounds |= _maps.at(i)->llBounds();
|
||||||
|
|
||||||
return bounds;
|
return bounds;
|
||||||
}
|
}
|
||||||
@ -295,18 +331,34 @@ void Atlas::unload()
|
|||||||
_bounds.clear();
|
_bounds.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
Map *Atlas::createTAR(const QString &path, bool *isDir)
|
Map *Atlas::createTAR(const QString &path, const Projection &proj, bool *isDir)
|
||||||
{
|
{
|
||||||
if (isDir)
|
if (isDir)
|
||||||
*isDir = true;
|
*isDir = true;
|
||||||
|
|
||||||
return new Atlas(path, true);
|
return new Atlas(path, true, proj);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map *Atlas::createTBA(const QString &path, bool *isDir)
|
Map *Atlas::createTBA(const QString &path, const Projection &proj, bool *isDir)
|
||||||
{
|
{
|
||||||
if (isDir)
|
if (isDir)
|
||||||
*isDir = true;
|
*isDir = true;
|
||||||
|
|
||||||
return new Atlas(path, false);
|
return new Atlas(path, false, proj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef QT_NO_DEBUG
|
||||||
|
QDebug operator<<(QDebug dbg, const Atlas::Bounds &bounds)
|
||||||
|
{
|
||||||
|
dbg.nospace() << "Bounds(" << bounds.xy << ", " << bounds.pp << ")";
|
||||||
|
|
||||||
|
return dbg.space();
|
||||||
|
}
|
||||||
|
|
||||||
|
QDebug operator<<(QDebug dbg, const Atlas::Zoom &zoom)
|
||||||
|
{
|
||||||
|
dbg.nospace() << "Zoom(" << zoom.first << ", " << zoom.last << ")";
|
||||||
|
|
||||||
|
return dbg.space();
|
||||||
|
}
|
||||||
|
#endif // QT_NO_DEBUG
|
||||||
|
@ -12,12 +12,13 @@ class Atlas : public Map
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Atlas(const QString &fileName, bool TAR, QObject *parent = 0);
|
Atlas(const QString &fileName, bool TAR, const Projection &proj,
|
||||||
|
QObject *parent = 0);
|
||||||
|
|
||||||
QString name() const {return _name;}
|
QString name() const {return _name;}
|
||||||
|
|
||||||
QRectF bounds();
|
QRectF bounds();
|
||||||
RectC llBounds(const Projection &proj);
|
RectC llBounds();
|
||||||
|
|
||||||
int zoom() const {return _zoom;}
|
int zoom() const {return _zoom;}
|
||||||
void setZoom(int zoom);
|
void setZoom(int zoom);
|
||||||
@ -37,8 +38,10 @@ public:
|
|||||||
bool isValid() const {return _valid;}
|
bool isValid() const {return _valid;}
|
||||||
QString errorString() const {return _errorString;}
|
QString errorString() const {return _errorString;}
|
||||||
|
|
||||||
static Map *createTAR(const QString &path, bool *isDir);
|
static Map *createTAR(const QString &path, const Projection &proj,
|
||||||
static Map *createTBA(const QString &path, bool *isDir);
|
bool *isDir);
|
||||||
|
static Map *createTBA(const QString &path, const Projection &proj,
|
||||||
|
bool *isDir);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Zoom {
|
struct Zoom {
|
||||||
@ -61,6 +64,9 @@ private:
|
|||||||
void computeZooms();
|
void computeZooms();
|
||||||
void computeBounds();
|
void computeBounds();
|
||||||
|
|
||||||
|
friend QDebug operator<<(QDebug dbg, const Bounds &bounds);
|
||||||
|
friend QDebug operator<<(QDebug dbg, const Zoom &zoom);
|
||||||
|
|
||||||
QString _name;
|
QString _name;
|
||||||
|
|
||||||
QList<OziMap*> _maps;
|
QList<OziMap*> _maps;
|
||||||
@ -73,4 +79,9 @@ private:
|
|||||||
QString _errorString;
|
QString _errorString;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifndef QT_NO_DEBUG
|
||||||
|
QDebug operator<<(QDebug dbg, const Atlas::Zoom &zoom);
|
||||||
|
QDebug operator<<(QDebug dbg, const Atlas::Bounds &bounds);
|
||||||
|
#endif // QT_NO_DEBUG
|
||||||
|
|
||||||
#endif // ATLAS_H
|
#endif // ATLAS_H
|
||||||
|
@ -462,8 +462,10 @@ void BSBMap::unload()
|
|||||||
_img = 0;
|
_img = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Map *BSBMap::create(const QString &path, bool *isMap)
|
Map *BSBMap::create(const QString &path, const Projection &proj, bool *isMap)
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(proj);
|
||||||
|
|
||||||
if (isMap)
|
if (isMap)
|
||||||
*isMap = false;
|
*isMap = false;
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ public:
|
|||||||
bool isValid() const {return _valid;}
|
bool isValid() const {return _valid;}
|
||||||
QString errorString() const {return _errorString;}
|
QString errorString() const {return _errorString;}
|
||||||
|
|
||||||
static Map *create(const QString &path, bool *isMap);
|
static Map *create(const QString &path, const Projection &proj, bool *isMap);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool parseBSB(const QByteArray &line);
|
bool parseBSB(const QByteArray &line);
|
||||||
|
@ -378,8 +378,10 @@ void ENCAtlas::draw(QPainter *painter, const QRectF &rect, Flags flags)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Map *ENCAtlas::create(const QString &path, bool *isDir)
|
Map *ENCAtlas::create(const QString &path, const Projection &proj, bool *isDir)
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(proj);
|
||||||
|
|
||||||
if (isDir)
|
if (isDir)
|
||||||
*isDir = true;
|
*isDir = true;
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ public:
|
|||||||
QString name() const {return _name;}
|
QString name() const {return _name;}
|
||||||
|
|
||||||
QRectF bounds() {return _bounds;}
|
QRectF bounds() {return _bounds;}
|
||||||
RectC llBounds(const Projection &) {return _llBounds;}
|
RectC llBounds() {return _llBounds;}
|
||||||
|
|
||||||
int zoom() const {return _zoom;}
|
int zoom() const {return _zoom;}
|
||||||
void setZoom(int zoom);
|
void setZoom(int zoom);
|
||||||
@ -44,7 +44,7 @@ public:
|
|||||||
bool isValid() const {return _valid;}
|
bool isValid() const {return _valid;}
|
||||||
QString errorString() const {return _errorString;}
|
QString errorString() const {return _errorString;}
|
||||||
|
|
||||||
static Map *create(const QString &path, bool *isDir);
|
static Map *create(const QString &path, const Projection &proj, bool *isDir);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void jobFinished(ENCJob *job);
|
void jobFinished(ENCJob *job);
|
||||||
|
@ -345,8 +345,10 @@ void ENCMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Map *ENCMap::create(const QString &path, bool *isMap)
|
Map *ENCMap::create(const QString &path, const Projection &proj, bool *isMap)
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(proj);
|
||||||
|
|
||||||
if (isMap)
|
if (isMap)
|
||||||
*isMap = false;
|
*isMap = false;
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ public:
|
|||||||
QString name() const {return _name;}
|
QString name() const {return _name;}
|
||||||
|
|
||||||
QRectF bounds() {return _bounds;}
|
QRectF bounds() {return _bounds;}
|
||||||
RectC llBounds(const Projection &) {return _llBounds;}
|
RectC llBounds() {return _llBounds;}
|
||||||
|
|
||||||
int zoom() const {return _zoom;}
|
int zoom() const {return _zoom;}
|
||||||
void setZoom(int zoom);
|
void setZoom(int zoom);
|
||||||
@ -45,7 +45,7 @@ public:
|
|||||||
bool isValid() const {return _valid;}
|
bool isValid() const {return _valid;}
|
||||||
QString errorString() const {return _errorString;}
|
QString errorString() const {return _errorString;}
|
||||||
|
|
||||||
static Map *create(const QString &path, bool *isMap);
|
static Map *create(const QString &path, const Projection &proj, bool *isMap);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void jobFinished(ENCJob *job);
|
void jobFinished(ENCJob *job);
|
||||||
|
@ -301,8 +301,10 @@ void GEMFMap::drawTile(QPainter *painter, QPixmap &pixmap, QPointF &tp)
|
|||||||
painter->drawPixmap(tp, pixmap);
|
painter->drawPixmap(tp, pixmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map *GEMFMap::create(const QString &path, bool *isDir)
|
Map *GEMFMap::create(const QString &path, const Projection &proj, bool *isDir)
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(proj);
|
||||||
|
|
||||||
if (isDir)
|
if (isDir)
|
||||||
*isDir = false;
|
*isDir = false;
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ public:
|
|||||||
GEMFMap(const QString &fileName, QObject *parent = 0);
|
GEMFMap(const QString &fileName, QObject *parent = 0);
|
||||||
|
|
||||||
QRectF bounds();
|
QRectF bounds();
|
||||||
RectC llBounds(const Projection &) {return _bounds;}
|
RectC llBounds() {return _bounds;}
|
||||||
|
|
||||||
int zoom() const {return _zi;}
|
int zoom() const {return _zi;}
|
||||||
void setZoom(int zoom) {_zi = zoom;}
|
void setZoom(int zoom) {_zi = zoom;}
|
||||||
@ -35,7 +35,7 @@ public:
|
|||||||
bool isValid() const {return _valid;}
|
bool isValid() const {return _valid;}
|
||||||
QString errorString() const {return _errorString;}
|
QString errorString() const {return _errorString;}
|
||||||
|
|
||||||
static Map *create(const QString &path, bool *isDir);
|
static Map *create(const QString &path, const Projection &proj, bool *isDir);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Region {
|
struct Region {
|
||||||
|
@ -73,8 +73,10 @@ void GeoTIFFMap::unload()
|
|||||||
_img = 0;
|
_img = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Map *GeoTIFFMap::create(const QString &path, bool *isDir)
|
Map *GeoTIFFMap::create(const QString &path, const Projection &proj, bool *isDir)
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(proj);
|
||||||
|
|
||||||
if (isDir)
|
if (isDir)
|
||||||
*isDir = false;
|
*isDir = false;
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ public:
|
|||||||
bool isValid() const {return _valid;}
|
bool isValid() const {return _valid;}
|
||||||
QString errorString() const {return _errorString;}
|
QString errorString() const {return _errorString;}
|
||||||
|
|
||||||
static Map *create(const QString &path, bool *isDir);
|
static Map *create(const QString &path, const Projection &proj, bool *isDir);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Projection _projection;
|
Projection _projection;
|
||||||
|
74
src/map/gmifile.cpp
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
#include <QIODevice>
|
||||||
|
#include "gmifile.h"
|
||||||
|
|
||||||
|
static CalibrationPoint calibrationPoint(const QByteArray line)
|
||||||
|
{
|
||||||
|
bool xOk, yOk, lonOk, latOk;
|
||||||
|
QList<QByteArray> list = line.split(';');
|
||||||
|
if (list.size() != 4)
|
||||||
|
return CalibrationPoint();
|
||||||
|
|
||||||
|
int x = list.at(0).toInt(&xOk);
|
||||||
|
int y = list.at(1).toInt(&yOk);
|
||||||
|
double lon = list.at(2).toDouble(&lonOk);
|
||||||
|
double lat = list.at(3).toDouble(&latOk);
|
||||||
|
|
||||||
|
return (xOk && yOk && latOk && lonOk)
|
||||||
|
? CalibrationPoint(PointD(x, y), Coordinates(lon, lat))
|
||||||
|
: CalibrationPoint();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GmiFile::parse(QIODevice &device)
|
||||||
|
{
|
||||||
|
int ln = 1;
|
||||||
|
int width, height;
|
||||||
|
bool ok;
|
||||||
|
|
||||||
|
if (!device.open(QIODevice::ReadOnly)) {
|
||||||
|
_errorString = device.errorString();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!device.atEnd()) {
|
||||||
|
QByteArray line = device.readLine(4096);
|
||||||
|
|
||||||
|
if (ln == 1) {
|
||||||
|
if (!line.startsWith("Map Calibration data file")) {
|
||||||
|
_errorString = "Not a GMI file";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (ln == 2)
|
||||||
|
_image = line.trimmed();
|
||||||
|
else if (ln == 3) {
|
||||||
|
width = line.toInt(&ok);
|
||||||
|
if (!ok || ok <= 0) {
|
||||||
|
_errorString = "Invalid image width";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (ln == 4) {
|
||||||
|
height = line.toInt(&ok);
|
||||||
|
if (!ok || ok <= 0) {
|
||||||
|
_errorString = "Invalid image height";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_size = QSize(width, height);
|
||||||
|
} else {
|
||||||
|
CalibrationPoint cp(calibrationPoint(line));
|
||||||
|
if (cp.isValid())
|
||||||
|
_points.append(cp);
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ln++;
|
||||||
|
}
|
||||||
|
|
||||||
|
device.close();
|
||||||
|
|
||||||
|
return (_points.size() >= 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
GmiFile::GmiFile(QIODevice &file)
|
||||||
|
{
|
||||||
|
_valid = parse(file);
|
||||||
|
}
|
31
src/map/gmifile.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#ifndef GMIFILE_H
|
||||||
|
#define GMIFILE_H
|
||||||
|
|
||||||
|
#include "calibrationpoint.h"
|
||||||
|
|
||||||
|
class QIODevice;
|
||||||
|
|
||||||
|
class GmiFile
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GmiFile(QIODevice &file);
|
||||||
|
|
||||||
|
bool isValid() const {return _valid;}
|
||||||
|
const QString &errorString() const {return _errorString;}
|
||||||
|
|
||||||
|
const QString &image() const {return _image;}
|
||||||
|
const QSize &size() const {return _size;}
|
||||||
|
const QList<CalibrationPoint> &calibrationPoints() const {return _points;}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool parse(QIODevice &device);
|
||||||
|
|
||||||
|
QString _image;
|
||||||
|
QSize _size;
|
||||||
|
QList<CalibrationPoint> _points;
|
||||||
|
|
||||||
|
bool _valid;
|
||||||
|
QString _errorString;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // GMIFILE_H
|
@ -264,16 +264,20 @@ void IMGMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Map* IMGMap::createIMG(const QString &path, bool *isDir)
|
Map* IMGMap::createIMG(const QString &path, const Projection &proj, bool *isDir)
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(proj);
|
||||||
|
|
||||||
if (isDir)
|
if (isDir)
|
||||||
*isDir = false;
|
*isDir = false;
|
||||||
|
|
||||||
return new IMGMap(path, false);
|
return new IMGMap(path, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map* IMGMap::createGMAP(const QString &path, bool *isDir)
|
Map* IMGMap::createGMAP(const QString &path, const Projection &proj, bool *isDir)
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(proj);
|
||||||
|
|
||||||
if (isDir)
|
if (isDir)
|
||||||
*isDir = true;
|
*isDir = true;
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ public:
|
|||||||
QString name() const {return _data.first()->name();}
|
QString name() const {return _data.first()->name();}
|
||||||
|
|
||||||
QRectF bounds() {return _bounds;}
|
QRectF bounds() {return _bounds;}
|
||||||
RectC llBounds(const Projection &) {return _data.first()->bounds();}
|
RectC llBounds() {return _data.first()->bounds();}
|
||||||
|
|
||||||
int zoom() const {return _zoom;}
|
int zoom() const {return _zoom;}
|
||||||
void setZoom(int zoom);
|
void setZoom(int zoom);
|
||||||
@ -77,8 +77,10 @@ public:
|
|||||||
bool isValid() const {return _valid;}
|
bool isValid() const {return _valid;}
|
||||||
QString errorString() const {return _errorString;}
|
QString errorString() const {return _errorString;}
|
||||||
|
|
||||||
static Map* createIMG(const QString &path, bool *isDir);
|
static Map* createIMG(const QString &path, const Projection &proj,
|
||||||
static Map* createGMAP(const QString &path, bool *isDir);
|
bool *isDir);
|
||||||
|
static Map* createGMAP(const QString &path, const Projection &proj,
|
||||||
|
bool *isDir);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void jobFinished(IMGMapJob *job);
|
void jobFinished(IMGMapJob *job);
|
||||||
|
@ -274,8 +274,10 @@ void JNXMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
|
|||||||
tree.Search(min, max, cb, &ctx);
|
tree.Search(min, max, cb, &ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map *JNXMap::create(const QString &path, bool *isDir)
|
Map *JNXMap::create(const QString &path, const Projection &proj, bool *isDir)
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(proj);
|
||||||
|
|
||||||
if (isDir)
|
if (isDir)
|
||||||
*isDir = false;
|
*isDir = false;
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ public:
|
|||||||
~JNXMap();
|
~JNXMap();
|
||||||
|
|
||||||
QRectF bounds();
|
QRectF bounds();
|
||||||
RectC llBounds(const Projection &) {return _bounds;}
|
RectC llBounds() {return _bounds;}
|
||||||
|
|
||||||
int zoom() const {return _zoom;}
|
int zoom() const {return _zoom;}
|
||||||
void setZoom(int zoom) {_zoom = zoom;}
|
void setZoom(int zoom) {_zoom = zoom;}
|
||||||
@ -39,7 +39,7 @@ public:
|
|||||||
bool isValid() const {return _valid;}
|
bool isValid() const {return _valid;}
|
||||||
QString errorString() const {return _errorString;}
|
QString errorString() const {return _errorString;}
|
||||||
|
|
||||||
static Map *create(const QString &path, bool *isDir);
|
static Map *create(const QString &path, const Projection &proj, bool *isDir);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Tile {
|
struct Tile {
|
||||||
|
@ -484,8 +484,10 @@ void KMZMap::draw(QPainter *painter, const QRectF &rect, int mapIndex)
|
|||||||
painter->restore();
|
painter->restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
Map *KMZMap::create(const QString &path, bool *isDir)
|
Map *KMZMap::create(const QString &path, const Projection &proj, bool *isDir)
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(proj);
|
||||||
|
|
||||||
if (isDir)
|
if (isDir)
|
||||||
*isDir = false;
|
*isDir = false;
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ public:
|
|||||||
KMZMap(const QString &fileName, QObject *parent = 0);
|
KMZMap(const QString &fileName, QObject *parent = 0);
|
||||||
~KMZMap();
|
~KMZMap();
|
||||||
|
|
||||||
RectC llBounds(const Projection &) {return _llbounds;}
|
RectC llBounds() {return _llbounds;}
|
||||||
QRectF bounds();
|
QRectF bounds();
|
||||||
|
|
||||||
int zoom() const {return _zoom;}
|
int zoom() const {return _zoom;}
|
||||||
@ -39,7 +39,7 @@ public:
|
|||||||
bool isValid() const {return _valid;}
|
bool isValid() const {return _valid;}
|
||||||
QString errorString() const {return _errorString;}
|
QString errorString() const {return _errorString;}
|
||||||
|
|
||||||
static Map *create(const QString &path, bool *isDir);
|
static Map *create(const QString &path, const Projection &proj, bool *isDir);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class Overlay {
|
class Overlay {
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#define SAMPLES 100
|
#define SAMPLES 100
|
||||||
|
#define DELTA 1e-6
|
||||||
|
|
||||||
static void growLeft(const Coordinates &c, RectC &rect)
|
static void growLeft(const Coordinates &c, RectC &rect)
|
||||||
{
|
{
|
||||||
@ -29,12 +30,8 @@ static void growBottom(const Coordinates &c, RectC &rect)
|
|||||||
rect.setBottom(c.lat());
|
rect.setBottom(c.lat());
|
||||||
}
|
}
|
||||||
|
|
||||||
RectC Map::llBounds(const Projection &proj)
|
RectC Map::llBounds()
|
||||||
{
|
{
|
||||||
Q_UNUSED(proj);
|
|
||||||
|
|
||||||
/* We use bounds() and xy2ll() here as this fallback implementation is
|
|
||||||
used ONLY for maps providing those functions since map creation. */
|
|
||||||
QRectF b(bounds());
|
QRectF b(bounds());
|
||||||
double dx = b.width() / SAMPLES;
|
double dx = b.width() / SAMPLES;
|
||||||
double dy = b.height() / SAMPLES;
|
double dy = b.height() / SAMPLES;
|
||||||
@ -55,14 +52,27 @@ RectC Map::llBounds(const Projection &proj)
|
|||||||
growRight(xy2ll(QPointF(b.right(), y)), rect);
|
growRight(xy2ll(QPointF(b.right(), y)), rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rect.right() <= -180.0 + DELTA)
|
||||||
|
rect.setRight(180.0);
|
||||||
|
if (rect.left() >= 180.0 - DELTA)
|
||||||
|
rect.setLeft(-180.0);
|
||||||
|
|
||||||
return rect;
|
return rect;
|
||||||
}
|
}
|
||||||
|
|
||||||
qreal Map::resolution(const QRectF &rect)
|
qreal Map::resolution(const QRectF &rect)
|
||||||
{
|
{
|
||||||
qreal cy = rect.center().y();
|
/* The haversine formula used in Coordinates::distanceTo() only gives
|
||||||
QPointF cl(rect.left(), cy);
|
"half world" distances and shorter so we have to use only the center
|
||||||
QPointF cr(rect.right(), cy);
|
"half rectangle" in case e.g. world map bounds are on the input */
|
||||||
|
QRectF halfRect(QPointF(rect.left() + (rect.width() / 4.0),
|
||||||
|
rect.top() + (rect.height() / 4.0)),
|
||||||
|
QPointF(rect.right() - (rect.width() / 4.0),
|
||||||
|
rect.bottom() - (rect.height() / 4.0)));
|
||||||
|
|
||||||
|
qreal cy = halfRect.center().y();
|
||||||
|
QPointF cl(halfRect.left(), cy);
|
||||||
|
QPointF cr(halfRect.right(), cy);
|
||||||
|
|
||||||
qreal ds = xy2ll(cl).distanceTo(xy2ll(cr));
|
qreal ds = xy2ll(cl).distanceTo(xy2ll(cr));
|
||||||
qreal ps = QLineF(cl, cr).length();
|
qreal ps = QLineF(cl, cr).length();
|
||||||
|
@ -28,19 +28,19 @@ public:
|
|||||||
: QObject(parent), _path(path) {}
|
: QObject(parent), _path(path) {}
|
||||||
virtual ~Map() {}
|
virtual ~Map() {}
|
||||||
|
|
||||||
/* Functions available since map creation */
|
|
||||||
const QString &path() const {return _path;}
|
const QString &path() const {return _path;}
|
||||||
virtual QString name() const {return Util::file2name(path());}
|
virtual QString name() const {return Util::file2name(path());}
|
||||||
virtual RectC llBounds(const Projection &proj);
|
|
||||||
|
|
||||||
virtual bool isValid() const {return true;}
|
virtual bool isValid() const {return true;}
|
||||||
virtual bool isReady() const {return true;}
|
virtual bool isReady() const {return true;}
|
||||||
virtual QString errorString() const {return QString();}
|
virtual QString errorString() const {return QString();}
|
||||||
|
|
||||||
/* Functions that shall be called after load() */
|
|
||||||
virtual void load(const Projection &, const Projection &, qreal, bool) {}
|
virtual void load(const Projection &, const Projection &, qreal, bool) {}
|
||||||
virtual void unload() {}
|
virtual void unload() {}
|
||||||
|
|
||||||
|
/* llBounds() is mandatory for maps that do not provide bounds() until
|
||||||
|
load() is called! */
|
||||||
|
virtual RectC llBounds();
|
||||||
virtual QRectF bounds() = 0;
|
virtual QRectF bounds() = 0;
|
||||||
virtual qreal resolution(const QRectF &rect);
|
virtual qreal resolution(const QRectF &rect);
|
||||||
|
|
||||||
|
@ -43,6 +43,7 @@ MapList::ParserMap MapList::parsers()
|
|||||||
map.insert("rtmap", &RMap::create);
|
map.insert("rtmap", &RMap::create);
|
||||||
map.insert("map", &MapsforgeMap::create);
|
map.insert("map", &MapsforgeMap::create);
|
||||||
map.insert("map", &OziMap::createMAP);
|
map.insert("map", &OziMap::createMAP);
|
||||||
|
map.insert("gmi", &OziMap::createMAP);
|
||||||
map.insert("kap", &BSBMap::create);
|
map.insert("kap", &BSBMap::create);
|
||||||
map.insert("kmz", &KMZMap::create);
|
map.insert("kmz", &KMZMap::create);
|
||||||
map.insert("aqm", &AQMMap::create);
|
map.insert("aqm", &AQMMap::create);
|
||||||
@ -64,7 +65,7 @@ MapList::ParserMap MapList::parsers()
|
|||||||
|
|
||||||
MapList::ParserMap MapList::_parsers = parsers();
|
MapList::ParserMap MapList::_parsers = parsers();
|
||||||
|
|
||||||
Map *MapList::loadFile(const QString &path, bool *isDir)
|
Map *MapList::loadFile(const QString &path, const Projection &proj, bool *isDir)
|
||||||
{
|
{
|
||||||
ParserMap::iterator it;
|
ParserMap::iterator it;
|
||||||
QFileInfo fi(Util::displayName(path));
|
QFileInfo fi(Util::displayName(path));
|
||||||
@ -75,7 +76,7 @@ Map *MapList::loadFile(const QString &path, bool *isDir)
|
|||||||
if ((it = _parsers.find(suffix)) != _parsers.end()) {
|
if ((it = _parsers.find(suffix)) != _parsers.end()) {
|
||||||
while (it != _parsers.end() && it.key() == suffix) {
|
while (it != _parsers.end() && it.key() == suffix) {
|
||||||
delete map;
|
delete map;
|
||||||
map = it.value()(path, isDir);
|
map = it.value()(path, proj, isDir);
|
||||||
if (map->isValid())
|
if (map->isValid())
|
||||||
return map;
|
return map;
|
||||||
else
|
else
|
||||||
@ -84,7 +85,7 @@ Map *MapList::loadFile(const QString &path, bool *isDir)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (it = _parsers.begin(); it != _parsers.end(); it++) {
|
for (it = _parsers.begin(); it != _parsers.end(); it++) {
|
||||||
map = it.value()(path, isDir);
|
map = it.value()(path, proj, isDir);
|
||||||
if (map->isValid())
|
if (map->isValid())
|
||||||
return map;
|
return map;
|
||||||
else {
|
else {
|
||||||
@ -102,7 +103,8 @@ Map *MapList::loadFile(const QString &path, bool *isDir)
|
|||||||
return map ? map : new InvalidMap(path, "Unknown file format");
|
return map ? map : new InvalidMap(path, "Unknown file format");
|
||||||
}
|
}
|
||||||
|
|
||||||
TreeNode<Map*> MapList::loadDir(const QString &path, TreeNode<Map*> *parent)
|
TreeNode<Map*> MapList::loadDir(const QString &path, const Projection &proj,
|
||||||
|
TreeNode<Map*> *parent)
|
||||||
{
|
{
|
||||||
QDir md(path);
|
QDir md(path);
|
||||||
md.setFilter(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
|
md.setFilter(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot);
|
||||||
@ -119,12 +121,12 @@ TreeNode<Map*> MapList::loadDir(const QString &path, TreeNode<Map*> *parent)
|
|||||||
QString suffix = fi.suffix().toLower();
|
QString suffix = fi.suffix().toLower();
|
||||||
|
|
||||||
if (fi.isDir()) {
|
if (fi.isDir()) {
|
||||||
TreeNode<Map*> child(loadDir(fi.absoluteFilePath(), &tree));
|
TreeNode<Map*> child(loadDir(fi.absoluteFilePath(), proj, &tree));
|
||||||
if (!child.isEmpty())
|
if (!child.isEmpty())
|
||||||
tree.addChild(child);
|
tree.addChild(child);
|
||||||
} else if (filter().contains("*." + suffix)) {
|
} else if (filter().contains("*." + suffix)) {
|
||||||
bool isDir = false;
|
bool isDir = false;
|
||||||
Map *map = loadFile(fi.absoluteFilePath(), &isDir);
|
Map *map = loadFile(fi.absoluteFilePath(), proj, &isDir);
|
||||||
if (isDir) {
|
if (isDir) {
|
||||||
if (parent)
|
if (parent)
|
||||||
parent->addItem(map);
|
parent->addItem(map);
|
||||||
@ -139,13 +141,13 @@ TreeNode<Map*> MapList::loadDir(const QString &path, TreeNode<Map*> *parent)
|
|||||||
return tree;
|
return tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
TreeNode<Map *> MapList::loadMaps(const QString &path)
|
TreeNode<Map *> MapList::loadMaps(const QString &path, const Projection &proj)
|
||||||
{
|
{
|
||||||
if (QFileInfo(path).isDir())
|
if (QFileInfo(path).isDir())
|
||||||
return loadDir(path);
|
return loadDir(path, proj);
|
||||||
else {
|
else {
|
||||||
TreeNode<Map*> tree;
|
TreeNode<Map*> tree;
|
||||||
tree.addItem(loadFile(path));
|
tree.addItem(loadFile(path, proj));
|
||||||
return tree;
|
return tree;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -173,7 +175,8 @@ QString MapList::formats()
|
|||||||
+ qApp->translate("MapList", "Osmdroid SQLite maps") + " (*.sqlite);;"
|
+ qApp->translate("MapList", "Osmdroid SQLite maps") + " (*.sqlite);;"
|
||||||
+ qApp->translate("MapList", "Locus/OsmAnd/RMaps SQLite maps")
|
+ qApp->translate("MapList", "Locus/OsmAnd/RMaps SQLite maps")
|
||||||
+ " (*.sqlitedb);;"
|
+ " (*.sqlitedb);;"
|
||||||
+ qApp->translate("MapList", "TrekBuddy maps/atlases") + " (*.tar *.tba);;"
|
+ qApp->translate("MapList", "TrekBuddy maps/atlases")
|
||||||
|
+ " (*.tar *.tba *.gmi *.map);;"
|
||||||
+ qApp->translate("MapList", "GeoTIFF images") + " (*.tif *.tiff);;"
|
+ qApp->translate("MapList", "GeoTIFF images") + " (*.tif *.tiff);;"
|
||||||
+ qApp->translate("MapList", "World-file georeferenced images")
|
+ qApp->translate("MapList", "World-file georeferenced images")
|
||||||
+ " (*.wld *.jgw *.gfw *.pgw *.tfw);;"
|
+ " (*.wld *.jgw *.gfw *.pgw *.tfw);;"
|
||||||
|
@ -10,16 +10,18 @@ class Projection;
|
|||||||
class MapList
|
class MapList
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static TreeNode<Map*> loadMaps(const QString &path);
|
static TreeNode<Map*> loadMaps(const QString &path, const Projection &proj);
|
||||||
static QString formats();
|
static QString formats();
|
||||||
static QStringList filter();
|
static QStringList filter();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef Map*(*ParserCb)(const QString &, bool *isDir);
|
typedef Map*(*ParserCb)(const QString &, const Projection &, bool *);
|
||||||
typedef QMultiMap<QString, ParserCb> ParserMap;
|
typedef QMultiMap<QString, ParserCb> ParserMap;
|
||||||
|
|
||||||
static Map *loadFile(const QString &path, bool *isDir = 0);
|
static Map *loadFile(const QString &path, const Projection &proj,
|
||||||
static TreeNode<Map*> loadDir(const QString &path, TreeNode<Map*> *parent = 0);
|
bool *isDir = 0);
|
||||||
|
static TreeNode<Map*> loadDir(const QString &path, const Projection &proj,
|
||||||
|
TreeNode<Map*> *parent = 0);
|
||||||
|
|
||||||
static ParserMap parsers();
|
static ParserMap parsers();
|
||||||
static ParserMap _parsers;
|
static ParserMap _parsers;
|
||||||
|
@ -209,8 +209,11 @@ void MapsforgeMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Map *MapsforgeMap::create(const QString &path, bool *isMap)
|
Map *MapsforgeMap::create(const QString &path, const Projection &proj,
|
||||||
|
bool *isMap)
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(proj);
|
||||||
|
|
||||||
if (isMap)
|
if (isMap)
|
||||||
*isMap = false;
|
*isMap = false;
|
||||||
|
|
||||||
|
@ -52,7 +52,7 @@ public:
|
|||||||
MapsforgeMap(const QString &fileName, QObject *parent = 0);
|
MapsforgeMap(const QString &fileName, QObject *parent = 0);
|
||||||
|
|
||||||
QRectF bounds() {return _bounds;}
|
QRectF bounds() {return _bounds;}
|
||||||
RectC llBounds(const Projection &) {return _data.bounds();}
|
RectC llBounds() {return _data.bounds();}
|
||||||
|
|
||||||
int zoom() const {return _zoom;}
|
int zoom() const {return _zoom;}
|
||||||
void setZoom(int zoom);
|
void setZoom(int zoom);
|
||||||
@ -74,7 +74,7 @@ public:
|
|||||||
bool isValid() const {return _data.isValid();}
|
bool isValid() const {return _data.isValid();}
|
||||||
QString errorString() const {return _data.errorString();}
|
QString errorString() const {return _data.errorString();}
|
||||||
|
|
||||||
static Map *create(const QString &path, bool *isMap);
|
static Map *create(const QString &path, const Projection &proj, bool *isMap);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void jobFinished(MapsforgeMapJob *job);
|
void jobFinished(MapsforgeMapJob *job);
|
||||||
|
@ -214,8 +214,9 @@ void MapSource::map(QXmlStreamReader &reader, Config &config)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Map *MapSource::create(const QString &path, bool *isDir)
|
Map *MapSource::create(const QString &path, const Projection &proj, bool *isDir)
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(proj);
|
||||||
Config config;
|
Config config;
|
||||||
QFile file(path);
|
QFile file(path);
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ class Projection;
|
|||||||
class MapSource
|
class MapSource
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static Map *create(const QString &path, bool *isDir);
|
static Map *create(const QString &path, const Projection &proj, bool *isDir);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum Type {
|
enum Type {
|
||||||
|
@ -338,8 +338,10 @@ Coordinates MBTilesMap::xy2ll(const QPointF &p)
|
|||||||
* coordinatesRatio());
|
* coordinatesRatio());
|
||||||
}
|
}
|
||||||
|
|
||||||
Map *MBTilesMap::create(const QString &path, bool *isDir)
|
Map *MBTilesMap::create(const QString &path, const Projection &proj, bool *isDir)
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(proj);
|
||||||
|
|
||||||
if (isDir)
|
if (isDir)
|
||||||
*isDir = false;
|
*isDir = false;
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ public:
|
|||||||
QString name() const {return _name;}
|
QString name() const {return _name;}
|
||||||
|
|
||||||
QRectF bounds();
|
QRectF bounds();
|
||||||
RectC llBounds(const Projection &) {return _bounds;}
|
RectC llBounds() {return _bounds;}
|
||||||
qreal resolution(const QRectF &rect);
|
qreal resolution(const QRectF &rect);
|
||||||
|
|
||||||
int zoom() const {return _zi;}
|
int zoom() const {return _zi;}
|
||||||
@ -34,7 +34,7 @@ public:
|
|||||||
bool isValid() const {return _valid;}
|
bool isValid() const {return _valid;}
|
||||||
QString errorString() const {return _errorString;}
|
QString errorString() const {return _errorString;}
|
||||||
|
|
||||||
static Map *create(const QString &path, bool *isDir);
|
static Map *create(const QString &path, const Projection &proj, bool *isDir);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
qreal tileSize() const;
|
qreal tileSize() const;
|
||||||
|
@ -590,8 +590,10 @@ Coordinates OruxMap::xy2ll(const QPointF &p)
|
|||||||
return z.projection.xy2ll(z.transform.img2proj(p * _mapRatio));
|
return z.projection.xy2ll(z.transform.img2proj(p * _mapRatio));
|
||||||
}
|
}
|
||||||
|
|
||||||
Map *OruxMap::create(const QString &path, bool *isDir)
|
Map *OruxMap::create(const QString &path, const Projection &proj, bool *isDir)
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(proj);
|
||||||
|
|
||||||
if (isDir)
|
if (isDir)
|
||||||
*isDir = true;
|
*isDir = true;
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ public:
|
|||||||
bool isValid() const {return _valid;}
|
bool isValid() const {return _valid;}
|
||||||
QString errorString() const {return _errorString;}
|
QString errorString() const {return _errorString;}
|
||||||
|
|
||||||
static Map *create(const QString &path, bool *isDir);
|
static Map *create(const QString &path, const Projection &proj, bool *isDir);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Zoom {
|
struct Zoom {
|
||||||
|
@ -309,8 +309,11 @@ Coordinates OsmdroidMap::xy2ll(const QPointF &p)
|
|||||||
return OSM::m2ll(QPointF(p.x() * scale, -p.y() * scale) * _mapRatio);
|
return OSM::m2ll(QPointF(p.x() * scale, -p.y() * scale) * _mapRatio);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map *OsmdroidMap::create(const QString &path, bool *isDir)
|
Map *OsmdroidMap::create(const QString &path, const Projection &proj,
|
||||||
|
bool *isDir)
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(proj);
|
||||||
|
|
||||||
if (isDir)
|
if (isDir)
|
||||||
*isDir = false;
|
*isDir = false;
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ public:
|
|||||||
OsmdroidMap(const QString &fileName, QObject *parent = 0);
|
OsmdroidMap(const QString &fileName, QObject *parent = 0);
|
||||||
|
|
||||||
QRectF bounds();
|
QRectF bounds();
|
||||||
RectC llBounds(const Projection &) {return _bounds;}
|
RectC llBounds() {return _bounds;}
|
||||||
qreal resolution(const QRectF &rect);
|
qreal resolution(const QRectF &rect);
|
||||||
|
|
||||||
int zoom() const {return _zoom;}
|
int zoom() const {return _zoom;}
|
||||||
@ -32,7 +32,7 @@ public:
|
|||||||
bool isValid() const {return _valid;}
|
bool isValid() const {return _valid;}
|
||||||
QString errorString() const {return _errorString;}
|
QString errorString() const {return _errorString;}
|
||||||
|
|
||||||
static Map *create(const QString &path, bool *isDir);
|
static Map *create(const QString &path, const Projection &proj, bool *isDir);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int limitZoom(int zoom) const;
|
int limitZoom(int zoom) const;
|
||||||
|
@ -12,58 +12,135 @@
|
|||||||
#include "ozf.h"
|
#include "ozf.h"
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
#include "mapfile.h"
|
#include "mapfile.h"
|
||||||
|
#include "gmifile.h"
|
||||||
#include "rectd.h"
|
#include "rectd.h"
|
||||||
#include "ozimap.h"
|
#include "ozimap.h"
|
||||||
|
|
||||||
|
|
||||||
OziMap::OziMap(const QString &fileName, bool TAR, QObject *parent)
|
static QString tarFile(const QString &path)
|
||||||
|
{
|
||||||
|
QDir dir(path);
|
||||||
|
QFileInfoList files = dir.entryInfoList(QDir::Files);
|
||||||
|
|
||||||
|
for (int i = 0; i < files.size(); i++) {
|
||||||
|
const QFileInfo &fi = files.at(i);
|
||||||
|
|
||||||
|
if (fi.suffix().toLower() == "tar")
|
||||||
|
return fi.absoluteFilePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString OziMap::calibrationFile(const QStringList &files, const QString path,
|
||||||
|
CalibrationType &type)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < files.size(); i++) {
|
||||||
|
QFileInfo fi(files.at(i));
|
||||||
|
QString suffix(fi.suffix().toLower());
|
||||||
|
|
||||||
|
if (path.endsWith(fi.path())) {
|
||||||
|
if (suffix == "map") {
|
||||||
|
type = MAP;
|
||||||
|
return files.at(i);
|
||||||
|
} else if (suffix == "gmi") {
|
||||||
|
type = GMI;
|
||||||
|
return files.at(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type = Unknown;
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
OziMap::OziMap(const QString &fileName, const Projection &proj, QObject *parent)
|
||||||
: Map(fileName, parent), _img(0), _tar(0), _ozf(0), _zoom(0), _mapRatio(1.0),
|
: Map(fileName, parent), _img(0), _tar(0), _ozf(0), _zoom(0), _mapRatio(1.0),
|
||||||
_valid(false)
|
_valid(false)
|
||||||
{
|
{
|
||||||
QFileInfo fi(fileName);
|
QFileInfo fi(fileName);
|
||||||
|
QString suffix(fi.suffix().toLower());
|
||||||
|
|
||||||
|
if (suffix == "tar") {
|
||||||
|
CalibrationType type;
|
||||||
|
|
||||||
if (TAR) {
|
|
||||||
_tar = new Tar(fileName);
|
_tar = new Tar(fileName);
|
||||||
if (!_tar->open()) {
|
if (!_tar->open()) {
|
||||||
_errorString = "Error reading tar file";
|
_errorString = "Error reading tar file";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
QStringList files(_tar->files());
|
||||||
|
QString cf(calibrationFile(files, ".", type));
|
||||||
|
|
||||||
QString mapFileName = fi.completeBaseName() + ".map";
|
if (type == GMI) {
|
||||||
QByteArray ba = _tar->file(mapFileName);
|
QByteArray ba(_tar->file(cf));
|
||||||
if (ba.isNull()) {
|
QBuffer buffer(&ba);
|
||||||
_errorString = "Map file not found";
|
GmiFile gmi(buffer);
|
||||||
return;
|
if (!gmi.isValid()) {
|
||||||
}
|
_errorString = gmi.errorString();
|
||||||
QBuffer buffer(&ba);
|
return;
|
||||||
MapFile mf(buffer);
|
} else {
|
||||||
if (!mf.isValid()) {
|
_name = Util::file2name(fileName);
|
||||||
_errorString = mf.errorString();
|
_map.size = gmi.size();
|
||||||
return;
|
_map.path = gmi.image();
|
||||||
|
_calibrationPoints = gmi.calibrationPoints();
|
||||||
|
_projection = proj;
|
||||||
|
computeTransform();
|
||||||
|
}
|
||||||
|
} else if (type == MAP) {
|
||||||
|
QByteArray ba(_tar->file(cf));
|
||||||
|
QBuffer buffer(&ba);
|
||||||
|
MapFile mf(buffer);
|
||||||
|
if (!mf.isValid()) {
|
||||||
|
_errorString = mf.errorString();
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
_name = mf.name();
|
||||||
|
_map.size = mf.size();
|
||||||
|
_map.path = mf.image();
|
||||||
|
_projection = mf.projection();
|
||||||
|
_transform = mf.transform();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
_name = mf.name();
|
_errorString = "No calibration file found";
|
||||||
_map.size = mf.size();
|
return;
|
||||||
_map.path = mf.image();
|
|
||||||
_projection = mf.projection();
|
|
||||||
_transform = mf.transform();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!setTileInfo(_tar->files()))
|
if (!setTileInfo(files))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_tar->close();
|
_tar->close();
|
||||||
} else {
|
} else {
|
||||||
QFile file(fileName);
|
QFile file(fileName);
|
||||||
MapFile mf(file);
|
|
||||||
if (!mf.isValid()) {
|
if (suffix == "map") {
|
||||||
_errorString = mf.errorString();
|
MapFile mf(file);
|
||||||
return;
|
if (!mf.isValid()) {
|
||||||
|
_errorString = mf.errorString();
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
_name = mf.name();
|
||||||
|
_map.size = mf.size();
|
||||||
|
_map.path = mf.image();
|
||||||
|
_projection = mf.projection();
|
||||||
|
_transform = mf.transform();
|
||||||
|
}
|
||||||
|
} else if (suffix == "gmi") {
|
||||||
|
GmiFile gmi(file);
|
||||||
|
if (!gmi.isValid()) {
|
||||||
|
_errorString = gmi.errorString();
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
_name = Util::file2name(fileName);
|
||||||
|
_map.size = gmi.size();
|
||||||
|
_map.path = gmi.image();
|
||||||
|
_calibrationPoints = gmi.calibrationPoints();
|
||||||
|
_projection = proj;
|
||||||
|
computeTransform();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
_name = mf.name();
|
_errorString = "Unknown file type";
|
||||||
_map.size = mf.size();
|
return;
|
||||||
_map.path = mf.image();
|
|
||||||
_projection = mf.projection();
|
|
||||||
_transform = mf.transform();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QDir set(fi.absolutePath() + "/" + "set");
|
QDir set(fi.absolutePath() + "/" + "set");
|
||||||
@ -79,34 +156,51 @@ OziMap::OziMap(const QString &fileName, bool TAR, QObject *parent)
|
|||||||
_valid = true;
|
_valid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
OziMap::OziMap(const QString &fileName, Tar &tar, QObject *parent)
|
OziMap::OziMap(const QString &dirName, Tar &tar, const Projection &proj,
|
||||||
: Map(fileName, parent), _img(0), _tar(0), _ozf(0), _zoom(0), _mapRatio(1.0),
|
QObject *parent) : Map(dirName, parent), _img(0), _tar(0), _ozf(0), _zoom(0),
|
||||||
_valid(false)
|
_mapRatio(1.0), _valid(false)
|
||||||
{
|
{
|
||||||
QFileInfo fi(fileName);
|
CalibrationType type;
|
||||||
QFileInfo map(fi.absolutePath());
|
QString cf(calibrationFile(tar.files(), dirName, type));
|
||||||
QFileInfo layer(map.absolutePath());
|
|
||||||
QString mapFile = layer.fileName() + "/" + map.fileName() + "/"
|
|
||||||
+ fi.fileName();
|
|
||||||
|
|
||||||
QByteArray ba = tar.file(mapFile);
|
if (type == MAP) {
|
||||||
if (ba.isNull()) {
|
QByteArray ba = tar.file(cf);
|
||||||
_errorString = "Map file not found";
|
QBuffer buffer(&ba);
|
||||||
return;
|
MapFile mf(buffer);
|
||||||
}
|
if (!mf.isValid()) {
|
||||||
QBuffer buffer(&ba);
|
_errorString = mf.errorString();
|
||||||
MapFile mf(buffer);
|
return;
|
||||||
if (!mf.isValid()) {
|
}
|
||||||
_errorString = mf.errorString();
|
|
||||||
|
_name = mf.name();
|
||||||
|
_map.size = mf.size();
|
||||||
|
_projection = mf.projection();
|
||||||
|
_transform = mf.transform();
|
||||||
|
} else if (type == GMI) {
|
||||||
|
QByteArray ba = tar.file(cf);
|
||||||
|
QBuffer buffer(&ba);
|
||||||
|
GmiFile gmi(buffer);
|
||||||
|
if (!gmi.isValid()) {
|
||||||
|
_errorString = gmi.errorString();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_name = Util::file2name(cf);
|
||||||
|
_map.size = gmi.size();
|
||||||
|
_calibrationPoints = gmi.calibrationPoints();
|
||||||
|
_projection = proj;
|
||||||
|
computeTransform();
|
||||||
|
} else {
|
||||||
|
_errorString = "No calibration file found";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_name = mf.name();
|
QString tf(tarFile(dirName));
|
||||||
_map.size = mf.size();
|
if (tf.isNull()) {
|
||||||
_projection = mf.projection();
|
_errorString = "No map tar file found";
|
||||||
_transform = mf.transform();
|
return;
|
||||||
_tar = new Tar(fi.absolutePath() + "/" + fi.completeBaseName() + ".tar");
|
}
|
||||||
|
_tar = new Tar(tf);
|
||||||
if (!_tar->open()) {
|
if (!_tar->open()) {
|
||||||
_errorString = _tar->fileName() + ": error reading tar file";
|
_errorString = _tar->fileName() + ": error reading tar file";
|
||||||
return;
|
return;
|
||||||
@ -208,10 +302,13 @@ bool OziMap::setTileInfo(const QStringList &tiles, const QString &path)
|
|||||||
void OziMap::load(const Projection &in, const Projection &out,
|
void OziMap::load(const Projection &in, const Projection &out,
|
||||||
qreal deviceRatio, bool hidpi)
|
qreal deviceRatio, bool hidpi)
|
||||||
{
|
{
|
||||||
Q_UNUSED(in);
|
|
||||||
Q_UNUSED(out);
|
Q_UNUSED(out);
|
||||||
|
|
||||||
_mapRatio = hidpi ? deviceRatio : 1.0;
|
_mapRatio = hidpi ? deviceRatio : 1.0;
|
||||||
|
if (!_calibrationPoints.isEmpty()) {
|
||||||
|
_projection = in;
|
||||||
|
computeTransform();
|
||||||
|
}
|
||||||
|
|
||||||
if (_tar) {
|
if (_tar) {
|
||||||
Q_ASSERT(!_tar->isOpen());
|
Q_ASSERT(!_tar->isOpen());
|
||||||
@ -395,18 +492,28 @@ void OziMap::rescale(int zoom)
|
|||||||
_scale = _ozf->scale(zoom);
|
_scale = _ozf->scale(zoom);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map *OziMap::createTAR(const QString &path, bool *isDir)
|
void OziMap::computeTransform()
|
||||||
|
{
|
||||||
|
QList<ReferencePoint> rp;
|
||||||
|
|
||||||
|
for (int i = 0; i < _calibrationPoints.size(); i++)
|
||||||
|
rp.append(_calibrationPoints.at(i).rp(_projection));
|
||||||
|
|
||||||
|
_transform = Transform(rp);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map *OziMap::createTAR(const QString &path, const Projection &proj, bool *isDir)
|
||||||
{
|
{
|
||||||
if (isDir)
|
if (isDir)
|
||||||
*isDir = false;
|
*isDir = false;
|
||||||
|
|
||||||
return new OziMap(path, true);
|
return new OziMap(path, proj);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map *OziMap::createMAP(const QString &path, bool *isDir)
|
Map *OziMap::createMAP(const QString &path, const Projection &proj, bool *isDir)
|
||||||
{
|
{
|
||||||
if (isDir)
|
if (isDir)
|
||||||
*isDir = false;
|
*isDir = false;
|
||||||
|
|
||||||
return new OziMap(path, false);
|
return new OziMap(path, proj);
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "transform.h"
|
#include "transform.h"
|
||||||
#include "projection.h"
|
#include "projection.h"
|
||||||
|
#include "calibrationpoint.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
|
|
||||||
class Tar;
|
class Tar;
|
||||||
@ -14,8 +15,10 @@ class OziMap : public Map
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
OziMap(const QString &fileName, bool TAR, QObject *parent = 0);
|
OziMap(const QString &fileName, const Projection &proj,
|
||||||
OziMap(const QString &fileName, Tar &tar, QObject *parent = 0);
|
QObject *parent = 0);
|
||||||
|
OziMap(const QString &dirName, Tar &tar, const Projection &proj,
|
||||||
|
QObject *parent = 0);
|
||||||
~OziMap();
|
~OziMap();
|
||||||
|
|
||||||
QString name() const {return _name;}
|
QString name() const {return _name;}
|
||||||
@ -47,10 +50,16 @@ public:
|
|||||||
QPointF pp2xy(const PointD &p) const
|
QPointF pp2xy(const PointD &p) const
|
||||||
{return _transform.proj2img(p) / _mapRatio;}
|
{return _transform.proj2img(p) / _mapRatio;}
|
||||||
|
|
||||||
static Map *createTAR(const QString &path, bool *isDir);
|
static Map *createTAR(const QString &path, const Projection &proj,
|
||||||
static Map *createMAP(const QString &path, bool *isDir);
|
bool *isDir);
|
||||||
|
static Map *createMAP(const QString &path, const Projection &proj,
|
||||||
|
bool *isDir);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
enum CalibrationType {
|
||||||
|
Unknown, MAP, GMI
|
||||||
|
};
|
||||||
|
|
||||||
struct ImageInfo {
|
struct ImageInfo {
|
||||||
QSize size;
|
QSize size;
|
||||||
QString path;
|
QString path;
|
||||||
@ -66,6 +75,10 @@ private:
|
|||||||
void drawImage(QPainter *painter, const QRectF &rect, Flags flags) const;
|
void drawImage(QPainter *painter, const QRectF &rect, Flags flags) const;
|
||||||
|
|
||||||
void rescale(int zoom);
|
void rescale(int zoom);
|
||||||
|
void computeTransform();
|
||||||
|
|
||||||
|
static QString calibrationFile(const QStringList &files, const QString path,
|
||||||
|
CalibrationType &type);
|
||||||
|
|
||||||
QString _name;
|
QString _name;
|
||||||
Projection _projection;
|
Projection _projection;
|
||||||
@ -77,6 +90,7 @@ private:
|
|||||||
int _zoom;
|
int _zoom;
|
||||||
QPointF _scale;
|
QPointF _scale;
|
||||||
qreal _mapRatio;
|
qreal _mapRatio;
|
||||||
|
QList<CalibrationPoint> _calibrationPoints;
|
||||||
|
|
||||||
bool _valid;
|
bool _valid;
|
||||||
QString _errorString;
|
QString _errorString;
|
||||||
|
@ -491,8 +491,10 @@ void QCTMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Map *QCTMap::create(const QString &path, bool *isDir)
|
Map *QCTMap::create(const QString &path, const Projection &proj, bool *isDir)
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(proj);
|
||||||
|
|
||||||
if (isDir)
|
if (isDir)
|
||||||
*isDir = false;
|
*isDir = false;
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ public:
|
|||||||
bool isValid() const {return _valid;}
|
bool isValid() const {return _valid;}
|
||||||
QString errorString() const {return _errorString;}
|
QString errorString() const {return _errorString;}
|
||||||
|
|
||||||
static Map *create(const QString &path, bool *isDir);
|
static Map *create(const QString &path, const Projection &proj, bool *isDir);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool readName(QDataStream &stream);
|
bool readName(QDataStream &stream);
|
||||||
|
@ -460,8 +460,10 @@ void RMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Map *RMap::create(const QString &path, bool *isDir)
|
Map *RMap::create(const QString &path, const Projection &proj, bool *isDir)
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(proj);
|
||||||
|
|
||||||
if (isDir)
|
if (isDir)
|
||||||
*isDir = false;
|
*isDir = false;
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ public:
|
|||||||
bool isValid() const {return _valid;}
|
bool isValid() const {return _valid;}
|
||||||
QString errorString() const {return _errorString;}
|
QString errorString() const {return _errorString;}
|
||||||
|
|
||||||
static Map *create(const QString &path, bool *isDir);
|
static Map *create(const QString &path, const Projection &proj, bool *isDir);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Header {
|
struct Header {
|
||||||
|
@ -256,8 +256,10 @@ Coordinates SqliteMap::xy2ll(const QPointF &p)
|
|||||||
return OSM::m2ll(QPointF(p.x() * scale, -p.y() * scale) * _mapRatio);
|
return OSM::m2ll(QPointF(p.x() * scale, -p.y() * scale) * _mapRatio);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map *SqliteMap::create(const QString &path, bool *isDir)
|
Map *SqliteMap::create(const QString &path, const Projection &proj, bool *isDir)
|
||||||
{
|
{
|
||||||
|
Q_UNUSED(proj);
|
||||||
|
|
||||||
if (isDir)
|
if (isDir)
|
||||||
*isDir = false;
|
*isDir = false;
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ public:
|
|||||||
SqliteMap(const QString &fileName, QObject *parent = 0);
|
SqliteMap(const QString &fileName, QObject *parent = 0);
|
||||||
|
|
||||||
QRectF bounds();
|
QRectF bounds();
|
||||||
RectC llBounds(const Projection &) {return _bounds;}
|
RectC llBounds() {return _bounds;}
|
||||||
qreal resolution(const QRectF &rect);
|
qreal resolution(const QRectF &rect);
|
||||||
|
|
||||||
int zoom() const {return _zoom;}
|
int zoom() const {return _zoom;}
|
||||||
@ -32,7 +32,7 @@ public:
|
|||||||
bool isValid() const {return _valid;}
|
bool isValid() const {return _valid;}
|
||||||
QString errorString() const {return _errorString;}
|
QString errorString() const {return _errorString;}
|
||||||
|
|
||||||
static Map *create(const QString &path, bool *isDir);
|
static Map *create(const QString &path, const Projection &proj, bool *isDir);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int limitZoom(int zoom) const;
|
int limitZoom(int zoom) const;
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include <QtConcurrent>
|
#include <QtConcurrent>
|
||||||
#include "tileloader.h"
|
#include "tileloader.h"
|
||||||
|
|
||||||
|
#define SUBSTITUTE_CHAR '$'
|
||||||
|
|
||||||
class TileImage
|
class TileImage
|
||||||
{
|
{
|
||||||
@ -34,6 +35,27 @@ private:
|
|||||||
int _scaledSize;
|
int _scaledSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static QString fsSafeStr(const QString &str)
|
||||||
|
{
|
||||||
|
QString ret(str);
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN32
|
||||||
|
ret.replace('<', SUBSTITUTE_CHAR);
|
||||||
|
ret.replace('>', SUBSTITUTE_CHAR);
|
||||||
|
ret.replace(':', SUBSTITUTE_CHAR);
|
||||||
|
ret.replace('"', SUBSTITUTE_CHAR);
|
||||||
|
ret.replace('/', SUBSTITUTE_CHAR);
|
||||||
|
ret.replace('\\', SUBSTITUTE_CHAR);
|
||||||
|
ret.replace('|', SUBSTITUTE_CHAR);
|
||||||
|
ret.replace('?', SUBSTITUTE_CHAR);
|
||||||
|
ret.replace('*', SUBSTITUTE_CHAR);
|
||||||
|
#else // Q_OS_WIN32
|
||||||
|
ret.replace('/', SUBSTITUTE_CHAR);
|
||||||
|
#endif // Q_OS_WIN32
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static QString quadKey(const QPoint &xy, int zoom)
|
static QString quadKey(const QPoint &xy, int zoom)
|
||||||
{
|
{
|
||||||
QString qk;
|
QString qk;
|
||||||
@ -198,7 +220,10 @@ QUrl TileLoader::tileUrl(const FetchTile &tile) const
|
|||||||
|
|
||||||
QString TileLoader::tileFile(const FetchTile &tile) const
|
QString TileLoader::tileFile(const FetchTile &tile) const
|
||||||
{
|
{
|
||||||
return _dir + QLatin1Char('/') + tile.zoom().toString() + QLatin1Char('-')
|
QString zoom(((QMetaType::Type)(tile.zoom().type()) == QMetaType::Int)
|
||||||
|
? tile.zoom().toString() : fsSafeStr(tile.zoom().toString()));
|
||||||
|
|
||||||
|
return _dir + QLatin1Char('/') + zoom + QLatin1Char('-')
|
||||||
+ QString::number(tile.xy().x()) + QLatin1Char('-')
|
+ QString::number(tile.xy().x()) + QLatin1Char('-')
|
||||||
+ QString::number(tile.xy().y());
|
+ QString::number(tile.xy().y());
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,9 @@
|
|||||||
#include "worldfilemap.h"
|
#include "worldfilemap.h"
|
||||||
|
|
||||||
|
|
||||||
WorldFileMap::WorldFileMap(const QString &fileName, QObject *parent)
|
WorldFileMap::WorldFileMap(const QString &fileName, const Projection &proj,
|
||||||
: Map(fileName, parent), _img(0), _mapRatio(1.0), _hasPRJ(false), _valid(false)
|
QObject *parent) : Map(fileName, parent), _img(0), _mapRatio(1.0),
|
||||||
|
_hasPRJ(false), _valid(false)
|
||||||
{
|
{
|
||||||
QFileInfo fi(fileName);
|
QFileInfo fi(fileName);
|
||||||
QDir dir(fi.absoluteDir());
|
QDir dir(fi.absoluteDir());
|
||||||
@ -37,7 +38,8 @@ WorldFileMap::WorldFileMap(const QString &fileName, QObject *parent)
|
|||||||
_errorString = prjFile + ": " + prj.errorString();
|
_errorString = prjFile + ": " + prj.errorString();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
} else
|
||||||
|
_projection = proj;
|
||||||
|
|
||||||
// Find the corresponding image file
|
// Find the corresponding image file
|
||||||
QList<QByteArray> formats(QImageReader::supportedImageFormats());
|
QList<QByteArray> formats(QImageReader::supportedImageFormats());
|
||||||
@ -81,14 +83,6 @@ Coordinates WorldFileMap::xy2ll(const QPointF &p)
|
|||||||
return _projection.xy2ll(_transform.img2proj(p * _mapRatio));
|
return _projection.xy2ll(_transform.img2proj(p * _mapRatio));
|
||||||
}
|
}
|
||||||
|
|
||||||
RectC WorldFileMap::llBounds(const Projection &proj)
|
|
||||||
{
|
|
||||||
if (_projection.isNull())
|
|
||||||
_projection = proj;
|
|
||||||
|
|
||||||
return Map::llBounds(proj);
|
|
||||||
}
|
|
||||||
|
|
||||||
QRectF WorldFileMap::bounds()
|
QRectF WorldFileMap::bounds()
|
||||||
{
|
{
|
||||||
return QRectF(QPointF(0, 0), _size / _mapRatio);
|
return QRectF(QPointF(0, 0), _size / _mapRatio);
|
||||||
@ -122,10 +116,11 @@ void WorldFileMap::unload()
|
|||||||
_img = 0;
|
_img = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Map *WorldFileMap::create(const QString &path, bool *isDir)
|
Map *WorldFileMap::create(const QString &path, const Projection &proj,
|
||||||
|
bool *isDir)
|
||||||
{
|
{
|
||||||
if (isDir)
|
if (isDir)
|
||||||
*isDir = false;
|
*isDir = false;
|
||||||
|
|
||||||
return new WorldFileMap(path);
|
return new WorldFileMap(path, proj);
|
||||||
}
|
}
|
||||||
|
@ -12,10 +12,10 @@ class WorldFileMap : public Map
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
WorldFileMap(const QString &fileName, QObject *parent = 0);
|
WorldFileMap(const QString &fileName, const Projection &proj,
|
||||||
|
QObject *parent = 0);
|
||||||
~WorldFileMap();
|
~WorldFileMap();
|
||||||
|
|
||||||
RectC llBounds(const Projection &proj);
|
|
||||||
QRectF bounds();
|
QRectF bounds();
|
||||||
QPointF ll2xy(const Coordinates &c);
|
QPointF ll2xy(const Coordinates &c);
|
||||||
Coordinates xy2ll(const QPointF &p);
|
Coordinates xy2ll(const QPointF &p);
|
||||||
@ -29,7 +29,7 @@ public:
|
|||||||
bool isValid() const {return _valid;}
|
bool isValid() const {return _valid;}
|
||||||
QString errorString() const {return _errorString;}
|
QString errorString() const {return _errorString;}
|
||||||
|
|
||||||
static Map *create(const QString &path, bool *isDir);
|
static Map *create(const QString &path, const Projection &proj, bool *isDir);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Projection _projection;
|
Projection _projection;
|
||||||
|