mirror of
https://github.com/tumic0/GPXSee.git
synced 2025-07-18 04:44:23 +02:00
Compare commits
18 Commits
Author | SHA1 | Date | |
---|---|---|---|
66036f6cd7 | |||
dfda3a6630 | |||
96e762beb5 | |||
b4be5ea206 | |||
56c77df176 | |||
1871f85acc | |||
3ec636632f | |||
5e1af275b8 | |||
cd220216dd | |||
0d6b02f466 | |||
059c515175 | |||
1dc963b133 | |||
f0036bfd28 | |||
688861bf65 | |||
c449024584 | |||
41188360bf | |||
1086a74f99 | |||
7b5a1c701d |
@ -1,23 +1,23 @@
|
||||
version: 13.4.{build}
|
||||
version: 13.5.{build}
|
||||
|
||||
configuration:
|
||||
- Release
|
||||
|
||||
image:
|
||||
- Visual Studio 2019
|
||||
- Visual Studio 2022
|
||||
|
||||
environment:
|
||||
NSISDIR: C:\Program Files (x86)\NSIS
|
||||
OPENSSLDIR: C:\OpenSSL-v111-Win64\bin
|
||||
matrix:
|
||||
- QTDIR: C:\Qt\5.15\msvc2019_64
|
||||
- QTDIR: C:\Qt\6.4\msvc2019_64
|
||||
- QTDIR: C:\Qt\6.5\msvc2019_64
|
||||
NSISDEF: /DQT6
|
||||
|
||||
install:
|
||||
- cmd: |-
|
||||
set PATH=%QTDIR%\bin;%NSISDIR%;%PATH%
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat
|
||||
call "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars64.bat
|
||||
|
||||
build_script:
|
||||
- cmd: |-
|
||||
|
4
.github/workflows/osx.yml
vendored
4
.github/workflows/osx.yml
vendored
@ -39,12 +39,12 @@ jobs:
|
||||
- name: Install Qt
|
||||
uses: jurplel/install-qt-action@v3
|
||||
with:
|
||||
version: '6.4.3'
|
||||
version: '6.5.1'
|
||||
modules: qtpositioning qt5compat qtserialport
|
||||
- name: Create localization
|
||||
run: lrelease gpxsee.pro
|
||||
- name: Configure build
|
||||
run: qmake gpxsee.pro
|
||||
run: qmake gpxsee.pro QMAKE_APPLE_DEVICE_ARCHS="x86_64h arm64"
|
||||
- name: Build project
|
||||
run: make -j3
|
||||
- name: Create DMG
|
||||
|
@ -3,7 +3,8 @@ unix:!macx:!android {
|
||||
} else {
|
||||
TARGET = GPXSee
|
||||
}
|
||||
VERSION = 13.4
|
||||
VERSION = 13.5
|
||||
|
||||
|
||||
QT += core \
|
||||
gui \
|
||||
|
@ -55,6 +55,11 @@
|
||||
<file alias="transform-move_32@2x.png">icons/GUI/transform-move_32@2x.png</file>
|
||||
</qresource>
|
||||
|
||||
<!-- Common map stuff -->
|
||||
<qresource prefix="/map">
|
||||
<file alias="arrow.png">icons/map/arrow.png</file>
|
||||
</qresource>
|
||||
|
||||
<!-- POIs (IMG & ENC style) -->
|
||||
<qresource prefix="/POI">
|
||||
<file alias="airfield-11.png">icons/map/POI/airfield-11.png</file>
|
||||
|
BIN
icons/map/arrow.png
Normal file
BIN
icons/map/arrow.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 175 B |
@ -37,7 +37,7 @@ Unicode true
|
||||
; The name of the installer
|
||||
Name "GPXSee"
|
||||
; Program version
|
||||
!define VERSION "13.4"
|
||||
!define VERSION "13.5"
|
||||
|
||||
; The file to write
|
||||
OutFile "GPXSee-${VERSION}_x64.exe"
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include <QGraphicsScene>
|
||||
#include <QEvent>
|
||||
#include <QMouseEvent>
|
||||
#include <QGestureEvent>
|
||||
#include <QScrollBar>
|
||||
#include <QGraphicsSimpleTextItem>
|
||||
#include <QPalette>
|
||||
@ -37,6 +38,8 @@ GraphView::GraphView(QWidget *parent)
|
||||
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
setBackgroundBrush(QBrush(palette().brush(QPalette::Base)));
|
||||
viewport()->setAttribute(Qt::WA_AcceptTouchEvents);
|
||||
grabGesture(Qt::PinchGesture);
|
||||
|
||||
_xAxis = new AxisItem(AxisItem::X);
|
||||
_xAxis->setZValue(1.0);
|
||||
@ -381,6 +384,27 @@ void GraphView::wheelEvent(QWheelEvent *e)
|
||||
QGraphicsView::wheelEvent(e);
|
||||
}
|
||||
|
||||
void GraphView::pinchGesture(QPinchGesture *gesture)
|
||||
{
|
||||
QPinchGesture::ChangeFlags changeFlags = gesture->changeFlags();
|
||||
|
||||
if (changeFlags & QPinchGesture::ScaleFactorChanged) {
|
||||
QPointF pos = mapToScene(gesture->centerPoint().toPoint());
|
||||
QRectF gr(_grid->boundingRect());
|
||||
QPointF r(pos.x() / gr.width(), pos.y() / gr.height());
|
||||
|
||||
_zoom = qMax(_zoom * gesture->scaleFactor(), 1.0);
|
||||
redraw();
|
||||
|
||||
QRectF ngr(_grid->boundingRect());
|
||||
QPointF npos(mapFromScene(QPointF(r.x() * ngr.width(),
|
||||
r.y() * ngr.height())));
|
||||
QScrollBar *sb = horizontalScrollBar();
|
||||
sb->setSliderPosition(sb->sliderPosition() + npos.x()
|
||||
- gesture->centerPoint().x());
|
||||
}
|
||||
}
|
||||
|
||||
void GraphView::paintEvent(QPaintEvent *e)
|
||||
{
|
||||
QRectF viewRect(mapToScene(rect()).boundingRect());
|
||||
@ -577,3 +601,19 @@ void GraphView::changeEvent(QEvent *e)
|
||||
|
||||
QGraphicsView::changeEvent(e);
|
||||
}
|
||||
|
||||
bool GraphView::event(QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::Gesture)
|
||||
return gestureEvent(static_cast<QGestureEvent*>(event));
|
||||
|
||||
return QGraphicsView::event(event);
|
||||
}
|
||||
|
||||
bool GraphView::gestureEvent(QGestureEvent *event)
|
||||
{
|
||||
if (QGesture *pinch = event->gesture(Qt::PinchGesture))
|
||||
pinchGesture(static_cast<QPinchGesture *>(pinch));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -18,6 +18,8 @@ class PathItem;
|
||||
class GridItem;
|
||||
class QGraphicsSimpleTextItem;
|
||||
class GraphicsScene;
|
||||
class QGestureEvent;
|
||||
class QPinchGesture;
|
||||
|
||||
class GraphView : public QGraphicsView
|
||||
{
|
||||
@ -59,6 +61,7 @@ protected:
|
||||
void wheelEvent(QWheelEvent *e);
|
||||
void changeEvent(QEvent *e);
|
||||
void paintEvent(QPaintEvent *e);
|
||||
bool event(QEvent *event);
|
||||
|
||||
const QString &yLabel() const {return _yLabel;}
|
||||
const QString &yUnits() const {return _yUnits;}
|
||||
@ -94,6 +97,8 @@ private:
|
||||
void removeItem(QGraphicsItem *item);
|
||||
void addItem(QGraphicsItem *item);
|
||||
bool singleGraph() const;
|
||||
bool gestureEvent(QGestureEvent *event);
|
||||
void pinchGesture(QPinchGesture *gesture);
|
||||
|
||||
GraphicsScene *_scene;
|
||||
|
||||
|
@ -25,6 +25,8 @@ class MapData
|
||||
{
|
||||
public:
|
||||
struct Poly {
|
||||
Poly() : oneway(false) {}
|
||||
|
||||
/* QPointF insted of Coordinates for performance reasons (no need to
|
||||
duplicate all the vectors for drawing). Note, that we do not want to
|
||||
ll2xy() the points in the MapData class as this can not be done in
|
||||
@ -34,6 +36,7 @@ public:
|
||||
Raster raster;
|
||||
quint32 type;
|
||||
RectC boundingRect;
|
||||
bool oneway;
|
||||
|
||||
bool operator<(const Poly &other) const
|
||||
{return type > other.type;}
|
||||
|
@ -479,6 +479,8 @@ bool NETFile::link(const SubDiv *subdiv, quint32 shift, Handle &hdl,
|
||||
|
||||
if (lbl)
|
||||
linkLabel(hdl, linkOffset, lbl, lblHdl, poly.label);
|
||||
if ((linkInfo.flags >> 3) & 1)
|
||||
poly.oneway = true;
|
||||
|
||||
lines->append(poly);
|
||||
|
||||
|
@ -25,6 +25,12 @@ static const QColor shieldBgColor1("#dd3e3e");
|
||||
static const QColor shieldBgColor2("#379947");
|
||||
static const QColor shieldBgColor3("#4a7fc1");
|
||||
|
||||
static const QImage *arrow()
|
||||
{
|
||||
static QImage img(":/map/arrow.png");
|
||||
return &img;
|
||||
}
|
||||
|
||||
static QFont pixelSizeFont(int pixelSize)
|
||||
{
|
||||
QFont f;
|
||||
@ -327,14 +333,25 @@ void RasterTile::processStreetNames(const QList<MapData::Poly> &lines,
|
||||
const QFont *fnt = font(style.textFontSize(), Style::Small);
|
||||
const QColor *color = style.textColor().isValid()
|
||||
? &style.textColor() : 0;
|
||||
const QColor *hColor = Style::isContourLine(poly.type) ? 0 : &haloColor;
|
||||
const QImage *img = poly.oneway ? arrow() : 0;
|
||||
|
||||
TextPathItem *item = new TextPathItem(poly.points,
|
||||
&poly.label.text(), _rect, fnt, color, Style::isContourLine(poly.type)
|
||||
? 0 : &haloColor);
|
||||
&poly.label.text(), _rect, fnt, color, hColor, img);
|
||||
if (item->isValid() && !item->collides(textItems))
|
||||
textItems.append(item);
|
||||
else
|
||||
else {
|
||||
delete item;
|
||||
|
||||
if (img) {
|
||||
TextPathItem *item = new TextPathItem(poly.points, 0, _rect, 0,
|
||||
0, 0, img);
|
||||
if (item->isValid() && !item->collides(textItems))
|
||||
textItems.append(item);
|
||||
else
|
||||
delete item;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -292,6 +292,8 @@ bool RGNFile::polyObjects(Handle &hdl, const SubDiv *subdiv,
|
||||
|
||||
poly.type = (segmentType == Polygon)
|
||||
? ((quint32)(type & 0x7F)) << 8 : ((quint32)(type & 0x3F)) << 8;
|
||||
if (segmentType == Line && type & 0x40)
|
||||
poly.oneway = true;
|
||||
|
||||
|
||||
QPoint pos(subdiv->lon() + LS(lon, 24-subdiv->bits()),
|
||||
|
@ -1,7 +1,6 @@
|
||||
#include <cmath>
|
||||
#include <QPainter>
|
||||
#include <QCache>
|
||||
#include "common/programpaths.h"
|
||||
#include "map/rectd.h"
|
||||
#include "rastertile.h"
|
||||
|
||||
|
@ -167,18 +167,19 @@ void MapsforgeMap::cancelJobs(bool wait)
|
||||
|
||||
void MapsforgeMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
|
||||
{
|
||||
QPointF tl(floor(rect.left() / _data.tileSize()) * _data.tileSize(),
|
||||
floor(rect.top() / _data.tileSize()) * _data.tileSize());
|
||||
int tileSize = (_data.tileSize() < 384)
|
||||
? _data.tileSize() << 1 : _data.tileSize();
|
||||
QPointF tl(floor(rect.left() / tileSize) * tileSize,
|
||||
floor(rect.top() / tileSize) * tileSize);
|
||||
QSizeF s(rect.right() - tl.x(), rect.bottom() - tl.y());
|
||||
int width = ceil(s.width() / _data.tileSize());
|
||||
int height = ceil(s.height() / _data.tileSize());
|
||||
int width = ceil(s.width() / tileSize);
|
||||
int height = ceil(s.height() / tileSize);
|
||||
|
||||
QList<RasterTile> tiles;
|
||||
|
||||
for (int i = 0; i < width; i++) {
|
||||
for (int j = 0; j < height; j++) {
|
||||
QPoint ttl(tl.x() + i * _data.tileSize(), tl.y() + j
|
||||
* _data.tileSize());
|
||||
QPoint ttl(tl.x() + i * tileSize, tl.y() + j * tileSize);
|
||||
if (isRunning(_zoom, ttl))
|
||||
continue;
|
||||
|
||||
@ -187,8 +188,7 @@ void MapsforgeMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
|
||||
painter->drawPixmap(ttl, pm);
|
||||
else {
|
||||
tiles.append(RasterTile(_projection, _transform, &_style, &_data,
|
||||
_zoom, QRect(ttl, QSize(_data.tileSize(), _data.tileSize())),
|
||||
_tileRatio));
|
||||
_zoom, QRect(ttl, QSize(tileSize, tileSize)), _tileRatio));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,9 +18,8 @@ OnlineMap::OnlineMap(const QString &fileName, const QString &name,
|
||||
{
|
||||
_tileLoader = new TileLoader(QDir(ProgramPaths::tilesDir()).filePath(_name),
|
||||
this);
|
||||
_tileLoader->setUrl(url);
|
||||
_tileLoader->setUrl(url, quadTiles ? TileLoader::QuadTiles : TileLoader::XYZ);
|
||||
_tileLoader->setHeaders(headers);
|
||||
_tileLoader->setQuadTiles(quadTiles);
|
||||
connect(_tileLoader, &TileLoader::finished, this, &OnlineMap::tilesLoaded);
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,7 @@ static QString quadKey(const QPoint &xy, int zoom)
|
||||
}
|
||||
|
||||
TileLoader::TileLoader(const QString &dir, QObject *parent)
|
||||
: QObject(parent), _dir(dir), _scaledSize(0), _quadTiles(false)
|
||||
: QObject(parent), _urlType(XYZ), _dir(dir), _scaledSize(0)
|
||||
{
|
||||
if (!QDir().mkpath(_dir))
|
||||
qWarning("%s: %s", qPrintable(_dir), "Error creating tiles directory");
|
||||
@ -176,19 +176,21 @@ QUrl TileLoader::tileUrl(const FetchTile &tile) const
|
||||
{
|
||||
QString url(_url);
|
||||
|
||||
if (!tile.bbox().isNull()) {
|
||||
QString bbox = QString("%1,%2,%3,%4").arg(
|
||||
QString::number(tile.bbox().left(), 'f', 6),
|
||||
QString::number(tile.bbox().bottom(), 'f', 6),
|
||||
QString::number(tile.bbox().right(), 'f', 6),
|
||||
QString::number(tile.bbox().top(), 'f', 6));
|
||||
url.replace("$bbox", bbox);
|
||||
} else if (_quadTiles) {
|
||||
url.replace("$quadkey", quadKey(tile.xy(), tile.zoom().toInt()));
|
||||
} else {
|
||||
url.replace("$z", tile.zoom().toString());
|
||||
url.replace("$x", QString::number(tile.xy().x()));
|
||||
url.replace("$y", QString::number(tile.xy().y()));
|
||||
switch (_urlType) {
|
||||
case BoundingBox:
|
||||
url.replace("$bbox", QString("%1,%2,%3,%4").arg(
|
||||
QString::number(tile.bbox().left(), 'f', 6),
|
||||
QString::number(tile.bbox().bottom(), 'f', 6),
|
||||
QString::number(tile.bbox().right(), 'f', 6),
|
||||
QString::number(tile.bbox().top(), 'f', 6)));
|
||||
break;
|
||||
case QuadTiles:
|
||||
url.replace("$quadkey", quadKey(tile.xy(), tile.zoom().toInt()));
|
||||
break;
|
||||
default:
|
||||
url.replace("$z", tile.zoom().toString());
|
||||
url.replace("$x", QString::number(tile.xy().x()));
|
||||
url.replace("$y", QString::number(tile.xy().y()));
|
||||
}
|
||||
|
||||
return QUrl(url);
|
||||
|
@ -11,12 +11,17 @@ class TileLoader : public QObject
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum UrlType {
|
||||
XYZ,
|
||||
QuadTiles,
|
||||
BoundingBox
|
||||
};
|
||||
|
||||
TileLoader(const QString &dir, QObject *parent = 0);
|
||||
|
||||
void setUrl(const QString &url) {_url = url;}
|
||||
void setUrl(const QString &url, UrlType type) {_url = url; _urlType = type;}
|
||||
void setHeaders(const QList<HTTPHeader> &headers) {_headers = headers;}
|
||||
void setScaledSize(int size);
|
||||
void setQuadTiles(bool quadTiles) {_quadTiles = quadTiles;}
|
||||
|
||||
void loadTilesAsync(QVector<FetchTile> &list);
|
||||
void loadTilesSync(QVector<FetchTile> &list);
|
||||
@ -31,10 +36,10 @@ private:
|
||||
|
||||
Downloader *_downloader;
|
||||
QString _url;
|
||||
UrlType _urlType;
|
||||
QString _dir;
|
||||
QList<HTTPHeader> _headers;
|
||||
int _scaledSize;
|
||||
bool _quadTiles;
|
||||
};
|
||||
|
||||
#endif // TILELOADER_H
|
||||
|
@ -85,7 +85,7 @@ WMSMap::WMSMap(const QString &fileName, const QString &name,
|
||||
|
||||
void WMSMap::init()
|
||||
{
|
||||
_tileLoader->setUrl(tileUrl());
|
||||
_tileLoader->setUrl(tileUrl(), TileLoader::BoundingBox);
|
||||
_bounds = RectD(_wms->bbox(), _wms->projection());
|
||||
computeZooms();
|
||||
updateTransform();
|
||||
|
@ -31,7 +31,7 @@ WMTSMap::WMTSMap(const QString &fileName, const QString &name,
|
||||
|
||||
void WMTSMap::init()
|
||||
{
|
||||
_tileLoader->setUrl(_wmts->tileUrl());
|
||||
_tileLoader->setUrl(_wmts->tileUrl(), TileLoader::XYZ);
|
||||
_bounds = RectD(_wmts->bbox(), _wmts->projection());
|
||||
updateTransform();
|
||||
}
|
||||
|
Reference in New Issue
Block a user