mirror of
https://github.com/tumic0/GPXSee.git
synced 2025-01-19 04:02:09 +01:00
Do not do any time consuming actions in the mapview redraw callback
On all vector maps (ENC, IMG and Mapsforge), do the data loading asynchronous like the tile rendering.
This commit is contained in:
parent
4615709b99
commit
a92d6efec6
@ -893,7 +893,7 @@ void MapData::clear()
|
|||||||
_points.RemoveAll();
|
_points.RemoveAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapData::points(const RectC &rect, QList<Point*> *points)
|
void MapData::points(const RectC &rect, QList<Point*> *points) const
|
||||||
{
|
{
|
||||||
double min[2], max[2];
|
double min[2], max[2];
|
||||||
|
|
||||||
@ -901,7 +901,7 @@ void MapData::points(const RectC &rect, QList<Point*> *points)
|
|||||||
_points.Search(min, max, pointCb, points);
|
_points.Search(min, max, pointCb, points);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapData::lines(const RectC &rect, QList<Line*> *lines)
|
void MapData::lines(const RectC &rect, QList<Line*> *lines) const
|
||||||
{
|
{
|
||||||
double min[2], max[2];
|
double min[2], max[2];
|
||||||
|
|
||||||
@ -909,7 +909,7 @@ void MapData::lines(const RectC &rect, QList<Line*> *lines)
|
|||||||
_lines.Search(min, max, lineCb, lines);
|
_lines.Search(min, max, lineCb, lines);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapData::polygons(const RectC &rect, QList<Poly*> *polygons)
|
void MapData::polygons(const RectC &rect, QList<Poly*> *polygons) const
|
||||||
{
|
{
|
||||||
double min[2], max[2];
|
double min[2], max[2];
|
||||||
|
|
||||||
|
@ -72,9 +72,9 @@ public:
|
|||||||
RectC bounds() const {return _bounds;}
|
RectC bounds() const {return _bounds;}
|
||||||
Range zooms() const;
|
Range zooms() const;
|
||||||
|
|
||||||
void polygons(const RectC &rect, QList<Poly*> *polygons);
|
void polygons(const RectC &rect, QList<Poly*> *polygons) const;
|
||||||
void lines(const RectC &rect, QList<Line*> *lines);
|
void lines(const RectC &rect, QList<Line*> *lines) const;
|
||||||
void points(const RectC &rect, QList<Point*> *points);
|
void points(const RectC &rect, QList<Point*> *points) const;
|
||||||
|
|
||||||
void load();
|
void load();
|
||||||
void clear();
|
void clear();
|
||||||
|
@ -3,11 +3,14 @@
|
|||||||
#include "common/linec.h"
|
#include "common/linec.h"
|
||||||
#include "map/bitmapline.h"
|
#include "map/bitmapline.h"
|
||||||
#include "map/textpathitem.h"
|
#include "map/textpathitem.h"
|
||||||
|
#include "map/rectd.h"
|
||||||
#include "style.h"
|
#include "style.h"
|
||||||
#include "rastertile.h"
|
#include "rastertile.h"
|
||||||
|
|
||||||
using namespace ENC;
|
using namespace ENC;
|
||||||
|
|
||||||
|
#define TEXT_EXTENT 160
|
||||||
|
|
||||||
#define TSSLPT_SIZE 0.005 /* ll */
|
#define TSSLPT_SIZE 0.005 /* ll */
|
||||||
#define RDOCAL_SIZE 12 /* px */
|
#define RDOCAL_SIZE 12 /* px */
|
||||||
#define CURENT_SIZE 12 /* px */
|
#define CURENT_SIZE 12 /* px */
|
||||||
@ -227,10 +230,11 @@ QPolygonF RasterTile::tsslptArrow(const Coordinates &c, qreal angle) const
|
|||||||
return polygon;
|
return polygon;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterTile::drawArrows(QPainter *painter)
|
void RasterTile::drawArrows(QPainter *painter,
|
||||||
|
const QList<MapData::Poly*> &polygons)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < _polygons.size(); i++) {
|
for (int i = 0; i < polygons.size(); i++) {
|
||||||
const MapData::Poly *poly = _polygons.at(i);
|
const MapData::Poly *poly = polygons.at(i);
|
||||||
|
|
||||||
if (poly->type()>>16 == TSSLPT) {
|
if (poly->type()>>16 == TSSLPT) {
|
||||||
QPolygonF polygon(tsslptArrow(centroid(poly->path().first()),
|
QPolygonF polygon(tsslptArrow(centroid(poly->path().first()),
|
||||||
@ -243,13 +247,14 @@ void RasterTile::drawArrows(QPainter *painter)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterTile::drawPolygons(QPainter *painter)
|
void RasterTile::drawPolygons(QPainter *painter,
|
||||||
|
const QList<MapData::Poly*> &polygons)
|
||||||
{
|
{
|
||||||
const Style &s = style();
|
const Style &s = style();
|
||||||
|
|
||||||
for (int n = 0; n < s.drawOrder().size(); n++) {
|
for (int n = 0; n < s.drawOrder().size(); n++) {
|
||||||
for (int i = 0; i < _polygons.size(); i++) {
|
for (int i = 0; i < polygons.size(); i++) {
|
||||||
const MapData::Poly *poly = _polygons.at(i);
|
const MapData::Poly *poly = polygons.at(i);
|
||||||
if (poly->type() != s.drawOrder().at(n))
|
if (poly->type() != s.drawOrder().at(n))
|
||||||
continue;
|
continue;
|
||||||
const Style::Polygon &style = s.polygon(poly->type());
|
const Style::Polygon &style = s.polygon(poly->type());
|
||||||
@ -267,14 +272,14 @@ void RasterTile::drawPolygons(QPainter *painter)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterTile::drawLines(QPainter *painter)
|
void RasterTile::drawLines(QPainter *painter, const QList<MapData::Line*> &lines)
|
||||||
{
|
{
|
||||||
const Style &s = style();
|
const Style &s = style();
|
||||||
|
|
||||||
painter->setBrush(Qt::NoBrush);
|
painter->setBrush(Qt::NoBrush);
|
||||||
|
|
||||||
for (int i = 0; i < _lines.size(); i++) {
|
for (int i = 0; i < lines.size(); i++) {
|
||||||
const MapData::Line *line = _lines.at(i);
|
const MapData::Line *line = lines.at(i);
|
||||||
const Style::Line &style = s.line(line->type());
|
const Style::Line &style = s.line(line->type());
|
||||||
|
|
||||||
if (!style.img().isNull()) {
|
if (!style.img().isNull()) {
|
||||||
@ -293,12 +298,13 @@ void RasterTile::drawTextItems(QPainter *painter,
|
|||||||
textItems.at(i)->paint(painter);
|
textItems.at(i)->paint(painter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterTile::processPolygons(QList<TextItem*> &textItems)
|
void RasterTile::processPolygons(const QList<MapData::Poly*> &polygons,
|
||||||
|
QList<TextItem*> &textItems)
|
||||||
{
|
{
|
||||||
const Style &s = style();
|
const Style &s = style();
|
||||||
|
|
||||||
for (int i = 0; i < _polygons.size(); i++) {
|
for (int i = 0; i < polygons.size(); i++) {
|
||||||
const MapData::Poly *poly = _polygons.at(i);
|
const MapData::Poly *poly = polygons.at(i);
|
||||||
uint type = poly->type()>>16;
|
uint type = poly->type()>>16;
|
||||||
|
|
||||||
if (!(type == HRBFAC || type == I_TRNBSN
|
if (!(type == HRBFAC || type == I_TRNBSN
|
||||||
@ -319,18 +325,18 @@ void RasterTile::processPolygons(QList<TextItem*> &textItems)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterTile::processPoints(QList<TextItem*> &textItems,
|
void RasterTile::processPoints(QList<MapData::Point*> &points,
|
||||||
QList<TextItem*> &lights)
|
QList<TextItem*> &textItems, QList<TextItem*> &lights)
|
||||||
{
|
{
|
||||||
const Style &s = style();
|
const Style &s = style();
|
||||||
PointMap lightsMap, signalsMap;
|
PointMap lightsMap, signalsMap;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
std::sort(_points.begin(), _points.end(), pointLess);
|
std::sort(points.begin(), points.end(), pointLess);
|
||||||
|
|
||||||
/* Lights & Signals */
|
/* Lights & Signals */
|
||||||
for (i = 0; i < _points.size(); i++) {
|
for (i = 0; i < points.size(); i++) {
|
||||||
const MapData::Point *point = _points.at(i);
|
const MapData::Point *point = points.at(i);
|
||||||
if (point->type()>>16 == LIGHTS)
|
if (point->type()>>16 == LIGHTS)
|
||||||
lightsMap.insert(point->pos(), point);
|
lightsMap.insert(point->pos(), point);
|
||||||
else if (point->type()>>16 == FOGSIG)
|
else if (point->type()>>16 == FOGSIG)
|
||||||
@ -340,8 +346,8 @@ void RasterTile::processPoints(QList<TextItem*> &textItems,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Everything else */
|
/* Everything else */
|
||||||
for ( ; i < _points.size(); i++) {
|
for ( ; i < points.size(); i++) {
|
||||||
const MapData::Point *point = _points.at(i);
|
const MapData::Point *point = points.at(i);
|
||||||
QPoint pos(ll2xy(point->pos()).toPoint());
|
QPoint pos(ll2xy(point->pos()).toPoint());
|
||||||
const Style::Point &style = s.point(point->type());
|
const Style::Point &style = s.point(point->type());
|
||||||
|
|
||||||
@ -349,7 +355,7 @@ void RasterTile::processPoints(QList<TextItem*> &textItems,
|
|||||||
QImage *rimg = style.img().isNull()
|
QImage *rimg = style.img().isNull()
|
||||||
? image(point->type(), point->param()) : 0;
|
? image(point->type(), point->param()) : 0;
|
||||||
const QImage *img = style.img().isNull() ? rimg : &style.img();
|
const QImage *img = style.img().isNull() ? rimg : &style.img();
|
||||||
const QFont *fnt = showLabel(img, _zooms, _zoom, point->type())
|
const QFont *fnt = showLabel(img, _data->zooms(), _zoom, point->type())
|
||||||
? font(style.textFontSize()) : 0;
|
? font(style.textFontSize()) : 0;
|
||||||
const QColor *color = &style.textColor();
|
const QColor *color = &style.textColor();
|
||||||
const QColor *hColor = style.haloColor().isValid()
|
const QColor *hColor = style.haloColor().isValid()
|
||||||
@ -371,12 +377,13 @@ void RasterTile::processPoints(QList<TextItem*> &textItems,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterTile::processLines(QList<TextItem*> &textItems)
|
void RasterTile::processLines(const QList<MapData::Line*> &lines,
|
||||||
|
QList<TextItem*> &textItems)
|
||||||
{
|
{
|
||||||
const Style &s = style();
|
const Style &s = style();
|
||||||
|
|
||||||
for (int i = 0; i < _lines.size(); i++) {
|
for (int i = 0; i < lines.size(); i++) {
|
||||||
const MapData::Line *line = _lines.at(i);
|
const MapData::Line *line = lines.at(i);
|
||||||
const Style::Line &style = s.line(line->type());
|
const Style::Line &style = s.line(line->type());
|
||||||
|
|
||||||
if (style.img().isNull() && style.pen() == Qt::NoPen)
|
if (style.img().isNull() && style.pen() == Qt::NoPen)
|
||||||
@ -396,25 +403,51 @@ void RasterTile::processLines(QList<TextItem*> &textItems)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RasterTile::fetchData(QList<MapData::Poly*> &polygons,
|
||||||
|
QList<MapData::Line*> &lines, QList<MapData::Point*> &points)
|
||||||
|
{
|
||||||
|
QPoint ttl(_rect.topLeft());
|
||||||
|
|
||||||
|
QRectF polyRect(ttl, QPointF(ttl.x() + _rect.width(), ttl.y()
|
||||||
|
+ _rect.height()));
|
||||||
|
RectD polyRectD(_transform.img2proj(polyRect.topLeft()),
|
||||||
|
_transform.img2proj(polyRect.bottomRight()));
|
||||||
|
RectC polyRectC(polyRectD.toRectC(_proj, 20));
|
||||||
|
_data->lines(polyRectC, &lines);
|
||||||
|
_data->polygons(polyRectC, &polygons);
|
||||||
|
|
||||||
|
QRectF pointRect(QPointF(ttl.x() - TEXT_EXTENT, ttl.y() - TEXT_EXTENT),
|
||||||
|
QPointF(ttl.x() + _rect.width() + TEXT_EXTENT, ttl.y() + _rect.height()
|
||||||
|
+ TEXT_EXTENT));
|
||||||
|
RectD pointRectD(_transform.img2proj(pointRect.topLeft()),
|
||||||
|
_transform.img2proj(pointRect.bottomRight()));
|
||||||
|
_data->points(pointRectD.toRectC(_proj, 20), &points);
|
||||||
|
}
|
||||||
|
|
||||||
void RasterTile::render()
|
void RasterTile::render()
|
||||||
{
|
{
|
||||||
|
QList<MapData::Line*> lines;
|
||||||
|
QList<MapData::Poly*> polygons;
|
||||||
|
QList<MapData::Point*> points;
|
||||||
QList<TextItem*> textItems, lights;
|
QList<TextItem*> textItems, lights;
|
||||||
|
|
||||||
_pixmap.setDevicePixelRatio(_ratio);
|
_pixmap.setDevicePixelRatio(_ratio);
|
||||||
_pixmap.fill(Qt::transparent);
|
_pixmap.fill(Qt::transparent);
|
||||||
|
|
||||||
processPolygons(textItems);
|
fetchData(polygons, lines, points);
|
||||||
processPoints(textItems, lights);
|
|
||||||
processLines(textItems);
|
processPolygons(polygons, textItems);
|
||||||
|
processPoints(points, textItems, lights);
|
||||||
|
processLines(lines, textItems);
|
||||||
|
|
||||||
QPainter painter(&_pixmap);
|
QPainter painter(&_pixmap);
|
||||||
painter.setRenderHint(QPainter::SmoothPixmapTransform);
|
painter.setRenderHint(QPainter::SmoothPixmapTransform);
|
||||||
painter.setRenderHint(QPainter::Antialiasing);
|
painter.setRenderHint(QPainter::Antialiasing);
|
||||||
painter.translate(-_rect.x(), -_rect.y());
|
painter.translate(-_rect.x(), -_rect.y());
|
||||||
|
|
||||||
drawPolygons(&painter);
|
drawPolygons(&painter, polygons);
|
||||||
drawLines(&painter);
|
drawLines(&painter, lines);
|
||||||
drawArrows(&painter);
|
drawArrows(&painter, polygons);
|
||||||
|
|
||||||
drawTextItems(&painter, lights);
|
drawTextItems(&painter, lights);
|
||||||
drawTextItems(&painter, textItems);
|
drawTextItems(&painter, textItems);
|
||||||
|
@ -15,13 +15,10 @@ class RasterTile
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RasterTile(const Projection &proj, const Transform &transform,
|
RasterTile(const Projection &proj, const Transform &transform,
|
||||||
const Range &zooms, int zoom, const QRect &rect, qreal ratio,
|
const MapData *data, int zoom, const QRect &rect, qreal ratio)
|
||||||
const QList<MapData::Line*> &lines, const QList<MapData::Poly*> &polygons,
|
: _proj(proj), _transform(transform), _data(data), _zoom(zoom),
|
||||||
const QList<MapData::Point*> &points)
|
|
||||||
: _proj(proj), _transform(transform), _zooms(zooms), _zoom(zoom),
|
|
||||||
_rect(rect), _ratio(ratio),
|
_rect(rect), _ratio(ratio),
|
||||||
_pixmap(rect.width() * ratio, rect.height() * ratio), _lines(lines),
|
_pixmap(rect.width() * ratio, rect.height() * ratio), _valid(false) {}
|
||||||
_polygons(polygons), _points(points), _valid(false) {}
|
|
||||||
|
|
||||||
int zoom() const {return _zoom;}
|
int zoom() const {return _zoom;}
|
||||||
QPoint xy() const {return _rect.topLeft();}
|
QPoint xy() const {return _rect.topLeft();}
|
||||||
@ -44,31 +41,33 @@ private:
|
|||||||
const QImage *_rimg;
|
const QImage *_rimg;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void fetchData(QList<MapData::Poly*> &polygons, QList<MapData::Line*> &lines,
|
||||||
|
QList<MapData::Point*> &points);
|
||||||
QPointF ll2xy(const Coordinates &c) const
|
QPointF ll2xy(const Coordinates &c) const
|
||||||
{return _transform.proj2img(_proj.ll2xy(c));}
|
{return _transform.proj2img(_proj.ll2xy(c));}
|
||||||
QPainterPath painterPath(const Polygon &polygon) const;
|
QPainterPath painterPath(const Polygon &polygon) const;
|
||||||
QPolygonF polyline(const QVector<Coordinates> &path) const;
|
QPolygonF polyline(const QVector<Coordinates> &path) const;
|
||||||
QPolygonF tsslptArrow(const Coordinates &c, qreal angle) const;
|
QPolygonF tsslptArrow(const Coordinates &c, qreal angle) const;
|
||||||
void processPoints(QList<TextItem*> &textItems, QList<TextItem *> &lights);
|
void processPoints(QList<MapData::Point *> &points,
|
||||||
void processLines(QList<TextItem*> &textItems);
|
QList<TextItem*> &textItems, QList<TextItem *> &lights);
|
||||||
void processPolygons(QList<TextItem*> &textItems);
|
void processLines(const QList<MapData::Line *> &lines,
|
||||||
|
QList<TextItem*> &textItems);
|
||||||
|
void processPolygons(const QList<MapData::Poly *> &polygons,
|
||||||
|
QList<TextItem*> &textItems);
|
||||||
void drawBitmapPath(QPainter *painter, const QImage &img,
|
void drawBitmapPath(QPainter *painter, const QImage &img,
|
||||||
const Polygon &polygon);
|
const Polygon &polygon);
|
||||||
void drawArrows(QPainter *painter);
|
void drawArrows(QPainter *painter, const QList<MapData::Poly*> &polygons);
|
||||||
void drawPolygons(QPainter *painter);
|
void drawPolygons(QPainter *painter, const QList<MapData::Poly *> &polygons);
|
||||||
void drawLines(QPainter *painter);
|
void drawLines(QPainter *painter, const QList<MapData::Line *> &lines);
|
||||||
void drawTextItems(QPainter *painter, const QList<TextItem*> &textItems);
|
void drawTextItems(QPainter *painter, const QList<TextItem*> &textItems);
|
||||||
|
|
||||||
Projection _proj;
|
Projection _proj;
|
||||||
Transform _transform;
|
Transform _transform;
|
||||||
Range _zooms;
|
const MapData *_data;
|
||||||
int _zoom;
|
int _zoom;
|
||||||
QRect _rect;
|
QRect _rect;
|
||||||
qreal _ratio;
|
qreal _ratio;
|
||||||
QPixmap _pixmap;
|
QPixmap _pixmap;
|
||||||
QList<MapData::Line*> _lines;
|
|
||||||
QList<MapData::Poly*> _polygons;
|
|
||||||
QList<MapData::Point*> _points;
|
|
||||||
bool _valid;
|
bool _valid;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -53,7 +53,9 @@ void MapData::polys(const RectC &rect, int bits, QList<Poly> *polygons,
|
|||||||
max[0] = rect.right();
|
max[0] = rect.right();
|
||||||
max[1] = rect.top();
|
max[1] = rect.top();
|
||||||
|
|
||||||
|
_lock.lock();
|
||||||
_tileTree.Search(min, max, polyCb, &ctx);
|
_tileTree.Search(min, max, polyCb, &ctx);
|
||||||
|
_lock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapData::points(const RectC &rect, int bits, QList<Point> *points)
|
void MapData::points(const RectC &rect, int bits, QList<Point> *points)
|
||||||
@ -66,7 +68,9 @@ void MapData::points(const RectC &rect, int bits, QList<Point> *points)
|
|||||||
max[0] = rect.right();
|
max[0] = rect.right();
|
||||||
max[1] = rect.top();
|
max[1] = rect.top();
|
||||||
|
|
||||||
|
_lock.lock();
|
||||||
_tileTree.Search(min, max, pointCb, &ctx);
|
_tileTree.Search(min, max, pointCb, &ctx);
|
||||||
|
_lock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapData::load()
|
void MapData::load()
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QPointF>
|
#include <QPointF>
|
||||||
#include <QCache>
|
#include <QCache>
|
||||||
|
#include <QMutex>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include "common/rectc.h"
|
#include "common/rectc.h"
|
||||||
#include "common/rtree.h"
|
#include "common/rtree.h"
|
||||||
@ -97,11 +98,14 @@ private:
|
|||||||
QList<Poly> lines;
|
QList<Poly> lines;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef QCache<const SubDiv*, Polys> PolyCache;
|
||||||
|
typedef QCache<const SubDiv*, QList<Point> > PointCache;
|
||||||
|
|
||||||
struct PolyCTX
|
struct PolyCTX
|
||||||
{
|
{
|
||||||
PolyCTX(const RectC &rect, const Zoom &zoom,
|
PolyCTX(const RectC &rect, const Zoom &zoom,
|
||||||
QList<MapData::Poly> *polygons, QList<MapData::Poly> *lines,
|
QList<MapData::Poly> *polygons, QList<MapData::Poly> *lines,
|
||||||
QCache<const SubDiv*, MapData::Polys> *polyCache)
|
PolyCache *polyCache)
|
||||||
: rect(rect), zoom(zoom), polygons(polygons), lines(lines),
|
: rect(rect), zoom(zoom), polygons(polygons), lines(lines),
|
||||||
polyCache(polyCache) {}
|
polyCache(polyCache) {}
|
||||||
|
|
||||||
@ -109,20 +113,19 @@ private:
|
|||||||
const Zoom &zoom;
|
const Zoom &zoom;
|
||||||
QList<MapData::Poly> *polygons;
|
QList<MapData::Poly> *polygons;
|
||||||
QList<MapData::Poly> *lines;
|
QList<MapData::Poly> *lines;
|
||||||
QCache<const SubDiv*, MapData::Polys> *polyCache;
|
PolyCache *polyCache;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PointCTX
|
struct PointCTX
|
||||||
{
|
{
|
||||||
PointCTX(const RectC &rect, const Zoom &zoom,
|
PointCTX(const RectC &rect, const Zoom &zoom,
|
||||||
QList<MapData::Point> *points,
|
QList<MapData::Point> *points, PointCache *pointCache)
|
||||||
QCache<const SubDiv*, QList<MapData::Point> > *pointCache)
|
|
||||||
: rect(rect), zoom(zoom), points(points), pointCache(pointCache) {}
|
: rect(rect), zoom(zoom), points(points), pointCache(pointCache) {}
|
||||||
|
|
||||||
const RectC ▭
|
const RectC ▭
|
||||||
const Zoom &zoom;
|
const Zoom &zoom;
|
||||||
QList<MapData::Point> *points;
|
QList<MapData::Point> *points;
|
||||||
QCache<const SubDiv*, QList<MapData::Point> > *pointCache;
|
PointCache *pointCache;
|
||||||
};
|
};
|
||||||
|
|
||||||
const Zoom &zoom(int bits) const;
|
const Zoom &zoom(int bits) const;
|
||||||
@ -130,8 +133,9 @@ private:
|
|||||||
static bool polyCb(VectorTile *tile, void *context);
|
static bool polyCb(VectorTile *tile, void *context);
|
||||||
static bool pointCb(VectorTile *tile, void *context);
|
static bool pointCb(VectorTile *tile, void *context);
|
||||||
|
|
||||||
QCache<const SubDiv*, Polys> _polyCache;
|
PolyCache _polyCache;
|
||||||
QCache<const SubDiv*, QList<Point> > _pointCache;
|
PointCache _pointCache;
|
||||||
|
QMutex _lock;
|
||||||
|
|
||||||
friend class VectorTile;
|
friend class VectorTile;
|
||||||
};
|
};
|
||||||
|
@ -5,12 +5,14 @@
|
|||||||
#include "map/textpathitem.h"
|
#include "map/textpathitem.h"
|
||||||
#include "map/textpointitem.h"
|
#include "map/textpointitem.h"
|
||||||
#include "map/bitmapline.h"
|
#include "map/bitmapline.h"
|
||||||
|
#include "map/rectd.h"
|
||||||
#include "style.h"
|
#include "style.h"
|
||||||
#include "lblfile.h"
|
#include "lblfile.h"
|
||||||
#include "rastertile.h"
|
#include "rastertile.h"
|
||||||
|
|
||||||
using namespace IMG;
|
using namespace IMG;
|
||||||
|
|
||||||
|
#define TEXT_EXTENT 160
|
||||||
#define ICON_PADDING 2
|
#define ICON_PADDING 2
|
||||||
|
|
||||||
#define AREA(rect) \
|
#define AREA(rect) \
|
||||||
@ -147,40 +149,6 @@ static bool rectNearPolygon(const QPolygonF &polygon, const QRectF &rect)
|
|||||||
|| polygon.containsPoint(rect.bottomRight(), Qt::OddEvenFill)));
|
|| polygon.containsPoint(rect.bottomRight(), Qt::OddEvenFill)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RasterTile::render()
|
|
||||||
{
|
|
||||||
QList<TextItem*> textItems;
|
|
||||||
|
|
||||||
ll2xy(_polygons);
|
|
||||||
ll2xy(_lines);
|
|
||||||
ll2xy(_points);
|
|
||||||
|
|
||||||
processPoints(textItems);
|
|
||||||
processPolygons(textItems);
|
|
||||||
processLines(textItems);
|
|
||||||
|
|
||||||
_pixmap.setDevicePixelRatio(_ratio);
|
|
||||||
_pixmap.fill(Qt::transparent);
|
|
||||||
|
|
||||||
QPainter painter(&_pixmap);
|
|
||||||
painter.setRenderHint(QPainter::SmoothPixmapTransform);
|
|
||||||
painter.setRenderHint(QPainter::Antialiasing);
|
|
||||||
painter.translate(-_rect.x(), -_rect.y());
|
|
||||||
|
|
||||||
drawPolygons(&painter);
|
|
||||||
drawLines(&painter);
|
|
||||||
drawTextItems(&painter, textItems);
|
|
||||||
|
|
||||||
qDeleteAll(textItems);
|
|
||||||
|
|
||||||
_valid = true;
|
|
||||||
|
|
||||||
//painter.setPen(Qt::red);
|
|
||||||
//painter.setRenderHint(QPainter::Antialiasing, false);
|
|
||||||
//painter.drawRect(QRect(_xy, _pixmap.size()));
|
|
||||||
}
|
|
||||||
|
|
||||||
void RasterTile::ll2xy(QList<MapData::Poly> &polys)
|
void RasterTile::ll2xy(QList<MapData::Poly> &polys)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < polys.size(); i++) {
|
for (int i = 0; i < polys.size(); i++) {
|
||||||
@ -200,14 +168,15 @@ void RasterTile::ll2xy(QList<MapData::Point> &points)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterTile::drawPolygons(QPainter *painter)
|
void RasterTile::drawPolygons(QPainter *painter,
|
||||||
|
const QList<MapData::Poly> &polygons)
|
||||||
{
|
{
|
||||||
QCache<const LBLFile *, SubFile::Handle> hc(16);
|
QCache<const LBLFile *, SubFile::Handle> hc(16);
|
||||||
|
|
||||||
for (int n = 0; n < _style->drawOrder().size(); n++) {
|
for (int n = 0; n < _data->style()->drawOrder().size(); n++) {
|
||||||
for (int i = 0; i < _polygons.size(); i++) {
|
for (int i = 0; i < polygons.size(); i++) {
|
||||||
const MapData::Poly &poly = _polygons.at(i);
|
const MapData::Poly &poly = polygons.at(i);
|
||||||
if (poly.type != _style->drawOrder().at(n))
|
if (poly.type != _data->style()->drawOrder().at(n))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (poly.raster.isValid()) {
|
if (poly.raster.isValid()) {
|
||||||
@ -237,7 +206,7 @@ void RasterTile::drawPolygons(QPainter *painter)
|
|||||||
//painter->setBrush(Qt::NoBrush);
|
//painter->setBrush(Qt::NoBrush);
|
||||||
//painter->drawRect(QRectF(tl, br));
|
//painter->drawRect(QRectF(tl, br));
|
||||||
} else {
|
} else {
|
||||||
const Style::Polygon &style = _style->polygon(poly.type);
|
const Style::Polygon &style = _data->style()->polygon(poly.type);
|
||||||
|
|
||||||
painter->setPen(style.pen());
|
painter->setPen(style.pen());
|
||||||
painter->setBrush(style.brush());
|
painter->setBrush(style.brush());
|
||||||
@ -247,13 +216,13 @@ void RasterTile::drawPolygons(QPainter *painter)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterTile::drawLines(QPainter *painter)
|
void RasterTile::drawLines(QPainter *painter, const QList<MapData::Poly> &lines)
|
||||||
{
|
{
|
||||||
painter->setBrush(Qt::NoBrush);
|
painter->setBrush(Qt::NoBrush);
|
||||||
|
|
||||||
for (int i = 0; i < _lines.size(); i++) {
|
for (int i = 0; i < lines.size(); i++) {
|
||||||
const MapData::Poly &poly = _lines.at(i);
|
const MapData::Poly &poly = lines.at(i);
|
||||||
const Style::Line &style = _style->line(poly.type);
|
const Style::Line &style = _data->style()->line(poly.type);
|
||||||
|
|
||||||
if (style.background() == Qt::NoPen)
|
if (style.background() == Qt::NoPen)
|
||||||
continue;
|
continue;
|
||||||
@ -262,9 +231,9 @@ void RasterTile::drawLines(QPainter *painter)
|
|||||||
painter->drawPolyline(poly.points);
|
painter->drawPolyline(poly.points);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < _lines.size(); i++) {
|
for (int i = 0; i < lines.size(); i++) {
|
||||||
const MapData::Poly &poly = _lines.at(i);
|
const MapData::Poly &poly = lines.at(i);
|
||||||
const Style::Line &style = _style->line(poly.type);
|
const Style::Line &style = _data->style()->line(poly.type);
|
||||||
|
|
||||||
if (!style.img().isNull())
|
if (!style.img().isNull())
|
||||||
BitmapLine::draw(painter, poly.points, style.img());
|
BitmapLine::draw(painter, poly.points, style.img());
|
||||||
@ -295,13 +264,14 @@ static void removeDuplicitLabel(QList<TextItem *> &labels, const QString &text,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterTile::processPolygons(QList<TextItem*> &textItems)
|
void RasterTile::processPolygons(const QList<MapData::Poly> &polygons,
|
||||||
|
QList<TextItem*> &textItems)
|
||||||
{
|
{
|
||||||
QSet<QString> set;
|
QSet<QString> set;
|
||||||
QList<TextItem *> labels;
|
QList<TextItem *> labels;
|
||||||
|
|
||||||
for (int i = 0; i < _polygons.size(); i++) {
|
for (int i = 0; i < polygons.size(); i++) {
|
||||||
const MapData::Poly &poly = _polygons.at(i);
|
const MapData::Poly &poly = polygons.at(i);
|
||||||
bool exists = set.contains(poly.label.text());
|
bool exists = set.contains(poly.label.text());
|
||||||
|
|
||||||
if (poly.label.text().isEmpty())
|
if (poly.label.text().isEmpty())
|
||||||
@ -310,7 +280,7 @@ void RasterTile::processPolygons(QList<TextItem*> &textItems)
|
|||||||
if (_zoom <= 23 && (Style::isWaterArea(poly.type)
|
if (_zoom <= 23 && (Style::isWaterArea(poly.type)
|
||||||
|| Style::isMilitaryArea(poly.type)
|
|| Style::isMilitaryArea(poly.type)
|
||||||
|| Style::isNatureReserve(poly.type))) {
|
|| Style::isNatureReserve(poly.type))) {
|
||||||
const Style::Polygon &style = _style->polygon(poly.type);
|
const Style::Polygon &style = _data->style()->polygon(poly.type);
|
||||||
TextPointItem *item = new TextPointItem(
|
TextPointItem *item = new TextPointItem(
|
||||||
centroid(poly.points).toPoint(), &poly.label.text(), poiFont(),
|
centroid(poly.points).toPoint(), &poly.label.text(), poiFont(),
|
||||||
0, &style.brush().color(), &haloColor);
|
0, &style.brush().color(), &haloColor);
|
||||||
@ -331,20 +301,22 @@ void RasterTile::processPolygons(QList<TextItem*> &textItems)
|
|||||||
textItems.append(labels);
|
textItems.append(labels);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterTile::processLines(QList<TextItem*> &textItems)
|
void RasterTile::processLines(QList<MapData::Poly> &lines,
|
||||||
|
QList<TextItem*> &textItems)
|
||||||
{
|
{
|
||||||
std::stable_sort(_lines.begin(), _lines.end());
|
std::stable_sort(lines.begin(), lines.end());
|
||||||
|
|
||||||
if (_zoom >= 22)
|
if (_zoom >= 22)
|
||||||
processStreetNames(textItems);
|
processStreetNames(lines, textItems);
|
||||||
processShields(textItems);
|
processShields(lines, textItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterTile::processStreetNames(QList<TextItem*> &textItems)
|
void RasterTile::processStreetNames(const QList<MapData::Poly> &lines,
|
||||||
|
QList<TextItem*> &textItems)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < _lines.size(); i++) {
|
for (int i = 0; i < lines.size(); i++) {
|
||||||
const MapData::Poly &poly = _lines.at(i);
|
const MapData::Poly &poly = lines.at(i);
|
||||||
const Style::Line &style = _style->line(poly.type);
|
const Style::Line &style = _data->style()->line(poly.type);
|
||||||
|
|
||||||
if (style.img().isNull() && style.foreground() == Qt::NoPen)
|
if (style.img().isNull() && style.foreground() == Qt::NoPen)
|
||||||
continue;
|
continue;
|
||||||
@ -366,7 +338,8 @@ void RasterTile::processStreetNames(QList<TextItem*> &textItems)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterTile::processShields(QList<TextItem*> &textItems)
|
void RasterTile::processShields(const QList<MapData::Poly> &lines,
|
||||||
|
QList<TextItem*> &textItems)
|
||||||
{
|
{
|
||||||
for (int type = FIRST_SHIELD; type <= LAST_SHIELD; type++) {
|
for (int type = FIRST_SHIELD; type <= LAST_SHIELD; type++) {
|
||||||
if (minShieldZoom(static_cast<Shield::Type>(type)) > _zoom)
|
if (minShieldZoom(static_cast<Shield::Type>(type)) > _zoom)
|
||||||
@ -375,8 +348,8 @@ void RasterTile::processShields(QList<TextItem*> &textItems)
|
|||||||
QHash<Shield, QPolygonF> shields;
|
QHash<Shield, QPolygonF> shields;
|
||||||
QHash<Shield, const Shield*> sp;
|
QHash<Shield, const Shield*> sp;
|
||||||
|
|
||||||
for (int i = 0; i < _lines.size(); i++) {
|
for (int i = 0; i < lines.size(); i++) {
|
||||||
const MapData::Poly &poly = _lines.at(i);
|
const MapData::Poly &poly = lines.at(i);
|
||||||
const Shield &shield = poly.label.shield();
|
const Shield &shield = poly.label.shield();
|
||||||
if (!shield.isValid() || shield.type() != type
|
if (!shield.isValid() || shield.type() != type
|
||||||
|| !Style::isMajorRoad(poly.type))
|
|| !Style::isMajorRoad(poly.type))
|
||||||
@ -429,13 +402,14 @@ void RasterTile::processShields(QList<TextItem*> &textItems)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterTile::processPoints(QList<TextItem*> &textItems)
|
void RasterTile::processPoints(QList<MapData::Point> &points,
|
||||||
|
QList<TextItem*> &textItems)
|
||||||
{
|
{
|
||||||
std::sort(_points.begin(), _points.end());
|
std::sort(points.begin(), points.end());
|
||||||
|
|
||||||
for (int i = 0; i < _points.size(); i++) {
|
for (int i = 0; i < points.size(); i++) {
|
||||||
const MapData::Point &point = _points.at(i);
|
const MapData::Point &point = points.at(i);
|
||||||
const Style::Point &style = _style->point(point.type);
|
const Style::Point &style = _data->style()->point(point.type);
|
||||||
bool poi = Style::isPOI(point.type);
|
bool poi = Style::isPOI(point.type);
|
||||||
|
|
||||||
const QString *label = point.label.text().isEmpty()
|
const QString *label = point.label.text().isEmpty()
|
||||||
@ -461,3 +435,60 @@ void RasterTile::processPoints(QList<TextItem*> &textItems)
|
|||||||
delete item;
|
delete item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RasterTile::fetchData(QList<MapData::Poly> &polygons,
|
||||||
|
QList<MapData::Poly> &lines, QList<MapData::Point> &points)
|
||||||
|
{
|
||||||
|
QPoint ttl(_rect.topLeft());
|
||||||
|
|
||||||
|
QRectF polyRect(ttl, QPointF(ttl.x() + _rect.width(), ttl.y()
|
||||||
|
+ _rect.height()));
|
||||||
|
RectD polyRectD(_transform.img2proj(polyRect.topLeft()),
|
||||||
|
_transform.img2proj(polyRect.bottomRight()));
|
||||||
|
_data->polys(polyRectD.toRectC(_proj, 20), _zoom,
|
||||||
|
&polygons, &lines);
|
||||||
|
|
||||||
|
QRectF pointRect(QPointF(ttl.x() - TEXT_EXTENT, ttl.y() - TEXT_EXTENT),
|
||||||
|
QPointF(ttl.x() + _rect.width() + TEXT_EXTENT, ttl.y() + _rect.height()
|
||||||
|
+ TEXT_EXTENT));
|
||||||
|
RectD pointRectD(_transform.img2proj(pointRect.topLeft()),
|
||||||
|
_transform.img2proj(pointRect.bottomRight()));
|
||||||
|
_data->points(pointRectD.toRectC(_proj, 20), _zoom, &points);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RasterTile::render()
|
||||||
|
{
|
||||||
|
QList<MapData::Poly> polygons;
|
||||||
|
QList<MapData::Poly> lines;
|
||||||
|
QList<MapData::Point> points;
|
||||||
|
QList<TextItem*> textItems;
|
||||||
|
|
||||||
|
fetchData(polygons, lines, points);
|
||||||
|
ll2xy(polygons);
|
||||||
|
ll2xy(lines);
|
||||||
|
ll2xy(points);
|
||||||
|
|
||||||
|
processPoints(points, textItems);
|
||||||
|
processPolygons(polygons, textItems);
|
||||||
|
processLines(lines, textItems);
|
||||||
|
|
||||||
|
_pixmap.setDevicePixelRatio(_ratio);
|
||||||
|
_pixmap.fill(Qt::transparent);
|
||||||
|
|
||||||
|
QPainter painter(&_pixmap);
|
||||||
|
painter.setRenderHint(QPainter::SmoothPixmapTransform);
|
||||||
|
painter.setRenderHint(QPainter::Antialiasing);
|
||||||
|
painter.translate(-_rect.x(), -_rect.y());
|
||||||
|
|
||||||
|
drawPolygons(&painter, polygons);
|
||||||
|
drawLines(&painter, lines);
|
||||||
|
drawTextItems(&painter, textItems);
|
||||||
|
|
||||||
|
qDeleteAll(textItems);
|
||||||
|
|
||||||
|
_valid = true;
|
||||||
|
|
||||||
|
//painter.setPen(Qt::red);
|
||||||
|
//painter.setRenderHint(QPainter::Antialiasing, false);
|
||||||
|
//painter.drawRect(QRect(_xy, _pixmap.size()));
|
||||||
|
}
|
||||||
|
@ -17,14 +17,11 @@ class Style;
|
|||||||
class RasterTile
|
class RasterTile
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RasterTile(const Projection &proj, const Transform &transform,
|
RasterTile(const Projection &proj, const Transform &transform, MapData *data,
|
||||||
const Style *style, int zoom, const QRect &rect, qreal ratio,
|
int zoom, const QRect &rect, qreal ratio, const QString &key)
|
||||||
const QString &key, const QList<MapData::Poly> &polygons,
|
: _proj(proj), _transform(transform), _data(data), _zoom(zoom),
|
||||||
const QList<MapData::Poly> &lines, QList<MapData::Point> &points)
|
_rect(rect), _ratio(ratio), _key(key),
|
||||||
: _proj(proj), _transform(transform), _style(style), _zoom(zoom),
|
_pixmap(rect.width() * ratio, rect.height() * ratio), _valid(false) {}
|
||||||
_rect(rect), _ratio(ratio), _key(key),
|
|
||||||
_pixmap(rect.width() * ratio, rect.height() * ratio), _polygons(polygons),
|
|
||||||
_lines(lines), _points(points), _valid(false) {}
|
|
||||||
|
|
||||||
const QString &key() const {return _key;}
|
const QString &key() const {return _key;}
|
||||||
QPoint xy() const {return _rect.topLeft();}
|
QPoint xy() const {return _rect.topLeft();}
|
||||||
@ -34,32 +31,36 @@ public:
|
|||||||
void render();
|
void render();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void fetchData(QList<MapData::Poly> &polygons, QList<MapData::Poly> &lines,
|
||||||
|
QList<MapData::Point> &points);
|
||||||
QPointF ll2xy(const Coordinates &c) const
|
QPointF ll2xy(const Coordinates &c) const
|
||||||
{return _transform.proj2img(_proj.ll2xy(c));}
|
{return _transform.proj2img(_proj.ll2xy(c));}
|
||||||
void ll2xy(QList<MapData::Poly> &polys);
|
void ll2xy(QList<MapData::Poly> &polys);
|
||||||
void ll2xy(QList<MapData::Point> &points);
|
void ll2xy(QList<MapData::Point> &points);
|
||||||
|
|
||||||
void drawPolygons(QPainter *painter);
|
void drawPolygons(QPainter *painter, const QList<MapData::Poly> &polygons);
|
||||||
void drawLines(QPainter *painter);
|
void drawLines(QPainter *painter, const QList<MapData::Poly> &lines);
|
||||||
void drawTextItems(QPainter *painter, const QList<TextItem*> &textItems);
|
void drawTextItems(QPainter *painter, const QList<TextItem*> &textItems);
|
||||||
|
|
||||||
void processPolygons(QList<TextItem *> &textItems);
|
void processPolygons(const QList<MapData::Poly> &polygons,
|
||||||
void processLines(QList<TextItem*> &textItems);
|
QList<TextItem *> &textItems);
|
||||||
void processPoints(QList<TextItem*> &textItems);
|
void processLines(QList<MapData::Poly> &lines,
|
||||||
void processShields(QList<TextItem*> &textItems);
|
QList<TextItem*> &textItems);
|
||||||
void processStreetNames(QList<TextItem*> &textItems);
|
void processPoints(QList<MapData::Point> &points,
|
||||||
|
QList<TextItem*> &textItems);
|
||||||
|
void processShields(const QList<MapData::Poly> &lines,
|
||||||
|
QList<TextItem*> &textItems);
|
||||||
|
void processStreetNames(const QList<MapData::Poly> &lines,
|
||||||
|
QList<TextItem*> &textItems);
|
||||||
|
|
||||||
Projection _proj;
|
Projection _proj;
|
||||||
Transform _transform;
|
Transform _transform;
|
||||||
const Style *_style;
|
MapData *_data;
|
||||||
int _zoom;
|
int _zoom;
|
||||||
QRect _rect;
|
QRect _rect;
|
||||||
qreal _ratio;
|
qreal _ratio;
|
||||||
QString _key;
|
QString _key;
|
||||||
QPixmap _pixmap;
|
QPixmap _pixmap;
|
||||||
QList<MapData::Poly> _polygons;
|
|
||||||
QList<MapData::Poly> _lines;
|
|
||||||
QList<MapData::Point> _points;
|
|
||||||
bool _valid;
|
bool _valid;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -102,13 +102,16 @@ void VectorTile::clear()
|
|||||||
|
|
||||||
void VectorTile::polys(const RectC &rect, const Zoom &zoom,
|
void VectorTile::polys(const RectC &rect, const Zoom &zoom,
|
||||||
QList<MapData::Poly> *polygons, QList<MapData::Poly> *lines,
|
QList<MapData::Poly> *polygons, QList<MapData::Poly> *lines,
|
||||||
QCache<const SubDiv *, MapData::Polys> *polyCache)
|
MapData::PolyCache *polyCache)
|
||||||
{
|
{
|
||||||
SubFile::Handle *rgnHdl = 0, *lblHdl = 0, *netHdl = 0, *nodHdl = 0,
|
SubFile::Handle *rgnHdl = 0, *lblHdl = 0, *netHdl = 0, *nodHdl = 0,
|
||||||
*nodHdl2 = 0;
|
*nodHdl2 = 0;
|
||||||
|
|
||||||
if (_loaded < 0)
|
if (_loaded < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
//polyCache->lock.lock();
|
||||||
|
|
||||||
if (!_loaded) {
|
if (!_loaded) {
|
||||||
rgnHdl = new SubFile::Handle(_rgn);
|
rgnHdl = new SubFile::Handle(_rgn);
|
||||||
lblHdl = new SubFile::Handle(_lbl);
|
lblHdl = new SubFile::Handle(_lbl);
|
||||||
@ -116,6 +119,7 @@ void VectorTile::polys(const RectC &rect, const Zoom &zoom,
|
|||||||
nodHdl = new SubFile::Handle(_nod);
|
nodHdl = new SubFile::Handle(_nod);
|
||||||
|
|
||||||
if (!load(*rgnHdl, *lblHdl, *netHdl, *nodHdl)) {
|
if (!load(*rgnHdl, *lblHdl, *netHdl, *nodHdl)) {
|
||||||
|
//polyCache->lock.unlock();
|
||||||
delete rgnHdl; delete lblHdl; delete netHdl; delete nodHdl;
|
delete rgnHdl; delete lblHdl; delete netHdl; delete nodHdl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -166,6 +170,8 @@ void VectorTile::polys(const RectC &rect, const Zoom &zoom,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//polyCache->lock.unlock();
|
||||||
|
|
||||||
delete rgnHdl; delete lblHdl; delete netHdl; delete nodHdl; delete nodHdl2;
|
delete rgnHdl; delete lblHdl; delete netHdl; delete nodHdl; delete nodHdl2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ public:
|
|||||||
|
|
||||||
void polys(const RectC &rect, const Zoom &zoom,
|
void polys(const RectC &rect, const Zoom &zoom,
|
||||||
QList<MapData::Poly> *polygons, QList<MapData::Poly> *lines,
|
QList<MapData::Poly> *polygons, QList<MapData::Poly> *lines,
|
||||||
QCache<const SubDiv *, MapData::Polys> *polyCache);
|
MapData::PolyCache *polyCache);
|
||||||
void points(const RectC &rect, const Zoom &zoom,
|
void points(const RectC &rect, const Zoom &zoom,
|
||||||
QList<MapData::Point> *points, QCache<const SubDiv*,
|
QList<MapData::Point> *points, QCache<const SubDiv*,
|
||||||
QList<MapData::Point> > *pointCache);
|
QList<MapData::Point> > *pointCache);
|
||||||
|
@ -6,11 +6,10 @@
|
|||||||
#include "pcs.h"
|
#include "pcs.h"
|
||||||
#include "encmap.h"
|
#include "encmap.h"
|
||||||
|
|
||||||
#define TILE_SIZE 512
|
|
||||||
#define TEXT_EXTENT 160
|
|
||||||
|
|
||||||
using namespace ENC;
|
using namespace ENC;
|
||||||
|
|
||||||
|
#define TILE_SIZE 512
|
||||||
|
|
||||||
ENCMap::ENCMap(const QString &fileName, QObject *parent)
|
ENCMap::ENCMap(const QString &fileName, QObject *parent)
|
||||||
: Map(fileName, parent), _data(fileName), _projection(PCS::pcs(3857)),
|
: Map(fileName, parent), _data(fileName), _projection(PCS::pcs(3857)),
|
||||||
@ -180,32 +179,9 @@ void ENCMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
|
|||||||
QPixmap pm;
|
QPixmap pm;
|
||||||
if (QPixmapCache::find(key(_zoom, ttl), &pm))
|
if (QPixmapCache::find(key(_zoom, ttl), &pm))
|
||||||
painter->drawPixmap(ttl, pm);
|
painter->drawPixmap(ttl, pm);
|
||||||
else {
|
else
|
||||||
QList<MapData::Poly*> polygons;
|
tiles.append(RasterTile(_projection, _transform, &_data,
|
||||||
QList<MapData::Line*> lines;
|
_zoom, QRect(ttl, QSize(TILE_SIZE, TILE_SIZE)), _tileRatio));
|
||||||
QList<MapData::Point*> points;
|
|
||||||
|
|
||||||
QRectF polyRect(ttl, QPointF(ttl.x() + TILE_SIZE,
|
|
||||||
ttl.y() + TILE_SIZE));
|
|
||||||
polyRect &= _bounds;
|
|
||||||
RectD polyRectD(_transform.img2proj(polyRect.topLeft()),
|
|
||||||
_transform.img2proj(polyRect.bottomRight()));
|
|
||||||
RectC polyRectC(polyRectD.toRectC(_projection, 20));
|
|
||||||
_data.lines(polyRectC, &lines);
|
|
||||||
_data.polygons(polyRectC, &polygons);
|
|
||||||
|
|
||||||
QRectF pointRect(QPointF(ttl.x() - TEXT_EXTENT,
|
|
||||||
ttl.y() - TEXT_EXTENT), QPointF(ttl.x() + TILE_SIZE
|
|
||||||
+ TEXT_EXTENT, ttl.y() + TILE_SIZE + TEXT_EXTENT));
|
|
||||||
pointRect &= _bounds;
|
|
||||||
RectD pointRectD(_transform.img2proj(pointRect.topLeft()),
|
|
||||||
_transform.img2proj(pointRect.bottomRight()));
|
|
||||||
_data.points(pointRectD.toRectC(_projection, 20), &points);
|
|
||||||
|
|
||||||
tiles.append(RasterTile(_projection, _transform, _data.zooms(),
|
|
||||||
_zoom, QRect(ttl, QSize(TILE_SIZE, TILE_SIZE)), _tileRatio,
|
|
||||||
lines, polygons, points));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
using namespace IMG;
|
using namespace IMG;
|
||||||
|
|
||||||
#define TILE_SIZE 384
|
#define TILE_SIZE 384
|
||||||
#define TEXT_EXTENT 160
|
|
||||||
|
|
||||||
static RectC limitBounds(const RectC &bounds, const Projection &proj)
|
static RectC limitBounds(const RectC &bounds, const Projection &proj)
|
||||||
{
|
{
|
||||||
@ -241,30 +240,9 @@ void IMGMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
|
|||||||
if (QPixmapCache::find(key, &pm))
|
if (QPixmapCache::find(key, &pm))
|
||||||
painter->drawPixmap(ttl, pm);
|
painter->drawPixmap(ttl, pm);
|
||||||
else {
|
else {
|
||||||
QList<MapData::Poly> polygons, lines;
|
tiles.append(RasterTile(_projection, _transform, _data.at(n),
|
||||||
QList<MapData::Point> points;
|
_zoom, QRect(ttl, QSize(TILE_SIZE, TILE_SIZE)), _tileRatio,
|
||||||
|
key));
|
||||||
QRectF polyRect(ttl, QPointF(ttl.x() + TILE_SIZE,
|
|
||||||
ttl.y() + TILE_SIZE));
|
|
||||||
polyRect &= _bounds;
|
|
||||||
RectD polyRectD(_transform.img2proj(polyRect.topLeft()),
|
|
||||||
_transform.img2proj(polyRect.bottomRight()));
|
|
||||||
_data.at(n)->polys(polyRectD.toRectC(_projection, 20), _zoom,
|
|
||||||
&polygons, &lines);
|
|
||||||
|
|
||||||
QRectF pointRect(QPointF(ttl.x() - TEXT_EXTENT,
|
|
||||||
ttl.y() - TEXT_EXTENT), QPointF(ttl.x() + TILE_SIZE
|
|
||||||
+ TEXT_EXTENT, ttl.y() + TILE_SIZE + TEXT_EXTENT));
|
|
||||||
pointRect &= _bounds;
|
|
||||||
RectD pointRectD(_transform.img2proj(pointRect.topLeft()),
|
|
||||||
_transform.img2proj(pointRect.bottomRight()));
|
|
||||||
_data.at(n)->points(pointRectD.toRectC(_projection, 20),
|
|
||||||
_zoom, &points);
|
|
||||||
|
|
||||||
tiles.append(RasterTile(_projection, _transform,
|
|
||||||
_data.at(n)->style(), _zoom,
|
|
||||||
QRect(ttl, QSize(TILE_SIZE, TILE_SIZE)), _tileRatio, key,
|
|
||||||
polygons, lines, points));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -208,13 +208,15 @@ bool MapData::readTags(SubFile &subfile, int count,
|
|||||||
|
|
||||||
bool MapData::readSubFiles()
|
bool MapData::readSubFiles()
|
||||||
{
|
{
|
||||||
QDataStream stream(&_file);
|
/* both _pointFile and _pathFile can be used here */
|
||||||
|
QDataStream stream(&_pointFile);
|
||||||
|
|
||||||
for (int i = 0; i < _subFiles.size(); i++) {
|
for (int i = 0; i < _subFiles.size(); i++) {
|
||||||
const SubFileInfo &f = _subFiles.at(i);
|
const SubFileInfo &f = _subFiles.at(i);
|
||||||
quint64 offset, nextOffset;
|
quint64 offset, nextOffset;
|
||||||
|
|
||||||
stream.device()->seek(f.offset);
|
if (!stream.device()->seek(f.offset))
|
||||||
|
return false;
|
||||||
|
|
||||||
QPoint tl(OSM::ll2tile(_bounds.topLeft(), f.base));
|
QPoint tl(OSM::ll2tile(_bounds.topLeft(), f.base));
|
||||||
QPoint br(OSM::ll2tile(_bounds.bottomRight(), f.base));
|
QPoint br(OSM::ll2tile(_bounds.bottomRight(), f.base));
|
||||||
@ -359,7 +361,7 @@ bool MapData::readMapInfo(SubFile &hdr, QByteArray &projection, bool &debugMap)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MapData::readHeader()
|
bool MapData::readHeader(QFile &file)
|
||||||
{
|
{
|
||||||
char magic[MAGIC_SIZE];
|
char magic[MAGIC_SIZE];
|
||||||
quint32 hdrSize;
|
quint32 hdrSize;
|
||||||
@ -367,18 +369,18 @@ bool MapData::readHeader()
|
|||||||
bool debugMap;
|
bool debugMap;
|
||||||
|
|
||||||
|
|
||||||
if (_file.read(magic, MAGIC_SIZE) < (qint64)MAGIC_SIZE
|
if (file.read(magic, MAGIC_SIZE) < (qint64)MAGIC_SIZE
|
||||||
|| memcmp(magic, MAGIC, MAGIC_SIZE)) {
|
|| memcmp(magic, MAGIC, MAGIC_SIZE)) {
|
||||||
_errorString = "Not a Mapsforge map";
|
_errorString = "Not a Mapsforge map";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_file.read((char*)&hdrSize, sizeof(hdrSize)) < (qint64)sizeof(hdrSize)) {
|
if (file.read((char*)&hdrSize, sizeof(hdrSize)) < (qint64)sizeof(hdrSize)) {
|
||||||
_errorString = "Unexpected EOF";
|
_errorString = "Unexpected EOF";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SubFile hdr(_file, MAGIC_SIZE, qFromBigEndian(hdrSize));
|
SubFile hdr(file, MAGIC_SIZE, qFromBigEndian(hdrSize));
|
||||||
|
|
||||||
if (!readMapInfo(hdr, projection, debugMap)) {
|
if (!readMapInfo(hdr, projection, debugMap)) {
|
||||||
_errorString = "Error reading map info";
|
_errorString = "Error reading map info";
|
||||||
@ -407,18 +409,19 @@ bool MapData::readHeader()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
MapData::MapData(const QString &fileName) : _file(fileName), _valid(false)
|
MapData::MapData(const QString &fileName)
|
||||||
|
: _pointFile(fileName), _pathFile(fileName), _valid(false)
|
||||||
{
|
{
|
||||||
if (!_file.open(QFile::ReadOnly | QIODevice::Unbuffered)) {
|
QFile file(fileName);
|
||||||
_errorString = _file.errorString();
|
|
||||||
|
if (!file.open(QFile::ReadOnly | QIODevice::Unbuffered)) {
|
||||||
|
_errorString = file.errorString();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!readHeader())
|
if (!readHeader(file))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_file.close();
|
|
||||||
|
|
||||||
_pathCache.setMaxCost(256);
|
_pathCache.setMaxCost(256);
|
||||||
_pointCache.setMaxCost(256);
|
_pointCache.setMaxCost(256);
|
||||||
|
|
||||||
@ -444,13 +447,16 @@ RectC MapData::bounds() const
|
|||||||
|
|
||||||
void MapData::load()
|
void MapData::load()
|
||||||
{
|
{
|
||||||
if (_file.open(QIODevice::ReadOnly | QIODevice::Unbuffered))
|
_pointFile.open(QIODevice::ReadOnly | QIODevice::Unbuffered);
|
||||||
readSubFiles();
|
_pathFile.open(QIODevice::ReadOnly | QIODevice::Unbuffered);
|
||||||
|
|
||||||
|
readSubFiles();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapData::clear()
|
void MapData::clear()
|
||||||
{
|
{
|
||||||
_file.close();
|
_pointFile.close();
|
||||||
|
_pathFile.close();
|
||||||
|
|
||||||
_pathCache.clear();
|
_pathCache.clear();
|
||||||
_pointCache.clear();
|
_pointCache.clear();
|
||||||
@ -516,6 +522,9 @@ void MapData::points(const VectorTile *tile, const RectC &rect, int zoom,
|
|||||||
QList<Point> *list)
|
QList<Point> *list)
|
||||||
{
|
{
|
||||||
Key key(tile, zoom);
|
Key key(tile, zoom);
|
||||||
|
|
||||||
|
_pointLock.lock();
|
||||||
|
|
||||||
QList<Point> *cached = _pointCache.object(key);
|
QList<Point> *cached = _pointCache.object(key);
|
||||||
|
|
||||||
if (!cached) {
|
if (!cached) {
|
||||||
@ -527,6 +536,8 @@ void MapData::points(const VectorTile *tile, const RectC &rect, int zoom,
|
|||||||
delete p;
|
delete p;
|
||||||
} else
|
} else
|
||||||
copyPoints(rect, cached, list);
|
copyPoints(rect, cached, list);
|
||||||
|
|
||||||
|
_pointLock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapData::paths(const RectC &rect, int zoom, QList<Path> *list)
|
void MapData::paths(const RectC &rect, int zoom, QList<Path> *list)
|
||||||
@ -550,6 +561,9 @@ void MapData::paths(const VectorTile *tile, const RectC &rect, int zoom,
|
|||||||
QList<Path> *list)
|
QList<Path> *list)
|
||||||
{
|
{
|
||||||
Key key(tile, zoom);
|
Key key(tile, zoom);
|
||||||
|
|
||||||
|
_pathLock.lock();
|
||||||
|
|
||||||
QList<Path> *cached = _pathCache.object(key);
|
QList<Path> *cached = _pathCache.object(key);
|
||||||
|
|
||||||
if (!cached) {
|
if (!cached) {
|
||||||
@ -561,12 +575,14 @@ void MapData::paths(const VectorTile *tile, const RectC &rect, int zoom,
|
|||||||
delete p;
|
delete p;
|
||||||
} else
|
} else
|
||||||
copyPaths(rect, cached, list);
|
copyPaths(rect, cached, list);
|
||||||
|
|
||||||
|
_pathLock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MapData::readPaths(const VectorTile *tile, int zoom, QList<Path> *list)
|
bool MapData::readPaths(const VectorTile *tile, int zoom, QList<Path> *list)
|
||||||
{
|
{
|
||||||
const SubFileInfo &info = _subFiles.at(level(zoom));
|
const SubFileInfo &info = _subFiles.at(level(zoom));
|
||||||
SubFile subfile(_file, info.offset, info.size);
|
SubFile subfile(_pathFile, info.offset, info.size);
|
||||||
int rows = info.max - info.min + 1;
|
int rows = info.max - info.min + 1;
|
||||||
QVector<unsigned> paths(rows);
|
QVector<unsigned> paths(rows);
|
||||||
quint32 blocks, unused, val, cnt = 0;
|
quint32 blocks, unused, val, cnt = 0;
|
||||||
@ -652,7 +668,7 @@ bool MapData::readPaths(const VectorTile *tile, int zoom, QList<Path> *list)
|
|||||||
bool MapData::readPoints(const VectorTile *tile, int zoom, QList<Point> *list)
|
bool MapData::readPoints(const VectorTile *tile, int zoom, QList<Point> *list)
|
||||||
{
|
{
|
||||||
const SubFileInfo &info = _subFiles.at(level(zoom));
|
const SubFileInfo &info = _subFiles.at(level(zoom));
|
||||||
SubFile subfile(_file, info.offset, info.size);
|
SubFile subfile(_pointFile, info.offset, info.size);
|
||||||
int rows = info.max - info.min + 1;
|
int rows = info.max - info.min + 1;
|
||||||
QVector<unsigned> points(rows);
|
QVector<unsigned> points(rows);
|
||||||
quint32 val, unused, cnt = 0;
|
quint32 val, unused, cnt = 0;
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QCache>
|
#include <QCache>
|
||||||
|
#include <QMutex>
|
||||||
#include "common/hash.h"
|
#include "common/hash.h"
|
||||||
#include "common/rectc.h"
|
#include "common/rectc.h"
|
||||||
#include "common/rtree.h"
|
#include "common/rtree.h"
|
||||||
@ -138,7 +139,7 @@ private:
|
|||||||
bool readTagInfo(SubFile &hdr);
|
bool readTagInfo(SubFile &hdr);
|
||||||
bool readTagInfo(SubFile &hdr, QVector<TagSource> &tags);
|
bool readTagInfo(SubFile &hdr, QVector<TagSource> &tags);
|
||||||
bool readMapInfo(SubFile &hdr, QByteArray &projection, bool &debugMap);
|
bool readMapInfo(SubFile &hdr, QByteArray &projection, bool &debugMap);
|
||||||
bool readHeader();
|
bool readHeader(QFile &file);
|
||||||
bool readSubFiles();
|
bool readSubFiles();
|
||||||
void clearTiles();
|
void clearTiles();
|
||||||
|
|
||||||
@ -157,7 +158,7 @@ private:
|
|||||||
|
|
||||||
friend HASH_T qHash(const MapData::Key &key);
|
friend HASH_T qHash(const MapData::Key &key);
|
||||||
|
|
||||||
QFile _file;
|
QFile _pointFile, _pathFile;
|
||||||
RectC _bounds;
|
RectC _bounds;
|
||||||
quint16 _tileSize;
|
quint16 _tileSize;
|
||||||
QVector<SubFileInfo> _subFiles;
|
QVector<SubFileInfo> _subFiles;
|
||||||
@ -167,6 +168,7 @@ private:
|
|||||||
|
|
||||||
QCache<Key, QList<Path> > _pathCache;
|
QCache<Key, QList<Path> > _pathCache;
|
||||||
QCache<Key, QList<Point> > _pointCache;
|
QCache<Key, QList<Point> > _pointCache;
|
||||||
|
QMutex _pathLock, _pointLock;
|
||||||
|
|
||||||
bool _valid;
|
bool _valid;
|
||||||
QString _errorString;
|
QString _errorString;
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QCache>
|
#include <QCache>
|
||||||
#include "common/programpaths.h"
|
#include "common/programpaths.h"
|
||||||
|
#include "map/rectd.h"
|
||||||
#include "rastertile.h"
|
#include "rastertile.h"
|
||||||
|
|
||||||
using namespace Mapsforge;
|
using namespace Mapsforge;
|
||||||
|
|
||||||
|
#define TEXT_EXTENT 160
|
||||||
|
|
||||||
static qreal area(const QPainterPath &polygon)
|
static qreal area(const QPainterPath &polygon)
|
||||||
{
|
{
|
||||||
qreal area = 0;
|
qreal area = 0;
|
||||||
@ -52,14 +55,15 @@ static const QColor *haloColor(const Style::TextRender *ti)
|
|||||||
? &ti->strokeColor() : 0;
|
? &ti->strokeColor() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterTile::processPointLabels(QList<TextItem*> &textItems)
|
void RasterTile::processPointLabels(const QList<MapData::Point> &points,
|
||||||
|
QList<TextItem*> &textItems)
|
||||||
{
|
{
|
||||||
QList<const Style::TextRender*> labels(_style->pointLabels(_zoom));
|
QList<const Style::TextRender*> labels(_style->pointLabels(_zoom));
|
||||||
QList<const Style::Symbol*> symbols(_style->pointSymbols(_zoom));
|
QList<const Style::Symbol*> symbols(_style->pointSymbols(_zoom));
|
||||||
QList<PainterPoint> points;
|
QList<PainterPoint> painterPoints;
|
||||||
|
|
||||||
for (int i = 0; i < _points.size(); i++) {
|
for (int i = 0; i < points.size(); i++) {
|
||||||
const MapData::Point &point = _points.at(i);
|
const MapData::Point &point = points.at(i);
|
||||||
const QByteArray *lbl = 0;
|
const QByteArray *lbl = 0;
|
||||||
const Style::TextRender *ti = 0;
|
const Style::TextRender *ti = 0;
|
||||||
const Style::Symbol *si = 0;
|
const Style::Symbol *si = 0;
|
||||||
@ -83,13 +87,13 @@ void RasterTile::processPointLabels(QList<TextItem*> &textItems)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ti || si)
|
if (ti || si)
|
||||||
points.append(PainterPoint(&point, lbl, si, ti));
|
painterPoints.append(PainterPoint(&point, lbl, si, ti));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::sort(points.begin(), points.end());
|
std::sort(painterPoints.begin(), painterPoints.end());
|
||||||
|
|
||||||
for (int i = 0; i < points.size(); i++) {
|
for (int i = 0; i < painterPoints.size(); i++) {
|
||||||
const PainterPoint &p = points.at(i);
|
const PainterPoint &p = painterPoints.at(i);
|
||||||
const QImage *img = p.si ? &p.si->img() : 0;
|
const QImage *img = p.si ? &p.si->img() : 0;
|
||||||
const QFont *font = p.ti ? &p.ti->font() : 0;
|
const QFont *font = p.ti ? &p.ti->font() : 0;
|
||||||
const QColor *color = p.ti ? &p.ti->fillColor() : 0;
|
const QColor *color = p.ti ? &p.ti->fillColor() : 0;
|
||||||
@ -238,15 +242,16 @@ QPainterPath RasterTile::painterPath(const Polygon &polygon, bool curve) const
|
|||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterTile::pathInstructions(QVector<PainterPath> &paths,
|
void RasterTile::pathInstructions(const QList<MapData::Path> &paths,
|
||||||
|
QVector<PainterPath> &painterPaths,
|
||||||
QVector<RasterTile::RenderInstruction> &instructions)
|
QVector<RasterTile::RenderInstruction> &instructions)
|
||||||
{
|
{
|
||||||
QCache<PathKey, QList<const Style::PathRender *> > cache(8192);
|
QCache<PathKey, QList<const Style::PathRender *> > cache(8192);
|
||||||
QList<const Style::PathRender*> *ri;
|
QList<const Style::PathRender*> *ri;
|
||||||
|
|
||||||
for (int i = 0; i < _paths.size(); i++) {
|
for (int i = 0; i < paths.size(); i++) {
|
||||||
const MapData::Path &path = _paths.at(i);
|
const MapData::Path &path = paths.at(i);
|
||||||
PainterPath &rp = paths[i];
|
PainterPath &rp = painterPaths[i];
|
||||||
PathKey key(_zoom, path.closed, path.tags);
|
PathKey key(_zoom, path.closed, path.tags);
|
||||||
|
|
||||||
rp.path = &path;
|
rp.path = &path;
|
||||||
@ -264,14 +269,14 @@ void RasterTile::pathInstructions(QVector<PainterPath> &paths,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterTile::circleInstructions(
|
void RasterTile::circleInstructions(const QList<MapData::Point> &points,
|
||||||
QVector<RasterTile::RenderInstruction> &instructions)
|
QVector<RasterTile::RenderInstruction> &instructions)
|
||||||
{
|
{
|
||||||
QCache<PointKey, QList<const Style::CircleRender *> > cache(8192);
|
QCache<PointKey, QList<const Style::CircleRender *> > cache(8192);
|
||||||
QList<const Style::CircleRender*> *ri;
|
QList<const Style::CircleRender*> *ri;
|
||||||
|
|
||||||
for (int i = 0; i < _points.size(); i++) {
|
for (int i = 0; i < points.size(); i++) {
|
||||||
const MapData::Point &point = _points.at(i);
|
const MapData::Point &point = points.at(i);
|
||||||
PointKey key(_zoom, point.tags);
|
PointKey key(_zoom, point.tags);
|
||||||
|
|
||||||
if (!(ri = cache.object(key))) {
|
if (!(ri = cache.object(key))) {
|
||||||
@ -287,11 +292,12 @@ void RasterTile::circleInstructions(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterTile::drawPaths(QPainter *painter, QVector<PainterPath> &paths)
|
void RasterTile::drawPaths(QPainter *painter, const QList<MapData::Path> &paths,
|
||||||
|
const QList<MapData::Point> &points, QVector<PainterPath> &painterPaths)
|
||||||
{
|
{
|
||||||
QVector<RenderInstruction> instructions;
|
QVector<RenderInstruction> instructions;
|
||||||
pathInstructions(paths, instructions);
|
pathInstructions(paths, painterPaths, instructions);
|
||||||
circleInstructions(instructions);
|
circleInstructions(points, instructions);
|
||||||
std::sort(instructions.begin(), instructions.end());
|
std::sort(instructions.begin(), instructions.end());
|
||||||
|
|
||||||
for (int i = 0; i < instructions.size(); i++) {
|
for (int i = 0; i < instructions.size(); i++) {
|
||||||
@ -318,10 +324,37 @@ void RasterTile::drawPaths(QPainter *painter, QVector<PainterPath> &paths)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RasterTile::fetchData(QList<MapData::Path> &paths,
|
||||||
|
QList<MapData::Point> &points)
|
||||||
|
{
|
||||||
|
QPoint ttl(_rect.topLeft());
|
||||||
|
|
||||||
|
/* Add a "sub-pixel" margin to assure the tile areas do not
|
||||||
|
overlap on the border lines. This prevents areas overlap
|
||||||
|
artifacts at least when using the EPSG:3857 projection. */
|
||||||
|
QRectF pathRect(QPointF(ttl.x() + 0.5, ttl.y() + 0.5),
|
||||||
|
QPointF(ttl.x() + _rect.width() - 0.5, ttl.y() + _rect.height() - 0.5));
|
||||||
|
RectD pathRectD(_transform.img2proj(pathRect.topLeft()),
|
||||||
|
_transform.img2proj(pathRect.bottomRight()));
|
||||||
|
_data->paths(pathRectD.toRectC(_proj, 20), _zoom, &paths);
|
||||||
|
|
||||||
|
QRectF pointRect(QPointF(ttl.x() - TEXT_EXTENT, ttl.y() - TEXT_EXTENT),
|
||||||
|
QPointF(ttl.x() + _rect.width() + TEXT_EXTENT, ttl.y() + _rect.height()
|
||||||
|
+ TEXT_EXTENT));
|
||||||
|
RectD pointRectD(_transform.img2proj(pointRect.topLeft()),
|
||||||
|
_transform.img2proj(pointRect.bottomRight()));
|
||||||
|
_data->points(pointRectD.toRectC(_proj, 20), _zoom, &points);
|
||||||
|
}
|
||||||
|
|
||||||
void RasterTile::render()
|
void RasterTile::render()
|
||||||
{
|
{
|
||||||
|
QList<MapData::Path> paths;
|
||||||
|
QList<MapData::Point> points;
|
||||||
|
|
||||||
|
fetchData(paths, points);
|
||||||
|
|
||||||
QList<TextItem*> textItems;
|
QList<TextItem*> textItems;
|
||||||
QVector<PainterPath> renderPaths(_paths.size());
|
QVector<PainterPath> renderPaths(paths.size());
|
||||||
|
|
||||||
_pixmap.setDevicePixelRatio(_ratio);
|
_pixmap.setDevicePixelRatio(_ratio);
|
||||||
_pixmap.fill(Qt::transparent);
|
_pixmap.fill(Qt::transparent);
|
||||||
@ -330,9 +363,9 @@ void RasterTile::render()
|
|||||||
painter.setRenderHint(QPainter::Antialiasing);
|
painter.setRenderHint(QPainter::Antialiasing);
|
||||||
painter.translate(-_rect.x(), -_rect.y());
|
painter.translate(-_rect.x(), -_rect.y());
|
||||||
|
|
||||||
drawPaths(&painter, renderPaths);
|
drawPaths(&painter, paths, points, renderPaths);
|
||||||
|
|
||||||
processPointLabels(textItems);
|
processPointLabels(points, textItems);
|
||||||
processAreaLabels(textItems, renderPaths);
|
processAreaLabels(textItems, renderPaths);
|
||||||
processLineLabels(textItems, renderPaths);
|
processLineLabels(textItems, renderPaths);
|
||||||
drawTextItems(&painter, textItems);
|
drawTextItems(&painter, textItems);
|
||||||
|
@ -15,11 +15,10 @@ class RasterTile
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RasterTile(const Projection &proj, const Transform &transform,
|
RasterTile(const Projection &proj, const Transform &transform,
|
||||||
const Style *style, int zoom, const QRect &rect, qreal ratio,
|
const Style *style, MapData *data, int zoom, const QRect &rect,
|
||||||
const QList<MapData::Path> &paths, const QList<MapData::Point> &points)
|
qreal ratio) : _proj(proj), _transform(transform), _style(style),
|
||||||
: _proj(proj), _transform(transform), _style(style),
|
_data(data), _zoom(zoom), _rect(rect), _ratio(ratio),
|
||||||
_zoom(zoom), _rect(rect), _ratio(ratio), _pixmap(rect.width() * ratio,
|
_pixmap(rect.width() * ratio, rect.height() * ratio), _valid(false) {}
|
||||||
rect.height() * ratio), _paths(paths), _points(points), _valid(false) {}
|
|
||||||
|
|
||||||
int zoom() const {return _zoom;}
|
int zoom() const {return _zoom;}
|
||||||
QPoint xy() const {return _rect.topLeft();}
|
QPoint xy() const {return _rect.topLeft();}
|
||||||
@ -147,31 +146,33 @@ private:
|
|||||||
friend HASH_T qHash(const RasterTile::PathKey &key);
|
friend HASH_T qHash(const RasterTile::PathKey &key);
|
||||||
friend HASH_T qHash(const RasterTile::PointKey &key);
|
friend HASH_T qHash(const RasterTile::PointKey &key);
|
||||||
|
|
||||||
void pathInstructions(QVector<PainterPath> &paths,
|
void fetchData(QList<MapData::Path> &paths, QList<MapData::Point> &points);
|
||||||
|
void pathInstructions(const QList<MapData::Path> &paths,
|
||||||
|
QVector<PainterPath> &painterPaths,
|
||||||
|
QVector<RasterTile::RenderInstruction> &instructions);
|
||||||
|
void circleInstructions(const QList<MapData::Point> &points,
|
||||||
QVector<RasterTile::RenderInstruction> &instructions);
|
QVector<RasterTile::RenderInstruction> &instructions);
|
||||||
void circleInstructions(QVector<RasterTile::RenderInstruction> &instructions);
|
|
||||||
QPointF ll2xy(const Coordinates &c) const
|
QPointF ll2xy(const Coordinates &c) const
|
||||||
{return _transform.proj2img(_proj.ll2xy(c));}
|
{return _transform.proj2img(_proj.ll2xy(c));}
|
||||||
void processPointLabels(QList<TextItem*> &textItems);
|
void processPointLabels(const QList<MapData::Point> &points,
|
||||||
|
QList<TextItem*> &textItems);
|
||||||
void processAreaLabels(QList<TextItem*> &textItems,
|
void processAreaLabels(QList<TextItem*> &textItems,
|
||||||
QVector<PainterPath> &paths);
|
QVector<PainterPath> &paths);
|
||||||
void processLineLabels(QList<TextItem*> &textItems,
|
void processLineLabels(QList<TextItem*> &textItems,
|
||||||
QVector<PainterPath> &paths);
|
QVector<PainterPath> &paths);
|
||||||
QPainterPath painterPath(const Polygon &polygon, bool curve) const;
|
QPainterPath painterPath(const Polygon &polygon, bool curve) const;
|
||||||
void drawTextItems(QPainter *painter, const QList<TextItem*> &textItems);
|
void drawTextItems(QPainter *painter, const QList<TextItem*> &textItems);
|
||||||
void drawPaths(QPainter *painter, QVector<PainterPath> &paths);
|
void drawPaths(QPainter *painter, const QList<MapData::Path> &paths,
|
||||||
|
const QList<MapData::Point> &points, QVector<PainterPath> &painterPaths);
|
||||||
|
|
||||||
Projection _proj;
|
Projection _proj;
|
||||||
Transform _transform;
|
Transform _transform;
|
||||||
const Style *_style;
|
const Style *_style;
|
||||||
|
MapData *_data;
|
||||||
int _zoom;
|
int _zoom;
|
||||||
QRect _rect;
|
QRect _rect;
|
||||||
qreal _ratio;
|
qreal _ratio;
|
||||||
QPixmap _pixmap;
|
QPixmap _pixmap;
|
||||||
QList<MapData::Path> _paths;
|
|
||||||
QList<MapData::Point> _points;
|
|
||||||
|
|
||||||
bool _valid;
|
bool _valid;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2,15 +2,13 @@
|
|||||||
#include <QPixmapCache>
|
#include <QPixmapCache>
|
||||||
#include "common/wgs84.h"
|
#include "common/wgs84.h"
|
||||||
#include "common/util.h"
|
#include "common/util.h"
|
||||||
#include "pcs.h"
|
|
||||||
#include "rectd.h"
|
#include "rectd.h"
|
||||||
|
#include "pcs.h"
|
||||||
#include "mapsforgemap.h"
|
#include "mapsforgemap.h"
|
||||||
|
|
||||||
|
|
||||||
using namespace Mapsforge;
|
using namespace Mapsforge;
|
||||||
|
|
||||||
#define TEXT_EXTENT 160
|
|
||||||
|
|
||||||
MapsforgeMap::MapsforgeMap(const QString &fileName, QObject *parent)
|
MapsforgeMap::MapsforgeMap(const QString &fileName, QObject *parent)
|
||||||
: Map(fileName, parent), _data(fileName), _zoom(0),
|
: Map(fileName, parent), _data(fileName), _zoom(0),
|
||||||
_projection(PCS::pcs(3857)), _tileRatio(1.0)
|
_projection(PCS::pcs(3857)), _tileRatio(1.0)
|
||||||
@ -188,33 +186,9 @@ void MapsforgeMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
|
|||||||
if (QPixmapCache::find(key(_zoom, ttl), &pm))
|
if (QPixmapCache::find(key(_zoom, ttl), &pm))
|
||||||
painter->drawPixmap(ttl, pm);
|
painter->drawPixmap(ttl, pm);
|
||||||
else {
|
else {
|
||||||
QList<MapData::Path> paths;
|
tiles.append(RasterTile(_projection, _transform, &_style, &_data,
|
||||||
QList<MapData::Point> points;
|
_zoom, QRect(ttl, QSize(_data.tileSize(), _data.tileSize())),
|
||||||
|
_tileRatio));
|
||||||
/* Add a "sub-pixel" margin to assure the tile areas do not
|
|
||||||
overlap on the border lines. This prevents areas overlap
|
|
||||||
artifacts at least when using the EPSG:3857 projection. */
|
|
||||||
QRectF pathRect(QPointF(ttl.x() + 0.5, ttl.y() + 0.5),
|
|
||||||
QPointF(ttl.x() + _data.tileSize() - 0.5, ttl.y()
|
|
||||||
+ _data.tileSize() - 0.5));
|
|
||||||
pathRect &= _bounds;
|
|
||||||
RectD pathRectD(_transform.img2proj(pathRect.topLeft()),
|
|
||||||
_transform.img2proj(pathRect.bottomRight()));
|
|
||||||
_data.paths(pathRectD.toRectC(_projection, 20), _zoom, &paths);
|
|
||||||
|
|
||||||
QRectF pointRect(QPointF(ttl.x() - TEXT_EXTENT, ttl.y()
|
|
||||||
- TEXT_EXTENT), QPointF(ttl.x() + _data.tileSize()
|
|
||||||
+ TEXT_EXTENT, ttl.y() + _data.tileSize() + TEXT_EXTENT));
|
|
||||||
pointRect &= _bounds;
|
|
||||||
RectD pointRectD(_transform.img2proj(pointRect.topLeft()),
|
|
||||||
_transform.img2proj(pointRect.bottomRight()));
|
|
||||||
_data.points(pointRectD.toRectC(_projection, 20), _zoom,
|
|
||||||
&points);
|
|
||||||
|
|
||||||
if (paths.size() || points.size())
|
|
||||||
tiles.append(RasterTile(_projection, _transform, &_style,
|
|
||||||
_zoom, QRect(ttl, QSize(_data.tileSize(), _data.tileSize())),
|
|
||||||
_tileRatio, paths, points));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user