1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2025-07-23 23:24:24 +02:00

Compare commits

...

7 Commits

Author SHA1 Message Date
829d85a70a Optimize TextCodec initialization
QTextCodec initialization is very slow due to it's broken caching in Qt when
ICU is enabled. Make TetCodec initialize fast anyway as it may be used very
often in IMG maps (every LBL subfile has it's own codec!).
2023-12-21 01:31:44 +01:00
e05c2e0383 Version++ 2023-12-21 01:15:12 +01:00
bff27df10c Fixed race conditions on local static data 2023-12-21 01:13:36 +01:00
11ac5da640 Increase the default pixmap cache size on Android to 384MB
We need at least 4 * 4096x4096x4 for overzoomed vector tiles + additional
memory for remaining pixmaps (GUI icons, ...)
2023-12-18 21:18:50 +01:00
112dc59cf2 Fixed broken map scale (ruler) on HiDPI maps 2023-12-18 20:35:55 +01:00
aa892f6c3f Limit the overzoom by the resulting tile size rather than number of levels
Huge sizes may cause broken rendering and cache ping-pong. Do not allow
resulting tile sizes > 4096x4096px.
2023-12-18 20:32:00 +01:00
4e1b696869 Version++ 2023-12-18 20:27:10 +01:00
28 changed files with 229 additions and 218 deletions

View File

@ -1,4 +1,4 @@
version: 13.12.{build}
version: 13.14.{build}
configuration:
- Release

View File

@ -3,7 +3,7 @@ unix:!macx:!android {
} else {
TARGET = GPXSee
}
VERSION = 13.12
VERSION = 13.14
QT += core \
@ -134,6 +134,7 @@ HEADERS += src/common/config.h \
src/map/encjob.h \
src/map/encmap.h \
src/map/ENC/iso8211.h \
src/map/encstyle.h \
src/map/gemfmap.h \
src/map/gmifile.h \
src/map/oruxmap.h \
@ -349,6 +350,7 @@ SOURCES += src/main.cpp \
src/map/encatlas.cpp \
src/map/encmap.cpp \
src/map/ENC/iso8211.cpp \
src/map/encstyle.cpp \
src/map/gemfmap.cpp \
src/map/gmifile.cpp \
src/map/oruxmap.cpp \

View File

@ -37,7 +37,7 @@ Unicode true
; The name of the installer
Name "GPXSee"
; Program version
!define VERSION "13.12"
!define VERSION "13.14"
; The file to write
OutFile "GPXSee-${VERSION}_x64.exe"

View File

@ -33,7 +33,7 @@
: QPageSize::PageSizeId::A4)
#ifdef Q_OS_ANDROID
#define PIXMAP_CACHE 256
#define PIXMAP_CACHE 384
#define DEM_CACHE 128
#else // Q_OS_ANDROID
#define PIXMAP_CACHE 512

View File

@ -1,56 +1,48 @@
#include <QTextCodec>
#include "textcodec.h"
TextCodec::TextCodec()
/* When Qt is compiled with ICU support, QTextCodec::codecForName() is very
slow due to broken codec name caching (the function does dozens of
comparisons and only then asks the cache...), so we use our own map. */
static QMap<int, QTextCodec *> initCodecs()
{
_codec = QTextCodec::codecForName("Windows-1252");
QMap<int, QTextCodec *> map;
map.insert(65001, 0);
map.insert(874, QTextCodec::codecForName("Windows-874"));
map.insert(932, QTextCodec::codecForName("Shift-JIS"));
map.insert(936, QTextCodec::codecForName("GB18030"));
map.insert(949, QTextCodec::codecForName("EUC-KR"));
map.insert(950, QTextCodec::codecForName("Big5"));
map.insert(1250, QTextCodec::codecForName("Windows-1250"));
map.insert(1251, QTextCodec::codecForName("Windows-1251"));
map.insert(1252, QTextCodec::codecForName("Windows-1252"));
map.insert(1253, QTextCodec::codecForName("Windows-1253"));
map.insert(1254, QTextCodec::codecForName("Windows-1254"));
map.insert(1255, QTextCodec::codecForName("Windows-1255"));
map.insert(1256, QTextCodec::codecForName("Windows-1256"));
map.insert(1257, QTextCodec::codecForName("Windows-1257"));
map.insert(1258, QTextCodec::codecForName("Windows-1258"));
return map;
}
const QMap<int, QTextCodec *> &TextCodec::codecs()
{
static QMap<int, QTextCodec *> map = initCodecs();
return map;
}
TextCodec::TextCodec(int codepage)
{
switch (codepage) {
case 65001:
_codec = 0;
break;
case 932:
_codec = QTextCodec::codecForName("Shift-JIS");
break;
case 936:
_codec = QTextCodec::codecForName("GB18030");
break;
case 949:
_codec = QTextCodec::codecForName("EUC-KR");
break;
case 950:
_codec = QTextCodec::codecForName("Big5");
break;
case 1250:
_codec = QTextCodec::codecForName("Windows-1250");
break;
case 1251:
_codec = QTextCodec::codecForName("Windows-1251");
break;
case 1253:
_codec = QTextCodec::codecForName("Windows-1253");
break;
case 1254:
_codec = QTextCodec::codecForName("Windows-1254");
break;
case 1255:
_codec = QTextCodec::codecForName("Windows-1255");
break;
case 1256:
_codec = QTextCodec::codecForName("Windows-1256");
break;
case 1257:
_codec = QTextCodec::codecForName("Windows-1257");
break;
case 1258:
_codec = QTextCodec::codecForName("Windows-1258");
break;
default:
_codec = QTextCodec::codecForName("Windows-1252");
}
const QMap<int, QTextCodec *> &map = codecs();
QMap<int, QTextCodec *>::const_iterator it(map.find(codepage));
if (it == map.cend()) {
qWarning("%d: Unsupported codepage, using UTF-8", codepage);
_codec = 0;
} else
_codec = *it;
}
QString TextCodec::toString(const QByteArray &ba) const

View File

@ -2,19 +2,22 @@
#define TEXTCODEC_H
#include <QString>
#include <QMap>
class QTextCodec;
class TextCodec
{
public:
TextCodec();
TextCodec() : _codec(0) {}
TextCodec(int codepage);
QString toString(const QByteArray &ba) const;
private:
QTextCodec *_codec;
static const QMap<int, QTextCodec *> &codecs();
};
#endif // TEXTCODEC_H

View File

@ -128,7 +128,7 @@ qint64 CryptDevice::readData(char *data, qint64 maxSize)
class DataStream : public QDataStream
{
public:
DataStream(QIODevice *d) : QDataStream(d) {}
DataStream(QIODevice *d) : QDataStream(d), _codec(1252) {}
void setCodepage(quint16 codepage) {_codec = TextCodec(codepage);}

View File

@ -75,7 +75,7 @@ bool TwoNavParser::parse(QFile *file, QList<TrackData> &tracks,
QVector<Waypoint> &waypoints)
{
Q_UNUSED(polygons);
TextCodec codec;
TextCodec codec(1252);
GCS gcs;
bool ok, route = false, track = false, waypoint = false;

View File

@ -17,51 +17,6 @@ typedef QSet<Coordinates> PointSet;
static const float C1 = 0.866025f; /* sqrt(3)/2 */
static const QColor haloColor(Qt::white);
static QFont pixelSizeFont(int pixelSize)
{
QFont f;
f.setPixelSize(pixelSize);
return f;
}
static QFont *font(Style::FontSize size)
{
/* The fonts must be initialized on first usage (after the QGuiApplication
instance is created) */
static QFont large = pixelSizeFont(16);
static QFont normal = pixelSizeFont(12);
static QFont small = pixelSizeFont(10);
switch (size) {
case Style::None:
return 0;
case Style::Large:
return &large;
case Style::Small:
return &small;
default:
return &normal;
}
}
static const QImage *light()
{
static QImage img(":/marine/light.png");
return &img;
}
static const QImage *signal()
{
static QImage img(":/marine/fog-signal.png");
return &img;
}
static const Style& style()
{
static Style s;
return s;
}
static double area(const QVector<Coordinates> &polygon)
{
double area = 0;
@ -223,14 +178,12 @@ void RasterTile::drawArrows(QPainter *painter,
void RasterTile::drawPolygons(QPainter *painter,
const QList<MapData::Poly> &polygons)
{
const Style &s = style();
for (int n = 0; n < s.drawOrder().size(); n++) {
for (int n = 0; n < _style->drawOrder().size(); n++) {
for (int i = 0; i < polygons.size(); i++) {
const MapData::Poly &poly = polygons.at(i);
if (poly.type() != s.drawOrder().at(n))
if (poly.type() != _style->drawOrder().at(n))
continue;
const Style::Polygon &style = s.polygon(poly.type());
const Style::Polygon &style = _style->polygon(poly.type());
if (!style.img().isNull()) {
for (int i = 0; i < poly.path().size(); i++)
@ -257,13 +210,11 @@ void RasterTile::drawPolygons(QPainter *painter,
void RasterTile::drawLines(QPainter *painter, const QList<MapData::Line> &lines)
{
const Style &s = style();
painter->setBrush(Qt::NoBrush);
for (int i = 0; i < lines.size(); i++) {
const MapData::Line &line = lines.at(i);
const Style::Line &style = s.line(line.type());
const Style::Line &style = _style->line(line.type());
if (!style.img().isNull()) {
BitmapLine::draw(painter, polyline(line.path()), style.img());
@ -284,8 +235,6 @@ void RasterTile::drawTextItems(QPainter *painter,
void RasterTile::processPolygons(const QList<MapData::Poly> &polygons,
QList<TextItem*> &textItems)
{
const Style &s = style();
for (int i = 0; i < polygons.size(); i++) {
const MapData::Poly &poly = polygons.at(i);
uint type = poly.type()>>16;
@ -293,7 +242,7 @@ void RasterTile::processPolygons(const QList<MapData::Poly> &polygons,
if (!(type == HRBFAC || type == I_TRNBSN
|| poly.type() == SUBTYPE(I_BERTHS, 6)))
continue;
const Style::Point &style = s.point(poly.type());
const Style::Point &style = _style->point(poly.type());
const QImage *img = style.img().isNull() ? 0 : &style.img();
if (!img)
continue;
@ -311,7 +260,6 @@ void RasterTile::processPolygons(const QList<MapData::Poly> &polygons,
void RasterTile::processPoints(QList<MapData::Point> &points,
QList<TextItem*> &textItems, QList<TextItem*> &lights)
{
const Style &s = style();
PointSet lightsSet, signalsSet;
int i;
@ -332,12 +280,12 @@ void RasterTile::processPoints(QList<MapData::Point> &points,
for ( ; i < points.size(); i++) {
const MapData::Point &point = points.at(i);
QPoint pos(ll2xy(point.pos()).toPoint());
const Style::Point &style = s.point(point.type());
const Style::Point &style = _style->point(point.type());
const QString *label = point.label().isEmpty() ? 0 : &(point.label());
const QImage *img = style.img().isNull() ? 0 : &style.img();
const QFont *fnt = showLabel(img, _zoomRange, _zoom, point.type())
? font(style.textFontSize()) : 0;
? _style->font(style.textFontSize()) : 0;
const QColor *color = &style.textColor();
const QColor *hColor = style.haloColor().isValid()
? &style.haloColor() : 0;
@ -351,9 +299,11 @@ void RasterTile::processPoints(QList<MapData::Point> &points,
if (item->isValid() && !item->collides(textItems)) {
textItems.append(item);
if (lightsSet.contains(point.pos()))
lights.append(new TextPointItem(pos, 0, 0, light(), 0, 0, 0, 0));
lights.append(new TextPointItem(pos, 0, 0, _style->light(), 0,
0, 0, 0));
if (signalsSet.contains(point.pos()))
lights.append(new TextPointItem(pos, 0, 0, signal(), 0, 0, 0, 0));
lights.append(new TextPointItem(pos, 0, 0, _style->signal(), 0,
0, 0, 0));
} else
delete item;
}
@ -362,18 +312,16 @@ void RasterTile::processPoints(QList<MapData::Point> &points,
void RasterTile::processLines(const QList<MapData::Line> &lines,
QList<TextItem*> &textItems)
{
const Style &s = style();
for (int i = 0; i < lines.size(); i++) {
const MapData::Line &line = lines.at(i);
const Style::Line &style = s.line(line.type());
const Style::Line &style = _style->line(line.type());
if (style.img().isNull() && style.pen() == Qt::NoPen)
continue;
if (line.label().isEmpty() || style.textFontSize() == Style::None)
continue;
const QFont *fnt = font(style.textFontSize());
const QFont *fnt = _style->font(style.textFontSize());
const QColor *color = &style.textColor();
TextPathItem *item = new TextPathItem(polyline(line.path()),

View File

@ -7,6 +7,7 @@
#include "map/transform.h"
#include "map/textpointitem.h"
#include "mapdata.h"
#include "style.h"
#include "atlasdata.h"
class TextItem;
@ -17,15 +18,17 @@ class RasterTile
{
public:
RasterTile(const Projection &proj, const Transform &transform,
const MapData *data, int zoom, const Range &zoomRange, const QRect &rect,
qreal ratio) : _proj(proj), _transform(transform), _map(data), _atlas(0),
_zoom(zoom), _zoomRange(zoomRange), _rect(rect), _ratio(ratio),
_pixmap(rect.width() * ratio, rect.height() * ratio), _valid(false) {}
const Style *style, const MapData *data, int zoom, const Range &zoomRange,
const QRect &rect, qreal ratio) : _proj(proj), _transform(transform),
_style(style), _map(data), _atlas(0), _zoom(zoom), _zoomRange(zoomRange),
_rect(rect), _ratio(ratio), _pixmap(rect.width() * ratio, rect.height()
* ratio), _valid(false) {}
RasterTile(const Projection &proj, const Transform &transform,
AtlasData *data, int zoom, const Range &zoomRange, const QRect &rect,
qreal ratio) : _proj(proj), _transform(transform), _map(0), _atlas(data),
_zoom(zoom), _zoomRange(zoomRange), _rect(rect), _ratio(ratio),
_pixmap(rect.width() * ratio, rect.height() * ratio), _valid(false) {}
const Style *style, AtlasData *data, int zoom, const Range &zoomRange,
const QRect &rect, qreal ratio) : _proj(proj), _transform(transform),
_style(style), _map(0), _atlas(data), _zoom(zoom), _zoomRange(zoomRange),
_rect(rect), _ratio(ratio), _pixmap(rect.width() * ratio, rect.height()
* ratio), _valid(false) {}
int zoom() const {return _zoom;}
QPoint xy() const {return _rect.topLeft();}
@ -61,6 +64,7 @@ private:
Projection _proj;
Transform _transform;
const Style *_style;
const MapData *_map;
AtlasData *_atlas;
int _zoom;

View File

@ -14,6 +14,13 @@ static QImage railroad()
return img;
}
static QFont pixelSizeFont(int pixelSize)
{
QFont f;
f.setPixelSize(pixelSize);
return f;
}
void Style::polygonStyle()
{
_polygons[TYPE(M_COVR)] = Polygon(QBrush("#ffffff"));
@ -321,6 +328,13 @@ void Style::pointStyle()
Style::Style()
{
_light = QImage(":/marine/light.png");
_signal = QImage(":/marine/fog-signal.png");
_large = pixelSizeFont(16);
_normal = pixelSizeFont(12);
_small = pixelSizeFont(10);
polygonStyle();
lineStyle();
pointStyle();
@ -349,3 +363,17 @@ const Style::Point &Style::point(uint type) const
QMap<uint, Point>::const_iterator it = _points.find(type);
return (it == _points.constEnd()) ? null : *it;
}
const QFont *Style::font(Style::FontSize size) const
{
switch (size) {
case Style::None:
return 0;
case Style::Large:
return &_large;
case Style::Small:
return &_small;
default:
return &_normal;
}
}

View File

@ -3,6 +3,7 @@
#include <QPen>
#include <QBrush>
#include <QFont>
#include <QMap>
#include "objects.h"
@ -96,6 +97,10 @@ public:
const Point &point(uint type) const;
const QVector<uint> &drawOrder() const {return _drawOrder;}
const QFont *font(Style::FontSize size) const;
const QImage *light() const {return &_light;}
const QImage *signal() const {return &_signal;}
private:
void polygonStyle();
void lineStyle();
@ -105,6 +110,9 @@ private:
QMap<uint, Polygon> _polygons;
QMap<uint, Point> _points;
QVector<uint> _drawOrder;
QFont _small, _normal, _large;
QImage _light, _signal;
};
}

View File

@ -16,14 +16,14 @@ class LBLFile : public SubFile
{
public:
LBLFile(const IMGData *img)
: SubFile(img), _huffmanText(0), _table(0), _rasters(0), _imgIdSize(0),
_poiShift(0), _shift(0), _encoding(0) {}
: SubFile(img), _huffmanText(0), _table(0), _rasters(0), _codec(1252),
_imgIdSize(0), _poiShift(0), _shift(0), _encoding(0) {}
LBLFile(const QString *path)
: SubFile(path), _huffmanText(0), _table(0), _rasters(0), _imgIdSize(0),
_poiShift(0), _shift(0), _encoding(0) {}
: SubFile(path), _huffmanText(0), _table(0), _rasters(0), _codec(1252),
_imgIdSize(0), _poiShift(0), _shift(0), _encoding(0) {}
LBLFile(const SubFile *gmp, quint32 offset)
: SubFile(gmp, offset), _huffmanText(0), _table(0), _rasters(0),
_imgIdSize(0), _poiShift(0), _shift(0), _encoding(0) {}
_codec(1252), _imgIdSize(0), _poiShift(0), _shift(0), _encoding(0) {}
~LBLFile();
bool load(Handle &hdl, const RGNFile *rgn, Handle &rgnHdl);

View File

@ -28,57 +28,6 @@ static const QColor shieldBgColor1("#dd3e3e");
static const QColor shieldBgColor2("#379947");
static const QColor shieldBgColor3("#4a7fc1");
static QFont pixelSizeFont(int pixelSize)
{
QFont f;
f.setPixelSize(pixelSize);
return f;
}
static QFont *font(Style::FontSize size, Style::FontSize defaultSize
= Style::Normal)
{
/* The fonts must be initialized on first usage (after the QGuiApplication
instance is created) */
static QFont large = pixelSizeFont(16);
static QFont normal = pixelSizeFont(14);
static QFont small = pixelSizeFont(12);
static QFont extraSmall = pixelSizeFont(10);
switch (size) {
case Style::None:
return 0;
case Style::Large:
return &large;
case Style::Normal:
return &normal;
case Style::Small:
return &small;
case Style::ExtraSmall:
return &extraSmall;
default:
return font(defaultSize);
}
}
static QFont *poiFont(Style::FontSize size = Style::Normal, int zoom = -1,
bool extended = false)
{
static QFont poi = pixelSizeFont(10);
if (zoom > 25)
size = Style::Normal;
else if (extended)
size = Style::None;
switch (size) {
case Style::None:
return 0;
default:
return &poi;
}
}
static const QColor *shieldBgColor(Shield::Type type)
{
switch (type) {
@ -152,6 +101,21 @@ static bool rectNearPolygon(const QPolygonF &polygon, const QRectF &rect)
|| polygon.containsPoint(rect.bottomRight(), Qt::OddEvenFill)));
}
const QFont *RasterTile::poiFont(Style::FontSize size, int zoom, bool extended)
{
if (zoom > 25)
size = Style::Normal;
else if (extended)
size = Style::None;
switch (size) {
case Style::None:
return 0;
default:
return _data->style()->font(Style::ExtraSmall);
}
}
void RasterTile::ll2xy(QList<MapData::Poly> &polys)
{
for (int i = 0; i < polys.size(); i++) {
@ -324,7 +288,8 @@ void RasterTile::processStreetNames(const QList<MapData::Poly> &lines,
if (style.img().isNull() && style.foreground() == Qt::NoPen)
continue;
const QFont *fnt = font(style.textFontSize(), Style::Small);
const QFont *fnt = _data->style()->font(style.textFontSize(),
Style::Small);
const QColor *color = style.textColor().isValid()
? &style.textColor() : 0;
const QColor *hColor = Style::isContourLine(poly.type) ? 0 : &haloColor;
@ -435,7 +400,7 @@ void RasterTile::processPoints(QList<MapData::Point> &points,
const QImage *img = style.img().isNull() ? 0 : &style.img();
const QFont *fnt = poi
? poiFont(style.textFontSize(), _zoom, point.classLabel)
: font(style.textFontSize());
: _data->style()->font(style.textFontSize());
const QColor *color = style.textColor().isValid()
? &style.textColor() : &textColor;
const QColor *hcolor = Style::isDepthPoint(point.type)

View File

@ -5,6 +5,7 @@
#include "mapdata.h"
#include "map/projection.h"
#include "map/transform.h"
#include "style.h"
class QPainter;
class IMGMap;
@ -12,8 +13,6 @@ class TextItem;
namespace IMG {
class Style;
class RasterTile
{
public:
@ -53,6 +52,9 @@ private:
void processStreetNames(const QList<MapData::Poly> &lines,
QList<TextItem*> &textItems, const QImage (&arrows)[2]);
const QFont *poiFont(Style::FontSize size = Style::Normal,
int zoom = -1, bool extended = false);
Projection _proj;
Transform _transform;
MapData *_data;

View File

@ -4,6 +4,13 @@
using namespace IMG;
static QFont pixelSizeFont(int pixelSize)
{
QFont f;
f.setPixelSize(pixelSize);
return f;
}
static bool readColor(SubFile *file, SubFile::Handle &hdl, QColor &color)
{
quint8 b, g, r;
@ -1226,6 +1233,11 @@ bool Style::parseTYPFile(SubFile *file)
Style::Style(SubFile *typ)
{
_large = pixelSizeFont(16);
_normal = pixelSizeFont(14);
_small = pixelSizeFont(12);
_extraSmall = pixelSizeFont(10);
defaultLineStyle();
defaultPolygonStyle();
defaultPointStyle();
@ -1258,6 +1270,24 @@ const Style::Point &Style::point(quint32 type) const
return (it == _points.constEnd()) ? null : *it;
}
const QFont *Style::font(Style::FontSize size, Style::FontSize defaultSize) const
{
switch (size) {
case Style::None:
return 0;
case Style::Large:
return &_large;
case Style::Normal:
return &_normal;
case Style::Small:
return &_small;
case Style::ExtraSmall:
return &_extraSmall;
default:
return font(defaultSize);
}
}
#ifndef QT_NO_DEBUG
static QString penColor(const QPen &pen)
{

View File

@ -3,6 +3,7 @@
#include <QPen>
#include <QBrush>
#include <QFont>
#include <QDebug>
#include "subfile.h"
@ -94,6 +95,8 @@ public:
const Polygon &polygon(quint32 type) const;
const Point &point(quint32 type) const;
const QList<quint32> &drawOrder() const {return _drawOrder;}
const QFont *font(Style::FontSize size, Style::FontSize defaultSize
= Style::Normal) const;
static bool isPOI(quint32 type)
{return !((type >= TYPE(0x01) && type <= TYPE(0x1f))
@ -172,6 +175,8 @@ private:
QMap<quint32, Polygon> _polygons;
QMap<quint32, Point> _points;
QList<quint32> _drawOrder;
QFont _large, _normal, _small, _extraSmall;
};
}

View File

@ -295,7 +295,7 @@ int AQMMap::zoomFit(const QSize &size, const RectC &rect)
qreal AQMMap::resolution(const QRectF &rect)
{
const Zoom &z = _zooms.at(_zoom);
return OSM::resolution(rect.center(), z.zoom, z.tileSize);
return OSM::resolution(rect.center(), z.zoom, tileSize());
}
int AQMMap::zoomIn()

View File

@ -5,6 +5,7 @@
#include "rectd.h"
#include "pcs.h"
#include "encjob.h"
#include "encstyle.h"
#include "encatlas.h"
using namespace ENC;
@ -357,7 +358,7 @@ void ENCAtlas::draw(QPainter *painter, const QRectF &rect, Flags flags)
painter->drawPixmap(ttl, pm);
else
tiles.append(RasterTile(_projection, _transform,
_data.value(_usage), _zoom, zooms(_usage),
ENCStyle::style(), _data.value(_usage), _zoom, zooms(_usage),
QRect(ttl, QSize(TILE_SIZE, TILE_SIZE)), _tileRatio));
}
}

View File

@ -5,6 +5,7 @@
#include "rectd.h"
#include "pcs.h"
#include "encjob.h"
#include "encstyle.h"
#include "encmap.h"
@ -323,9 +324,9 @@ void ENCMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
if (QPixmapCache::find(key(_zoom, ttl), &pm))
painter->drawPixmap(ttl, pm);
else
tiles.append(RasterTile(_projection, _transform, _data,
_zoom, _zooms, QRect(ttl, QSize(TILE_SIZE, TILE_SIZE)),
_tileRatio));
tiles.append(RasterTile(_projection, _transform,
ENCStyle::style(), _data, _zoom, _zooms,
QRect(ttl, QSize(TILE_SIZE, TILE_SIZE)), _tileRatio));
}
}

7
src/map/encstyle.cpp Normal file
View File

@ -0,0 +1,7 @@
#include "encstyle.h"
const ENC::Style *ENCStyle::style()
{
static ENC::Style s;
return &s;
}

12
src/map/encstyle.h Normal file
View File

@ -0,0 +1,12 @@
#ifndef ENCSTYLE_H
#define ENCSTYLE_H
#include "ENC/style.h"
class ENCStyle
{
public:
static const ENC::Style *style();
};
#endif // ENCSTYLE_H

View File

@ -128,7 +128,7 @@ GEMFMap::GEMFMap(const QString &fileName, QObject *parent)
qreal GEMFMap::resolution(const QRectF &rect)
{
return OSM::resolution(rect.center(), _zooms.at(_zi).level, _tileSize);
return OSM::resolution(rect.center(), _zooms.at(_zi).level, tileSize());
}
int GEMFMap::zoomFit(const QSize &size, const RectC &rect)

View File

@ -9,7 +9,7 @@
#include "osm.h"
#include "mbtilesmap.h"
#define MAX_OVERZOOM 3
#define MAX_TILE_SIZE 4096
#define META_TYPE(type) static_cast<QMetaType::Type>(type)
static RectC str2bounds(const QString &str)
@ -79,24 +79,15 @@ bool MBTilesMap::getZooms()
" WHERE zoom_level = %1 LIMIT 1").arg(i);
QSqlQuery query(sql, _db);
if (query.first())
_zooms.append(Zoom(i, i));
_zoomsBase.append(Zoom(i, i));
}
if (!_zooms.size()) {
if (!_zoomsBase.size()) {
_errorString = "Empty tile set";
return false;
}
if (_scalable) {
for (int i = _zooms.last().base + 1; i <= OSM::ZOOMS.max(); i++) {
Zoom z(i, _zooms.last().base);
if (z.z - z.base > MAX_OVERZOOM)
break;
_zooms.append(Zoom(i, _zooms.last().base));
}
}
_zi = _zooms.size() - 1;
_zi = _zoomsBase.size() - 1;
return true;
}
@ -114,7 +105,7 @@ bool MBTilesMap::getBounds()
} else {
qWarning("%s: missing bounds metadata", qPrintable(path()));
int z = _zooms.first().z;
int z = _zoomsBase.first().z;
QString sql = QString("SELECT min(tile_column), min(tile_row), "
"max(tile_column), max(tile_row) FROM tiles WHERE zoom_level = %1")
.arg(z);
@ -222,12 +213,12 @@ MBTilesMap::MBTilesMap(const QString &fileName, QObject *parent)
}
getTileFormat();
if (!getTileSize())
return;
if (!getZooms())
return;
if (!getBounds())
return;
if (!getTileSize())
return;
getTilePixelRatio();
getName();
@ -243,10 +234,18 @@ void MBTilesMap::load(const Projection &in, const Projection &out,
Q_UNUSED(out);
_mapRatio = hidpi ? deviceRatio : 1.0;
_zooms = _zoomsBase;
if (_scalable) {
_scaledSize = _tileSize * deviceRatio;
_tileRatio = deviceRatio;
for (int i = _zooms.last().base + 1; i <= OSM::ZOOMS.max(); i++) {
Zoom z(i, _zooms.last().base);
if (_tileSize * _tileRatio * (1U<<(z.z - z.base)) > MAX_TILE_SIZE)
break;
_zooms.append(Zoom(i, _zooms.last().base));
}
}
_db.open();
@ -286,7 +285,7 @@ int MBTilesMap::zoomFit(const QSize &size, const RectC &rect)
qreal MBTilesMap::resolution(const QRectF &rect)
{
return OSM::resolution(rect.center(), _zooms.at(_zi).z, _tileSize);
return OSM::resolution(rect.center(), _zooms.at(_zi).z, tileSize());
}
int MBTilesMap::zoomIn()

View File

@ -146,7 +146,7 @@ private:
QString _name;
RectC _bounds;
QVector<Zoom> _zooms;
QVector<Zoom> _zooms, _zoomsBase;
int _zi;
int _tileSize;
qreal _mapRatio, _tileRatio;

View File

@ -8,7 +8,7 @@
#include "onlinemap.h"
#define MAX_OVERZOOM 3
#define MAX_TILE_SIZE 4096
OnlineMap::OnlineMap(const QString &fileName, const QString &name,
const QString &url, const Range &zooms, const RectC &bounds, qreal tileRatio,
@ -24,10 +24,7 @@ OnlineMap::OnlineMap(const QString &fileName, const QString &name,
_tileLoader->setHeaders(headers);
connect(_tileLoader, &TileLoader::finished, this, &OnlineMap::tilesLoaded);
if (_scalable) {
_baseZoom = _zooms.max();
_zooms.setMax(qMin(_zooms.max() + MAX_OVERZOOM, OSM::ZOOMS.max()));
}
_baseZoom = _zooms.max();
}
QRectF OnlineMap::bounds()
@ -61,7 +58,7 @@ int OnlineMap::zoomFit(const QSize &size, const RectC &rect)
qreal OnlineMap::resolution(const QRectF &rect)
{
return OSM::resolution(rect.center(), _zoom, _tileSize);
return OSM::resolution(rect.center(), _zoom, tileSize());
}
int OnlineMap::zoomIn()
@ -87,10 +84,17 @@ void OnlineMap::load(const Projection &in, const Projection &out,
Q_UNUSED(out);
_mapRatio = hidpi ? deviceRatio : 1.0;
_zooms.setMax(_baseZoom);
if (_scalable) {
_scaledSize = _tileSize * deviceRatio;
_tileRatio = deviceRatio;
for (int i = _baseZoom + 1; i <= OSM::ZOOMS.max(); i++) {
if (_tileSize * _tileRatio * (1U<<(i - _baseZoom)) > MAX_TILE_SIZE)
break;
_zooms.setMax(i);
}
}
}
@ -168,7 +172,7 @@ void OnlineMap::cancelJobs(bool wait)
void OnlineMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
{
int baseZoom = _scalable ? qMin(_baseZoom, _zoom) : _zoom;
int baseZoom = qMin(_baseZoom, _zoom);
unsigned overzoom = _zoom - baseZoom;
unsigned f = 1U<<overzoom;

View File

@ -198,7 +198,7 @@ int OsmdroidMap::zoomFit(const QSize &size, const RectC &rect)
qreal OsmdroidMap::resolution(const QRectF &rect)
{
return OSM::resolution(rect.center(), _zoom, _tileSize);
return OSM::resolution(rect.center(), _zoom, tileSize());
}
int OsmdroidMap::zoomIn()

View File

@ -146,7 +146,7 @@ int SqliteMap::zoomFit(const QSize &size, const RectC &rect)
qreal SqliteMap::resolution(const QRectF &rect)
{
return OSM::resolution(rect.center(), _zoom, _tileSize);
return OSM::resolution(rect.center(), _zoom, tileSize());
}
int SqliteMap::zoomIn()