geopro/src/app/panels/chart/ContourPlotItem.hpp

81 lines
3.9 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma once
#include <vector>
#include <QImage>
#include <QRectF>
#include <qwt_plot_item.h>
#include "model/Anomaly.hpp"
#include "model/Field.hpp"
#include "ContourBands.hpp"
class QPainter;
class QwtScaleMap;
namespace geopro::app {
class ColorMapService;
// 网格等值线图项QwtPlotItem非 Q_OBJECT
// - 填充:预渲染 QImage 热力图(双线性插值 + 离散色带取色draw 时 blit+平滑缩放
// (避免 banded 多边形数万顶点导致拖动卡顿);含 NaN 的像素透明 → 不规则白边。
// - 等值线buildContourBands 返回的矢量折线(黑细线),随轴变换映射后 drawPolyline。
// - 标注:沿线方向旋转的 level 数值(小字黑)。
// - 异常叠加:按 markType 画 点(方块)/线(折线)/面(闭合多边形)dashed→虚线。
class ContourPlotItem : public QwtPlotItem {
public:
ContourPlotItem();
// 构建填充图像 + 缓存等值线/异常。svc 不被拥有(由 GridDataChartView 持有)。
void setData(const core::Grid& g, ColorMapService* svc,
const std::vector<core::Anomaly>& anoms, bool showLines, bool showLabels);
void setShowLines(bool on) { showLines_ = on; }
void setShowLabels(bool on) { showLabels_ = on; }
void setShowAnomalies(bool on) { showAnomalies_ = on; }
// I8 简化容差:对等值线做 Douglas-Peucker 抽稀数据坐标系tol>0 生效)。
// 改容差即重算 lines_从原始 linesRaw_调用方随后 replot。
void setSimplifyTolerance(double tol);
// I7 等值线提示:按数据坐标命中最近等值线,返回其 level无命中返回 NaN
// hitDataRadius 为命中半径(数据坐标,由调用方按像素半径换算)。
double contourLevelNear(double dataX, double dataY, double hitDataRadius) const;
// 线形⚙ 配置(色阶编辑器下发):等值线色/线型(虚实)、标注色。默认黑实线。
void setLineColor(const core::Rgba& c) { lineColor_ = c; }
void setLineDashed(bool dashed) { lineDashed_ = dashed; }
void setLabelColor(const core::Rgba& c) { labelColor_ = c; }
// I12 定位:高亮指定下标的异常(黄色加粗描边),-1=清除。调用方随后 replot。
void setHighlightedAnomaly(int index) { highlightIdx_ = index; }
// I12 定位:取某异常的数据坐标包围盒(用于视图缩放);下标越界/无点返回 null。
QRectF anomalyBoundingRect(int index) const;
int rtti() const override { return QwtPlotItem::Rtti_PlotUserItem; }
QRectF boundingRect() const override;
void draw(QPainter* painter, const QwtScaleMap& xMap, const QwtScaleMap& yMap,
const QRectF& canvasRect) const override;
private:
void buildFillImage(const core::Grid& g, ColorMapService* svc);
void resolveLineLevels(const core::Grid& g, const core::ColorScale& cs);
void applySimplify(); // 从 linesRaw_ 按 simplifyTol_ 重算 lines_保留 level
QImage fillImage_; // 预渲染填充热力图ARGB32含透明无数据区
QRectF dataBBox_; // 数据包围盒x[xmin,xmax] y[ymin,ymax]
std::vector<render::ContourLine> linesRaw_; // 原始等值线(简化前,作简化数据源)
std::vector<render::ContourLine> lines_; // 当前绘制等值线(按容差简化后,含 level
double simplifyTol_ = 0.0; // I8 简化容差数据坐标0=不简化)
std::vector<core::Anomaly> anoms_; // 异常叠加
bool showLines_ = true;
bool showLabels_ = true;
bool showAnomalies_ = true;
core::Rgba lineColor_{0, 0, 0, 255}; // 等值线色(默认黑)
bool lineDashed_ = false; // 等值线虚实(默认实线)
core::Rgba labelColor_{0, 0, 0, 255}; // 标注色(默认黑)
int highlightIdx_ = -1; // I12 当前高亮异常下标(-1=无)
};
} // namespace geopro::app