1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2024-11-24 11:45:53 +01:00

Make the source projection of JNX and KMZ maps selectable

This commit is contained in:
Martin Tůma 2020-12-24 16:33:17 +01:00
parent 50d4ca1690
commit dde8e9a22c
13 changed files with 222 additions and 71 deletions

View File

@ -973,7 +973,8 @@ void GUI::openOptions()
SET_VIEW_OPTION(pathAntiAliasing, useAntiAliasing); SET_VIEW_OPTION(pathAntiAliasing, useAntiAliasing);
SET_VIEW_OPTION(useOpenGL, useOpenGL); SET_VIEW_OPTION(useOpenGL, useOpenGL);
SET_VIEW_OPTION(sliderColor, setMarkerColor); SET_VIEW_OPTION(sliderColor, setMarkerColor);
SET_VIEW_OPTION(projection, setProjection); SET_VIEW_OPTION(outputProjection, setOutputProjection);
SET_VIEW_OPTION(inputProjection, setInputProjection);
SET_TAB_OPTION(palette, setPalette); SET_TAB_OPTION(palette, setPalette);
SET_TAB_OPTION(graphWidth, setGraphWidth); SET_TAB_OPTION(graphWidth, setGraphWidth);
@ -2149,8 +2150,10 @@ void GUI::writeSettings()
_options.separateGraphPage); _options.separateGraphPage);
if (_options.sliderColor != SLIDER_COLOR_DEFAULT) if (_options.sliderColor != SLIDER_COLOR_DEFAULT)
settings.setValue(SLIDER_COLOR_SETTING, _options.sliderColor); settings.setValue(SLIDER_COLOR_SETTING, _options.sliderColor);
if (_options.projection != PROJECTION_DEFAULT) if (_options.outputProjection != OUTPUT_PROJECTION_DEFAULT)
settings.setValue(PROJECTION_SETTING, _options.projection); settings.setValue(OUTPUT_PROJECTION_SETTING, _options.outputProjection);
if (_options.inputProjection != INPUT_PROJECTION_DEFAULT)
settings.setValue(INPUT_PROJECTION_SETTING, _options.outputProjection);
if (_options.hidpiMap != HIDPI_MAP_DEFAULT) if (_options.hidpiMap != HIDPI_MAP_DEFAULT)
settings.setValue(HIDPI_MAP_SETTING, _options.hidpiMap); settings.setValue(HIDPI_MAP_SETTING, _options.hidpiMap);
settings.endGroup(); settings.endGroup();
@ -2442,8 +2445,10 @@ void GUI::readSettings()
SEPARATE_GRAPH_PAGE_DEFAULT).toBool(); SEPARATE_GRAPH_PAGE_DEFAULT).toBool();
_options.sliderColor = settings.value(SLIDER_COLOR_SETTING, _options.sliderColor = settings.value(SLIDER_COLOR_SETTING,
SLIDER_COLOR_DEFAULT).value<QColor>(); SLIDER_COLOR_DEFAULT).value<QColor>();
_options.projection = settings.value(PROJECTION_SETTING, PROJECTION_DEFAULT) _options.outputProjection = settings.value(OUTPUT_PROJECTION_SETTING,
.toInt(); OUTPUT_PROJECTION_DEFAULT).toInt();
_options.inputProjection = settings.value(INPUT_PROJECTION_SETTING,
INPUT_PROJECTION_DEFAULT).toInt();
_options.hidpiMap = settings.value(HIDPI_MAP_SETTING, HIDPI_MAP_SETTING) _options.hidpiMap = settings.value(HIDPI_MAP_SETTING, HIDPI_MAP_SETTING)
.toBool(); .toBool();
@ -2467,7 +2472,8 @@ void GUI::readSettings()
_mapView->useOpenGL(true); _mapView->useOpenGL(true);
_mapView->setDevicePixelRatio(devicePixelRatioF(), _mapView->setDevicePixelRatio(devicePixelRatioF(),
_options.hidpiMap ? devicePixelRatioF() : 1.0); _options.hidpiMap ? devicePixelRatioF() : 1.0);
_mapView->setProjection(_options.projection); _mapView->setOutputProjection(_options.outputProjection);
_mapView->setInputProjection(_options.inputProjection);
_mapView->setTimeZone(_options.timeZone.zone()); _mapView->setTimeZone(_options.timeZone.zone());
for (int i = 0; i < _tabs.count(); i++) { for (int i = 0; i < _tabs.count(); i++) {

View File

@ -67,10 +67,12 @@ MapView::MapView(Map *map, POI *poi, QWidget *parent)
_coordinates->setVisible(false); _coordinates->setVisible(false);
_scene->addItem(_coordinates); _scene->addItem(_coordinates);
_projection = PCS::pcs(3857); _outputProjection = PCS::pcs(3857);
_inputProjection = GCS::gcs(4326);
_map = map; _map = map;
_map->load(); _map->load();
_map->setProjection(_projection); _map->setOutputProjection(_outputProjection);
_map->setInputProjection(_inputProjection);
connect(_map, SIGNAL(tilesLoaded()), this, SLOT(reloadMap())); connect(_map, SIGNAL(tilesLoaded()), this, SLOT(reloadMap()));
_poi = poi; _poi = poi;
@ -369,7 +371,8 @@ void MapView::setMap(Map *map)
_map = map; _map = map;
_map->load(); _map->load();
_map->setProjection(_projection); _map->setOutputProjection(_outputProjection);
_map->setInputProjection(_inputProjection);
_map->setDevicePixelRatio(_deviceRatio, _mapRatio); _map->setDevicePixelRatio(_deviceRatio, _mapRatio);
connect(_map, SIGNAL(tilesLoaded()), this, SLOT(reloadMap())); connect(_map, SIGNAL(tilesLoaded()), this, SLOT(reloadMap()));
@ -1072,20 +1075,38 @@ void MapView::setDevicePixelRatio(qreal deviceRatio, qreal mapRatio)
reloadMap(); reloadMap();
} }
void MapView::setProjection(int id) void MapView::setOutputProjection(int id)
{ {
const PCS *pcs; const PCS *pcs;
const GCS *gcs; const GCS *gcs;
Coordinates center = _map->xy2ll(mapToScene(viewport()->rect().center())); Coordinates center = _map->xy2ll(mapToScene(viewport()->rect().center()));
if ((pcs = PCS::pcs(id))) if ((pcs = PCS::pcs(id)))
_projection = Projection(pcs); _outputProjection = Projection(pcs);
else if ((gcs = GCS::gcs(id))) else if ((gcs = GCS::gcs(id)))
_projection = Projection(gcs); _outputProjection = Projection(gcs);
else else
qWarning("%d: Unknown PCS/GCS id", id); qWarning("%d: Unknown PCS/GCS id", id);
_map->setProjection(_projection); _map->setOutputProjection(_outputProjection);
rescale();
centerOn(_map->ll2xy(center));
}
void MapView::setInputProjection(int id)
{
const PCS *pcs;
const GCS *gcs;
Coordinates center = _map->xy2ll(mapToScene(viewport()->rect().center()));
if ((pcs = PCS::pcs(id)))
_inputProjection = Projection(pcs);
else if ((gcs = GCS::gcs(id)))
_inputProjection = Projection(gcs);
else
qWarning("%d: Unknown PCS/GCS id", id);
_map->setInputProjection(_inputProjection);
rescale(); rescale();
centerOn(_map->ll2xy(center)); centerOn(_map->ll2xy(center));
} }

View File

@ -98,7 +98,8 @@ public slots:
void setCoordinatesFormat(CoordinatesFormat format); void setCoordinatesFormat(CoordinatesFormat format);
void setTimeZone(const QTimeZone &zone); void setTimeZone(const QTimeZone &zone);
void setDevicePixelRatio(qreal deviceRatio, qreal mapRatio); void setDevicePixelRatio(qreal deviceRatio, qreal mapRatio);
void setProjection(int id); void setOutputProjection(int id);
void setInputProjection(int id);
void fitContentToSize(); void fitContentToSize();
@ -155,7 +156,7 @@ private:
Palette _palette; Palette _palette;
qreal _mapOpacity; qreal _mapOpacity;
Projection _projection; Projection _outputProjection, _inputProjection;
bool _showMap, _showTracks, _showRoutes, _showAreas, _showWaypoints, bool _showMap, _showTracks, _showRoutes, _showAreas, _showWaypoints,
_showWaypointLabels, _showPOI, _showPOILabels, _showRouteWaypoints, _showWaypointLabels, _showPOI, _showPOILabels, _showRouteWaypoints,

View File

@ -46,17 +46,52 @@ void OptionsDialog::automaticPauseDetectionSet(bool set)
QWidget *OptionsDialog::createMapPage() QWidget *OptionsDialog::createMapPage()
{ {
_projection = new LimitedComboBox(200); int last = -1;
_outputProjection = new LimitedComboBox(200);
QList<KV<int, QString> > projections(GCS::list() + PCS::list()); QList<KV<int, QString> > projections(GCS::list() + PCS::list());
std::sort(projections.begin(), projections.end()); std::sort(projections.begin(), projections.end());
for (int i = 0; i < projections.size(); i++) { for (int i = 0; i < projections.size(); i++) {
QString text = QString::number(projections.at(i).key()) + " - " const KV<int, QString> &proj = projections.at(i);
+ projections.at(i).value(); // There may be same EPSG codes with different names
_projection->addItem(text, QVariant(projections.at(i).key())); if (proj.key() == last)
continue;
else
last = proj.key();
QString text = QString::number(proj.key()) + " - " + proj.value();
_outputProjection->addItem(text, QVariant(proj.key()));
} }
_projection->setCurrentIndex(_projection->findData(_options.projection)); _outputProjection->setCurrentIndex(_outputProjection->findData(
_options.outputProjection));
_inputProjection = new LimitedComboBox(200);
last = -1;
for (int i = 0; i < projections.size(); i++) {
const KV<int, QString> &proj = projections.at(i);
// There may be same EPSG codes with different names
if (proj.key() == last)
continue;
else
last = proj.key();
if (proj.key() == 4326 || proj.key() == 3857) {
QString text = QString::number(proj.key()) + " - " + proj.value();
_inputProjection->addItem(text, QVariant(proj.key()));
}
}
_inputProjection->setCurrentIndex(_inputProjection->findData(
_options.inputProjection));
QLabel *inInfo = new QLabel(tr("Select the propper projection of"
" JNX and KMZ maps. Both EPSG:3857 and EPSG:4326 projected maps"
" exist and there is no projection info in the map file."));
QLabel *outInfo = new QLabel(tr("Select the desired projection of IMG"
" maps. The projection must be valid for the whole map area."));
QFont f = inInfo->font();
f.setPointSize(f.pointSize() - 1);
inInfo->setWordWrap(true);
outInfo->setWordWrap(true);
inInfo->setFont(f);
outInfo->setFont(f);
_hidpi = new QRadioButton(tr("High-resolution")); _hidpi = new QRadioButton(tr("High-resolution"));
_lodpi = new QRadioButton(tr("Standard")); _lodpi = new QRadioButton(tr("Standard"));
@ -68,21 +103,24 @@ QWidget *OptionsDialog::createMapPage()
"The map is sharp but map objects are small/hard to read.")); "The map is sharp but map objects are small/hard to read."));
QLabel *llo = new QLabel(tr("Non-HiDPI maps are loaded such as they are. " QLabel *llo = new QLabel(tr("Non-HiDPI maps are loaded such as they are. "
"Map objects have the expected size but the map is blurry.")); "Map objects have the expected size but the map is blurry."));
QFont f = lhi->font();
f.setPointSize(f.pointSize() - 1); f.setPointSize(f.pointSize() - 1);
lhi->setWordWrap(true); lhi->setWordWrap(true);
llo->setWordWrap(true); llo->setWordWrap(true);
lhi->setFont(f); lhi->setFont(f);
llo->setFont(f); llo->setFont(f);
QFormLayout *vectorLayout = new QFormLayout();
vectorLayout->addRow(tr("Projection:"), _projection);
QWidget *vectorMapsTab = new QWidget(); QFormLayout *projLayout = new QFormLayout();
QVBoxLayout *vectorMapsTabLayout = new QVBoxLayout(); projLayout->addRow(tr("Input:"), _inputProjection);
vectorMapsTabLayout->addLayout(vectorLayout); projLayout->addWidget(inInfo);
vectorMapsTabLayout->addStretch(); projLayout->addRow(tr("Output:"), _outputProjection);
vectorMapsTab->setLayout(vectorMapsTabLayout); projLayout->addWidget(outInfo);
QWidget *projectionTab = new QWidget();
QVBoxLayout *projectionTabLayout = new QVBoxLayout();
projectionTabLayout->addLayout(projLayout);
projectionTabLayout->addStretch();
projectionTab->setLayout(projectionTabLayout);
QVBoxLayout *hidpiTabLayout = new QVBoxLayout(); QVBoxLayout *hidpiTabLayout = new QVBoxLayout();
hidpiTabLayout->addWidget(_lodpi); hidpiTabLayout->addWidget(_lodpi);
@ -96,7 +134,7 @@ QWidget *OptionsDialog::createMapPage()
hidpiTab->setLayout(hidpiTabLayout); hidpiTab->setLayout(hidpiTabLayout);
QTabWidget *mapPage = new QTabWidget(); QTabWidget *mapPage = new QTabWidget();
mapPage->addTab(vectorMapsTab, tr("Vector maps")); mapPage->addTab(projectionTab, tr("Projection"));
mapPage->addTab(hidpiTab, tr("HiDPI display mode")); mapPage->addTab(hidpiTab, tr("HiDPI display mode"));
return mapPage; return mapPage;
@ -742,8 +780,10 @@ void OptionsDialog::accept()
_options.sliderColor = _sliderColor->color(); _options.sliderColor = _sliderColor->color();
_options.graphAntiAliasing = _graphAA->isChecked(); _options.graphAntiAliasing = _graphAA->isChecked();
_options.projection = _projection->itemData(_projection->currentIndex()) _options.outputProjection = _outputProjection->itemData(
.toInt(); _outputProjection->currentIndex()).toInt();
_options.inputProjection = _inputProjection->itemData(
_inputProjection->currentIndex()).toInt();
_options.hidpiMap = _hidpi->isChecked(); _options.hidpiMap = _hidpi->isChecked();
_options.elevationFilter = _elevationFilter->value(); _options.elevationFilter = _elevationFilter->value();

View File

@ -39,7 +39,8 @@ struct Options {
int mapOpacity; int mapOpacity;
QColor backgroundColor; QColor backgroundColor;
// Map // Map
int projection; int outputProjection;
int inputProjection;
bool hidpiMap; bool hidpiMap;
// Data // Data
int elevationFilter; int elevationFilter;
@ -120,7 +121,8 @@ private:
ColorBox *_sliderColor; ColorBox *_sliderColor;
QCheckBox *_graphAA; QCheckBox *_graphAA;
// Map // Map
LimitedComboBox *_projection; LimitedComboBox *_outputProjection;
LimitedComboBox *_inputProjection;
QRadioButton *_hidpi; QRadioButton *_hidpi;
QRadioButton *_lodpi; QRadioButton *_lodpi;
// Data // Data

View File

@ -200,8 +200,10 @@
#define SEPARATE_GRAPH_PAGE_DEFAULT false #define SEPARATE_GRAPH_PAGE_DEFAULT false
#define SLIDER_COLOR_SETTING "sliderColor" #define SLIDER_COLOR_SETTING "sliderColor"
#define SLIDER_COLOR_DEFAULT QColor(Qt::red) #define SLIDER_COLOR_DEFAULT QColor(Qt::red)
#define PROJECTION_SETTING "projection" #define OUTPUT_PROJECTION_SETTING "outputProjection"
#define PROJECTION_DEFAULT 3857 #define OUTPUT_PROJECTION_DEFAULT 3857
#define INPUT_PROJECTION_SETTING "inputProjection"
#define INPUT_PROJECTION_DEFAULT 4326
#define HIDPI_MAP_SETTING "HiDPIMap" #define HIDPI_MAP_SETTING "HiDPIMap"
#define HIDPI_MAP_DEFAULT true #define HIDPI_MAP_DEFAULT true

View File

@ -202,7 +202,7 @@ void IMGMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
} }
} }
void IMGMap::setProjection(const Projection &projection) void IMGMap::setOutputProjection(const Projection &projection)
{ {
if (projection == _projection) if (projection == _projection)
return; return;

View File

@ -33,7 +33,7 @@ public:
void draw(QPainter *painter, const QRectF &rect, Flags flags); void draw(QPainter *painter, const QRectF &rect, Flags flags);
void setProjection(const Projection &projection); void setOutputProjection(const Projection &projection);
void load(); void load();
void unload(); void unload();

View File

@ -84,15 +84,6 @@ bool JNXMap::readTiles()
} }
} }
QByteArray guid;
if (!(readValue(dummy) && readString(guid)))
return false;
/* Use WebMercator projection for nakarte.tk maps */
if (guid == "12345678-1234-1234-1234-123456789ABC")
_projection = Projection(PCS::pcs(3857));
else
_projection = Projection(GCS::gcs(4326));
_zooms = QVector<Zoom>(lh.size()); _zooms = QVector<Zoom>(lh.size());
for (int i = 0; i < lh.count(); i++) { for (int i = 0; i < lh.count(); i++) {
Zoom &z = _zooms[i]; Zoom &z = _zooms[i];
@ -104,21 +95,22 @@ bool JNXMap::readTiles()
z.tiles = QVector<Tile>(l.count); z.tiles = QVector<Tile>(l.count);
for (quint32 j = 0; j < l.count; j++) { for (quint32 j = 0; j < l.count; j++) {
Tile &tile = z.tiles[j]; Tile &tile = z.tiles[j];
qint32 top, right, bottom, left;
quint16 width, height;
if (!(readValue(top) && readValue(right) && readValue(bottom) if (!(readValue(tile.top) && readValue(tile.right)
&& readValue(left) && readValue(width) && readValue(tile.bottom) && readValue(tile.left)
&& readValue(height) && readValue(tile.size) && readValue(tile.width) && readValue(tile.height)
&& readValue(tile.offset))) && readValue(tile.size) && readValue(tile.offset)))
return false; return false;
RectD rect(_projection.ll2xy(Coordinates(ic2dc(left), ic2dc(top))), RectC llrect(Coordinates(ic2dc(tile.left), ic2dc(tile.top)),
_projection.ll2xy(Coordinates(ic2dc(right), ic2dc(bottom)))); Coordinates(ic2dc(tile.right), ic2dc(tile.bottom)));
RectD rect(_projection.ll2xy(llrect.topLeft()),
_projection.ll2xy(llrect.bottomRight()));
if (j == 0) { if (j == 0) {
ReferencePoint tl(PointD(0, 0), rect.topLeft()); ReferencePoint tl(PointD(0, 0), rect.topLeft());
ReferencePoint br(PointD(width, height), rect.bottomRight()); ReferencePoint br(PointD(tile.width, tile.height),
rect.bottomRight());
z.transform = Transform(tl, br); z.transform = Transform(tl, br);
} }
@ -143,6 +135,7 @@ JNXMap::JNXMap(const QString &fileName, QObject *parent)
_valid(false) _valid(false)
{ {
_name = QFileInfo(fileName).fileName(); _name = QFileInfo(fileName).fileName();
_projection = Projection(GCS::gcs(4326));
if (!_file.open(QIODevice::ReadOnly)) { if (!_file.open(QIODevice::ReadOnly)) {
_errorString = fileName + ": " + _file.errorString(); _errorString = fileName + ": " + _file.errorString();
@ -267,3 +260,44 @@ void JNXMap::draw(QPainter *painter, const QRectF &rect, Flags flags)
max[1] = rr.bottom(); max[1] = rr.bottom();
tree.Search(min, max, cb, &ctx); tree.Search(min, max, cb, &ctx);
} }
void JNXMap::setInputProjection(const Projection &projection)
{
if (projection == _projection)
return;
_projection = projection;
for (int i = 0; i < _zooms.size(); i++) {
Zoom &z = _zooms[i];
z.tree.RemoveAll();
for (int j = 0; j < z.tiles.size(); j++) {
Tile &tile = z.tiles[j];
RectC llrect(Coordinates(ic2dc(tile.left), ic2dc(tile.top)),
Coordinates(ic2dc(tile.right), ic2dc(tile.bottom)));
RectD rect(_projection.ll2xy(llrect.topLeft()),
_projection.ll2xy(llrect.bottomRight()));
if (j == 0) {
ReferencePoint tl(PointD(0, 0), rect.topLeft());
ReferencePoint br(PointD(tile.width, tile.height),
rect.bottomRight());
z.transform = Transform(tl, br);
}
QRectF trect(z.transform.proj2img(rect.topLeft()),
z.transform.proj2img(rect.bottomRight()));
tile.pos = trect.topLeft();
qreal min[2], max[2];
min[0] = trect.left();
min[1] = trect.top();
max[0] = trect.right();
max[1] = trect.bottom();
z.tree.Insert(min, max, &tile);
}
}
}

View File

@ -36,6 +36,7 @@ public:
void draw(QPainter *painter, const QRectF &rect, Flags flags); void draw(QPainter *painter, const QRectF &rect, Flags flags);
void setInputProjection(const Projection &projection);
void setDevicePixelRatio(qreal /*deviceRatio*/, qreal mapRatio) void setDevicePixelRatio(qreal /*deviceRatio*/, qreal mapRatio)
{_mapRatio = mapRatio;} {_mapRatio = mapRatio;}
@ -44,9 +45,12 @@ public:
private: private:
struct Tile { struct Tile {
QPointF pos; qint32 top, right, bottom, left;
quint16 width, height;
quint32 size; quint32 size;
quint32 offset; quint32 offset;
QPointF pos;
}; };
struct Zoom { struct Zoom {

View File

@ -28,13 +28,15 @@
#define TL(m) ((m).bbox().topLeft()) #define TL(m) ((m).bbox().topLeft())
#define BR(m) ((m).bbox().bottomRight()) #define BR(m) ((m).bbox().bottomRight())
KMZMap::Overlay::Overlay(const QString &path, const QSize &size, KMZMap::Overlay::Overlay(const QString &path, const QSize &size,
const RectC &bbox, double rotation) : _path(path), _bbox(bbox), const RectC &bbox, double rotation, const Projection *proj)
_rotation(rotation), _img(0) : _path(path), _size(size), _bbox(bbox), _rotation(rotation), _img(0),
_proj(proj)
{ {
ReferencePoint tl(PointD(0, 0), PointD(bbox.left(), bbox.top())); ReferencePoint tl(PointD(0, 0), _proj->ll2xy(bbox.topLeft()));
ReferencePoint br(PointD(size.width(), size.height()), ReferencePoint br(PointD(size.width(), size.height()),
PointD(bbox.right(), bbox.bottom())); _proj->ll2xy(bbox.bottomRight()));
QTransform t; QTransform t;
t.rotate(-rotation); t.rotate(-rotation);
@ -87,6 +89,24 @@ void KMZMap::Overlay::unload()
_img = 0; _img = 0;
} }
void KMZMap::Overlay::setProjection(const Projection *proj)
{
_proj = proj;
ReferencePoint tl(PointD(0, 0), _proj->ll2xy(_bbox.topLeft()));
ReferencePoint br(PointD(_size.width(), _size.height()),
_proj->ll2xy(_bbox.bottomRight()));
QTransform t;
t.rotate(-_rotation);
QRectF b(0, 0, _size.width(), _size.height());
QPolygonF ma = t.map(b);
_bounds = ma.boundingRect();
_transform = Transform(tl, br);
}
bool KMZMap::resCmp(const Overlay &m1, const Overlay &m2) bool KMZMap::resCmp(const Overlay &m1, const Overlay &m2)
{ {
qreal r1, r2; qreal r1, r2;
@ -150,7 +170,6 @@ void KMZMap::computeBounds()
_bounds = QVector<Bounds>(_maps.count()); _bounds = QVector<Bounds>(_maps.count());
for (int i = 0; i < _maps.count(); i++) { for (int i = 0; i < _maps.count(); i++) {
QRectF xy(offsets.at(i), _maps.at(i).bounds().size()); QRectF xy(offsets.at(i), _maps.at(i).bounds().size());
_bounds[i] = Bounds(_maps.at(i).bbox(), xy); _bounds[i] = Bounds(_maps.at(i).bbox(), xy);
_adjust = qMin(qMin(_maps.at(i).bounds().left(), _adjust = qMin(qMin(_maps.at(i).bounds().left(),
_maps.at(i).bounds().top()), _adjust); _maps.at(i).bounds().top()), _adjust);
@ -227,7 +246,7 @@ void KMZMap::groundOverlay(QXmlStreamReader &reader, QZipReader &zip)
QSize size(ir.size()); QSize size(ir.size());
if (size.isValid()) if (size.isValid())
_maps.append(Overlay(image, size, rect, rotation)); _maps.append(Overlay(image, size, rect, rotation, &_projection));
else else
reader.raiseError(image + ": Invalid image file"); reader.raiseError(image + ": Invalid image file");
} else } else
@ -282,6 +301,8 @@ KMZMap::KMZMap(const QString &fileName, QObject *parent)
QByteArray xml(zip.fileData("doc.kml")); QByteArray xml(zip.fileData("doc.kml"));
QXmlStreamReader reader(xml); QXmlStreamReader reader(xml);
_projection = Projection(GCS::gcs(4326));
if (reader.readNextStartElement()) { if (reader.readNextStartElement()) {
if (reader.name() == QLatin1String("kml")) if (reader.name() == QLatin1String("kml"))
kml(reader, zip); kml(reader, zip);
@ -450,6 +471,20 @@ void KMZMap::unload()
_zip = 0; _zip = 0;
} }
void KMZMap::setInputProjection(const Projection &projection)
{
if (projection == _projection)
return;
_projection = projection;
for (int i = 0; i < _maps.size(); i++)
_maps[i].setProjection(&_projection);
_bounds.clear();
computeBounds();
}
void KMZMap::draw(QPainter *painter, const QRectF &rect, int mapIndex, void KMZMap::draw(QPainter *painter, const QRectF &rect, int mapIndex,
Flags flags) Flags flags)
{ {

View File

@ -1,6 +1,7 @@
#ifndef KMZMAP_H #ifndef KMZMAP_H
#define KMZMAP_H #define KMZMAP_H
#include "projection.h"
#include "transform.h" #include "transform.h"
#include "rectd.h" #include "rectd.h"
#include "map.h" #include "map.h"
@ -34,6 +35,8 @@ public:
void load(); void load();
void unload(); void unload();
void setInputProjection(const Projection &projection);
bool isValid() const {return _valid;} bool isValid() const {return _valid;}
QString errorString() const {return _errorString;} QString errorString() const {return _errorString;}
@ -41,18 +44,16 @@ private:
class Overlay { class Overlay {
public: public:
Overlay(const QString &path, const QSize &size, const RectC &bbox, Overlay(const QString &path, const QSize &size, const RectC &bbox,
double rotation); double rotation, const Projection *proj);
bool operator==(const Overlay &other) const bool operator==(const Overlay &other) const
{return _path == other._path;} {return _path == other._path;}
QPointF ll2xy(const Coordinates &c) const QPointF ll2xy(const Coordinates &c) const
{return QPointF(_transform.proj2img(QPointF(c.lon(), c.lat())));} {return QPointF(_transform.proj2img(_proj->ll2xy(c)));}
Coordinates xy2ll(const QPointF &p) const Coordinates xy2ll(const QPointF &p) const
{ {return _proj->xy2ll(_transform.img2proj(p));}
PointD pp(_transform.img2proj(p));
return Coordinates(pp.x(), pp.y());
}
const QString &path() const {return _path;}
const RectC &bbox() const {return _bbox;} const RectC &bbox() const {return _bbox;}
const QRectF &bounds() const {return _bounds;} const QRectF &bounds() const {return _bounds;}
qreal resolution(const QRectF &rect) const; qreal resolution(const QRectF &rect) const;
@ -63,13 +64,16 @@ private:
void load(QZipReader *zip); void load(QZipReader *zip);
void unload(); void unload();
void setProjection(const Projection *proj);
private: private:
QString _path; QString _path;
QSize _size;
QRectF _bounds; QRectF _bounds;
RectC _bbox; RectC _bbox;
qreal _rotation; qreal _rotation;
Image *_img; Image *_img;
const Projection *_proj;
Transform _transform; Transform _transform;
}; };
@ -112,6 +116,7 @@ private:
int _mapIndex; int _mapIndex;
QZipReader *_zip; QZipReader *_zip;
qreal _adjust; qreal _adjust;
Projection _projection;
bool _valid; bool _valid;
QString _errorString; QString _errorString;

View File

@ -49,7 +49,8 @@ public:
virtual void load() {} virtual void load() {}
virtual void unload() {} virtual void unload() {}
virtual void setDevicePixelRatio(qreal, qreal) {} virtual void setDevicePixelRatio(qreal, qreal) {}
virtual void setProjection(const Projection &) {} virtual void setOutputProjection(const Projection &) {}
virtual void setInputProjection(const Projection &) {}
virtual bool isValid() const {return true;} virtual bool isValid() const {return true;}
virtual bool isReady() const {return true;} virtual bool isReady() const {return true;}