251 lines
5.7 KiB
C++
251 lines
5.7 KiB
C++
#include "stdafx.h"
|
|
#include <iostream>
|
|
#include <cmath>
|
|
|
|
#include <QWheelEvent>
|
|
#include <QPoint>
|
|
|
|
#include "ImageViewer.h"
|
|
#include "RasterLayer.h"
|
|
|
|
|
|
#define VIEW_CENTER viewport()->rect().center()
|
|
#define VIEW_WIDTH viewport()->rect().width()
|
|
#define VIEW_HEIGHT viewport()->rect().height()
|
|
|
|
Mapcavas::Mapcavas(QWidget* pParent) :QGraphicsView(pParent)
|
|
{
|
|
setRenderHint(QPainter::Antialiasing);
|
|
setRenderHint(QPainter::SmoothPixmapTransform);
|
|
setDragMode(QGraphicsView::ScrollHandDrag);
|
|
|
|
// 使用 Qt 默认 anchor 行为以外的配置
|
|
setTransformationAnchor(QGraphicsView::NoAnchor);
|
|
setResizeAnchor(QGraphicsView::NoAnchor);
|
|
|
|
m_qtGraphicsScene = new QGraphicsScene(this);
|
|
this->setScene(m_qtGraphicsScene);
|
|
m_qtGraphicsScene->setSceneRect(-1e6, -1e6, 2e6, 2e6);
|
|
|
|
m_framNumberLabel = new QLabel(this);
|
|
m_framNumberLabel->setAlignment(Qt::AlignHCenter);
|
|
m_framNumberLabel->setAlignment(Qt::AlignVCenter);
|
|
|
|
QFont ft;
|
|
ft.setPointSize(14);
|
|
m_framNumberLabel->setFont(ft);
|
|
m_framNumberLabel->setText("0");
|
|
|
|
|
|
m_GraphicsPixmapItemHandle = nullptr;
|
|
|
|
m_scale = 1.0;
|
|
m_zoomDelta = 0.1;
|
|
m_translateSpeed = 1.0;
|
|
m_bMouseTranslate = false;
|
|
|
|
|
|
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
|
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
|
setFrameShape(QFrame::NoFrame);
|
|
}
|
|
|
|
Mapcavas::~Mapcavas()
|
|
{
|
|
|
|
}
|
|
|
|
void Mapcavas::DisplayFrameNumber(int frameNumber)
|
|
{
|
|
m_framNumberLabel->setText(QString::number(frameNumber));
|
|
m_framNumberLabel->adjustSize();
|
|
}
|
|
|
|
void Mapcavas::SetImage(QPixmap *image)
|
|
{
|
|
if (!HasImage())
|
|
{
|
|
m_GraphicsPixmapItemHandle = m_qtGraphicsScene->addPixmap(*image);
|
|
}
|
|
else
|
|
{
|
|
m_GraphicsPixmapItemHandle->setPixmap(*image);
|
|
}
|
|
ensureSceneVisible();
|
|
}
|
|
|
|
void Mapcavas::ensureSceneVisible()
|
|
{
|
|
resetTransform();
|
|
|
|
auto view_rect = viewport()->rect();
|
|
auto scene_rect = this->scene()->itemsBoundingRect();
|
|
|
|
double x_ratio = view_rect.width() / scene_rect.width();
|
|
double y_ratio = view_rect.height() / scene_rect.height();
|
|
double scale_factor = std::min(x_ratio, y_ratio) * 0.9;
|
|
|
|
scale(scale_factor, scale_factor);
|
|
m_scale *= scale_factor;
|
|
|
|
centerOn(scene_rect.center());
|
|
}
|
|
|
|
bool Mapcavas::HasImage()
|
|
{
|
|
if (m_GraphicsPixmapItemHandle == nullptr)
|
|
{
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
void Mapcavas::wheelEvent(QWheelEvent *event)
|
|
{
|
|
if (HasImage())
|
|
{
|
|
QPointF oldPos = mapToScene(event->pos());
|
|
|
|
QPoint scrollAmount = event->angleDelta();
|
|
scrollAmount.y() > 0 ? zoomIn() : zoomOut();
|
|
|
|
QPointF newPos = mapToScene(event->pos());
|
|
|
|
QPointF delta = newPos - oldPos;
|
|
translate(delta.x(), delta.y());
|
|
}
|
|
}
|
|
|
|
void Mapcavas::scaling(qreal scaleFactor)
|
|
{
|
|
scale(scaleFactor, scaleFactor);
|
|
}
|
|
|
|
void Mapcavas::mousePressEvent(QMouseEvent *event)
|
|
{
|
|
if (event->button()==Qt::LeftButton)
|
|
{
|
|
m_bMouseTranslate = true;
|
|
m_lastMousePos = event->pos();
|
|
|
|
const QPointF scenePt = mapToScene(m_lastMousePos);
|
|
const int x = static_cast<int>(std::floor(scenePt.x()));
|
|
const int y = static_cast<int>(std::floor(scenePt.y()));
|
|
|
|
if (m_rasterLayer && m_rasterLayer->isValidPixel(x, y))
|
|
{
|
|
QVector<double> wavelengths;
|
|
QVector<double> spectrum;
|
|
if (m_rasterLayer->readPixelSpectrum(x, y, wavelengths, spectrum))
|
|
{
|
|
emit leftMouseButtonPressed(x, y, wavelengths, spectrum);
|
|
}
|
|
}
|
|
}
|
|
QGraphicsView::mousePressEvent(event);
|
|
}
|
|
|
|
void Mapcavas::mouseMoveEvent(QMouseEvent *event)
|
|
{
|
|
if (m_bMouseTranslate){
|
|
QPointF mouseDelta = mapToScene(event->pos()) - mapToScene(m_lastMousePos);
|
|
translate(mouseDelta.x(),mouseDelta.y());
|
|
}
|
|
|
|
m_lastMousePos = event->pos();
|
|
QGraphicsView::mousePressEvent(event);
|
|
}
|
|
|
|
void Mapcavas::mouseReleaseEvent(QMouseEvent *event)
|
|
{
|
|
m_bMouseTranslate = false;
|
|
QGraphicsView::mouseReleaseEvent(event);
|
|
}
|
|
|
|
void Mapcavas::mouseDoubleClickEvent(QMouseEvent *event)
|
|
{
|
|
QGraphicsView::mouseDoubleClickEvent(event);
|
|
}
|
|
|
|
void Mapcavas::zoomIn()
|
|
{
|
|
zoom(1 + m_zoomDelta);
|
|
}
|
|
|
|
void Mapcavas::zoomOut()
|
|
{
|
|
zoom(1 - m_zoomDelta);
|
|
}
|
|
|
|
void Mapcavas::zoom(float scaleFactor)
|
|
{
|
|
qreal factor = transform().scale(scaleFactor, scaleFactor).mapRect(QRectF(0, 0, 1, 1)).width();
|
|
if (factor < 0.07 || factor > 100)
|
|
return;
|
|
|
|
scale(scaleFactor, scaleFactor);
|
|
m_scale *= scaleFactor;
|
|
}
|
|
|
|
void Mapcavas::setTranslateSpeed(qreal speed)
|
|
{
|
|
Q_ASSERT_X(speed >= 0.0 && speed <= 2.0,
|
|
"InteractiveView::setTranslateSpeed", "Speed should be in range [0.0, 2.0].");
|
|
m_translateSpeed = speed;
|
|
}
|
|
|
|
qreal Mapcavas::translateSpeed() const
|
|
{
|
|
return m_translateSpeed;
|
|
}
|
|
|
|
void Mapcavas::setZoomDelta(qreal delta)
|
|
{
|
|
Q_ASSERT_X(delta >= 0.0 && delta <= 1.0,
|
|
"InteractiveView::setZoomDelta", "Delta should be in range [0.0, 1.0].");
|
|
m_zoomDelta = delta;
|
|
}
|
|
|
|
qreal Mapcavas::zoomDelta() const
|
|
{
|
|
return m_zoomDelta;
|
|
}
|
|
|
|
// new: set associated raster layer
|
|
void Mapcavas::setLayers(RasterLayer* layer)
|
|
{
|
|
m_rasterLayer = layer;
|
|
}
|
|
|
|
RasterLayer* Mapcavas::rasterLayer() const
|
|
{
|
|
return m_rasterLayer;
|
|
}
|
|
|
|
// new: refresh the map by rendering using the RasterLayer's render method
|
|
void Mapcavas::freshmap()
|
|
{
|
|
if (!m_rasterLayer) return;
|
|
|
|
RasterLayer::RenderParams params = m_rasterLayer->currentRenderParams();
|
|
QImage img = m_rasterLayer->render(params);
|
|
if (img.isNull()) return;
|
|
|
|
QPixmap pm = QPixmap::fromImage(img);
|
|
SetImage(&pm);
|
|
}
|
|
|
|
void Mapcavas::freshmap(const RasterLayer::RenderParams& params)
|
|
{
|
|
if (!m_rasterLayer) return;
|
|
|
|
QImage img = m_rasterLayer->render(params);
|
|
if (img.isNull()) return;
|
|
|
|
QPixmap pm = QPixmap::fromImage(img);
|
|
SetImage(&pm);
|
|
}
|