mirror of
https://github.com/tumic0/GPXSee.git
synced 2025-07-17 04:14:24 +02:00
Compare commits
19 Commits
11.1
...
e35cf68309
Author | SHA1 | Date | |
---|---|---|---|
e35cf68309 | |||
3be8ec748a | |||
5ba00e016b | |||
0f3fea5460 | |||
e7d6c3f76a | |||
ca0089e486 | |||
c9930a7aa3 | |||
c9b06ba3cf | |||
a168d28d81 | |||
8f05346ced | |||
8e62bd83d6 | |||
471ea7a6ee | |||
353a606864 | |||
3dc998a5c0 | |||
22e25671ce | |||
6d07af868e | |||
d9f57eddf2 | |||
ad664d5299 | |||
13dc02d144 |
48
.github/workflows/android.yml
vendored
Normal file
48
.github/workflows/android.yml
vendored
Normal file
@ -0,0 +1,48 @@
|
||||
name: Android
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: GPXSee
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: set up JDK 11
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: '11'
|
||||
- name: Setup Android SDK
|
||||
uses: android-actions/setup-android@v2
|
||||
- name: Run sdkmanager update
|
||||
run: ${ANDROID_HOME}/tools/bin/sdkmanager --update
|
||||
- name: Install android platform, platform-tools, build-tools and ndk
|
||||
run: ${ANDROID_HOME}/tools/bin/sdkmanager --install "cmdline-tools;latest" "platform-tools" "platforms;android-31" "build-tools;31.0.0" "ndk;22.1.7171670"
|
||||
- name: Install Qt (Desktop)
|
||||
uses: jurplel/install-qt-action@v2
|
||||
with:
|
||||
aqtversion: '==2.1.0'
|
||||
version: '6.3.0'
|
||||
- name: Install Qt (Android)
|
||||
uses: jurplel/install-qt-action@v2
|
||||
with:
|
||||
aqtversion: '==2.1.0'
|
||||
version: '6.3.0'
|
||||
target: 'android'
|
||||
arch: 'android_armv7'
|
||||
modules: qtpositioning qt5compat
|
||||
- name: Install Android OpenSSL
|
||||
run: git clone https://github.com/KDAB/android_openssl.git
|
||||
- name: Configure build
|
||||
run: qmake gpxsee.pro OPENSSL_PATH=android_openssl
|
||||
- name: Build project
|
||||
run: make -j2 apk
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: GPXSee-armv7.apk
|
||||
path: android-build/build/outputs/apk/debug/android-build-debug.apk
|
@ -545,7 +545,9 @@ android {
|
||||
return($$first(vCode)$$first(suffix))
|
||||
}
|
||||
|
||||
include($$OPENSSL_PATH/openssl.pri)
|
||||
!include($$OPENSSL_PATH/openssl.pri) {
|
||||
message("OpenSSL not found, building without HTTPS support!")
|
||||
}
|
||||
|
||||
ANDROID_VERSION_NAME = $$VERSION
|
||||
ANDROID_VERSION_CODE = $$versionCode($$ANDROID_VERSION_NAME)
|
||||
|
@ -149,18 +149,3 @@ GMAPData::~GMAPData()
|
||||
{
|
||||
qDeleteAll(_files);
|
||||
}
|
||||
|
||||
bool GMAPData::isGMAP(const QString &path)
|
||||
{
|
||||
QFile file(path);
|
||||
|
||||
if (!file.open(QFile::ReadOnly | QFile::Text))
|
||||
return false;
|
||||
|
||||
QXmlStreamReader reader(&file);
|
||||
if (reader.readNextStartElement()
|
||||
&& reader.name() == QLatin1String("MapProduct"))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -14,8 +14,6 @@ public:
|
||||
GMAPData(const QString &fileName);
|
||||
~GMAPData();
|
||||
|
||||
static bool isGMAP(const QString &path);
|
||||
|
||||
private:
|
||||
bool readXML(const QString &path, QString &dataDir, QString &typFile,
|
||||
QString &baseMap);
|
||||
|
@ -77,29 +77,26 @@ void Atlas::computeBounds()
|
||||
QRectF(offsets.at(i), _maps.at(i)->bounds().size()));
|
||||
}
|
||||
|
||||
Atlas::Atlas(const QString &fileName, QObject *parent)
|
||||
Atlas::Atlas(const QString &fileName, bool TAR, QObject *parent)
|
||||
: Map(fileName, parent), _zoom(0), _mapIndex(-1), _valid(false)
|
||||
{
|
||||
QFileInfo fi(fileName);
|
||||
QByteArray ba;
|
||||
QString suffix = fi.suffix().toLower();
|
||||
Tar tar(fileName);
|
||||
|
||||
|
||||
_name = fi.dir().dirName();
|
||||
|
||||
if (suffix == "tar") {
|
||||
if (TAR) {
|
||||
if (!tar.open()) {
|
||||
_errorString = "Error reading tar file";
|
||||
return;
|
||||
}
|
||||
QString tbaFileName = fi.completeBaseName() + ".tba";
|
||||
ba = tar.file(tbaFileName);
|
||||
} else if (suffix == "tba") {
|
||||
} else {
|
||||
QFile tbaFile(fileName);
|
||||
if (!tbaFile.open(QIODevice::ReadOnly)) {
|
||||
_errorString = QString("Error opening tba file: %1")
|
||||
.arg(tbaFile.errorString());
|
||||
_errorString = tbaFile.errorString();
|
||||
return;
|
||||
}
|
||||
ba = tbaFile.readAll();
|
||||
@ -123,7 +120,7 @@ Atlas::Atlas(const QString &fileName, QObject *parent)
|
||||
if (tar.isOpen())
|
||||
map = new OziMap(mapFile, tar, this);
|
||||
else
|
||||
map = new OziMap(mapFile, this);
|
||||
map = new OziMap(mapFile, TAR, this);
|
||||
|
||||
if (map->isValid())
|
||||
_maps.append(map);
|
||||
@ -293,10 +290,18 @@ void Atlas::unload()
|
||||
_maps.at(i)->unload();
|
||||
}
|
||||
|
||||
Map *Atlas::create(const QString &path, const Projection &, bool *isDir)
|
||||
Map *Atlas::createTAR(const QString &path, const Projection &, bool *isDir)
|
||||
{
|
||||
if (isDir)
|
||||
*isDir = true;
|
||||
|
||||
return new Atlas(path);
|
||||
return new Atlas(path, true);
|
||||
}
|
||||
|
||||
Map *Atlas::createTBA(const QString &path, const Projection &, bool *isDir)
|
||||
{
|
||||
if (isDir)
|
||||
*isDir = true;
|
||||
|
||||
return new Atlas(path, false);
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ class Atlas : public Map
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Atlas(const QString &fileName, QObject *parent = 0);
|
||||
Atlas(const QString &fileName, bool TAR, QObject *parent = 0);
|
||||
|
||||
QString name() const {return _name;}
|
||||
|
||||
@ -34,7 +34,8 @@ public:
|
||||
bool isValid() const {return _valid;}
|
||||
QString errorString() const {return _errorString;}
|
||||
|
||||
static Map *create(const QString &path, const Projection &, bool *isDir);
|
||||
static Map *createTAR(const QString &path, const Projection &, bool *isDir);
|
||||
static Map *createTBA(const QString &path, const Projection &, bool *isDir);
|
||||
|
||||
private:
|
||||
struct Zoom {
|
||||
|
@ -40,11 +40,11 @@ static QList<MapData*> overlays(const QString &fileName)
|
||||
return list;
|
||||
}
|
||||
|
||||
IMGMap::IMGMap(const QString &fileName, QObject *parent)
|
||||
IMGMap::IMGMap(const QString &fileName, bool GMAP, QObject *parent)
|
||||
: Map(fileName, parent), _projection(PCS::pcs(3857)), _tileRatio(1.0),
|
||||
_valid(false)
|
||||
{
|
||||
if (GMAPData::isGMAP(fileName))
|
||||
if (GMAP)
|
||||
_data.append(new GMAPData(fileName));
|
||||
else {
|
||||
_data.append(new IMGData(fileName));
|
||||
@ -291,10 +291,18 @@ void IMGMap::setOutputProjection(const Projection &projection)
|
||||
QPixmapCache::clear();
|
||||
}
|
||||
|
||||
Map* IMGMap::create(const QString &path, const Projection &, bool *isDir)
|
||||
Map* IMGMap::createIMG(const QString &path, const Projection &, bool *isDir)
|
||||
{
|
||||
if (isDir)
|
||||
*isDir = GMAPData::isGMAP(path);
|
||||
*isDir = false;
|
||||
|
||||
return new IMGMap(path);
|
||||
return new IMGMap(path, false);
|
||||
}
|
||||
|
||||
Map* IMGMap::createGMAP(const QString &path, const Projection &, bool *isDir)
|
||||
{
|
||||
if (isDir)
|
||||
*isDir = true;
|
||||
|
||||
return new IMGMap(path, true);
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ class IMGMap : public Map
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
IMGMap(const QString &fileName, QObject *parent = 0);
|
||||
IMGMap(const QString &fileName, bool GMAP, QObject *parent = 0);
|
||||
~IMGMap() {qDeleteAll(_data);}
|
||||
|
||||
QString name() const {return _data.first()->name();}
|
||||
@ -79,7 +79,8 @@ public:
|
||||
bool isValid() const {return _valid;}
|
||||
QString errorString() const {return _errorString;}
|
||||
|
||||
static Map* create(const QString &path, const Projection &, bool *isDir);
|
||||
static Map* createIMG(const QString &path, const Projection &, bool *isDir);
|
||||
static Map* createGMAP(const QString &path, const Projection &, bool *isDir);
|
||||
|
||||
private slots:
|
||||
void jobFinished(IMGMapJob *job);
|
||||
|
@ -148,8 +148,7 @@ bool MapFile::parseMapFile(QIODevice &device, QList<CalibrationPoint> &points,
|
||||
int el;
|
||||
|
||||
if (!device.open(QIODevice::ReadOnly)) {
|
||||
_errorString = QString("Error opening file: %1")
|
||||
.arg(device.errorString());
|
||||
_errorString = device.errorString();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -24,12 +24,12 @@ MapList::ParserMap MapList::parsers()
|
||||
{
|
||||
MapList::ParserMap map;
|
||||
|
||||
map.insert("tar", &Atlas::create);
|
||||
map.insert("tar", &OziMap::create);
|
||||
map.insert("tba", &Atlas::create);
|
||||
map.insert("tar", &Atlas::createTAR);
|
||||
map.insert("tar", &OziMap::createTAR);
|
||||
map.insert("tba", &Atlas::createTBA);
|
||||
map.insert("xml", &MapSource::create);
|
||||
map.insert("xml", &IMGMap::create);
|
||||
map.insert("img", &IMGMap::create);
|
||||
map.insert("xml", &IMGMap::createGMAP);
|
||||
map.insert("img", &IMGMap::createIMG);
|
||||
map.insert("jnx", &JNXMap::create);
|
||||
map.insert("tif", &GeoTIFFMap::create);
|
||||
map.insert("tiff", &GeoTIFFMap::create);
|
||||
@ -37,7 +37,7 @@ MapList::ParserMap MapList::parsers()
|
||||
map.insert("rmap", &RMap::create);
|
||||
map.insert("rtmap", &RMap::create);
|
||||
map.insert("map", &MapsforgeMap::create);
|
||||
map.insert("map", &OziMap::create);
|
||||
map.insert("map", &OziMap::createMAP);
|
||||
map.insert("kap", &BSBMap::create);
|
||||
map.insert("kmz", &KMZMap::create);
|
||||
map.insert("aqm", &AQMMap::create);
|
||||
@ -71,15 +71,24 @@ Map *MapList::loadFile(const QString &path, const Projection &proj, bool *isDir)
|
||||
++it;
|
||||
}
|
||||
} else {
|
||||
QStringList errors;
|
||||
|
||||
for (it = _parsers.begin(); it != _parsers.end(); it++) {
|
||||
map = it.value()(path, proj, isDir);
|
||||
if (map->isValid())
|
||||
break;
|
||||
else {
|
||||
errors.append(it.key() + ": " + map->errorString());
|
||||
delete map;
|
||||
map = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!map) {
|
||||
qWarning("Error loading map file: %s:", qPrintable(path));
|
||||
for (int i = 0; i < errors.size(); i++)
|
||||
qWarning(qPrintable(errors.at(i)));
|
||||
}
|
||||
}
|
||||
|
||||
return map ? map : new InvalidMap(path, "Unknown file format");
|
||||
|
@ -10,6 +10,7 @@
|
||||
using namespace Mapsforge;
|
||||
|
||||
#define MAGIC "mapsforge binary OSM"
|
||||
#define MAGIC_SIZE (sizeof(MAGIC) - 1)
|
||||
#define MD(val) ((val) / 1e6)
|
||||
#define OFFSET_MASK 0x7FFFFFFFFFL
|
||||
|
||||
@ -282,43 +283,68 @@ bool MapData::readSubFiles()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MapData::readHeader()
|
||||
bool MapData::readZoomInfo(SubFile &subfile)
|
||||
{
|
||||
quint8 zooms;
|
||||
|
||||
if (!subfile.readByte(zooms))
|
||||
return false;
|
||||
|
||||
_subFiles.resize(zooms);
|
||||
for (quint8 i = 0; i < zooms; i++) {
|
||||
if (!(subfile.readByte(_subFiles[i].base)
|
||||
&& subfile.readByte(_subFiles[i].min)
|
||||
&& subfile.readByte(_subFiles[i].max)
|
||||
&& subfile.readUInt64(_subFiles[i].offset)
|
||||
&& subfile.readUInt64(_subFiles[i].size)))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MapData::readTagInfo(SubFile &subfile)
|
||||
{
|
||||
char magic[sizeof(MAGIC) - 1];
|
||||
quint32 hdrSize, version;
|
||||
quint64 fileSize, date;
|
||||
qint32 minLat, minLon, maxLat, maxLon;
|
||||
quint16 tags;
|
||||
quint8 flags, zooms;
|
||||
QByteArray projection, tag;
|
||||
QByteArray tag;
|
||||
|
||||
if (!subfile.readUInt16(tags))
|
||||
return false;
|
||||
_pointTags.resize(tags);
|
||||
for (quint16 i = 0; i < tags; i++) {
|
||||
if (!subfile.readString(tag))
|
||||
return false;
|
||||
_pointTags[i] = tag;
|
||||
}
|
||||
|
||||
if (_file.read(magic, sizeof(magic)) < (int)sizeof(magic)
|
||||
|| memcmp(magic, MAGIC, sizeof(magic)))
|
||||
return false;
|
||||
if (_file.read((char*)&hdrSize, sizeof(hdrSize)) < (qint64)sizeof(hdrSize))
|
||||
if (!subfile.readUInt16(tags))
|
||||
return false;
|
||||
_pathTags.resize(tags);
|
||||
for (quint16 i = 0; i < tags; i++) {
|
||||
if (!subfile.readString(tag))
|
||||
return false;
|
||||
_pathTags[i] = tag;
|
||||
}
|
||||
|
||||
SubFile subfile(_file, sizeof(magic) + sizeof(hdrSize),
|
||||
qFromBigEndian(hdrSize));
|
||||
if (!subfile.seek(0))
|
||||
return false;
|
||||
if (!(subfile.readUInt32(version) && subfile.readUInt64(fileSize)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MapData::readMapInfo(SubFile &subfile, QByteArray &projection,
|
||||
bool &debugMap)
|
||||
{
|
||||
quint64 fileSize, date;
|
||||
quint32 version;
|
||||
qint32 minLat, minLon, maxLat, maxLon;
|
||||
quint8 flags;
|
||||
|
||||
if (!(subfile.seek(MAGIC_SIZE + 4)
|
||||
&& subfile.readUInt32(version) && subfile.readUInt64(fileSize)
|
||||
&& subfile.readUInt64(date) && subfile.readInt32(minLat)
|
||||
&& subfile.readInt32(minLon) && subfile.readInt32(maxLat)
|
||||
&& subfile.readInt32(maxLon) && subfile.readUInt16(_tileSize)
|
||||
&& subfile.readString(projection) && subfile.readByte(flags)))
|
||||
return false;
|
||||
|
||||
if (projection != "Mercator") {
|
||||
_errorString = projection + ": invalid/unsupported projection";
|
||||
return false;
|
||||
}
|
||||
if (flags & 0x80) {
|
||||
_errorString = "DEBUG maps not supported";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (flags & 0x40) {
|
||||
qint32 startLon, startLat;
|
||||
if (!(subfile.readInt32(startLat) && subfile.readInt32(startLon)))
|
||||
@ -345,39 +371,58 @@ bool MapData::readHeader()
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!subfile.readUInt16(tags))
|
||||
return false;
|
||||
_pointTags.resize(tags);
|
||||
for (quint16 i = 0; i < tags; i++) {
|
||||
if (!subfile.readString(tag))
|
||||
return false;
|
||||
_pointTags[i] = tag;
|
||||
}
|
||||
|
||||
if (!subfile.readUInt16(tags))
|
||||
return false;
|
||||
_pathTags.resize(tags);
|
||||
for (quint16 i = 0; i < tags; i++) {
|
||||
if (!subfile.readString(tag))
|
||||
return false;
|
||||
_pathTags[i] = tag;
|
||||
}
|
||||
|
||||
if (!subfile.readByte(zooms))
|
||||
return false;
|
||||
_subFiles.resize(zooms);
|
||||
for (quint8 i = 0; i < zooms; i++) {
|
||||
if (!(subfile.readByte(_subFiles[i].base)
|
||||
&& subfile.readByte(_subFiles[i].min)
|
||||
&& subfile.readByte(_subFiles[i].max)
|
||||
&& subfile.readUInt64(_subFiles[i].offset)
|
||||
&& subfile.readUInt64(_subFiles[i].size)))
|
||||
return false;
|
||||
}
|
||||
|
||||
_bounds = RectC(Coordinates(MD(minLon), MD(maxLat)),
|
||||
Coordinates(MD(maxLon), MD(minLat)));
|
||||
_bounds &= OSM::BOUNDS;
|
||||
debugMap = flags & 0x80;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MapData::readHeader()
|
||||
{
|
||||
char magic[MAGIC_SIZE];
|
||||
quint32 hdrSize;
|
||||
QByteArray projection;
|
||||
bool debugMap;
|
||||
|
||||
|
||||
if (_file.read(magic, MAGIC_SIZE) < (qint64)MAGIC_SIZE
|
||||
|| memcmp(magic, MAGIC, MAGIC_SIZE)) {
|
||||
_errorString = "Not a Mapsforge map";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_file.read((char*)&hdrSize, sizeof(hdrSize)) < (qint64)sizeof(hdrSize)) {
|
||||
_errorString = "Unexpected EOF";
|
||||
return false;
|
||||
}
|
||||
|
||||
SubFile subfile(_file, 0, qFromBigEndian(hdrSize));
|
||||
|
||||
if (!readMapInfo(subfile, projection, debugMap)) {
|
||||
_errorString = "Error reading map info";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!readTagInfo(subfile)) {
|
||||
_errorString = "Error reading tags info";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!readZoomInfo(subfile)) {
|
||||
_errorString = "Error reading zooms info";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (projection != "Mercator") {
|
||||
_errorString = projection + ": invalid/unsupported projection";
|
||||
return false;
|
||||
}
|
||||
if (debugMap) {
|
||||
_errorString = "DEBUG maps not supported";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -13,6 +13,8 @@
|
||||
|
||||
namespace Mapsforge {
|
||||
|
||||
class SubFile;
|
||||
|
||||
class MapData
|
||||
{
|
||||
public:
|
||||
@ -129,6 +131,9 @@ private:
|
||||
|
||||
typedef RTree<VectorTile *, double, 2> TileTree;
|
||||
|
||||
bool readZoomInfo(SubFile &subfile);
|
||||
bool readTagInfo(SubFile &subfile);
|
||||
bool readMapInfo(SubFile &subfile, QByteArray &projection, bool &debugMap);
|
||||
bool readHeader();
|
||||
bool readSubFiles();
|
||||
void clearTiles();
|
||||
|
@ -17,15 +17,13 @@
|
||||
#include "ozimap.h"
|
||||
|
||||
|
||||
OziMap::OziMap(const QString &fileName, QObject *parent)
|
||||
OziMap::OziMap(const QString &fileName, bool TAR, QObject *parent)
|
||||
: Map(fileName, parent), _img(0), _tar(0), _ozf(0), _zoom(0), _mapRatio(1.0),
|
||||
_valid(false)
|
||||
{
|
||||
QFileInfo fi(fileName);
|
||||
QString suffix = fi.suffix().toLower();
|
||||
|
||||
|
||||
if (suffix == "tar") {
|
||||
if (TAR) {
|
||||
_tar = new Tar(fileName);
|
||||
if (!_tar->open()) {
|
||||
_errorString = "Error reading tar file";
|
||||
@ -380,10 +378,18 @@ void OziMap::setDevicePixelRatio(qreal deviceRatio, qreal mapRatio)
|
||||
_img->setDevicePixelRatio(_mapRatio);
|
||||
}
|
||||
|
||||
Map *OziMap::create(const QString &path, const Projection &, bool *isDir)
|
||||
Map *OziMap::createTAR(const QString &path, const Projection &, bool *isDir)
|
||||
{
|
||||
if (isDir)
|
||||
*isDir = true;
|
||||
|
||||
return new OziMap(path);
|
||||
return new OziMap(path, true);
|
||||
}
|
||||
|
||||
Map *OziMap::createMAP(const QString &path, const Projection &, bool *isDir)
|
||||
{
|
||||
if (isDir)
|
||||
*isDir = true;
|
||||
|
||||
return new OziMap(path, false);
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ class OziMap : public Map
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
OziMap(const QString &fileName, QObject *parent = 0);
|
||||
OziMap(const QString &fileName, bool TAR, QObject *parent = 0);
|
||||
OziMap(const QString &fileName, Tar &tar, QObject *parent = 0);
|
||||
~OziMap();
|
||||
|
||||
@ -47,7 +47,8 @@ public:
|
||||
QPointF pp2xy(const PointD &p) const
|
||||
{return _transform.proj2img(p) / _mapRatio;}
|
||||
|
||||
static Map *create(const QString &path, const Projection &, bool *isDir);
|
||||
static Map *createTAR(const QString &path, const Projection &, bool *isDir);
|
||||
static Map *createMAP(const QString &path, const Projection &, bool *isDir);
|
||||
|
||||
private:
|
||||
struct ImageInfo {
|
||||
|
Reference in New Issue
Block a user