327 lines
11 KiB
C++
327 lines
11 KiB
C++
#include "ManualLabelToolWidget.h"
|
||
#include <qdockwidget.h>
|
||
#include <qgslayertreeview.h>
|
||
#include <qgslayertreemodel.h>
|
||
#include <qgslayertreemapcanvasbridge.h>
|
||
<<<<<<< HEAD
|
||
#include <qgslayertreeview.h>
|
||
#include <qgslayertreemapcanvasbridge.h>
|
||
#include <qlabel.h>
|
||
#include <qstatusbar.h>
|
||
#include <QMenuBar>
|
||
#include <QToolBar>
|
||
#include <qgsmapcanvas.h>
|
||
#include <qgsrasterlayer.h>
|
||
#include <qgsmaptoolpan.h>
|
||
#include <qgsunittypes.h>
|
||
#include <QString>
|
||
#include <qgis.h>
|
||
#include <QgsMapSettings.h>
|
||
#include <QFile>
|
||
#include <QFileDialog>
|
||
#include <QDialog>
|
||
#include <QString>
|
||
#include <qfileinfo.h>
|
||
#include <qdir.h>
|
||
#include <qgsmaplayer.h>
|
||
#include <qgsproject.h>
|
||
//QgsUnitTypes
|
||
|
||
// 定义访问参数
|
||
#define RASTERFILEFILTER u8"所有文件 (*.*);;TIF (*.tif);;TIFF (*.tiff);;bin (*.bin);;dat (*.dat);;"
|
||
|
||
|
||
=======
|
||
>>>>>>> bc199244a3370d5bb7d3f52d5c17e6e2c467f20a
|
||
|
||
ManualLabelToolWidget::ManualLabelToolWidget(QWidget *parent)
|
||
: QMainWindow(parent)
|
||
{
|
||
this->init_UI();
|
||
|
||
}
|
||
|
||
ManualLabelToolWidget::~ManualLabelToolWidget()
|
||
{
|
||
}
|
||
|
||
void ManualLabelToolWidget::init_UI()
|
||
{
|
||
<<<<<<< HEAD
|
||
this->setWindowTitle(tr(u8"AI标注软件"));
|
||
// 初始大小
|
||
{
|
||
this->resize(1920,1080);
|
||
}
|
||
|
||
//地图控制
|
||
{
|
||
// 1. inti map canvas
|
||
this->map_canvas = new QgsMapCanvas();
|
||
this->setCentralWidget((this->map_canvas));
|
||
|
||
// 2. map tool pan
|
||
this->map_tool_pan = new QgsMapToolPan(this->map_canvas);
|
||
this->map_canvas->setMapTool(this->map_tool_pan);
|
||
|
||
// 3. map layer manager
|
||
this->map_layerTreeView = new QgsLayerTreeView(this);
|
||
// 4. create map model
|
||
this->map_layerModel = new QgsLayerTreeModel(QgsProject::instance()->layerTreeRoot(), this);
|
||
this->map_layerModel->setFlag(QgsLayerTreeModel::AllowNodeRename); // 允许重命名
|
||
this->map_layerModel->setFlag(QgsLayerTreeModel::AllowNodeReorder); // 允许调整顺序
|
||
this->map_layerModel->setFlag(QgsLayerTreeModel::AllowNodeChangeVisibility); // 允许改变可见性
|
||
this->map_layerModel->setFlag(QgsLayerTreeModel::ShowLegendAsTree); // 以树状图显示图例
|
||
this->map_layerModel->setAutoCollapseLegendNodes(10); // 自动折叠过多图例项
|
||
|
||
this->map_layerTreeView->setModel(this->map_layerModel);
|
||
// create bridge between mapcontrol and layer
|
||
this->map_layer_Bridge = new QgsLayerTreeMapCanvasBridge(QgsProject::instance()->layerTreeRoot(), this->map_canvas, this);
|
||
|
||
|
||
// layer 布局
|
||
// 1. 创建一个QDockWidget(停靠窗口)来承载图层树视图
|
||
this->layerTreeDock = new QDockWidget(tr(u8"图层管理器"), this);
|
||
this->layerTreeDock->setWidget(this->map_layerTreeView);
|
||
|
||
// 2. 将已有的图层树视图(m_layerTreeView)设置为这个停靠窗口的中心部件
|
||
layerTreeDock->setWidget(this->map_layerTreeView);
|
||
|
||
// 3. (可选但推荐)设置停靠窗口允许停靠的区域
|
||
layerTreeDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
|
||
|
||
// 5. 将停靠窗口添加到主窗口的左侧区域
|
||
this->addDockWidget(Qt::LeftDockWidgetArea, this->layerTreeDock);
|
||
|
||
|
||
}
|
||
|
||
// 状态工具栏
|
||
{
|
||
appStatusBar = this->statusBar(); // 获取或创建状态栏
|
||
|
||
scaleLabel = new QLabel(tr(u8"比例尺:"));
|
||
CoordinaryTextLabel = new QLabel(tr(u8"坐标系:"));
|
||
PointXYLabel = new QLabel(tr(u8"坐标:"));
|
||
UnitLabel = new QLabel(tr(u8"单位:"));
|
||
appStatusBar->addPermanentWidget(PointXYLabel); //
|
||
appStatusBar->addPermanentWidget(scaleLabel); //
|
||
appStatusBar->addPermanentWidget(UnitLabel); //
|
||
appStatusBar->addPermanentWidget(CoordinaryTextLabel); //
|
||
|
||
// 连接比例尺变化信号
|
||
connect(map_canvas, SIGNAL(scaleChanged(double)) , this, SLOT(updateScaleLabel(double)));
|
||
connect(map_canvas, SIGNAL(xyCoordinates(const QgsPointXY&)), this, SLOT(updateCoordinateLabel(const QgsPointXY&)));
|
||
|
||
connect(map_canvas, SIGNAL(extentsChanged()), this, SLOT(onMapExtentsChanged()));
|
||
|
||
|
||
}
|
||
|
||
// 菜单栏
|
||
{
|
||
menubar = this->menuBar();
|
||
|
||
// 在菜单栏上添加"文件"和"编辑"菜单
|
||
fileMenu = menubar->addMenu(tr(u8"文件"));
|
||
|
||
|
||
// 向"文件"菜单中添加菜单项(QAction)
|
||
newAction = fileMenu->addAction(tr(u8"新建"));
|
||
fileMenu->addSeparator(); // 添加分割线[1,5](@ref)
|
||
openMenu = fileMenu->addMenu(tr(u8"打开"));
|
||
|
||
openRasterFolderAction = openMenu->addAction(tr(u8"打开影像文件夹"));
|
||
openRasterAction = openMenu->addAction(tr(u8"打开影像"));
|
||
openSLCRasterAction = openMenu->addAction(tr(u8"SLC影像"));
|
||
editMenu = menubar->addMenu(tr(u8"编辑"));
|
||
|
||
// 事件绑定
|
||
QObject::connect(this->openRasterAction, SIGNAL(triggered()), this, SLOT(openRasterLayerTriggered()));
|
||
|
||
}
|
||
|
||
// AI标注工具栏
|
||
{
|
||
AiLabelToolBar = new QToolBar(tr(u8"AI标注工具栏"), this);
|
||
this->addToolBar(Qt::LeftToolBarArea, AiLabelToolBar);
|
||
}
|
||
|
||
}
|
||
|
||
void ManualLabelToolWidget::open()
|
||
{
|
||
}
|
||
|
||
|
||
void ManualLabelToolWidget::openRasterLayerTriggered()
|
||
{
|
||
if (lastFileDialogPath.isEmpty()) {
|
||
lastFileDialogPath = ".";
|
||
}
|
||
// 打开影像
|
||
// 2. 选择多个文件
|
||
QString rasterPath = QFileDialog::getOpenFileName(
|
||
this,
|
||
tr(u8"请选择影像文件"),
|
||
lastFileDialogPath,
|
||
tr(RASTERFILEFILTER)
|
||
);
|
||
|
||
lastFileDialogPath = rasterPath;
|
||
// 读取数据
|
||
this->openRaster(rasterPath);
|
||
}
|
||
|
||
void ManualLabelToolWidget::openRaster(QString& filePath)
|
||
{
|
||
QString filename = QFileInfo(filePath).fileName();
|
||
|
||
QgsRasterLayer* rasterLayer = new QgsRasterLayer(filePath, filename);
|
||
if (!rasterLayer->isValid()) {
|
||
qDebug() << "Failed to load raster layer!";
|
||
// 错误处理
|
||
return;
|
||
}
|
||
|
||
QgsProject::instance()->addMapLayer(rasterLayer);
|
||
|
||
}
|
||
|
||
void ManualLabelToolWidget::updateCoordinateLabel(const QgsPointXY& point)
|
||
{
|
||
QString coordText = QString(tr(u8"坐标:X:%1 Y:%2")).arg(QString::number(point.x(), 'f', 2)).arg(QString::number(point.y(), 'f', 2));
|
||
PointXYLabel->setText(coordText);
|
||
}
|
||
|
||
void ManualLabelToolWidget::onMapExtentsChanged()
|
||
{
|
||
QgsRectangle currentExtent = map_canvas->extent();
|
||
|
||
//// 现在你可以使用这个范围信息了,例如:
|
||
//// 1. 打印范围坐标
|
||
//qDebug() << "新范围 - Xmin:" << currentExtent.xMinimum()
|
||
// << "Ymin:" << currentExtent.yMinimum()
|
||
// << "Xmax:" << currentExtent.xMaximum()
|
||
// << "Ymax:" << currentExtent.yMaximum();
|
||
}
|
||
|
||
void ManualLabelToolWidget::onLayersChanged(QgsMapLayer* layer)
|
||
{
|
||
|
||
// WGS坐标系
|
||
QgsCoordinateReferenceSystem currentCrs = map_canvas->mapSettings().destinationCrs();
|
||
// 获取坐标系的描述信息和认证标识符,例如 "WGS 84 / EPSG:4326"
|
||
QString description = currentCrs.description();
|
||
QString authid = currentCrs.authid();
|
||
|
||
|
||
// 获取当前项目中所有图层
|
||
QList<QgsMapLayer*> layers = QgsProject::instance()->mapLayers().values();
|
||
int layerCount = layers.size();
|
||
|
||
// 判断当前是否仅有一层
|
||
if (layerCount == 0&&description == "") {
|
||
QgsMapLayer* theOnlyLayer = layers.first();
|
||
|
||
// 检查图层是否有效且拥有定义的坐标系
|
||
if (theOnlyLayer && theOnlyLayer->isValid() && theOnlyLayer->crs().isValid()) {
|
||
// 将地图画布的目标坐标系设置为与图层一致
|
||
map_canvas->mapSettings().setDestinationCrs(theOnlyLayer->crs());
|
||
// 可选:将地图范围缩放至该图层的全范围,提供更好的初始视图
|
||
map_canvas->setExtent(theOnlyLayer->extent());
|
||
// 刷新画布,使更改生效
|
||
map_canvas->refresh();
|
||
qDebug() << "图层数量为1,已同步画布坐标系至:" << theOnlyLayer->crs().description();
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
void ManualLabelToolWidget::updateScaleLabel(double scale)
|
||
{
|
||
// 将比例尺数值格式化为易读的字符串,例如 1:10000
|
||
QString scaleText = QString(tr(u8"比例尺:1:%1")).arg(QString::number(scale, 'f', 0));
|
||
scaleLabel->setText(scaleText);
|
||
|
||
// 同时更新单位标签
|
||
Qgis::DistanceUnit unit = map_canvas->mapUnits();
|
||
QString unitString;
|
||
if (unit == Qgis::DistanceUnit::Meters) {
|
||
unitString = tr(u8"米");
|
||
}
|
||
else if (unit == Qgis::DistanceUnit::Degrees) {
|
||
unitString = tr(u8"度");
|
||
}
|
||
else if (unit == Qgis::DistanceUnit::Feet) {
|
||
unitString = tr(u8"英尺");
|
||
}
|
||
else {
|
||
unitString = tr(u8"未知");
|
||
}
|
||
UnitLabel->setText(QString(tr(u8"单位:%1")).arg(unitString));
|
||
|
||
// WGS坐标系
|
||
QgsCoordinateReferenceSystem currentCrs = map_canvas->mapSettings().destinationCrs();
|
||
// 获取坐标系的描述信息和认证标识符,例如 "WGS 84 / EPSG:4326"
|
||
QString description = currentCrs.description();
|
||
QString authid = currentCrs.authid();
|
||
|
||
if (description == "") {
|
||
// 假设 ui->label_crs 是用于显示坐标系信息的QLabel
|
||
CoordinaryTextLabel->setText(QString(tr(u8"坐标系:未知")));
|
||
}
|
||
else {
|
||
// 假设 ui->label_crs 是用于显示坐标系信息的QLabel
|
||
CoordinaryTextLabel->setText(QString(tr(u8"坐标系:%1 (%2)")).arg(description).arg(authid));
|
||
}
|
||
|
||
|
||
}
|
||
=======
|
||
// 1. inti map canvas
|
||
this->map_canvas = new QgsMapCanvas();
|
||
this->setCentralWidget((this->map_canvas));
|
||
|
||
// 2. map tool pan
|
||
this->map_tool_pan = new QgsMapToolPan(this->map_canvas);
|
||
this->map_canvas->setMapTool(this->map_tool_pan);
|
||
|
||
// 3. map layer manager
|
||
this->map_layerTreeView =new QgsLayerTreeView(this);
|
||
// 4. create map model
|
||
this->map_layerModel = new QgsLayerTreeModel(QgsProject::instance()->layerTreeRoot(), this);
|
||
this->map_layerModel->setFlag(QgsLayerTreeModel::AllowNodeRename); // 允许重命名
|
||
this->map_layerModel->setFlag(QgsLayerTreeModel::AllowNodeReorder); // 允许调整顺序
|
||
this->map_layerModel->setFlag(QgsLayerTreeModel::AllowNodeChangeVisibility); // 允许改变可见性
|
||
this->map_layerModel->setFlag(QgsLayerTreeModel::ShowLegendAsTree); // 以树状图显示图例
|
||
this->map_layerModel->setAutoCollapseLegendNodes(10); // 自动折叠过多图例项
|
||
|
||
this->map_layerTreeView->setModel(this->map_layerModel);
|
||
// create bridge between mapcontrol and layer
|
||
this->map_layer_Bridge = new QgsLayerTreeMapCanvasBridge(QgsProject::instance()->layerTreeRoot(), this->map_canvas, this);
|
||
|
||
|
||
// layer 布局
|
||
// 1. 创建一个QDockWidget(停靠窗口)来承载图层树视图
|
||
this->layerTreeDock =new QDockWidget(tr(u8"图层管理器"), this);
|
||
this->layerTreeDock->setWidget(this->map_layerTreeView);
|
||
|
||
// 2. 将已有的图层树视图(m_layerTreeView)设置为这个停靠窗口的中心部件
|
||
layerTreeDock->setWidget(this->map_layerTreeView);
|
||
|
||
// 3. (可选但推荐)设置停靠窗口允许停靠的区域
|
||
layerTreeDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
|
||
|
||
|
||
|
||
// 5. 将停靠窗口添加到主窗口的左侧区域
|
||
this->addDockWidget(Qt::LeftDockWidgetArea, this->layerTreeDock);
|
||
|
||
|
||
|
||
|
||
}
|
||
|
||
>>>>>>> bc199244a3370d5bb7d3f52d5c17e6e2c467f20a
|