mirror of
https://github.com/tumic0/GPXSee.git
synced 2024-11-30 22:51:16 +01:00
Provide propper map bounds for overviews
This commit is contained in:
parent
4cef089c81
commit
239e571358
@ -1,3 +1,4 @@
|
|||||||
|
#include <cmath>
|
||||||
#include <QCursor>
|
#include <QCursor>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QGraphicsSceneMouseEvent>
|
#include <QGraphicsSceneMouseEvent>
|
||||||
@ -8,6 +9,66 @@
|
|||||||
#include "mapitem.h"
|
#include "mapitem.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void growLeft(Map *map, const Coordinates &c, QRectF &rect)
|
||||||
|
{
|
||||||
|
QPointF p(map->ll2xy(c));
|
||||||
|
|
||||||
|
if (p.x() < rect.left())
|
||||||
|
rect.setLeft(p.x());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void growRight(Map *map, const Coordinates &c, QRectF &rect)
|
||||||
|
{
|
||||||
|
|
||||||
|
QPointF p(map->ll2xy(c));
|
||||||
|
|
||||||
|
if (p.x() > rect.right())
|
||||||
|
rect.setRight(p.x());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void growTop(Map *map, const Coordinates &c, QRectF &rect)
|
||||||
|
{
|
||||||
|
QPointF p(map->ll2xy(c));
|
||||||
|
|
||||||
|
if (p.y() > rect.top())
|
||||||
|
rect.setTop(p.y());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void growBottom(Map *map, const Coordinates &c, QRectF &rect)
|
||||||
|
{
|
||||||
|
QPointF p(map->ll2xy(c));
|
||||||
|
|
||||||
|
if (p.y() < rect.bottom())
|
||||||
|
rect.setBottom(p.y());
|
||||||
|
}
|
||||||
|
|
||||||
|
static QRectF bbox(const RectC &rect, Map *map, int samples = 100)
|
||||||
|
{
|
||||||
|
if (!rect.isValid())
|
||||||
|
return QRectF();
|
||||||
|
|
||||||
|
double dx = rect.width() / samples;
|
||||||
|
double dy = rect.height() / samples;
|
||||||
|
|
||||||
|
QPointF tl(map->ll2xy(rect.topLeft()));
|
||||||
|
QPointF br(map->ll2xy(rect.bottomRight()));
|
||||||
|
QRectF prect(tl, br);
|
||||||
|
|
||||||
|
for (int i = 0; i <= samples; i++) {
|
||||||
|
double x = remainder(rect.left() + i * dx, 360.0);
|
||||||
|
growTop(map, Coordinates(x, rect.bottom()), prect);
|
||||||
|
growBottom(map, Coordinates(x, rect.top()), prect);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i <= samples; i++) {
|
||||||
|
double y = rect.bottom() + i * dy;
|
||||||
|
growLeft(map, Coordinates(rect.left(), y), prect);
|
||||||
|
growRight(map, Coordinates(rect.right(), y), prect);
|
||||||
|
}
|
||||||
|
|
||||||
|
return prect;
|
||||||
|
}
|
||||||
|
|
||||||
QString MapItem::info() const
|
QString MapItem::info() const
|
||||||
{
|
{
|
||||||
ToolTip tt;
|
ToolTip tt;
|
||||||
@ -28,8 +89,9 @@ MapItem::MapItem(MapAction *action, Map *map, GraphicsItem *parent)
|
|||||||
|
|
||||||
_name = src->name();
|
_name = src->name();
|
||||||
_fileName = src->path();
|
_fileName = src->path();
|
||||||
_bounds = RectC(src->xy2ll(src->bounds().topLeft()),
|
// Zoom to the maximal zoom level to get the most accurate bounds
|
||||||
src->xy2ll(src->bounds().bottomRight()));
|
src->zoomFit(QSize(), RectC());
|
||||||
|
_bounds = src->llBounds();
|
||||||
|
|
||||||
connect(this, SIGNAL(triggered()), action, SLOT(trigger()));
|
connect(this, SIGNAL(triggered()), action, SLOT(trigger()));
|
||||||
|
|
||||||
@ -51,23 +113,18 @@ void MapItem::updatePainterPath()
|
|||||||
{
|
{
|
||||||
_painterPath = QPainterPath();
|
_painterPath = QPainterPath();
|
||||||
|
|
||||||
if (_bounds.left() > _bounds.right()) {
|
QRectF r(bbox(_bounds, _map));
|
||||||
QRectF r1(_map->ll2xy(_bounds.topLeft()), _map->ll2xy(Coordinates(180,
|
|
||||||
_bounds.bottomRight().lat())));
|
if (r.left() > r.right()) {
|
||||||
QRectF r2(_map->ll2xy(Coordinates(-180, _bounds.topLeft().lat())),
|
QRectF r1(bbox(RectC(_bounds.topLeft(),
|
||||||
_map->ll2xy(_bounds.bottomRight()));
|
Coordinates(180, _bounds.bottomRight().lat())), _map));
|
||||||
QRectF r(_map->ll2xy(_bounds.topLeft()),
|
QRectF r2(bbox(RectC(Coordinates(-180, _bounds.topLeft().lat()),
|
||||||
_map->ll2xy(_bounds.bottomRight()));
|
_bounds.bottomRight()), _map));
|
||||||
|
|
||||||
if (r1.united(r2) == r)
|
|
||||||
_painterPath.addRect(r);
|
|
||||||
else {
|
|
||||||
_painterPath.addRect(r1);
|
_painterPath.addRect(r1);
|
||||||
_painterPath.addRect(r2);
|
_painterPath.addRect(r2);
|
||||||
}
|
|
||||||
} else
|
} else
|
||||||
_painterPath.addRect(QRectF(_map->ll2xy(_bounds.topLeft()),
|
_painterPath.addRect(r);
|
||||||
_map->ll2xy(_bounds.bottomRight())));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
|
void MapItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
|
||||||
|
@ -294,8 +294,7 @@ int MapView::fitMapZoom() const
|
|||||||
RectC br = _tr | _rr | _wr | _ar;
|
RectC br = _tr | _rr | _wr | _ar;
|
||||||
|
|
||||||
return _map->zoomFit(viewport()->size() - QSize(2*MARGIN, 2*MARGIN),
|
return _map->zoomFit(viewport()->size() - QSize(2*MARGIN, 2*MARGIN),
|
||||||
br.isNull() ? RectC(_map->xy2ll(_map->bounds().topLeft()),
|
br.isNull() ? _map->llBounds() : br);
|
||||||
_map->xy2ll(_map->bounds().bottomRight())) : br);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QPointF MapView::contentCenter() const
|
QPointF MapView::contentCenter() const
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#include <QtGlobal>
|
#include <QtGlobal>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include "common/rectc.h"
|
#include "common/rectc.h"
|
||||||
#include "osm.h"
|
|
||||||
#include "emptymap.h"
|
#include "emptymap.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#ifndef EMPTYMAP_H
|
#ifndef EMPTYMAP_H
|
||||||
#define EMPTYMAP_H
|
#define EMPTYMAP_H
|
||||||
|
|
||||||
|
#include "osm.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
|
|
||||||
class EmptyMap : public Map
|
class EmptyMap : public Map
|
||||||
@ -13,6 +14,7 @@ public:
|
|||||||
QString name() const {return QString();}
|
QString name() const {return QString();}
|
||||||
|
|
||||||
QRectF bounds();
|
QRectF bounds();
|
||||||
|
RectC llBounds() {return OSM::BOUNDS;}
|
||||||
qreal resolution(const QRectF &rect);
|
qreal resolution(const QRectF &rect);
|
||||||
|
|
||||||
int zoom() const {return _zoom;}
|
int zoom() const {return _zoom;}
|
||||||
|
@ -18,6 +18,7 @@ public:
|
|||||||
QString name() const {return _data.first()->name();}
|
QString name() const {return _data.first()->name();}
|
||||||
|
|
||||||
QRectF bounds() {return _bounds;}
|
QRectF bounds() {return _bounds;}
|
||||||
|
RectC llBounds() {return _dataBounds;}
|
||||||
|
|
||||||
int zoom() const {return _zoom;}
|
int zoom() const {return _zoom;}
|
||||||
void setZoom(int zoom);
|
void setZoom(int zoom);
|
||||||
|
@ -20,6 +20,7 @@ public:
|
|||||||
QString name() const {return _name;}
|
QString name() const {return _name;}
|
||||||
|
|
||||||
QRectF bounds();
|
QRectF bounds();
|
||||||
|
RectC llBounds() {return _bounds;}
|
||||||
|
|
||||||
int zoom() const {return _zoom;}
|
int zoom() const {return _zoom;}
|
||||||
void setZoom(int zoom) {_zoom = zoom;}
|
void setZoom(int zoom) {_zoom = zoom;}
|
||||||
|
@ -1,6 +1,67 @@
|
|||||||
|
#include <cmath>
|
||||||
#include <QLineF>
|
#include <QLineF>
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define SAMPLES 100
|
||||||
|
|
||||||
|
void Map::growLeft(const QPointF &p, RectC &rect)
|
||||||
|
{
|
||||||
|
Coordinates c(xy2ll(p));
|
||||||
|
|
||||||
|
if (c.lon() < rect.left())
|
||||||
|
rect.setLeft(c.lon());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Map::growRight(const QPointF &p, RectC &rect)
|
||||||
|
{
|
||||||
|
Coordinates c(xy2ll(p));
|
||||||
|
|
||||||
|
if (c.lon() > rect.right())
|
||||||
|
rect.setRight(c.lon());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Map::growTop(const QPointF &p, RectC &rect)
|
||||||
|
{
|
||||||
|
Coordinates c(xy2ll(p));
|
||||||
|
|
||||||
|
if (c.lat() > rect.top())
|
||||||
|
rect.setTop(c.lat());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Map::growBottom(const QPointF &p, RectC &rect)
|
||||||
|
{
|
||||||
|
Coordinates c(xy2ll(p));
|
||||||
|
|
||||||
|
if (c.lat() < rect.bottom())
|
||||||
|
rect.setBottom(c.lat());
|
||||||
|
}
|
||||||
|
|
||||||
|
RectC Map::llBounds()
|
||||||
|
{
|
||||||
|
QRectF b(bounds());
|
||||||
|
double dx = b.width() / SAMPLES;
|
||||||
|
double dy = b.height() / SAMPLES;
|
||||||
|
|
||||||
|
Coordinates tl(xy2ll(b.topLeft()));
|
||||||
|
Coordinates br(xy2ll(b.bottomRight()));
|
||||||
|
RectC rect(tl, br);
|
||||||
|
|
||||||
|
for (int i = 0; i <= SAMPLES; i++) {
|
||||||
|
double x = b.left() + i * dx;
|
||||||
|
growBottom(QPointF(x, b.bottom()), rect);
|
||||||
|
growTop(QPointF(x, b.top()), rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i <= SAMPLES; i++) {
|
||||||
|
double y = b.top() + i * dy;
|
||||||
|
growLeft(QPointF(b.left(), y), rect);
|
||||||
|
growRight(QPointF(b.right(), y), rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
|
|
||||||
qreal Map::resolution(const QRectF &rect)
|
qreal Map::resolution(const QRectF &rect)
|
||||||
{
|
{
|
||||||
qreal cy = rect.center().y();
|
qreal cy = rect.center().y();
|
||||||
|
@ -5,11 +5,10 @@
|
|||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QRectF>
|
#include <QRectF>
|
||||||
#include <QFlags>
|
#include <QFlags>
|
||||||
#include "common/coordinates.h"
|
#include "common/rectc.h"
|
||||||
|
|
||||||
|
|
||||||
class QPainter;
|
class QPainter;
|
||||||
class RectC;
|
|
||||||
class Projection;
|
class Projection;
|
||||||
|
|
||||||
class Map : public QObject
|
class Map : public QObject
|
||||||
@ -31,6 +30,7 @@ public:
|
|||||||
const QString &path() const {return _path;}
|
const QString &path() const {return _path;}
|
||||||
virtual QString name() const = 0;
|
virtual QString name() const = 0;
|
||||||
|
|
||||||
|
virtual RectC llBounds();
|
||||||
virtual QRectF bounds() = 0;
|
virtual QRectF bounds() = 0;
|
||||||
virtual qreal resolution(const QRectF &rect);
|
virtual qreal resolution(const QRectF &rect);
|
||||||
|
|
||||||
@ -60,6 +60,11 @@ signals:
|
|||||||
void mapLoaded();
|
void mapLoaded();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void growLeft(const QPointF &p, RectC &rect);
|
||||||
|
void growRight(const QPointF &p, RectC &rect);
|
||||||
|
void growTop(const QPointF &p, RectC &rect);
|
||||||
|
void growBottom(const QPointF &p, RectC &rect);
|
||||||
|
|
||||||
QString _path;
|
QString _path;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ public:
|
|||||||
QString name() const {return _name;}
|
QString name() const {return _name;}
|
||||||
|
|
||||||
QRectF bounds();
|
QRectF bounds();
|
||||||
|
RectC llBounds() {return _bounds;}
|
||||||
qreal resolution(const QRectF &rect);
|
qreal resolution(const QRectF &rect);
|
||||||
|
|
||||||
int zoom() const {return _zoom;}
|
int zoom() const {return _zoom;}
|
||||||
|
@ -19,6 +19,7 @@ public:
|
|||||||
QString name() const {return _name;}
|
QString name() const {return _name;}
|
||||||
|
|
||||||
QRectF bounds();
|
QRectF bounds();
|
||||||
|
RectC llBounds() {return _bounds;}
|
||||||
qreal resolution(const QRectF &rect);
|
qreal resolution(const QRectF &rect);
|
||||||
|
|
||||||
int zoom() const {return _zoom;}
|
int zoom() const {return _zoom;}
|
||||||
|
@ -4,69 +4,92 @@
|
|||||||
#include "rectd.h"
|
#include "rectd.h"
|
||||||
|
|
||||||
|
|
||||||
static void growRect(const Projection &proj, const Coordinates &c, RectD &rect)
|
static void growLeft(const Projection &proj, const Coordinates &c, RectD &rect)
|
||||||
{
|
{
|
||||||
if (c.isNull())
|
|
||||||
return;
|
|
||||||
|
|
||||||
PointD p(proj.ll2xy(c));
|
PointD p(proj.ll2xy(c));
|
||||||
|
|
||||||
if (rect.isNull())
|
|
||||||
rect = RectD(p, p);
|
|
||||||
else {
|
|
||||||
if (p.x() < rect.left())
|
if (p.x() < rect.left())
|
||||||
rect.setLeft(p.x());
|
rect.setLeft(p.x());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void growRight(const Projection &proj, const Coordinates &c, RectD &rect)
|
||||||
|
{
|
||||||
|
PointD p(proj.ll2xy(c));
|
||||||
|
|
||||||
if (p.x() > rect.right())
|
if (p.x() > rect.right())
|
||||||
rect.setRight(p.x());
|
rect.setRight(p.x());
|
||||||
if (p.y() < rect.bottom())
|
}
|
||||||
rect.setBottom(p.y());
|
|
||||||
|
static void growTop(const Projection &proj, const Coordinates &c, RectD &rect)
|
||||||
|
{
|
||||||
|
PointD p(proj.ll2xy(c));
|
||||||
|
|
||||||
if (p.y() > rect.top())
|
if (p.y() > rect.top())
|
||||||
rect.setTop(p.y());
|
rect.setTop(p.y());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void growBottom(const Projection &proj, const Coordinates &c, RectD &rect)
|
||||||
|
{
|
||||||
|
PointD p(proj.ll2xy(c));
|
||||||
|
|
||||||
|
if (p.y() < rect.bottom())
|
||||||
|
rect.setBottom(p.y());
|
||||||
}
|
}
|
||||||
|
|
||||||
static void growRect(const Projection &proj, const PointD &p, RectC &rect)
|
static void growLeft(const Projection &proj, const PointD &p, RectC &rect)
|
||||||
{
|
{
|
||||||
if (p.isNull())
|
|
||||||
return;
|
|
||||||
|
|
||||||
Coordinates c(proj.xy2ll(p));
|
Coordinates c(proj.xy2ll(p));
|
||||||
|
|
||||||
if (rect.isNull())
|
|
||||||
rect = RectC(c, c);
|
|
||||||
else {
|
|
||||||
if (c.lon() < rect.left())
|
if (c.lon() < rect.left())
|
||||||
rect.setLeft(c.lon());
|
rect.setLeft(c.lon());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void growRight(const Projection &proj, const PointD &p, RectC &rect)
|
||||||
|
{
|
||||||
|
Coordinates c(proj.xy2ll(p));
|
||||||
|
|
||||||
if (c.lon() > rect.right())
|
if (c.lon() > rect.right())
|
||||||
rect.setRight(c.lon());
|
rect.setRight(c.lon());
|
||||||
if (c.lat() < rect.bottom())
|
}
|
||||||
rect.setBottom(c.lat());
|
|
||||||
|
static void growTop(const Projection &proj, const PointD &p, RectC &rect)
|
||||||
|
{
|
||||||
|
Coordinates c(proj.xy2ll(p));
|
||||||
|
|
||||||
if (c.lat() > rect.top())
|
if (c.lat() > rect.top())
|
||||||
rect.setTop(c.lat());
|
rect.setTop(c.lat());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void growBottom(const Projection &proj, const PointD &p, RectC &rect)
|
||||||
|
{
|
||||||
|
Coordinates c(proj.xy2ll(p));
|
||||||
|
|
||||||
|
if (c.lat() < rect.bottom())
|
||||||
|
rect.setBottom(c.lat());
|
||||||
}
|
}
|
||||||
|
|
||||||
RectD::RectD(const RectC &rect, const Projection &proj, int samples)
|
RectD::RectD(const RectC &rect, const Projection &proj, int samples)
|
||||||
{
|
{
|
||||||
RectD prect;
|
if (!rect.isValid())
|
||||||
|
return;
|
||||||
|
|
||||||
if (rect.isValid()) {
|
|
||||||
double dx = rect.width() / samples;
|
double dx = rect.width() / samples;
|
||||||
double dy = rect.height() / samples;
|
double dy = rect.height() / samples;
|
||||||
|
|
||||||
growRect(proj, rect.topLeft(), prect);
|
PointD tl(proj.ll2xy(rect.topLeft()));
|
||||||
|
PointD br(proj.ll2xy(rect.bottomRight()));
|
||||||
|
RectD prect(tl, br);
|
||||||
|
|
||||||
for (int i = 0; i <= samples; i++) {
|
for (int i = 0; i <= samples; i++) {
|
||||||
double x = remainder(rect.left() + i * dx, 360.0);
|
double x = remainder(rect.left() + i * dx, 360.0);
|
||||||
growRect(proj, Coordinates(x, rect.bottom()), prect);
|
growBottom(proj, Coordinates(x, rect.bottom()), prect);
|
||||||
growRect(proj, Coordinates(x, rect.top()), prect);
|
growTop(proj, Coordinates(x, rect.top()), prect);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i <= samples; i++) {
|
for (int i = 0; i <= samples; i++) {
|
||||||
double y = rect.bottom() + i * dy;
|
double y = rect.bottom() + i * dy;
|
||||||
growRect(proj, Coordinates(rect.left(), y), prect);
|
growLeft(proj, Coordinates(rect.left(), y), prect);
|
||||||
growRect(proj, Coordinates(rect.right(), y), prect);
|
growRight(proj, Coordinates(rect.right(), y), prect);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*this = prect;
|
*this = prect;
|
||||||
@ -77,22 +100,23 @@ RectC RectD::toRectC(const Projection &proj, int samples) const
|
|||||||
if (!isValid())
|
if (!isValid())
|
||||||
return RectC();
|
return RectC();
|
||||||
|
|
||||||
RectC rect;
|
|
||||||
double dx = width() / samples;
|
double dx = width() / samples;
|
||||||
double dy = height() / samples;
|
double dy = height() / samples;
|
||||||
|
|
||||||
growRect(proj, topLeft(), rect);
|
Coordinates tl(proj.xy2ll(topLeft()));
|
||||||
|
Coordinates br(proj.xy2ll(bottomRight()));
|
||||||
|
RectC rect(tl, br);
|
||||||
|
|
||||||
for (int i = 0; i <= samples; i++) {
|
for (int i = 0; i <= samples; i++) {
|
||||||
double x = left() + i * dx;
|
double x = left() + i * dx;
|
||||||
growRect(proj, PointD(x, bottom()), rect);
|
growBottom(proj, PointD(x, bottom()), rect);
|
||||||
growRect(proj, PointD(x, top()), rect);
|
growTop(proj, PointD(x, top()), rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i <= samples; i++) {
|
for (int i = 0; i <= samples; i++) {
|
||||||
double y = bottom() + i * dy;
|
double y = bottom() + i * dy;
|
||||||
growRect(proj, PointD(left(), y), rect);
|
growLeft(proj, PointD(left(), y), rect);
|
||||||
growRect(proj, PointD(right(), y), rect);
|
growRight(proj, PointD(right(), y), rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rect;
|
return rect;
|
||||||
|
@ -20,6 +20,7 @@ public:
|
|||||||
QString name() const {return _name;}
|
QString name() const {return _name;}
|
||||||
|
|
||||||
QRectF bounds();
|
QRectF bounds();
|
||||||
|
RectC llBounds() {return _wms->bbox();}
|
||||||
|
|
||||||
int zoom() const {return _zoom;}
|
int zoom() const {return _zoom;}
|
||||||
void setZoom(int zoom);
|
void setZoom(int zoom);
|
||||||
|
@ -85,6 +85,7 @@ QRectF WMTSMap::bounds()
|
|||||||
bounds = QRectF(_transform.proj2img(_bounds.topLeft())
|
bounds = QRectF(_transform.proj2img(_bounds.topLeft())
|
||||||
/ coordinatesRatio(), _transform.proj2img(
|
/ coordinatesRatio(), _transform.proj2img(
|
||||||
_bounds.bottomRight()) / coordinatesRatio());
|
_bounds.bottomRight()) / coordinatesRatio());
|
||||||
|
|
||||||
return bounds.isValid() ? tileBounds.intersected(bounds) : tileBounds;
|
return bounds.isValid() ? tileBounds.intersected(bounds) : tileBounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user