增加了风场cmod5反演

master
chenzenghui 2025-11-20 17:32:46 +08:00
parent dc29eb1744
commit 898bd5fd6e
7184 changed files with 124932 additions and 894 deletions

View File

@ -1,129 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="17.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{89CAC2D1-AF91-42BC-BDE1-2BC8C490CE7A}</ProjectGuid>
<Keyword>QtVS_v304</Keyword>
<WindowsTargetPlatformVersion Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">10.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">10.0</WindowsTargetPlatformVersion>
<QtMsBuild Condition="'$(QtMsBuild)'=='' OR !Exists('$(QtMsBuild)\qt.targets')">$(MSBuildProjectDirectory)\QtMsBuild</QtMsBuild>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v143</PlatformToolset>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v143</PlatformToolset>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Condition="Exists('$(QtMsBuild)\qt_defaults.props')">
<Import Project="$(QtMsBuild)\qt_defaults.props" />
</ImportGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="QtSettings">
<QtInstall>qgis_qt5</QtInstall>
<QtModules>core;gui;widgets</QtModules>
<QtBuildConfig>debug</QtBuildConfig>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="QtSettings">
<QtInstall>tools_qt5</QtInstall>
<QtModules>core;xml;gui;widgets</QtModules>
<QtBuildConfig>release</QtBuildConfig>
<QtPlugin>true</QtPlugin>
</PropertyGroup>
<Target Name="QtMsBuildNotFound" BeforeTargets="CustomBuild;ClCompile" Condition="!Exists('$(QtMsBuild)\qt.targets') or !Exists('$(QtMsBuild)\qt.props')">
<Message Importance="High" Text="QtMsBuild: could not locate qt.targets, qt.props; project may not build correctly." />
</Target>
<ImportGroup Label="ExtensionSettings" />
<ImportGroup Label="Shared" />
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(QtMsBuild)\Qt.props" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(QtMsBuild)\Qt.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<IncludePath>D:\OSGeo4W\apps\qgis-dev\include;D:\OSGeo4W\include;$(IncludePath)</IncludePath>
<ReferencePath>D:\OSGeo4W\lib;D:\OSGeo4W\apps\qgis-dev\lib;$(ReferencePath)</ReferencePath>
<LibraryPath>D:\OSGeo4W\lib;D:\OSGeo4W\apps\qgis-dev\lib;$(LibraryPath)</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Link>
<AdditionalDependencies>qgis_core.lib;qgis_app.lib;qgis_gui.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<ClCompile>
<PreprocessorDefinitions>_USE_MATH_DEFINES;_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'" Label="Configuration">
<ClCompile>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'" Label="Configuration">
<ClCompile>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>false</GenerateDebugInformation>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<<<<<<< HEAD
<ClCompile Include="RasterOperator.cpp" />
=======
>>>>>>> bc199244a3370d5bb7d3f52d5c17e6e2c467f20a
<QtRcc Include="ManualLabelToolWidget.qrc" />
<QtMoc Include="ManualLabelToolWidget.h" />
<ClCompile Include="ManualLabelToolWidget.cpp" />
<ClCompile Include="main.cpp" />
</ItemGroup>
<<<<<<< HEAD
<ItemGroup>
<ClInclude Include="RasterOperator.h" />
</ItemGroup>
=======
>>>>>>> bc199244a3370d5bb7d3f52d5c17e6e2c467f20a
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Condition="Exists('$(QtMsBuild)\qt.targets')">
<Import Project="$(QtMsBuild)\qt.targets" />
</ImportGroup>
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -1,326 +0,0 @@
#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

View File

@ -1,103 +0,0 @@
#pragma once
#include <QtWidgets/QMainWindow>
<<<<<<< HEAD
#include <memory>
#include <qgspointxy.h>
class QgsMapCanvas;
class QgsMapToolPan;
class QgsLayerTreeModel;
class QgsLayerTreeView;
class QgsLayerTreeMapCanvasBridge;
class QDockWidget;
class QLabel;
class QStatusBar;
class QMenuBar;
class QToolBar;
class QgsMapLayer;
=======
#include <qgsmapcanvas.h>
#include <qgsrasterlayer.h>
#include <qgsmaptoolpan.h>
#include <memory>
#include <qgslayertreeview.h>
#include <qgslayertreemapcanvasbridge.h>
>>>>>>> bc199244a3370d5bb7d3f52d5c17e6e2c467f20a
class ManualLabelToolWidget : public QMainWindow
{
Q_OBJECT
public:
ManualLabelToolWidget(QWidget *parent = nullptr);
~ManualLabelToolWidget();
<<<<<<< HEAD
=======
>>>>>>> bc199244a3370d5bb7d3f52d5c17e6e2c467f20a
private: // UI
void init_UI();// Init UI
private: // 组件
QgsMapCanvas* map_canvas=nullptr; // map widget
QgsMapToolPan* map_tool_pan = nullptr; // map tool for pan zoom
QgsLayerTreeModel* map_layerModel = nullptr;
QgsLayerTreeView* map_layerTreeView = nullptr;
QgsLayerTreeMapCanvasBridge* map_layer_Bridge = nullptr;
private: // 布局
QDockWidget* layerTreeDock;
<<<<<<< HEAD
// 状态栏
QLabel* scaleLabel; // 比例尺
QLabel* CoordinaryTextLabel; // 图层坐标系
QLabel* PointXYLabel;// 鼠标指针坐标
QLabel* UnitLabel;
QStatusBar* appStatusBar;// 状态控制栏
private: // 菜单栏
QMenuBar* menubar;
private: // 绘制图层
QToolBar* AiLabelToolBar;
private: // 文件菜单
QMenu* fileMenu;
QAction* newAction;
QMenu* openMenu;
QAction* openRasterFolderAction;
QAction* openRasterAction;
QAction* openSLCRasterAction;
private:// 编辑菜单
QMenu* editMenu;
public slots:// 功能函数区
void open();
void openRasterLayerTriggered();
void openRaster(QString &path);
public slots: // 状态栏函数
void updateScaleLabel(double);
void updateCoordinateLabel(const QgsPointXY&);
void onMapExtentsChanged();
void onLayersChanged(QgsMapLayer* layer);
public: // 常用变量区
QString lastFileDialogPath;
=======
>>>>>>> bc199244a3370d5bb7d3f52d5c17e6e2c467f20a
};

View File

@ -1,27 +0,0 @@
//#include "ManualLabelToolWidget.h"
//#include <QtWidgets/QApplication>
//
//int main(int argc, char *argv[])
//{
// QApplication app(argc, argv);
// ManualLabelToolWidget window;
// window.show();
// return app.exec();
//}
#include <QApplication>
#include <QmainWindow>
#include <qgsmapcanvas.h>
#include <qgsrasterlayer.h>
#include <qgsmaptoolpan.h>
#include "ManualLabelToolWidget.h"
//整数类型主函数(整数类型统计参数个数,字符类型指针数组指向字符串参数)
int main(int argc, char** argv)
{
//QApplication有且仅有一个应用程序类的对象
QApplication app(argc, argv);
ManualLabelToolWidget labeltoolwidget;
labeltoolwidget.show();
//等待用户操作
return app.exec();
}

@ -1 +1 @@
Subproject commit 1c1cbc3d7f3418f9e26d5a2892eace6a87e0c5e1
Subproject commit 1f5664c3c340d2815dea05d04e542a50e15079f7

View File

@ -0,0 +1,50 @@
// CustomCursorTool.cpp
#include "CustomCursorTool.h"
#include <qgsmapcanvas.h>
#include <qgsproject.h>
#include <qgsvectorlayer.h>
#include <qgsrasterlayer.h>
#include <qgsfeatureiterator.h>
#include <qgsgeometry.h>
#include <qgsrasteridentifyresult.h>
#include <QApplication>
#include <qgsmaplayer.h>
#include "qgsmapmouseevent.h"
#include "qgsmaptoolidentify.h"
#include <qgsmapcanvas.h>
#include <qgsvectorlayer.h>
#include <qgsrasterlayer.h>
CustomCursorTool::CustomCursorTool(QgsMapCanvas* canvas)
: QgsMapToolIdentify(canvas)
{
canvas->setCursor(Qt::CrossCursor);
}
void CustomCursorTool::canvasMoveEvent(QgsMapMouseEvent* e)
{
if (!canvas()) return;
QgsPointXY pointxy= e->pos();
QList<QgsMapToolIdentify::IdentifyResult> result;
QList<QgsMapLayer*> allLayers = mCanvas->layers();
if (allLayers.count() == 0) {
return;
}
QList < QgsMapToolIdentify::IdentifyResult > rasterlayerresult=this->identify(e->x(), e->y(), IdentifyMode::ActiveLayer, allLayers,QgsMapToolIdentify::Type::RasterLayer);
QList < QgsMapToolIdentify::IdentifyResult > meshlayerresult=this->identify(e->x(), e->y(), IdentifyMode::ActiveLayer, allLayers, QgsMapToolIdentify::Type::MeshLayer);
for (int32_t i = 0; i < rasterlayerresult.count(); i++) {
result.append(rasterlayerresult[i]);
}
for (int32_t i = 0; i < meshlayerresult.count(); i++) {
result.append(meshlayerresult[i]);
}
if (result.count() > 0){
emit identifyResultChange(result);
}
else {
}
}

View File

@ -0,0 +1,34 @@
// CustomCursorTool.h
#ifndef CUSTOMCURSORTOOL_H
#define CUSTOMCURSORTOOL_H
#include <qgsmaptool.h>
#include <qgsmapcanvas.h>
#include <qgsvector.h>
#include <qgsvectorlayer.h>
#include <qgsrasterlayer.h>
#include <qgsmeshlayer.h>
#include <qgspoint.h>
#include <QMouseEvent>
#include "qgsmaptoolidentify.h"
class QgsMapMouseEvent;
class CustomCursorTool : public QgsMapToolIdentify
{
Q_OBJECT
public:
explicit CustomCursorTool(QgsMapCanvas* canvas);
~CustomCursorTool() override = default;
signals:
void identifyResultChange(QList<QgsMapToolIdentify::IdentifyResult> result);
private :
void canvasMoveEvent(QgsMapMouseEvent* e) override; // ´¦ÀíÊó±êÒÆ¶¯Ê¼þ
};
#endif // CUSTOMCURSORTOOL_H

View File

@ -0,0 +1,281 @@
#include "LAMPDataManagerDialog.h"
#include <QFileInfo>
#include <QHeaderView>
#include <QToolButton>
#include <QSpacerItem>
#include <QCloseEvent>
#include "ManualLabelToolWidget.h"
#include "WidgetSettingClass.h"
#include <QFileDialog>
#include <QDialog>
#include "LampDataItem.h"
#include "LampWindDataItem.h"
#include <filesystem>
LampDataManager::LampDataManager(ManualLabelToolWidget* InmainWidget, QWidget* parent)
: QDialog(parent),
mainWidget(InmainWidget)
{
setupUI();
clearCurrentFile();
dataitems.clear();
this->setWindowTitle(u8"数据管理");
this->resize(500, 600);
}
LampDataManager::~LampDataManager()
{
}
void LampDataManager::LoadRasterFile(QString RasterPath)
{
}
void LampDataManager::showtreeWidgetBtnClicked()
{
if (isShowTreeWidgetflag) {
//
this->datatreeWidget->setHidden(true);
isShowTreeWidgetflag = false;
showtreeWidgetBtn->setText(tr(u8"展开数据列表"));
}
else {
this->datatreeWidget->setHidden(false);
isShowTreeWidgetflag = true;
showtreeWidgetBtn->setText(tr(u8"隐藏数据列表"));
}
}
void LampDataManager::showtextEditBtnClicked()
{
if (isShowExtendWidgetflag) {
this->textEdit->setHidden(true);
isShowExtendWidgetflag = false;
showtextEditBtn->setText(tr(u8"展开详细信息"));
}
else {
this->textEdit->setHidden(false);
isShowExtendWidgetflag = true;
showtextEditBtn->setText(tr(u8"隐藏详细信息"));
}
}
void LampDataManager::openRasterFile()
{
QString lastFileDialogPath = WidgetSettingClass::instance().getLastFileDialogPath();
if (lastFileDialogPath.isEmpty()) {
lastFileDialogPath = ".";
}
// 打开影像
// 2. 选择多个文件
QString lampwindPath = QFileDialog::getOpenFileName(
this,
tr(u8"请选择影像文件"),
lastFileDialogPath,
tr(LAMPWINDDATAFILEFILTER)
);
if (std::filesystem::exists(lampwindPath.toUtf8().constData())) {
WidgetSettingClass::instance().setLastFileDialogPath(lampwindPath);
this->openLampWindFile(lampwindPath);
}
}
void LampDataManager::openLampWindDataFile()
{
QString lastFileDialogPath = WidgetSettingClass::instance().getLastFileDialogPath();
if (lastFileDialogPath.isEmpty()) {
lastFileDialogPath = ".";
}
// 打开影像
// 2. 选择多个文件
QString lampwindPath = QFileDialog::getOpenFileName(
this,
tr(u8"请选择风场文件"),
lastFileDialogPath,
tr(LAMPWINDDATAFILEFILTER)
);
if (std::filesystem::exists(lampwindPath.toUtf8().constData())) {
WidgetSettingClass::instance().setLastFileDialogPath(lampwindPath);
this->openLampWindFile(lampwindPath);
}
}
void LampDataManager::closeEvent(QCloseEvent* event)
{
event->ignore();
this->hide();
}
void LampDataManager::reject()
{
this->hide();
}
void LampDataManager::setupUI()
{
// 4. 设置布局 - 这是将工具栏集成到对话框的关键步骤
QVBoxLayout* layout = new QVBoxLayout(this);
fileToolbar = new QToolBar(this);
showtreeWidgetBtn = new QPushButton(tr(u8"隐藏数据列表"), this);
datatreeWidget = new QTreeWidget(this);
showtextEditBtn = new QPushButton(tr(u8"隐藏详细信息"), this);
textEdit = new QTextEdit(this);
layout->addWidget(fileToolbar); // 将工具栏添加到布局顶部
layout->addWidget(showtreeWidgetBtn); // 将工具栏添加到布局顶部
layout->addWidget(datatreeWidget); // 将工具栏添加到布局顶部
layout->addWidget(showtextEditBtn); // 将工具栏添加到布局顶部
layout->addWidget(textEdit); // 将工具栏添加到布局顶部
layout->setAlignment(Qt::AlignTop);
setLayout(layout);
isShowTreeWidgetflag = true;
isShowExtendWidgetflag = true;
datatreeWidget->setColumnCount(2); // 设置两列
datatreeWidget->setHeaderLabels(QStringList() << u8"名称" << u8"类型"); // 设置列标题
datatreeWidget->setColumnWidth(0, 150);
LoadFileAction = fileToolbar->addAction(tr(u8"加载数据"));
//openFileAction = fileToolbar->addAction(tr(u8"打开数据"));
removeFileAction = fileToolbar->addAction(tr(u8"移除数据"));
removeAllFileAction = fileToolbar->addAction(tr(u8"移除所有数据"));
QObject::connect(this->showtreeWidgetBtn, SIGNAL(clicked()), this, SLOT(showtreeWidgetBtnClicked()));
QObject::connect(this->showtextEditBtn, SIGNAL(clicked()), this, SLOT(showtextEditBtnClicked()));
QObject::connect(this->removeFileAction, SIGNAL(triggered()), this, SLOT(removeNodeItem()));
QObject::connect(this->removeAllFileAction, SIGNAL(triggered()), this, SLOT(removeALLNodeItems()));
QObject::connect(this->LoadFileAction, SIGNAL(triggered()), this, SLOT(onShowData()));
QObject::connect(this->datatreeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)), this, SLOT(oncurrentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)));
}
void LampDataManager::openLampWindFile(QString winddatapath)
{
LampWindDataItem* item = new LampWindDataItem(this->datatreeWidget);
item->OpenFileData(winddatapath);
this->AddDataNode(item);
}
void LampDataManager::AddDataNode(LampDataItem* item)
{
item->InitTreeNode();
this->dataitems.append(item);
}
void LampDataManager::oncurrentItemChanged(QTreeWidgetItem* current, QTreeWidgetItem* previous)
{
QTreeWidgetItem* currentItem = datatreeWidget->currentItem();
if (currentItem == nullptr) return;
QTreeWidgetItem* rootnode = nullptr;
if (currentItem->parent() == nullptr) {
rootnode = currentItem;
}
else {
// 当前项是子节点
QTreeWidgetItem* parent = currentItem->parent();
rootnode = parent;
}
if (rootnode) {
LampDataItem* lampItem = static_cast<LampDataItem*>(rootnode);
QString context = lampItem->getDescription();
this->textEdit->clear();
this->textEdit->setText(context);
}
}
void LampDataManager::removeNodeItem()
{
QTreeWidgetItem* currentItem = datatreeWidget->currentItem();
if (currentItem == nullptr) return;
QTreeWidgetItem* rootnode = nullptr;
if (currentItem->parent() == nullptr) {
rootnode = currentItem;
}
else {
// 当前项是子节点
QTreeWidgetItem* parent = currentItem->parent();
rootnode = parent;
}
if (rootnode) {
LampDataItem* lampItem = static_cast<LampDataItem*>(rootnode);
int32_t hashcode = lampItem->getHash();
for (int32_t i = 0; i < this->dataitems.count(); i++) {
if (this->dataitems[i]->getHash() == hashcode) {
this->dataitems.removeAt(i);
break;
}
}
int index = datatreeWidget->indexOfTopLevelItem(rootnode);
if (index >= 0) {
delete datatreeWidget->takeTopLevelItem(index);
}
}
this->textEdit->clear();
}
void LampDataManager::removeALLNodeItems()
{
if (!datatreeWidget) return;
// 循环取出并删除每一个顶级节点
while (datatreeWidget->topLevelItemCount() > 0) {
QTreeWidgetItem* item = datatreeWidget->takeTopLevelItem(0); // 取出第0个顶级节点
if (item) {
delete item; // 必须手动删除takeTopLevelItem仅移除关联
}
}
this->dataitems.clear();
this->textEdit->clear();
}
void LampDataManager::onShowData()
{
// 检查是否选择并加载数据
for (int32_t i = 0; i < datatreeWidget->topLevelItemCount(); i++) {
QTreeWidgetItem* item = datatreeWidget->topLevelItem(i);
LampDataItem* lampItem = static_cast<LampDataItem*>(item);
lampItem->showData(mainWidget);
}
}
void LampDataManager::loadFile(const QString& filePath)
{
}
void LampDataManager::clearCurrentFile()
{
}
void LampDataManager::onLoadDataClicked()
{
}

View File

@ -0,0 +1,109 @@
#pragma once
#include <QMainWindow>
#include <QWidget>
#include <QTreeWidget>
#include <QTreeWidgetItem>
#include <QPushButton>
#include <QCheckBox>
#include <QGroupBox>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QLineEdit>
#include <QToolBar>
#include <QAction>
#include <QComboBox>
#include <QDateTime>
#include <QDialog>
#include <QList>
#include <QTextEdit>
#include <QList>
class ManualLabelToolWidget;
class LampDataItem;
class QTreeTreeWidgetItem;
class LampDataManager : public QDialog
{
Q_OBJECT
public:
explicit LampDataManager(ManualLabelToolWidget* mainWidget,QWidget* parent = nullptr);
~LampDataManager();
void loadFile(const QString& filePath);
void clearCurrentFile();
public slots:
void onLoadDataClicked();
void showtreeWidgetBtnClicked();
void showtextEditBtnClicked();
void openRasterFile();
void openLampWindDataFile();
// 节点相关操作
void AddDataNode(LampDataItem* item);
// 软件
void oncurrentItemChanged(QTreeWidgetItem* current, QTreeWidgetItem* previous);
void removeNodeItem();
void removeALLNodeItems();
void onShowData();
public:
void openLampWindFile(QString winddatapath);
void LoadRasterFile(QString RasterPath);
public:
private:
void setupUI();
signals:
void dataLoaded(const QString& filePath, int bandIndex, bool grayscale, bool newView);
protected:
// 重写关闭事件
void closeEvent(QCloseEvent* event) override;
// 重写reject槽函数以响应Esc键
void reject() override;
private:
ManualLabelToolWidget* mainWidget;
private:// UI 元素
QVBoxLayout* layout;
QToolBar* fileToolbar;
QPushButton* showtreeWidgetBtn;
QTreeWidget* datatreeWidget;
QPushButton* showtextEditBtn;
QTextEdit* textEdit;
bool isShowTreeWidgetflag;
bool isShowExtendWidgetflag;
private://fileToolbar
//QAction* openFileAction;
QAction* removeFileAction;
QAction* removeAllFileAction;
QAction* LoadFileAction;
//QPushButton* LoadFileAction;
private:// datatreeWidget
QList<LampDataItem*> dataitems;
};

View File

@ -0,0 +1,41 @@
#include "LampDataItem.h"
LampDataItem::LampDataItem(QTreeWidget* IntreeWidget)
:QTreeWidgetItem(IntreeWidget)
, treeWidget(IntreeWidget)
{
}
LampDataItem::~LampDataItem()
{
}
void LampDataItem::showData(ManualLabelToolWidget* mainWidget)
{
}
QString LampDataItem::getDescription()
{
return u8"";
}
void LampDataItem::InitTreeNode()
{
}
void LampDataItem::OpenFileData(QString path)
{
}
int32_t LampDataItem::getHash()
{
return hashCode;
}
void LampDataItem::setSelectItems(QList<QString> selectItemName)
{
}

View File

@ -0,0 +1,32 @@
#pragma once
#include <QObject>
#include <QTreeWidget>
#include <QTreeWidgetItem>
#include <QString>
class ManualLabelToolWidget;
class LampDataItem : public QTreeWidgetItem
{
public:
// ¹¹Ô캯Êý
explicit LampDataItem(QTreeWidget* treeWidget = nullptr);
~LampDataItem();
public: // »ù´¡º¯Êý
virtual void InitTreeNode();
virtual void showData(ManualLabelToolWidget* mainWidget);
virtual QString getDescription();
virtual void setSelectItems(QList<QString> selectItemName);
virtual void OpenFileData(QString path);
virtual int32_t getHash();
public:
QTreeWidget* treeWidget;
QString ItemType;
int32_t hashCode;
};

View File

@ -0,0 +1,230 @@
#include <qgspoint.h>
#include "LampWindDataItem.h"
#include "BaseTool.h"
#include <QFileInfo>
#include "ManualLabelToolWidget.h"
#include <QgsMeshLayer.h>
#include <qgsmeshdataprovider.h>
#include <qgsmeshlayerutils.h>
#include <qgsmeshdataset.h>
#include <qgsproject.h>
#include <qgsvectorlayer.h>
#include <qgsmeshrenderersettings.h>
#include <qgscoordinatereferencesystem.h>
#include <qgsmapcanvas.h>
#include <qgsfeature.h>
#include <qgsgeometry.h>
#include <qgsfield.h>
#include <qgssymbol.h>
#include <qgssinglesymbolrenderer.h>
#include <qgslinesymbol.h>
#include <qgsmarkersymbol.h>
#include <qgsrenderer.h>
#include <qgsmarkersymbollayer.h>
#include <qgsmesheditor.h>
#include <qgsmeshdatasetgroupstore.h>
#include <qgsmeshdatasetgrouptreeview.h>
#include <qgsvectorfieldsymbollayer.h>
#include <qgsmemoryproviderutils.h>
#include <qgsgraduatedsymbolrenderer.h>
#include <omp.h>
#include "WidgetSettingClass.h"
#include "ImageOperatorBase.h"
#include "Wind2ERANc.h"
#include <QProgressDialog>
#include <QObject>
#include <QString>
LampWindDataItem::LampWindDataItem(QTreeWidget* IntreeWidget)
:LampDataItem(IntreeWidget)
{
timeArr.clear();
Filename.clear();
Filepath.clear();
time_filepath.clear();
selectItems.clear();
this->treeWidget = IntreeWidget;
this->ItemType = u8"LampWind";
}
LampWindDataItem::~LampWindDataItem()
{
}
void LampWindDataItem::InitTreeNode()
{
// 创建根节点,子节点,父窗体: QTreeWidget* treeWidget;
// 其中要求子节点选中的时候,需要能够知道根节点的文本
this->setText(0, this->Filename);
this->setText(1, u8"WindData");
this->setCheckState(0, Qt::Unchecked);
// 添加子节点
for (const auto& key : timeArr.keys()) {
QTreeWidgetItem* childItem1 = new QTreeWidgetItem(this); // 指定父节点为rootItem
childItem1->setText(0, key);
childItem1->setText(1, "");
childItem1->setCheckState(0, Qt::Unchecked); // 在第一列添加复选框 [3](@ref)
}
//treeWidget->expandAll();
}
void LampWindDataItem::showData(ManualLabelToolWidget* mainWidget)
{
// 获取当前节点的setCheckState
if (this->checkState(0) == Qt::Checked) {
for (int32_t i = 0; i < this->childCount(); i++) {
int32_t tid = timeArr[this->child(i)->text(0)];
this->ShowWindData(mainWidget, tid, this->child(i)->text(0));
}
}
else {
for (int32_t i = 0; i < this->childCount(); i++) {
if (this->child(i)->checkState(0) == Qt::Checked) {
int32_t tid = timeArr[this->child(i)->text(0)];
this->ShowWindData(mainWidget, tid, this->child(i)->text(0));
}
}
}
}
QString LampWindDataItem::getDescription()
{
QString starttimestr = Timenanosecond2timeStr(info.firstTimestamp);
QString endtimestr = Timenanosecond2timeStr(info.lastTimestamp);
return QString(u8"FilePath: %1\nFileName: %2\nHeight:%3 \nWidth:%4 \nNum:%5, \nfirstTs:%6, \nlastTs:%7, \nminLon:%8, \nmaxLon:%9, \nminLat:%10, \nmaxLat:%11, \nESPG:%12, \nTransX:%13, %14, %15, \nTransY:%15, %16, %17, \nSize:%18 \n")
.arg(this->Filepath).arg(this->Filename)
.arg(info.Height).arg(info.Width).arg(info.Num)
.arg(starttimestr).arg(endtimestr)
.arg(info.minLon).arg(info.maxLon).arg(info.minLat).arg(info.maxLat)
.arg(info.ESPGCODE)
.arg(info.T11).arg(info.T12).arg(info.T13)
.arg(info.T21).arg(info.T22).arg(info.T23)
.arg(info.fileSize);
}
void LampWindDataItem::setSelectItems(QList<QString> selectItemName)
{
}
void LampWindDataItem::OpenFileData(QString path)
{
// 读取数据
this->info = getDataFileInfo(path.toUtf8().constData());
int64_t* timeArr = new int64_t[this->info.Num];
QString ncfilename = QFileInfo(path).completeBaseName();
QProgressDialog* progressDialog = new QProgressDialog(this->treeWidget);
progressDialog->setWindowTitle( (u8"请稍候")); // 设置对话框标题
progressDialog->setLabelText( (u8"正在处理中...")); // 设置说明文字
progressDialog->resize(150, 50);
// 生成缓存文件地址
FileCacheFolderPath = WidgetSettingClass::instance().getTempFolder() + "\\"+ ncfilename;
QDir dir;
dir.mkpath(FileCacheFolderPath);
ERA5NetCDFConverter cover;
if (get_WindDataFileTimeArr(path.toUtf8().constData(), this->info, timeArr) == 0) {
this->timeArr.clear();
progressDialog->setRange(0, this->info.Num); // 设置进度范围例如从0到100 [3,4](@ref)
for (int64_t i = 0; i < this->info.Num; i++) {
QString timeflag = Timenanosecond2timeStr(timeArr[i]);
QString timefilename= QString(u8"\\mesh_wind_%1.nc").arg(timeflag.replace(":", "").replace(".", "M"));
QString temppath = FileCacheFolderPath + "\\" + timefilename;
time_filepath.insert(i, temppath);
cover.convert_to_era5_netcdf(
path.toUtf8().constData(),
temppath.toUtf8().constData(),
i
);
this->timeArr.insert(QString(u8"%1").arg(timeflag),i);
if (i % 30 == 0) {
progressDialog->setValue(i);
progressDialog->show();
}
}
}else{}
this->hashCode = pathToHashCode_Qt(path);
this->Filepath = path;
this->Filename=QFileInfo(path).fileName();
progressDialog->close();
delArrPtr(timeArr);
}
void LampWindDataItem::ShowWindData(ManualLabelToolWidget* mainWidget, int64_t tid, QString timeStr)
{
// 创建缓存文件
//QString temppath = WidgetSettingClass::instance().getTempFolder() + QString(u8"\\mesh_wind_%1.nc").arg(timeStr.replace(":", "").replace(".", "M"));
QgsMapCanvas* map_canvas = mainWidget->map_canvas; // 地图
QString url = time_filepath[tid];
QgsMeshLayer* meshLayer = new QgsMeshLayer(url, timeStr, "mdal");
//qDebug() << temppath;
QString EPSGStr = QString(u8"EPSG:%1").arg(info.ESPGCODE);
// 获取数据提供者
QgsMeshDataProvider* dp = meshLayer->dataProvider();
if (!dp) {
qDebug() << "Failed to get data provider!";
return;
}
meshLayer->setCrs(QgsCoordinateReferenceSystem(EPSGStr));
// 获取数据集组数量
int gprCount = dp->datasetGroupCount();
int targetVectorIndex = -1; // 初始化为-1表示未找到
// 遍历所有数据集组,寻找第一个矢量数据集
for (int i = 0; i < gprCount; ++i) {
QgsMeshDatasetIndex index(i, 0); // 组索引i时间步0
QgsMeshDatasetGroupMetadata meta = dp->datasetGroupMetadata(index);
bool isVector = meta.isVector();
QString name = meta.name();
if (isVector) {
targetVectorIndex = i;
break;
}
}
// 如果找到了矢量数据集组
if (targetVectorIndex != -1) {
// 获取当前的渲染器设置
QgsMeshRendererSettings s = meshLayer->rendererSettings();
// 设置激活的矢量数据集组和标量数据集组
s.setActiveVectorDatasetGroup(targetVectorIndex);
s.setActiveScalarDatasetGroup(targetVectorIndex);
// 将修改后的设置应用回图层
meshLayer->setRendererSettings(s);
qDebug() << "Successfully set active dataset group to index:" << targetVectorIndex;
}
else {
qDebug() << "No vector dataset group found!";
}
mainWidget->AddLayers(meshLayer);
map_canvas->setExtent(meshLayer->extent());
map_canvas->refresh();
}

View File

@ -0,0 +1,38 @@
#pragma once
#include "LampDataItem.h"
#include <QString>
#include <QMap>
#include <QList>
#include "WindDataFileOperator.h"
// 风场文件Item
class QgsMeshLayer;
class QgsVectorLayer;
class QgsSymbol;
class QgsMapCanvas;
class LampWindDataItem:public LampDataItem
{
public:
// 初始化代码
LampWindDataItem(QTreeWidget* treeWidget);
~LampWindDataItem();
public: // 基础函数
void InitTreeNode() override;
void showData(ManualLabelToolWidget* mainWidget) override;
QString getDescription() override;
void setSelectItems(QList<QString> selectItemName) override;
void OpenFileData(QString path) override;
public:
void ShowWindData(ManualLabelToolWidget* mainWidget, int64_t tid,QString timeStr);
public:
QString Filename;
QString Filepath;
DataFileInfo info;
QMap<QString,int64_t> timeArr;
QMap<int64_t, QString> time_filepath;
QList<QString> selectItems;
QString FileCacheFolderPath;
};

View File

@ -0,0 +1,148 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>qml;cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>qrc;rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="Form Files">
<UniqueIdentifier>{99349809-55BA-4b9d-BF79-8FDBB0286EB3}</UniqueIdentifier>
<Extensions>ui</Extensions>
</Filter>
<Filter Include="Translation Files">
<UniqueIdentifier>{639EADAA-A684-42e4-A9AD-28FC9BCB8F7C}</UniqueIdentifier>
<Extensions>ts</Extensions>
</Filter>
<Filter Include="ImageTools">
<UniqueIdentifier>{52e7c8b2-7a19-4ead-9f28-ef550a98ee93}</UniqueIdentifier>
</Filter>
<Filter Include="datamanager">
<UniqueIdentifier>{c712db7e-8172-42c7-ac70-bdf85c9c9d8a}</UniqueIdentifier>
</Filter>
<Filter Include="ManualLabelToolWidget">
<UniqueIdentifier>{2192b24d-785f-4815-a5fd-d0a4e96e11da}</UniqueIdentifier>
</Filter>
<Filter Include="openglwidget">
<UniqueIdentifier>{1ba868a3-5a19-4e4a-a422-0a3fc9672258}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<QtRcc Include="ManualLabelToolWidget.qrc">
<Filter>Resource Files</Filter>
</QtRcc>
<QtRcc Include="images\images.qrc">
<Filter>Resource Files</Filter>
</QtRcc>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="RasterOperator.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="QImageCursorWidget.cpp">
<Filter>ImageTools</Filter>
</ClCompile>
<ClCompile Include="WindConverTools.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="WidgetSettingClass.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="UnitTest.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="LAMPDataManagerDialog.cpp">
<Filter>datamanager</Filter>
</ClCompile>
<ClCompile Include="LampDataItem.cpp">
<Filter>datamanager</Filter>
</ClCompile>
<ClCompile Include="LampWindDataItem.cpp">
<Filter>datamanager</Filter>
</ClCompile>
<ClCompile Include="ManualLabelToolWidget.cpp">
<Filter>ManualLabelToolWidget</Filter>
</ClCompile>
<ClCompile Include="QtWindComputer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="QBatchStaticEchoDialog.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="CustomCursorTool.cpp">
<Filter>ImageTools</Filter>
</ClCompile>
<ClCompile Include="windLayerTreeViewMenuProvider.cpp">
<Filter>ImageTools</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="RasterOperator.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="UnitTest.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="LampDataItem.h">
<Filter>datamanager</Filter>
</ClInclude>
<ClInclude Include="LampWindDataItem.h">
<Filter>datamanager</Filter>
</ClInclude>
<ClInclude Include="resource.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<QtMoc Include="QImageCursorWidget.h">
<Filter>ImageTools</Filter>
</QtMoc>
<QtMoc Include="WidgetSettingClass.h">
<Filter>Header Files</Filter>
</QtMoc>
<QtMoc Include="WindConverTools.h">
<Filter>Header Files</Filter>
</QtMoc>
<QtMoc Include="LAMPDataManagerDialog.h">
<Filter>datamanager</Filter>
</QtMoc>
<QtMoc Include="ManualLabelToolWidget.h">
<Filter>ManualLabelToolWidget</Filter>
</QtMoc>
<QtMoc Include="QtWindComputer.h">
<Filter>Header Files</Filter>
</QtMoc>
<QtMoc Include="QBatchStaticEchoDialog.h">
<Filter>Header Files</Filter>
</QtMoc>
<QtMoc Include="CustomCursorTool.h">
<Filter>ImageTools</Filter>
</QtMoc>
<QtMoc Include="windLayerTreeViewMenuProvider.h">
<Filter>ImageTools</Filter>
</QtMoc>
</ItemGroup>
<ItemGroup>
<QtUic Include="QtWindComputer.ui">
<Filter>Form Files</Filter>
</QtUic>
<QtUic Include="QBatchStaticEchoDialog.ui">
<Filter>Form Files</Filter>
</QtUic>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Manual-Label-Tool-Widget.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>

View File

@ -0,0 +1,472 @@
#include "ManualLabelToolWidget.h"
#include <qdockwidget.h>
#include <qgslayertreeview.h>
#include <qgslayertreemodel.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 <QApplication>
#include <QScreen>
#include <QString>
#include <qfileinfo.h>
#include <qdir.h>
#include <qgsmaplayer.h>
#include <qgsproject.h>
#include "WidgetSettingClass.h"
#include "LAMPDataManagerDialog.h"
#include <qgsproviderregistry.h>
#include <qgsapplication.h>
//#include <qgslayertreeview.h>
#include <qgslayertree.h>
#include <qgslayerpropertiesdialog.h>
#include "QBatchStaticEchoDialog.h"
#include "QImageCursorWidget.h"
#include <QToolButton.h>
#include <QgsMapToolZoom.h>
#include <QgsMapToolIdentify.h>
#include "CustomCursorTool.h"
#include "qgslayerpropertiesdialog.h"
#include "windLayerTreeViewMenuProvider.h"
//QgsUnitTypes
ManualLabelToolWidget::ManualLabelToolWidget(QWidget* parent)
: QMainWindow(parent)
{
this->init_UI();
}
ManualLabelToolWidget::~ManualLabelToolWidget()
{
}
void ManualLabelToolWidget::init_UI()
{
// 初始大小
{
this->setWindowTitle(tr(u8"微波风能分析软件"));
// 获取主屏幕的可用区域(不包含任务栏)
QRect availableGeometry = QApplication::primaryScreen()->availableGeometry();
// 计算期望的窗口大小例如屏幕可用区域的80%
int width = availableGeometry.width() * 0.8;
int height = availableGeometry.height() * 0.8;
// 调整窗口大小
resize(width, height);
// 可选:将窗口移动到屏幕中央
move(availableGeometry.center() - rect().center());
}
{
datamanagerDialog = new LampDataManager(this);
onshowDatamanagerActionTriggered();
}
//地图控制
{
// 1. inti map canvas
this->map_canvas = new QgsMapCanvas(this);
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);
// 关键缓存与渲染配置
map_canvas->setCachingEnabled(true); // 启用缓存,这是实现分块加载效果的关键[citation:6][citation:8]
map_canvas->setParallelRenderingEnabled(true); // 启用并行渲染以提高性能[citation:6]
// 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);
this->map_layer_Bridge = new QgsLayerTreeMapCanvasBridge(QgsProject::instance()->layerTreeRoot(), this->map_canvas, this);
this->layerTreeDock = new QDockWidget(tr(u8"图层管理器"), this);
this->layerTreeDock->setWidget(this->map_layerTreeView);
layerTreeDock->setWidget(this->map_layerTreeView);
layerTreeDock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
this->addDockWidget(Qt::LeftDockWidgetArea, this->layerTreeDock);
windLayerTreeViewMenuProvider* mLayerTreeViewMenuProvider = new windLayerTreeViewMenuProvider(map_layerTreeView, map_canvas, this);
this->map_layerTreeView->setMenuProvider(mLayerTreeViewMenuProvider);
}
// 状态工具栏
{
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影像"));
openLampWindDataAction = openMenu->addAction(tr(u8"风场数据"));
// 事件绑定
QObject::connect(this->openRasterAction, SIGNAL(triggered()), this, SLOT(openRaster()));
QObject::connect(this->openLampWindDataAction, SIGNAL(triggered()), this->datamanagerDialog, SLOT(openLampWindDataFile()));
editMenu = menubar->addMenu(tr(u8"编辑"));
SARWindInversionMenu = menubar->addMenu(tr(u8"SAR风场反演"));
SARImageImportAction = SARWindInversionMenu->addAction(tr(u8"SAR数据导入"));
SARInversionAtion = SARWindInversionMenu->addAction(tr(u8"SAR风场分析工具"));
SARInversionResulutShowAtion = SARWindInversionMenu->addAction(tr(u8"风场数据结果展示"));
//SARWindAysysMenu = SARWindInversionMenu->addMenu(tr(u8"风场分析"));
//SARImageAysysAction = SARWindAysysMenu->addAction(tr(u8"目标时间序列分析"));
QObject::connect(SARInversionAtion, SIGNAL(triggered()), this, SLOT(onshowSARInversionAtionTriggered()));
}
// 图像工具
{
datatoolbar = new QToolBar(tr(u8"工具"));
showDatamanagerAction = datatoolbar->addAction(tr(u8"数据管理"));
mapToolActionGroup = new QActionGroup(this);
ZoomInToolbtn = new QAction(tr(u8"放大"));
ZoomInToolbtn->setCheckable(true);
mapToolActionGroup->addAction(ZoomInToolbtn);
ZoomOutToolbtn = new QAction(tr(u8"缩小"));
ZoomOutToolbtn->setCheckable(true);
mapToolActionGroup->addAction(ZoomOutToolbtn);
MapPanToolbtn = new QAction(tr(u8"平移"));
MapPanToolbtn->setCheckable(true);
MapPanToolbtn->setChecked(true);
mapToolActionGroup->addAction(MapPanToolbtn);
IdentifyToolbtn = new QAction(tr(u8"识别"));
IdentifyToolbtn->setCheckable(true);
mapToolActionGroup->addAction(IdentifyToolbtn);
cursorAction = new QAction(tr(u8"游标"));
cursorAction->setCheckable(true);
mapToolActionGroup->addAction(cursorAction);
datatoolbar->addAction(ZoomInToolbtn);
datatoolbar->addAction(ZoomOutToolbtn);
datatoolbar->addAction(MapPanToolbtn);
datatoolbar->addAction(cursorAction);
m_mapToolPan = new QgsMapToolPan(this->map_canvas);
m_mapToolZoomIn = new QgsMapToolZoom(this->map_canvas, false);
m_mapToolZoomOut = new QgsMapToolZoom(this->map_canvas, true);
m_mapIdentifyToolPan = new QgsMapToolIdentify(this->map_canvas);
m_CustomCursorTool = new CustomCursorTool(this->map_canvas);
ZoomInToolbtn->setText(u8"放大");
ZoomOutToolbtn->setText(u8"缩小");
MapPanToolbtn->setText(u8"平移");
IdentifyToolbtn->setText(u8"识别");
connect(mapToolActionGroup, &QActionGroup::triggered, this, &ManualLabelToolWidget::onMapToolActionTriggered);
//QObject::connect(cursorAction, SIGNAL(triggered()), this, SLOT(onCursorImageToolTriggered()));
QObject::connect(showDatamanagerAction, SIGNAL(triggered()), this, SLOT(onshowDatamanagerActionTriggered()));
this->addToolBar(Qt::TopToolBarArea, datatoolbar);
}
// AI标注工具栏
{
AiLabelToolBar = new QToolBar(tr(u8"AI标注工具栏"), this);
this->addToolBar(Qt::LeftToolBarArea, AiLabelToolBar);
}
// 检查插件
{
QString qgisPrefixPath = WidgetSettingClass::instance().getExeDirectionApplicationPath();
// 3. 显式设置插件目录确保QGIS能找到动态提供者
QString pluginPath = qgisPrefixPath + "/plugins";
QgsApplication::setPluginPath(pluginPath);
// 4. 设置QGIS的共享数据目录包含proj.db等
QString pkgDataPath = qgisPrefixPath + "/share/qgis";
QgsApplication::setPkgDataPath(pkgDataPath);
QgsApplication::initQgis();
QStringList providers = QgsProviderRegistry::instance()->providerList();
qDebug() << u8"已注册的提供者:" << providers;
// 检查 "mesh_memory" 或相关的 "mdal" 提供者是否存在
if (providers.contains("mesh_memory")) {
qDebug() << u8"'mesh_memory' 提供者可用。";
}
else {
qDebug() << u8"警告:未找到相关的网格数据提供者。";
}
if (providers.contains("mdal")) {
qDebug() << u8"'mdal' 提供者可用,它可能包含在 'mdal' 中。";
}
else {
qDebug() << u8"警告:未找到相关的网格数据提供者。";
}
}
}
void ManualLabelToolWidget::open()
{
}
void ManualLabelToolWidget::openRaster()
{
QString lastFileDialogPath = WidgetSettingClass::instance().getLastFileDialogPath();
if (lastFileDialogPath.isEmpty()) {
lastFileDialogPath = ".";
}
// 打开影像
// 2. 选择多个文件
QString lampwindPath = QFileDialog::getOpenFileName(
this,
tr(u8"请选择影像文件"),
lastFileDialogPath,
tr(LAMPWINDDATAFILEFILTER)
);
QString filename = QFileInfo(lampwindPath).fileName();
QgsRasterLayer* rasterLayer = new QgsRasterLayer(lampwindPath, filename);
if (!rasterLayer->isValid()) {
qDebug() << "Failed to load raster layer!";
// 错误处理
return;
}
this->AddLayers(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::AddLayers(QgsMapLayer* layer)
{
if (!layer || !layer->isValid()) {
qDebug() << "无效图层,无法添加!";
return;
}
if (QgsProject::instance()->mapLayers().size() == 0) {
// 检查图层是否有效且拥有定义的坐标系
if (layer && layer->isValid() && layer->crs().isValid()) {
// 将地图画布的目标坐标系设置为与图层一致
map_canvas->mapSettings().setDestinationCrs(layer->crs());
// 可选:将地图范围缩放至该图层的全范围,提供更好的初始视图
map_canvas->setExtent(layer->extent());
// 刷新画布,使更改生效
map_canvas->refresh();
qDebug() << "图层数量为1已同步画布坐标系至" << layer->crs().description();
}
}
QgsProject::instance()->addMapLayer(layer);
}
void ManualLabelToolWidget::updateScaleLabel(double scale)
{
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));
QgsCoordinateReferenceSystem currentCrs = map_canvas->mapSettings().destinationCrs();
QString description = currentCrs.description();
QString authid = currentCrs.authid();
if (description == "") {
CoordinaryTextLabel->setText(QString(tr(u8"坐标系:未知")));
}
else {
CoordinaryTextLabel->setText(QString(tr(u8"坐标系:%1")).arg(description));
}
}
void ManualLabelToolWidget::onshowDatamanagerActionTriggered()
{
if (nullptr == datamanagerDialog) {
datamanagerDialog = new LampDataManager(this);
}
else {}
QRect parentGeometry = this->geometry();
QSize dialogSize = datamanagerDialog->size();
// 计算居中位置
int x = parentGeometry.x() + (parentGeometry.width() - dialogSize.width()) / 2;
int y = parentGeometry.y() + (parentGeometry.height() - dialogSize.height()) / 2;
// 设置对话框位置
datamanagerDialog->move(x, y);
datamanagerDialog->show();
datamanagerDialog->raise(); // 确保对话框在最前面
datamanagerDialog->activateWindow(); // 激活对话框获取焦点
}
void ManualLabelToolWidget::setupLayerTreeContextMenu()
{
// 启用图层树视图的默认上下文菜单
this->map_layerTreeView->setMenuProvider(this->map_layerTreeView->menuProvider());
// 或者自定义菜单
this->map_layerTreeView->setContextMenuPolicy(Qt::CustomContextMenu);
connect(this->map_layerTreeView, &QgsLayerTreeView::customContextMenuRequested,
this, &ManualLabelToolWidget::onLayerTreeContextMenu);
}
void ManualLabelToolWidget::onLayerTreeContextMenu(const QPoint& pos)
{
QModelIndex index = map_layerTreeView->indexAt(pos);
if (!index.isValid())
return;
QgsLayerTreeNode* node = map_layerTreeView->layerTreeModel()->index2node(index);
if (!node)
return;
QMenu* menu = new QMenu(this);
if (QgsLayerTree::isLayer(node))
{
QgsMapLayer* layer = QgsLayerTree::toLayer(node)->layer();
if (layer)
{
// 添加属性表菜单项
QAction* attributeTableAction = menu->addAction(tr("打开属性表"));
// 添加图层属性菜单项
QAction* layerPropertiesAction = menu->addAction(tr("图层属性"));
}
}
menu->exec(map_layerTreeView->mapToGlobal(pos));
delete menu;
}
void ManualLabelToolWidget::onshowSARInversionAtionTriggered()
{
QBatchStaticEchoDialog* d = new QBatchStaticEchoDialog(this);
d->show();
}
void ManualLabelToolWidget::onMapToolActionTriggered(QAction* action)
{
if (action == ZoomInToolbtn) {
this->map_canvas->setMapTool(m_mapToolZoomIn);
}
else if (action == ZoomOutToolbtn) {
this->map_canvas->setMapTool(m_mapToolZoomOut);
}
else if (action == MapPanToolbtn) {
this->map_canvas->setMapTool(m_mapToolPan);
}
else if (action == IdentifyToolbtn) {
this->map_canvas->setMapTool(m_mapIdentifyToolPan);
}
else if (action == cursorAction) {
this->map_canvas->setMapTool(m_CustomCursorTool);
if (!cursorInfoDialog)
{
cursorInfoDialog = new QImageCursorWidget(this); // 游标显示窗口
}
QObject::connect(m_CustomCursorTool, &CustomCursorTool::identifyResultChange, cursorInfoDialog, &QImageCursorWidget::showCursor, Qt::ConnectionType::AutoConnection);
cursorInfoDialog->show();
map_canvas->setCursor(Qt::CrossCursor);
}
else {
map_canvas->setCursor(Qt::CursorShape::ArrowCursor);
}
}

View File

@ -0,0 +1,139 @@
#pragma once
#include <QtWidgets/QMainWindow>
#include <memory>
#include <qgspointxy.h>
class QgsMapCanvas;
class QgsMapToolPan;
class QgsLayerTreeModel;
class QgsLayerTreeView;
class QgsLayerTreeMapCanvasBridge;
class QDockWidget;
class QLabel;
class QStatusBar;
class QMenuBar;
class QToolBar;
class QgsMapLayer;
class QImageCursorWidget;
class LampDataManager;
class QToolButton;
class QgsMapToolZoom;
class QgsMapToolIdentify;
class QActionGroup;
class CustomCursorTool;
class QgsLayerTreeViewMenuProvider;
class ManualLabelToolWidget : public QMainWindow
{
Q_OBJECT
public:
ManualLabelToolWidget(QWidget *parent = nullptr);
~ManualLabelToolWidget();
private: // UI
void init_UI();// Init UI
private:
LampDataManager* datamanagerDialog;
public: // 组件
QgsMapCanvas* map_canvas=nullptr; // map widget
QgsMapToolPan* map_tool_pan = nullptr; // map tool for pan zoom
QgsLayerTreeModel* map_layerModel = nullptr;
QgsLayerTreeView* map_layerTreeView = nullptr;
QgsLayerTreeMapCanvasBridge* map_layer_Bridge = nullptr;
private: // 布局
QDockWidget* layerTreeDock;
// 状态栏
QLabel* scaleLabel; // 比例尺
QLabel* CoordinaryTextLabel; // 图层坐标系
QLabel* PointXYLabel;// 鼠标指针坐标
QLabel* UnitLabel;
QStatusBar* appStatusBar;// 状态控制栏
private: // 菜单栏
QMenuBar* menubar;
private: // AI 工具栏
QToolBar* AiLabelToolBar;
private: // 文件菜单
QMenu* fileMenu;
QAction* newAction;
QMenu* openMenu;
QAction* openRasterFolderAction;
QAction* openRasterAction;
QAction* openSLCRasterAction;
QAction* openLampWindDataAction;
//private:// 编辑菜单
// QMenu* editMenu;
private: // 风场分析
QMenu* SARWindFieldMenu;
QAction* SARWindSpeedStatisticsAction;
QAction* SARInversionResulutShowAtion;
QMenu* SARWindAysysMenu;
QAction* SARImageAysysAction;
private: // 风能分析
QMenu* SARWindPowerMenu;
QAction* SARWindPowerDensityAction; // 风功率密度
QAction* SARWindPowerAction; // 风能密度
private: // 数据操作工具
QToolBar* datatoolbar;
QAction* showDatamanagerAction; // 打开数据管理工具
QAction* cursorAction;
QImageCursorWidget* cursorTextShowDialog = nullptr;
private: // 图层工具
QActionGroup* mapToolActionGroup;
QAction* ZoomInToolbtn;
QAction* ZoomOutToolbtn;
QAction* MapPanToolbtn;
QAction* IdentifyToolbtn;
QgsMapToolPan* m_mapToolPan;
QgsMapToolZoom* m_mapToolZoomIn;
QgsMapToolZoom* m_mapToolZoomOut;
QgsMapToolIdentify* m_mapIdentifyToolPan;
CustomCursorTool* m_CustomCursorTool;
QImageCursorWidget* cursorInfoDialog;
public slots:// 功能函数区
void open();
void openRaster();
// 状态栏函数
void updateScaleLabel(double);
void updateCoordinateLabel(const QgsPointXY&);
void onMapExtentsChanged();
// 数据管理窗口展示
void onshowDatamanagerActionTriggered();
void setupLayerTreeContextMenu();
void onLayerTreeContextMenu(const QPoint& pos);
void onshowSARInversionAtionTriggered();
void onMapToolActionTriggered(QAction* action);
public: // 图层操作函数
void AddLayers(QgsMapLayer* layer);
public: // 常用变量区
};

View File

@ -0,0 +1,230 @@
#include "QBatchStaticEchoDialog.h"
#include <QMessageBox>
#include <QFileInfo>
#include <QDebug>
//#include "EchoReader.h"
QStringList readFilePaths(const QString& filePath) {
QStringList pathList; // 用于存储文件路径的列表
// 1. 创建QFile对象并打开文件
QFile file(filePath);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
qDebug() << "无法打开文件:" << file.errorString();
return pathList; // 返回空列表
}
QTextStream in(&file);
in.setCodec("UTF-8");
while (!in.atEnd()) {
QString line = in.readLine().trimmed(); // 读取一行并去除首尾空白字符
if (!line.isEmpty()) { // 确保不是空行
pathList.append(line);
}
}
// 4. 关闭文件
file.close();
return pathList;
}
QBatchStaticEchoDialog::QBatchStaticEchoDialog(QWidget* parent)
: QDialog(parent)
{
setupUI();
setupConnections();
}
QBatchStaticEchoDialog::~QBatchStaticEchoDialog()
{
// Qt的父子对象机制会自动处理内存释放
}
void QBatchStaticEchoDialog::setupUI()
{
// 设置对话框属性
setWindowTitle(u8"风场数据处理");
setMinimumSize(600, 500);
// 创建主布局
QVBoxLayout* mainLayout = new QVBoxLayout(this);
// 创建文件列表区域
QLabel* listLabel = new QLabel(u8"文件列表:", this);
fileListWidget = new QListWidget(this);
fileListWidget->setSelectionMode(QAbstractItemView::ExtendedSelection); // 支持多选
// 创建按钮区域
QHBoxLayout* buttonLayout = new QHBoxLayout();
addButton = new QPushButton(u8"添加文件", this);
addTextButton = new QPushButton(u8"添加数据条目文件", this);
removeButton = new QPushButton(u8"移除选中", this);
processButton = new QPushButton(u8"开始处理", this);
buttonLayout->addWidget(addButton);
buttonLayout->addWidget(addTextButton);
buttonLayout->addWidget(removeButton);
buttonLayout->addStretch(); // 添加弹性空间
buttonLayout->addWidget(processButton);
// 创建复选框区域
QHBoxLayout* checkBoxLayout = new QHBoxLayout();
statisticCheckBox = new QCheckBox(u8"风能计算", this);
echoCheckBox = new QCheckBox(u8"风能统计", this);
statisticCheckBox->setChecked(true); // 默认选中
checkBoxLayout->addWidget(statisticCheckBox);
checkBoxLayout->addWidget(echoCheckBox);
checkBoxLayout->addStretch();
// 创建进度条区域
QLabel* progressLabel = new QLabel(u8"处理进度:", this);
progressBar = new QProgressBar(this);
progressBar->setMinimum(0);
progressBar->setMaximum(100);
progressBar->setValue(0);
progressBar->setVisible(true); // 默认显示
// 将组件添加到主布局
mainLayout->addWidget(listLabel);
mainLayout->addWidget(fileListWidget);
mainLayout->addLayout(buttonLayout);
mainLayout->addLayout(checkBoxLayout);
mainLayout->addWidget(progressLabel);
mainLayout->addWidget(progressBar);
setLayout(mainLayout);
}
void QBatchStaticEchoDialog::setupConnections()
{
// 连接按钮信号槽
connect(addButton, &QPushButton::clicked, this, &QBatchStaticEchoDialog::onAddFiles);
connect(addTextButton, &QPushButton::clicked, this, &QBatchStaticEchoDialog::onAddTextFiles);
connect(removeButton, &QPushButton::clicked, this, &QBatchStaticEchoDialog::onRemoveFile);
connect(processButton, &QPushButton::clicked, this, &QBatchStaticEchoDialog::onProcessFiles);
}
void QBatchStaticEchoDialog::onAddFiles()
{
// 使用QFileDialog选择多个文件[2,5](@ref)
QStringList files = QFileDialog::getOpenFileNames(
this,
u8"选择要处理的文件",
QDir::homePath(),
u8"All Files (*.*)"
);
if (!files.isEmpty()) {
foreach(QString file, files) {
QFileInfo fileInfo(file);
// 避免重复添加
if (fileListWidget->findItems(fileInfo.fileName(), Qt::MatchExactly).isEmpty()) {
QListWidgetItem* item = new QListWidgetItem(fileInfo.fileName());
item->setData(Qt::UserRole, file); // 存储完整路径
fileListWidget->addItem(item);
}
}
}
}
void QBatchStaticEchoDialog::onAddTextFiles()
{
QString filePath = QFileDialog::getOpenFileName(
this, // 父窗口
u8"请选择一个文件", // 对话框标题
"./", // 初始目录(这里设为程序当前目录)
u8"txt (*.txt);;" // 文件过滤器
);
QStringList dataliststr = readFilePaths(filePath);
foreach(QString file, dataliststr) {
QFileInfo fileInfo(file);
if (fileInfo.exists()) {
// 避免重复添加
if (fileListWidget->findItems(fileInfo.fileName(), Qt::MatchExactly).isEmpty()) {
QListWidgetItem* item = new QListWidgetItem(fileInfo.fileName());
item->setData(Qt::UserRole, file); // 存储完整路径
fileListWidget->addItem(item);
}
}
}
}
void QBatchStaticEchoDialog::onRemoveFile()
{
// 移除选中的项目[3](@ref)
QList<QListWidgetItem*> selectedItems = fileListWidget->selectedItems();
foreach(QListWidgetItem * item, selectedItems) {
delete fileListWidget->takeItem(fileListWidget->row(item));
}
}
void QBatchStaticEchoDialog::onProcessFiles()
{
QString selectedDir = "";
QFileDialog dialog(this);
dialog.setFileMode(QFileDialog::Directory); // 设置模式为选择目录
dialog.setOption(QFileDialog::ShowDirsOnly, true);
dialog.setViewMode(QFileDialog::Detail); // 设置视图为详细信息模式
if (dialog.exec() == QDialog::Accepted) {
selectedDir=dialog.selectedFiles().first();
}
else {
return;
}
if (fileListWidget->count() == 0) {
QMessageBox::warning(this, u8"警告", u8"请先添加要处理的文件!");
return;
}
bool enableStatistic = statisticCheckBox->isChecked();
bool enableEcho = echoCheckBox->isChecked();
if (!enableStatistic && !enableEcho) {
QMessageBox::warning(this, u8"警告", u8"请至少选择一个处理选项(统计或接回波)!");
return;
}
progressBar->setValue(0);
int totalFiles = fileListWidget->count();
for (int i = 0; i < totalFiles; ++i) {
QListWidgetItem* item = fileListWidget->item(i);
QString filePath = item->data(Qt::UserRole).toString();
if (this->echoCheckBox->isChecked()) {
QString echodatafilepath = QString(u8"%1\\%2").arg(selectedDir).arg(QFileInfo(filePath).fileName());
std::string infilepath = filePath.toUtf8().constData();
std::string outfilepath = echodatafilepath.toUtf8().constData();
//ParseEchoData(infilepath, outfilepath);
}
if (this->statisticCheckBox->isChecked()) {
QString staticfilepath = QString(u8"%1\\%2").arg(selectedDir).arg(u8"staticResult.dat");
std::string infilepath = filePath.toUtf8().constData();
std::string outfilepath = staticfilepath.toUtf8().constData();
//StaticEchoData(infilepath, outfilepath);
//ReadEchoInfoFile(outfilepath);
}
// 更新进度
int progress = (i + 1) * 100 / totalFiles;
progressBar->setValue(progress);
}
QMessageBox::information(this, u8"完成", u8"文件处理完成!");
}
void QBatchStaticEchoDialog::updateProgress(int value)
{
progressBar->setValue(value);
}

View File

@ -0,0 +1,42 @@
#pragma once
#include <QDialog>
#include <QListWidget>
#include <QPushButton>
#include <QCheckBox>
#include <QProgressBar>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QFileDialog>
class QBatchStaticEchoDialog : public QDialog
{
Q_OBJECT
public:
explicit QBatchStaticEchoDialog(QWidget* parent = nullptr);
~QBatchStaticEchoDialog();
private slots:
void onAddFiles(); // 添加文件
void onAddTextFiles(); // 添加文件
void onRemoveFile(); // 移除选中文件
void onProcessFiles(); // 处理文件(根据复选框状态)
void updateProgress(int value); // 更新进度条
private:
void setupUI(); // 初始化界面
void setupConnections(); // 连接信号槽
// 界面组件
QListWidget* fileListWidget;
QPushButton* addButton;
QPushButton* addTextButton;
QPushButton* removeButton;
QPushButton* processButton;
QCheckBox* statisticCheckBox;
QCheckBox* echoCheckBox;
QProgressBar* progressBar;
};
QStringList readFilePaths(const QString& filePath);

View File

@ -0,0 +1,22 @@
<UI version="4.0" >
<class>QBatchStaticEchoDialogClass</class>
<widget class="QMainWindow" name="QBatchStaticEchoDialogClass" >
<property name="objectName" >
<string notr="true">QBatchStaticEchoDialogClass</string>
</property>
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>600</width>
<height>400</height>
</rect>
</property>
<property name="windowTitle" >
<string>QBatchStaticEchoDialog</string>
</property> <widget class="QMenuBar" name="menuBar" /> <widget class="QToolBar" name="mainToolBar" /> <widget class="QWidget" name="centralWidget" /> <widget class="QStatusBar" name="statusBar" />
</widget>
<layoutDefault spacing="6" margin="11" />
<pixmapfunction></pixmapfunction>
<connections/>
</UI>

View File

@ -0,0 +1,181 @@
#include "QImageCursorWidget.h"
#include <QApplication>
#include <QMainWindow>
#include <QVBoxLayout>
#include <QWidget>
#include <memory>
#include <qgsrasteridentifyresult.h>
#include <qgsmapcanvas.h>
#include <QCheckBox>
#include <QTreeView>
#include <qgsraster.h>
#include <qgsrasterlayer.h>
#include <qgsmeshlayer.h>
QImageCursorWidget::QImageCursorWidget(QWidget *parent)
: QDialog(parent)
{
maplayer_treewidgetItem.clear();
this->initUi();
this->setWindowTitle(u8"游标窗口");
this->resize(400, 600);
}
QImageCursorWidget::~QImageCursorWidget()
{}
void QImageCursorWidget::initUi()
{
// 创建主布局(垂直分布)
QVBoxLayout* mainLayout = new QVBoxLayout(this);
// 1. 创建菜单按钮栏这里使用QToolBar或QWidget配合QHBoxLayout模拟
QWidget* toolBarWidget = new QWidget(this);
QHBoxLayout* toolBarLayout = new QHBoxLayout(toolBarWidget);
toolBarLayout->setContentsMargins(0, 0, 0, 0); // 可选:移除边距使布局更紧凑
// 创建复选框按钮:“时序图”、“方向图”
QCheckBox* checkBoxTimeSeries = new QCheckBox(tr(u8"时序图"), toolBarWidget);
QCheckBox* checkBoxDirection = new QCheckBox(tr(u8"方向图"), toolBarWidget);
// 将复选框添加到按钮栏布局
toolBarLayout->addWidget(checkBoxTimeSeries);
toolBarLayout->addWidget(checkBoxDirection);
toolBarLayout->addStretch(); // 添加一个弹性空间,使按钮靠左排列
// 2. 创建TreeView
treewidgetResults = new QTreeWidget(this);
treewidgetResults->setColumnCount(2);
treewidgetResults->setHeaderLabels(QStringList() << u8"属性" << u8"");
// 3. 将按钮栏和TreeView添加到主垂直布局中
mainLayout->addWidget(toolBarWidget);
mainLayout->addWidget(treewidgetResults);
// 4. 可选设置布局的比例例如让TreeView占据更多空间
mainLayout->setStretchFactor(toolBarWidget, 0); // 工具栏不拉伸
mainLayout->setStretchFactor(treewidgetResults, 1); // TreeView可拉伸
// 设置当前窗口的布局为主布局
this->setLayout(mainLayout);
}
void QImageCursorWidget::showCursor(QList<QgsMapToolIdentify::IdentifyResult> result)
{
maplayer_treewidgetItem.clear();
treewidgetResults->clear();
treewidgetResults->setColumnCount(2);
treewidgetResults->setHeaderLabels(QStringList() << u8"属性" << u8"");
int32_t layerCount = result.count();
for (int32_t i = 0; i < layerCount; i++) {
if (result[i].mLayer->type() == Qgis::LayerType::Raster) {
}
else if (result[i].mLayer->type() == Qgis::LayerType::Mesh) {
}
}
this->populateTreeWidget(result);
}
void QImageCursorWidget::populateTreeWidget(const QList<QgsMapToolIdentify::IdentifyResult>& results)
{
for (const QgsMapToolIdentify::IdentifyResult& result : results) {
if (result.mLayer->type() == Qgis::LayerType::Raster) {
addFeature(qobject_cast<QgsRasterLayer*>(result.mLayer), result.mLabel, result.mAttributes, result.mDerivedAttributes, result.mFields, result.mFeature, result.mParams);
}
else if (result.mLayer->type() == Qgis::LayerType::Mesh) {
addFeature(qobject_cast<QgsMeshLayer*>(result.mLayer), result.mLabel, result.mAttributes, result.mDerivedAttributes);
}
else {
}
}
treewidgetResults->expandAll();
}
void QImageCursorWidget::addKeyValuePair(QTreeWidgetItem* parent, const QString& key, const QString& value)
{
QTreeWidgetItem* item = new QTreeWidgetItem(parent);
item->setText(0, key);
item->setText(1, value);
}
QTreeWidgetItem* QImageCursorWidget::layerItem(QgsMapLayer* layer)
{
QTreeWidgetItem* layItem = nullptr;
if (maplayer_treewidgetItem.contains(layer)) {
layItem = maplayer_treewidgetItem[layer];
treewidgetResults->addTopLevelItem(layItem);
}
else {
layItem = new QTreeWidgetItem(treewidgetResults);
layItem->setText(0, layer->name());
maplayer_treewidgetItem.insert(layer, layItem);
treewidgetResults->addTopLevelItem(layItem);
}
return layItem;
}
void QImageCursorWidget::addFeature(QgsRasterLayer* layer,
const QString& label, const QMap<QString, QString>& attributes,
const QMap<QString, QString>& derivedAttributes, const QgsFields& fields,
const QgsFeature& feature, const QMap<QString, QVariant>& params)
{
QTreeWidgetItem* layItem = layerItem(layer);
QTreeWidgetItem* labelNode = new QTreeWidgetItem();
labelNode->setText(0, label);
// attributes
for (auto it = attributes.begin(); it != attributes.end(); ++it) {
QTreeWidgetItem* tempnode = new QTreeWidgetItem();
tempnode->setText(0, it.key());
tempnode->setText(1, it.value());
labelNode->addChild(tempnode);
}
layItem->addChild(labelNode);
// derivedAttributes
QTreeWidgetItem* driverNode = new QTreeWidgetItem();
for (auto it = derivedAttributes.begin(); it != derivedAttributes.end(); ++it) {
QTreeWidgetItem* tempnode = new QTreeWidgetItem();
tempnode->setText(0, it.key());
tempnode->setText(1, it.value());
driverNode->addChild(tempnode);
}
layItem->addChild(driverNode);
}
void QImageCursorWidget::addFeature(QgsMeshLayer* layer, const QString& label, const QMap<QString, QString>& attributes, const QMap<QString, QString>& derivedAttributes)
{
QTreeWidgetItem* layItem = layerItem(layer);
QTreeWidgetItem* labelNode = new QTreeWidgetItem();
labelNode->setText(0, label);
// attributes
for (auto it = attributes.begin(); it != attributes.end(); ++it) {
QTreeWidgetItem* tempnode = new QTreeWidgetItem();
tempnode->setText(0, it.key());
tempnode->setText(1, it.value());
labelNode->addChild(tempnode);
}
layItem->addChild(labelNode);
// derivedAttributes
QTreeWidgetItem* driverNode = new QTreeWidgetItem();
driverNode->setText(0, u8"(derivedAttributes)");
for (auto it = derivedAttributes.begin(); it != derivedAttributes.end(); ++it) {
QTreeWidgetItem* tempnode = new QTreeWidgetItem();
tempnode->setText(0, it.key());
tempnode->setText(1, it.value());
driverNode->addChild(tempnode);
}
layItem->addChild(driverNode);
}

View File

@ -0,0 +1,58 @@
#pragma once
#include <QDialog>
#include <QApplication>
#include <QMainWindow>
#include <QVBoxLayout>
#include <QWidget>
//#include <matplot/matplot.h>
#include <memory>
#include <qtextedit.h>
#include <qgsrasteridentifyresult.h>
#include <qgsmaptoolidentify.h>
#include <qgsmaptoolidentifyfeature.h>
#include <QTreeWidget>
#include <QTreeWidgetItem>
#include <qwt_polar.h>
#include <qwt_plot_curve.h>
#include <QMap>
class QCheckBox;
class QTreeView;
class QTreeWidgetItem;
class QgsHighlight;
class QImageCursorWidget : public QDialog
{
Q_OBJECT
public:
QImageCursorWidget(QWidget *parent = nullptr);
~QImageCursorWidget();
void initUi();
public slots:
void showCursor(QList<QgsMapToolIdentify::IdentifyResult> result);
void populateTreeWidget(const QList<QgsMapToolIdentify::IdentifyResult>& results);
void addKeyValuePair(QTreeWidgetItem* parent, const QString& key, const QString& value);
public:
void addFeature(QgsMeshLayer* layer, const QString& label, const QMap<QString, QString>& attributes, const QMap<QString, QString>& derivedAttributes);
void addFeature(QgsRasterLayer* layer, const QString& label, const QMap<QString, QString>& attributes, const QMap<QString, QString>& derivedAttributes, const QgsFields& fields = QgsFields(), const QgsFeature& feature = QgsFeature(), const QMap<QString, QVariant>& params = (QMap<QString, QVariant>()));
QTreeWidgetItem* layerItem(QgsMapLayer* object);
private:
QCheckBox* checkBoxTimeSeries;
QCheckBox* checkBoxDirection;
QTreeWidget* treewidgetResults;
QHash<QgsMapLayer*, QTreeWidgetItem*> maplayer_treewidgetItem;
};

View File

@ -0,0 +1,11 @@
#include "QtWindComputer.h"
QtWindComputer::QtWindComputer(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
}
QtWindComputer::~QtWindComputer()
{}

View File

@ -0,0 +1,17 @@
#pragma once
#include <QMainWindow>
#include "ui_QtWindComputer.h"
class QtWindComputer : public QMainWindow
{
Q_OBJECT
public:
QtWindComputer(QWidget *parent = nullptr);
~QtWindComputer();
private:
Ui::QtWindComputerClass ui;
};

View File

@ -0,0 +1,22 @@
<UI version="4.0" >
<class>QtWindComputerClass</class>
<widget class="QMainWindow" name="QtWindComputerClass" >
<property name="objectName" >
<string notr="true">QtWindComputerClass</string>
</property>
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
<width>600</width>
<height>400</height>
</rect>
</property>
<property name="windowTitle" >
<string>QtWindComputer</string>
</property> <widget class="QMenuBar" name="menuBar" /> <widget class="QToolBar" name="mainToolBar" /> <widget class="QWidget" name="centralWidget" /> <widget class="QStatusBar" name="statusBar" />
</widget>
<layoutDefault spacing="6" margin="11" />
<pixmapfunction></pixmapfunction>
<connections/>
</UI>

View File

@ -0,0 +1,34 @@
#include "UnitTest.h"
#include <QmainWindow>
#include <qgsmapcanvas.h>
#include <qgsrasterlayer.h>
#include <qgsmaptoolpan.h>
#include "ManualLabelToolWidget.h"
#include "LAMPDataManagerDialog.h"
#include "WindConverTools.h"
void TestManualLabelToolWidget()
{
ManualLabelToolWidget labeltoolwidget;
labeltoolwidget.show();
}
void TestNc2WindDataTool() {
QString ncfilepath = u8"D:\\Programs\\SpacetyLabelAIPlante\\Manual-Labeling-Tool\\WindFileData\\data\\total_precipitation202001.nc";
QString binfilepath = u8"D:\\Programs\\SpacetyLabelAIPlante\\Manual-Labeling-Tool\\WindFileData\\output\\converted_wind_data.bin";
nc2windataTool* tool=new nc2windataTool(ncfilepath,binfilepath,nullptr);
tool->Excute();
}
void TestALL()
{
TestManualLabelToolWidget();
//TestLampDataManagerWidget();
//TestNc2WindDataTool();
}

View File

@ -0,0 +1,6 @@
#pragma once
void TestALL();

View File

@ -0,0 +1,124 @@
#include "WidgetSettingClass.h"
#include <QFileInfo>
#include <QDir>
WidgetSettingClass::~WidgetSettingClass()
{
}
WidgetSettingClass& WidgetSettingClass::instance()
{
static WidgetSettingClass instance;
return instance;
}
// 实现构造函数和其他方法...
WidgetSettingClass::WidgetSettingClass(QObject* parent)
: QObject(parent), m_settings(new QSettings(this))
{
lastFileDialogPath = QString();
iniPath = this->getExeDirectionApplicationPath()+u8"\\LAMPWINDData.ini";
if (!QFileInfo(iniPath).exists()) {
QSettings writeSettings(iniPath, QSettings::IniFormat);
writeSettings.setValue("Application/Name", u8"风场处理软件");
writeSettings.setValue("Application/Version", 1.0);
writeSettings.setValue("Application/LastfilePath", this->getExeDirectionApplicationPath());
}
QSettings readSettings(iniPath, QSettings::IniFormat);
QString appName = readSettings.value("Application/Name").toString();
double version = readSettings.value("Application/Version").toDouble();
this->lastFileDialogPath= readSettings.value("Application/LastfilePath").toString();
}
QString WidgetSettingClass::getWindTool_nc2WindDataToolPath()
{
QString appDir = QCoreApplication::applicationDirPath();
QDir baseDir(appDir);
QString toolPyPath = baseDir.absoluteFilePath(u8"tools\\windTools\\ERA5ToWindDataConverter.py");
toolPyPath = QDir::cleanPath(toolPyPath);
return toolPyPath;
}
QString WidgetSettingClass::getWindTool_PythonEnvPath()
{
QString appDir = QCoreApplication::applicationDirPath();
QDir baseDir(appDir);
QString pythonExePath = baseDir.absoluteFilePath(u8"pyEnv\\lampprocess\\python.exe");
pythonExePath = QDir::cleanPath(pythonExePath);
qDebug() << "Python executable path:" << pythonExePath;
return pythonExePath;
}
QString WidgetSettingClass::getExeApplicationPath()
{
// 先得到完整的可执行文件路径
QString appFilePath = QCoreApplication::applicationFilePath();
// 使用QFileInfo提取其所在的绝对路径
QFileInfo fileInfo(appFilePath);
return fileInfo.absolutePath(); // 返回目录路径
}
QString WidgetSettingClass::getExeDirectionApplicationPath()
{
return QCoreApplication::applicationDirPath();
}
QString WidgetSettingClass::getWindReaddLLApplicationPath()
{
QString appDir = QCoreApplication::applicationDirPath();
QDir baseDir(appDir);
QString toolPath = baseDir.absoluteFilePath(u8"WindDataOperator.dll");
toolPath = QDir::cleanPath(toolPath);
return toolPath;
}
QString WidgetSettingClass::getLastFileDialogPath()
{
return this->lastFileDialogPath;
}
void WidgetSettingClass::setLastFileDialogPath(QString path)
{
lastFileDialogPath = path;
iniPath = this->getExeDirectionApplicationPath() + u8"\\LAMPWINDData.ini";
if (!QFileInfo(iniPath).exists()) {
QSettings writeSettings(iniPath, QSettings::IniFormat);
writeSettings.setValue("Application/LastfilePath", lastFileDialogPath);
}
else {
QSettings writeSettings(iniPath, QSettings::IniFormat);
writeSettings.setValue("Application/LastfilePath", lastFileDialogPath);
}
}
QString WidgetSettingClass::getTempFolder()
{
QString tempPath2 = QDir::tempPath();
qDebug() << u8"系统临时文件夹路径 (QDir): " << tempPath2;
QString tempfolderpath= tempPath2 + "\\lampwind";
QDir dir;
// 首先检查路径是否已经存在
if (dir.exists(tempfolderpath)) {
qDebug() << "目录已存在:" << tempfolderpath;
}
else if (dir.mkpath(tempfolderpath)) {
qDebug() << "目录创建成功:" << tempfolderpath;
}
else {
qDebug() << "目录创建失败:" << tempfolderpath;
}
return tempfolderpath;
}

View File

@ -0,0 +1,55 @@
#pragma once
#ifndef __WIDGETSETTINGCLASS__H__
#define __WIDGETSETTINGCLASS__H__
#include <QCoreApplication>
#include <QSettings>
#include <QDebug>
#include <QString>
#include <QObject>
#include <QMutex>
#include <QScopedPointer>
// 定义访问参数
#define RASTERFILEFILTER u8"所有文件 (*.*);;TIF (*.tif);;TIFF (*.tiff);;bin (*.bin);;dat (*.dat);;"
#define LAMPWINDDATAFILEFILTER u8"所有文件 (*.*);;风场文件 (*.lampwind);;TIF (*.tif);;TIFF (*.tiff);;bin (*.bin);;dat (*.dat);;"
class WidgetSettingClass : public QObject
{
Q_OBJECT
public:
// 获取单例实例的静态方法
static WidgetSettingClass& instance();
// 禁止拷贝构造和赋值
WidgetSettingClass(const WidgetSettingClass&) = delete;
WidgetSettingClass& operator=(const WidgetSettingClass&) = delete;
public:
static QScopedPointer<WidgetSettingClass> m_instance;
public:
// 私有构造函数和析构函数
explicit WidgetSettingClass(QObject* parent = nullptr);
~WidgetSettingClass();
private:
QSettings* m_settings;
QString lastFileDialogPath;
QString iniPath;
public:
QString getWindTool_nc2WindDataToolPath();
QString getWindTool_PythonEnvPath();
QString getExeApplicationPath();
QString getExeDirectionApplicationPath();
QString getWindReaddLLApplicationPath();
QString getLastFileDialogPath();
void setLastFileDialogPath(QString path);
QString getTempFolder();
};
#endif

View File

@ -0,0 +1,80 @@
#include "WindConverTools.h"
#include "WidgetSettingClass.h"
#include <QFileInfo>
#include <QProcess>
nc2windataTool::nc2windataTool(QString Inncfilepath, QString InwindBinPath, LAMPDataManagerDialog* IndatamanagerDiglog)
{
this->ncfilepath = Inncfilepath;
this->windBinPath = InwindBinPath;
this->datamanagerDiglog = IndatamanagerDiglog;
}
nc2windataTool::~nc2windataTool()
{
}
int32_t nc2windataTool::Excute()
{
WidgetSettingClass& config = WidgetSettingClass::instance();
QString pythonPath = config.getWindTool_PythonEnvPath();
QString nc2windToolPath = config.getWindTool_nc2WindDataToolPath();
QString dllPath = config.getWindReaddLLApplicationPath();
// 2. 检查文件是否存在
if (!QFileInfo(pythonPath).exists()) {
qDebug() << u8"错误Python解释器路径不存在 -" << pythonPath;
return -1;
}
if (!QFileInfo(nc2windToolPath).exists()) {
qDebug() << u8"错误Python脚本路径不存在 -" << nc2windToolPath;
return -1;
}
if (!QFileInfo(ncfilepath).exists()) {
qDebug() << u8"错误:参数文件路径不存在 -" << ncfilepath;
return -1;
}
if (!QFileInfo(dllPath).exists()) {
qDebug() << u8"错误:程序库文件路径不存在 -" << dllPath;
return -1;
}
// 构建参数列表
QStringList arguments;
arguments
//<< "/c"
//<< pythonPath
<< nc2windToolPath // Python脚本路径
<< "-i" << ncfilepath
<< "-o" << windBinPath
<< "-d" << dllPath;
// 连接finished信号到成员槽函数
//connect(m_process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
// this, &nc2windataTool::on_process_finished);
m_process= new QProcess(this);
//m_process->execute("cmd.exe", arguments);
m_process->start(pythonPath, arguments);
if (!m_process->waitForStarted(3000)) { // 等待进程启动超时3秒
qDebug() << u8"启动失败:" << m_process->errorString();
}
else {
qDebug() << u8"进程已启动...";
}
return 0;
}
void nc2windataTool::on_process_finished(int exitCode, QProcess::ExitStatus exitStatus)
{
if (!QFileInfo(windBinPath).exists()) {
qDebug() << u8"错误:结果文件不存在 -" << windBinPath;
return ;
}
// 数据加载
// LAMPDataManagerDialog* IndatamanagerDiglog
}

View File

@ -0,0 +1,31 @@
#pragma once
#include <QString>
#include <QObject>
#include <QProcess>
class LAMPDataManagerDialog;
class QProcess;
class nc2windataTool :public QObject {
Q_OBJECT
public:
nc2windataTool(QString ncfilepath, QString windBinPath, LAMPDataManagerDialog* datamanagerDiglog);
~nc2windataTool();
int32_t Excute();
public slots:
void on_process_finished(int exitCode, QProcess::ExitStatus exitStatus);
private:
LAMPDataManagerDialog* datamanagerDiglog;
QProcess* m_process; // ½«QProcess×÷Ϊ³ÉÔ±±äÁ¿
QString ncfilepath;
QString windBinPath;
};

View File

@ -0,0 +1,13 @@
########################################################
# Files
########################################################
# Build
########################################################
# Continue on to subdirs
add_subdirectory(icons)
add_subdirectory(themes)
add_subdirectory(svg)

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 781 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

View File

@ -0,0 +1,13 @@
These are examples used in the GitHub landing page README.md
icebergs.gif, network_analysis_2.png - Ben Hur, own work @benhur07b
plugins_1.png - self-explanatory screenshot
qgis_map_showcase.png - screen shot from https://www.flickr.com/groups/qgis/pool/
These no longer used, but might be helpful if need smaller thumbnails / side-by-side images
QGIS_ex1.png - https://www.qgis.org/en/_images/qgisdesktopscreenshot.jpg via https://www.qgis.org/en/site/about/index.html
QGIS_ex2.png - https://www.flickr.com/photos/7361002@N08/50870685936/in/pool-2244553@N22 via https://www.qgis.org/en/site/about/screenshots.html
QGIS_ex3.png - https://docs.qgis.org/3.16/en/_images/models_model.png
QGIS_ex4.png - https://docs.qgis.org/3.16/en/_images/python_console_editor.png
QGIS_ex5.png - https://docs.qgis.org/3.16/en/_images/server_wfs3_feature.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

View File

@ -0,0 +1 @@
<svg height="492.18411" width="489.33719" xmlns="http://www.w3.org/2000/svg"><g fill="none" stroke-linecap="round" stroke-linejoin="round" transform="translate(-86.767507 -101.99995)"><path d="m105.71429 120.93361 451.42857 454.28572" stroke="#e1270a" stroke-width="37.5"/><path d="m557.14286 126.6479-451.42857 448.57143" stroke="#e1270a" stroke-width="37.5"/><g stroke="#fff" stroke-width="19.6"><path d="m105.71429 120.93361 451.42857 454.28572"/><path d="m557.14286 126.6479-451.42857 448.57143"/></g></g></svg>

After

Width:  |  Height:  |  Size: 515 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1960.148" height="1881.596" viewBox="0 0 1470.111 1411.197"><path d="M733.188 0C658.67 0 592.634 42.28 556.674 102.913c-9.04-1.247-18.174-2.116-27.474-2.116h-324C93.232 100.795 0 195.995 0 305.995c0 56.07 22.427 107.361 60.734 145.668 13.96 13.96 31.8 26.463 51.564 36.552-31.083 78.07-47.495 161.929-47.495 247.383v1.2c0 130.236 37.202 257.711 108.112 367.16a150.015 150.015 0 0 0 19.822 24.505c-4.844-4.843-6.84-6.975-9.6-9.836 1.161 1.673 1.937 2.799 3.326 4.789 6.072 8.696 12.683 18.426 22.82 31.095a150.028 150.028 0 0 0 11.054 12.349c-17.093-17.094-4.426-4.64-1.689-1.474 2.738 3.166 6.644 7.707 10.915 12.665 8.543 9.916 17.912 20.833 26.656 30.45 1.6 1.759 3.24 3.48 4.922 5.16 125.992 125.993 297.148 197.535 476.865 197.535 74.448 0 140.43-42.203 176.412-102.746 8.68 1.148 17.447 1.946 26.365 1.946h324c110.278 0 202.316-92.36 205.07-200.243 2.38-55.62-19.252-111.305-59.2-150.412l-.194-.21c-.18-.18-.401-.343-.582-.522-1.92-1.86-3.828-3.732-5.832-5.512l-.01.27c-12.866-11.633-28.183-22.132-45.139-30.788 31.083-78.07 47.495-161.928 47.495-247.382v-2.4c0-130.236-37.202-257.711-108.111-367.16a150.015 150.015 0 0 0-19.823-24.505c4.222 4.222 5.989 6.085 8.366 8.535-1.213-1.678-2.164-2.982-3.63-5.026a2824.753 2824.753 0 0 1-15.533-21.88 150.018 150.018 0 0 0-16.805-20.027c21.512 21.512 6.133 6.55 3.381 3.265-2.752-3.285-6.762-8.092-11.288-13.441-9.052-10.699-18.258-21.99-32.893-36.626l-.643-.639C1082.622 70.427 912.048 0 733.188 0Zm3.543 410.48c69.824.868 132.035 27.228 181.99 77.184h.003c23.96 26.345 24.378 28.39 34.406 43.045 8.922 13.686 16.276 28.062 22.312 42.85-14.669-3.1-29.207-4.76-43.057-4.76-1.92 0-3.84.037-5.76.111-108.838 4.184-202.641 99.119-198.119 212.277l-.085-2.731 4.779 219.83c-69.314-1.168-131.083-27.497-180.739-77.153l-.003-.003c-24.323-24.775-35.707-39.88-55.886-83.661 14.257 3.154 28.214 4.932 41.026 4.932 55.328 0 108.31-20.77 148.879-65.407 38.96-41.602 55.12-94.987 55.12-140.996 0-1.087-.011-2.174-.035-3.26zm461.662 760.211a149.933 149.933 0 0 0 4.226 4.685c-.543-.44-1.01-.874-1.517-1.313-.926-.915-1.864-1.818-2.75-2.767z" style="color:#000;fill:#fff;fill-opacity:.70069897;stroke:none;stroke-width:300;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:.468781;-inkscape-stroke:none;paint-order:stroke fill markers"/><g style="fill:#000;fill-opacity:.700699;stroke:none;stroke-width:100;stroke-dasharray:none;stroke-opacity:.468781;paint-order:stroke fill markers"><path d="M604.8 1042.8c-110.4 0-213.6-43.199-291.6-121.2-9.602-9.602-31.199-34.801-32.398-37.199-7.2-8.398-21.602-28.801-21.602-30-105.6-162-82.801-379.2 54-516 1.2-1.2 22.801-21.602 31.199-27.602l3.602 220.8c0 14.398 6 28.801 16.8 39.602 10.802 10.801 24 15.602 39.603 15.602 14.398 0 28.8-6 38.398-16.801 10.8-10.801 15.602-25.199 15.602-39.602l-7.2-331.2c0-30-25.199-54-55.199-54h-324c-31.199 0-55.199 25.199-55.199 55.199 0 14.398 6 28.801 16.801 39.602 10.801 10.801 24 16.801 39.602 16.801h165.6l-12 13.199c-93.602 97.199-145.2 225.6-145.2 360v1.2c0 102 28.801 200.4 84 285.6 1.2 1.198 18 26.397 27.602 38.397 2.399 2.399 28.801 33.602 40.801 46.801 98.398 98.398 230.4 153.6 370.8 153.6 31.2 0 55.2-25.199 55.2-55.199-.012-30.008-24.013-57.605-55.212-57.605zM1171.2 960c-10.801-10.801-24-16.801-39.602-16.801h-165.6l12-13.199c93.602-97.199 145.2-225.6 145.2-360v-2.398c0-102-28.801-200.4-84-285.6-1.2-1.2-19.199-26.398-27.602-38.398-2.398-2.399-27.602-33.602-40.801-46.801-99.598-98.402-230.4-152.4-370.8-152.4-31.199 0-55.199 25.199-55.199 55.199 0 31.199 25.199 55.199 55.199 55.199 110.4 0 213.6 43.199 291.6 121.2 9.602 9.601 31.199 34.8 32.398 37.199 7.2 8.398 21.602 28.8 21.602 30 105.6 162 82.801 379.2-54 516-1.2 1.199-22.801 21.602-31.199 27.602l-4.8-219.6c0-14.398-6-28.801-16.802-38.398-10.8-10.801-25.199-15.602-39.602-15.602-31.199 1.199-55.199 26.398-54 56.398l7.2 331.2c0 30 25.198 54 55.198 54h324c31.2 0 55.2-25.2 55.2-55.2 1.203-15.593-4.797-29.991-15.599-39.593z" style="fill:#000;fill-opacity:.700699;stroke:none;stroke-width:100;stroke-dasharray:none;stroke-opacity:.468781;paint-order:stroke fill markers" transform="translate(133.194 105.597)"/></g></svg>

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@ -0,0 +1 @@
<svg height="600" viewBox="0 0 9 6" width="900" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><clipPath id="a"><path id="b" d="m0 0 4.5 3-4.5 3"/></clipPath><clipPath id="c"><path d="m0 0h9v6h-9z"/></clipPath><g clip-path="url(#c)"><path d="m0 0v6h9v-6z" fill="#002395"/><path d="m0 0v3h9v-3z" fill="#de3831"/><g stroke="#fff" stroke-width="2"><path id="d" d="m0 0 4.5 3-4.5 3m4.5-3h4.5"/><use clip-path="url(#a)" stroke="#ffb612" xlink:href="#b"/></g><use fill="none" stroke="#007a4d" stroke-width="1.2" xlink:href="#d"/></g></svg>

After

Width:  |  Height:  |  Size: 564 B

View File

@ -0,0 +1 @@
<svg height="800" viewBox="0 0 9 6" width="1200" xmlns="http://www.w3.org/2000/svg"><path d="m0 0h9v6h-9z" fill="#fff"/><path d="m0 0h9v4h-9z" fill="#007a3d"/><path d="m0 0h9v2h-9z"/><path d="m0 6v-6l3 3z" fill="#ce1126"/></svg>

After

Width:  |  Height:  |  Size: 228 B

View File

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
version="1.0"
width="1200"
height="600"
viewBox="0 -300 1200 600"
id="svg2">
<defs
id="defs21" />
<rect
width="1200"
height="600"
x="0"
y="-300"
style="fill:#0092c7;fill-opacity:1"
id="blue_stripe" />
<rect
width="1200"
height="200"
x="0"
y="-100"
style="fill:#ea0437;fill-opacity:1"
id="red_stripe" />
<rect
width="1200"
height="200"
x="0"
y="100"
style="fill:#00ae68;fill-opacity:1"
id="green_stripe" />
<circle
cx="560"
cy="0"
r="84"
style="fill:#ffffff"
id="white_circle" />
<circle
cx="582"
cy="0"
r="70"
style="fill:#ea0437;fill-opacity:1"
id="red_circle" />
<path
d="M 70.255954,-339.97293 L 48.485805,-349.82516 L 40.104505,-327.4475 L 31.677263,-349.8079 L 9.9273944,-339.91098 L 19.779625,-361.68113 L -2.5980343,-370.06243 L 19.762365,-378.48967 L 9.8654446,-400.23954 L 31.635594,-390.38731 L 40.016894,-412.76497 L 48.444136,-390.40457 L 70.194004,-400.30149 L 60.341774,-378.53134 L 82.719433,-370.15004 L 60.359034,-361.7228 L 70.255954,-339.97293 z "
transform="matrix(1.0548817,1.8411178e-3,-1.8411178e-3,1.0548817,602.05929,390.34455)"
style="fill:#ffffff;fill-opacity:1"
id="path4162" />
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1 @@
<svg height="600" viewBox="0 0 5 3" width="1000" xmlns="http://www.w3.org/2000/svg"><path d="m0 0h5v3h-5z" fill="#fff"/><path d="m0 1h5v2h-5z" fill="#00966e"/><path d="m0 2h5v1h-5z" fill="#d62612"/></svg>

After

Width:  |  Height:  |  Size: 204 B

View File

@ -0,0 +1 @@
<svg height="300" viewBox="0 0 20 12" width="500" xmlns="http://www.w3.org/2000/svg"><path d="m0 0h20v12h-20z" fill="#006a4e"/><circle cx="9" cy="6" fill="#f42a41" r="4"/></svg>

After

Width:  |  Height:  |  Size: 177 B

View File

@ -0,0 +1 @@
<svg height="400" viewBox="0 0 16 8" width="800" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="m0 0h16v8h-16z" fill="#002395"/><path d="m4.24 0h8v8z" fill="#fecb00"/><g id="a"><path id="b" d="m2.353283.5248529.446717-1.3748529.446717 1.374853-1.16952-.849706h1.445606z" fill="#fff"/><use x="1" xlink:href="#b" y="1"/><use x="2" xlink:href="#b" y="2"/></g><use x="3" xlink:href="#a" y="3"/><use x="6" xlink:href="#a" y="6"/></svg>

After

Width:  |  Height:  |  Size: 470 B

View File

@ -0,0 +1 @@
<svg height="540" width="810" xmlns="http://www.w3.org/2000/svg"><path d="m0 0h810v540h-810z" fill="#fcdd09"/><path d="m0 90h810m0 120h-810m0 120h810m0 120h-810" stroke="#da121a" stroke-width="60"/></svg>

After

Width:  |  Height:  |  Size: 204 B

View File

@ -0,0 +1 @@
<svg height="600" width="900" xmlns="http://www.w3.org/2000/svg"><path d="m0 0h900v600h-900z" fill="#d7141a"/><path d="m0 0h900v300h-900z" fill="#fff"/><path d="m450 300-450-300v600z" fill="#11457e"/></svg>

After

Width:  |  Height:  |  Size: 206 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -0,0 +1 @@
<svg height="560" width="740" xmlns="http://www.w3.org/2000/svg"><path d="m0 0h740v560h-740z" fill="#c60c30"/><g fill="#fff"><path d="m240 0h80v560h-80z"/><path d="m0 240h740v80h-740z"/></g></svg>

After

Width:  |  Height:  |  Size: 196 B

View File

@ -0,0 +1 @@
<svg height="300" width="450" xmlns="http://www.w3.org/2000/svg"><path d="m0 0h450v300h-450z" fill="#de1800"/><path d="m0 0h225v100h-225z"/><path d="m0 200h225v100h-225z" fill="#ffce00"/><path d="m225 100h225v100h-225z" fill="#fff"/><path d="m150 75h150v150h-150z" fill="#de1800"/><g fill="#fff"><path d="m210 100h30v100h-30z"/><path d="m175 135h100v30h-100z"/></g></svg>

After

Width:  |  Height:  |  Size: 371 B

View File

@ -0,0 +1 @@
<svg height="400" viewBox="0 0 27 18" width="600" xmlns="http://www.w3.org/2000/svg"><path d="m0 0h27v18h-27z" fill="#0d5eaf"/><path d="m5 0v11m-5-6h10m0-2h17m-17 4h17m-27 4h27m-27 4h27" fill="none" stroke="#fff" stroke-width="2"/></svg>

After

Width:  |  Height:  |  Size: 237 B

View File

@ -0,0 +1,10 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 60 30" width="1200" height="600">
<clipPath id="t">
<path d="M30,15 h30 v15 z v15 h-30 z h-30 v-15 z v-15 h30 z"/>
</clipPath>
<path d="M0,0 v30 h60 v-30 z" fill="#00247d"/>
<path d="M0,0 L60,30 M60,0 L0,30" stroke="#fff" stroke-width="6"/>
<path d="M0,0 L60,30 M60,0 L0,30" clip-path="url(#t)" stroke="#cf142b" stroke-width="4"/>
<path d="M30,0 v30 M0,15 h60" stroke="#fff" stroke-width="10"/>
<path d="M30,0 v30 M0,15 h60" stroke="#cf142b" stroke-width="6"/>
</svg>

After

Width:  |  Height:  |  Size: 522 B

View File

@ -0,0 +1 @@
<svg height="650" viewBox="0 0 7410 3900" width="1235" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="m0 0h7410v3900h-7410z" fill="#b22234"/><path d="m0 450h7410m0 600h-7410m0 600h7410m0 600h-7410m0 600h7410m0 600h-7410" stroke="#fff" stroke-width="300"/><path d="m0 0h2964v2100h-2964z" fill="#3c3b6e"/><g fill="#fff"><g id="a"><g id="b"><g id="c"><g id="d"><path id="e" d="m247 90 70.53423 217.082039-184.661012-134.164078h228.253564l-184.661012 134.164078z"/><use xlink:href="#e" y="420"/><use xlink:href="#e" y="840"/><use xlink:href="#e" y="1260"/></g><use xlink:href="#e" y="1680"/></g><use x="247" xlink:href="#d" y="210"/></g><use x="494" xlink:href="#b"/></g><use x="988" xlink:href="#a"/><use x="1976" xlink:href="#b"/><use x="2470" xlink:href="#c"/></g></svg>

After

Width:  |  Height:  |  Size: 809 B

View File

@ -0,0 +1 @@
<svg height="400" width="600" xmlns="http://www.w3.org/2000/svg"><path d="m0 0h202v202h-202" fill="#fff"/><path d="m0 200h200v-200h400v400h-600m58-243 41-126 41 126-107-78h133" fill="#090"/></svg>

After

Width:  |  Height:  |  Size: 196 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 50 KiB

View File

@ -0,0 +1 @@
<svg height="630" viewBox="0 0 33 21" width="990" xmlns="http://www.w3.org/2000/svg"><path d="m0 0h33v21h-33z" fill="#fff"/><path d="m0 0h33v14h-33z"/><path d="m0 0h33v7h-33z" fill="#0072ce"/></svg>

After

Width:  |  Height:  |  Size: 198 B

View File

@ -0,0 +1 @@
<svg height="560" viewBox="0 0 50 28" width="1000" xmlns="http://www.w3.org/2000/svg"><path d="m0 0v28h50v-28z" fill="#d52b1e"/><g stroke-width="4.3"><path d="m0 0 50 28m0-28-50 28" stroke="#009b48"/><path d="m25 0v28m-25-14h50" stroke="#fff"/></g></svg>

After

Width:  |  Height:  |  Size: 254 B

View File

@ -0,0 +1 @@
<svg height="360" width="630" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="m0 0h630v360h-630z" fill="#da0000"/><path d="m0 0h630v240h-630z" fill="#fff"/><path d="m0 0h630v120h-630z" fill="#239f40"/><g transform="translate(8.4 100.4)"><g id="a"><g id="b" fill="none" stroke="#fff" stroke-width="2"><path id="c" d="m0 1h26m-25 9v-5h8v4h8v-4h-5m-8 4h2m20 0h-5v-4h8m0-5v9h8v-9m-4 0v9" transform="scale(1.4)"/><path id="d" d="m0 7h9m1 0h9" transform="scale(2.8)"/><use xlink:href="#d" y="120"/><use xlink:href="#c" y="145.2"/></g><g id="e"><use x="56" xlink:href="#b"/><use x="112" xlink:href="#b"/><use x="168" xlink:href="#b"/></g></g><use x="168" xlink:href="#e"/><use x="392" xlink:href="#a"/></g><g fill="#da0000" transform="matrix(45 0 0 45 315 180)"><g id="f"><path d="m-.54815.83638a.912046.912046 0 0 0 .876694-1.558764 1 1 0 0 1 -.876694 1.558764"/><path d="m.618339.661409a.763932.763932 0 0 0 -.196695-1.402458 1 1 0 0 1 .196695 1.402458"/><path d="m0 1-.05-1 .05-.787278a.309995.309995 0 0 0 .118034.099087v.587785l-.040225.993311z"/><path d="m-.02-.85.02.018783a.14431.14431 0 0 0 .252075-.136491.136408.136408 0 0 1 -.252075.043074"/></g><use transform="scale(-1 1)" xlink:href="#f"/></g></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1 @@
<svg height="1100" width="1800" xmlns="http://www.w3.org/2000/svg"><path d="m0 0h1800v1100h-1800z" fill="#fff"/><g fill="#003580"><path d="m0 400h1800v300h-1800z"/><path d="m500 0h300v1100h-300z"/></g></svg>

After

Width:  |  Height:  |  Size: 207 B

View File

@ -0,0 +1 @@
<svg height="600" width="900" xmlns="http://www.w3.org/2000/svg"><path d="m0 0h900v600h-900z" fill="#ed2939"/><path d="m0 0h600v600h-600z" fill="#fff"/><path d="m0 0h300v600h-300z" fill="#002395"/></svg>

After

Width:  |  Height:  |  Size: 203 B

View File

@ -0,0 +1 @@
<svg height="600" width="1200" xmlns="http://www.w3.org/2000/svg"><path d="m0 0h1200v600h-1200z" fill="#169b62"/><path d="m400 0h800v600h-800z" fill="#fff"/><path d="m800 0h400v600h-400z" fill="#ff883e"/></svg>

After

Width:  |  Height:  |  Size: 210 B

View File

@ -0,0 +1 @@
<svg height="600" viewBox="0 0 5 3" width="1000" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><clipPath id="a"><path d="m0 0h5v3h-5z"/></clipPath><g clip-path="url(#a)"><path d="m0 0h50v30h-50z" fill="#0065bd"/><path d="m0 0 5 3m-5 0 5-3" fill="none" stroke="#fff" stroke-width=".6"/></g></svg>

After

Width:  |  Height:  |  Size: 327 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 52 KiB

View File

@ -0,0 +1 @@
<svg height="480" viewBox="0 0 220 160" width="660" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><path id="a" d="m0-29.14101615-25.23686028 43.71152423h50.47372056z" fill="none" stroke="#0038b8" stroke-width="5.5"/></defs><path d="m0 0h220v160h-220z" fill="#fff"/><path d="m0 15h220v25h-220z" fill="#0038b8"/><path d="m0 120h220v25h-220z" fill="#0038b8"/><use transform="translate(110 80)" xlink:href="#a"/><use transform="matrix(-1 0 0 -1 110 80)" xlink:href="#a"/></svg>

After

Width:  |  Height:  |  Size: 511 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 225 150" width="1350" height="900"><rect width="225" height="150" fill="#f93"/><rect width="225" height="50" y="50" fill="#fff"/><rect width="225" height="50" y="100" fill="#128807"/><g transform="translate(112.5,75)"><circle r="20" fill="#008"/><circle r="17.5" fill="#fff"/><circle r="3.5" fill="#008"/><g id="d"><g id="c"><g id="b"><g id="a"><circle r="0.875" fill="#008" transform="rotate(7.5) translate(17.5)"/><path fill="#008" d="M 0,17.5 0.6,7 C 0.6,7 0,2 0,2 0,2 -0.6,7 -0.6,7 L 0,17.5 z"/></g><use xlink:href="#a" transform="rotate(15)"/></g><use xlink:href="#b" transform="rotate(30)"/></g><use xlink:href="#c" transform="rotate(60)"/></g><use xlink:href="#d" transform="rotate(120)"/><use xlink:href="#d" transform="rotate(-120)"/></g></svg>

After

Width:  |  Height:  |  Size: 849 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 66 KiB

View File

@ -0,0 +1 @@
<svg height="600" viewBox="0 0 6 3" width="1200" xmlns="http://www.w3.org/2000/svg"><path d="m0 0h6v3h-6z" fill="#436f4d"/><path d="m0 0h6v2h-6z" fill="#fff"/><path d="m0 0h6v1h-6z" fill="#cd2a3e"/></svg>

After

Width:  |  Height:  |  Size: 204 B

View File

@ -0,0 +1 @@
<svg height="300" viewBox="0 0 3 2" width="450" xmlns="http://www.w3.org/2000/svg"><path d="m0 0h3v2h-3z" fill="#fff"/><path d="m0 0h3v1h-3z" fill="#f00"/></svg>

After

Width:  |  Height:  |  Size: 161 B

View File

@ -0,0 +1 @@
<svg height="576" width="800" xmlns="http://www.w3.org/2000/svg"><path d="m0 0h800v576h-800" fill="#02529c"/><path d="m224 0h128v576h-128m-224-352h800v128h-800" fill="#fff"/><path d="m256 0h64v576h-64m-256-320h800v64h-800" fill="#dc1e35"/></svg>

After

Width:  |  Height:  |  Size: 245 B

View File

@ -0,0 +1 @@
<svg height="1000" viewBox="0 0 3 2" width="1500" xmlns="http://www.w3.org/2000/svg"><path d="m0 0h3v2h-3z" fill="#009246"/><path d="m1 0h2v2h-2z" fill="#fff"/><path d="m2 0h1v2h-1z" fill="#ce2b37"/></svg>

After

Width:  |  Height:  |  Size: 205 B

View File

@ -0,0 +1 @@
<svg height="600" width="900" xmlns="http://www.w3.org/2000/svg"><path d="m0 0h900v600h-900z" fill="#fff"/><circle cx="450" cy="300" fill="#bc002d" r="180"/></svg>

After

Width:  |  Height:  |  Size: 163 B

View File

@ -0,0 +1 @@
<svg height="600" viewBox="0 0 300 200" width="900" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><g id="a"><path id="b" clip-path="url(#c)" d="m-55 74a55 55 0 0 1 110 0v-148a55 55 0 0 1 -110 0z"/><use transform="rotate(90)" xlink:href="#b"/></g><clipPath id="c"><path d="m-109 104a104 104 0 0 0 0-208h218a104 104 0 0 0 0 208z"/></clipPath></defs><path d="m0 0h300v200h-300z" fill="#fff"/><g fill="#f00"><path d="m130 0v80h-130v40h130v80h40v-80h130v-40h-130v-80z"/><use transform="translate(64.45 39.45)" xlink:href="#a"/><use transform="translate(235.55 160.55)" xlink:href="#a"/><use transform="translate(235.55 39.45)" xlink:href="#a"/><use transform="translate(64.45 160.55)" xlink:href="#a"/></g></svg>

After

Width:  |  Height:  |  Size: 745 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 9.7 KiB

View File

@ -0,0 +1 @@
<svg height="600" viewBox="-36 -24 72 48" width="900" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="m-36-24h72v48h-72z" fill="#fff"/><g transform="matrix(.5547002 -.83205029 .83205029 .5547002 0 0)"><g id="a"><path id="b" d="m-6-25h12m-12 3h12m-12 3h12" stroke="#000" stroke-width="2"/><use xlink:href="#b" y="44"/></g><path d="m0 17v10" stroke="#fff"/><circle fill="#cd2e3a" r="12"/><path d="m0-12a6 6 0 0 0 0 12 6 6 0 0 1 0 12 12 12 0 0 1 0-24z" fill="#0047a0"/></g><g transform="matrix(-.5547002 -.83205029 .83205029 -.5547002 0 0)"><use xlink:href="#a"/><path d="m0-23.5v3m0 37.5v3.5m0 3v3" stroke="#fff"/></g></svg>

After

Width:  |  Height:  |  Size: 661 B

View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="750" height="450" viewBox="0 0 250 150">
<clipPath id="c">
<circle r="25"/>
</clipPath>
<rect width="250" height="150" fill="#e8112d"/>
<g transform="translate(125,75)">
<g id="r20" transform="scale(0.25)">
<g id="r4">
<path id="r1" d="m-8.4,108c8.4,22 -9.6,56 8.4,72c-6,-24 14-50 8.4,-72s-25.2,-22 -16.8,0z" fill="#ffef00"/>
<use xlink:href="#r1" transform="rotate(90)"/>
<use xlink:href="#r1" transform="rotate(180)"/>
<use xlink:href="#r1" transform="rotate(270)"/>
</g>
<use xlink:href="#r4" transform="rotate(18)"/>
<use xlink:href="#r4" transform="rotate(36)"/>
<use xlink:href="#r4" transform="rotate(54)"/>
<use xlink:href="#r4" transform="rotate(72)"/>
</g>
<use xlink:href="#r20" transform="rotate(9)"/>
<circle r="27" fill="#e8112d"/>
<circle cy="-1.5" r="22.5" fill="#ffef00"/>
<g id="x" fill="#e8112d" clip-path="url(#c)">
<path d="M-23.055236,18a37.755236,37.755236 0 1,1 75.510472,0H52.760449a36.260449,36.260449 0 1,0 -72.520898,0z"/>
<path d="M-17.601203,18a35.301203,35.301203 0 1,1 70.602406,0H53.424578a33.924578,33.924578 0 1,0 -67.849156,0z"/>
<path d="M20.7,-15.052356a33.052356,33.052356 0 1,0 0,66.104712L22.5,49.819805a31.819805,31.819805 0 1,1 0,-63.63961z"/>
</g>
<use xlink:href="#x" transform="scale(-1,1)"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1 @@
<svg height="400" width="600" xmlns="http://www.w3.org/2000/svg"><path d="m0 0h600v400h-600z" fill="#ce1126"/><path d="m0 100h600v200h-600z" fill="#002868"/><circle cx="300" cy="200" fill="#fff" r="80"/></svg>

After

Width:  |  Height:  |  Size: 209 B

View File

@ -0,0 +1 @@
<svg height="300" viewBox="0 0 5 3" width="500" xmlns="http://www.w3.org/2000/svg"><path d="m0 0h5v3h-5z" fill="#c1272d"/><path d="m0 0h5v2h-5z" fill="#006a44"/><path d="m0 0h5v1h-5z" fill="#fdb913"/></svg>

After

Width:  |  Height:  |  Size: 206 B

View File

@ -0,0 +1 @@
<svg height="600" width="1200" xmlns="http://www.w3.org/2000/svg"><path d="m0 0h1200v600h-1200" fill="#9e3039"/><path d="m0 240h1200v120h-1200" fill="#fff"/></svg>

After

Width:  |  Height:  |  Size: 163 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 225 150" width="1350" height="900"><rect width="225" height="150" fill="#f93"/><rect width="225" height="50" y="50" fill="#fff"/><rect width="225" height="50" y="100" fill="#128807"/><g transform="translate(112.5,75)"><circle r="20" fill="#008"/><circle r="17.5" fill="#fff"/><circle r="3.5" fill="#008"/><g id="d"><g id="c"><g id="b"><g id="a"><circle r="0.875" fill="#008" transform="rotate(7.5) translate(17.5)"/><path fill="#008" d="M 0,17.5 0.6,7 C 0.6,7 0,2 0,2 0,2 -0.6,7 -0.6,7 L 0,17.5 z"/></g><use xlink:href="#a" transform="rotate(15)"/></g><use xlink:href="#b" transform="rotate(30)"/></g><use xlink:href="#c" transform="rotate(60)"/></g><use xlink:href="#d" transform="rotate(120)"/><use xlink:href="#d" transform="rotate(-120)"/></g></svg>

After

Width:  |  Height:  |  Size: 849 B

View File

@ -0,0 +1 @@
<svg height="2400" width="4800" xmlns="http://www.w3.org/2000/svg"><g fill="#f9cf02"><g transform="scale(5)"><path d="m0 0h960v480h-960z" fill="#c4272f"/><path d="m320 0h320v480h-320z" fill="#015197"/><circle cx="160" cy="164" r="44"/><circle cx="160" cy="144" fill="#c4272f" r="48"/><circle cx="160" cy="152" r="32"/><path d="m140 92a20 20 0 0 0 40 0c0-8-5-9-5-12s3-7-3-12c3 5-2 6-2 11s2 5 2 9a4 4 0 0 1 -8 0c0-4 4-8 4-14s-1-8-4-13-8-9-4-13c-6 2-3 10-3 15s-4 8-4 14 3 7 3 11a4 4 0 0 1 -8 0c0-4 2-4 2-9s-5-6-2-11c-6 5-3 9-3 12s-5 4-5 12z"/><path d="m72 216v192h40v-192zm136 0v192h40v-192zm-88 32v16h80v-16zm0 112v16h80v-16zm0-144h80l-40 24zm0 168h80l-40 24z"/></g><g stroke="#c4272f" stroke-width="24"><circle cx="800" cy="1560" r="212"/><path d="m800 1348a106 106 0 0 1 0 212 106 106 0 0 0 0 212" fill="none"/></g></g><g fill="#c4272f"><circle cx="800" cy="1454" r="40"/><circle cx="800" cy="1666" r="40"/></g></svg>

After

Width:  |  Height:  |  Size: 917 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 225 150" width="1350" height="900"><rect width="225" height="150" fill="#f93"/><rect width="225" height="50" y="50" fill="#fff"/><rect width="225" height="50" y="100" fill="#128807"/><g transform="translate(112.5,75)"><circle r="20" fill="#008"/><circle r="17.5" fill="#fff"/><circle r="3.5" fill="#008"/><g id="d"><g id="c"><g id="b"><g id="a"><circle r="0.875" fill="#008" transform="rotate(7.5) translate(17.5)"/><path fill="#008" d="M 0,17.5 0.6,7 C 0.6,7 0,2 0,2 0,2 -0.6,7 -0.6,7 L 0,17.5 z"/></g><use xlink:href="#a" transform="rotate(15)"/></g><use xlink:href="#b" transform="rotate(30)"/></g><use xlink:href="#c" transform="rotate(60)"/></g><use xlink:href="#d" transform="rotate(120)"/><use xlink:href="#d" transform="rotate(-120)"/></g></svg>

After

Width:  |  Height:  |  Size: 849 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -0,0 +1 @@
<svg height="800" width="1100" xmlns="http://www.w3.org/2000/svg"><path d="m0 0h1100v800h-1100z" fill="#ef2b2d"/><path d="m300 0h200v800h-200z" fill="#fff"/><path d="m0 300h1100v200h-1100z" fill="#fff"/><g fill="#002868"><path d="m350 0h100v800h-100z"/><path d="m0 350h1100v100h-1100z"/></g></svg>

After

Width:  |  Height:  |  Size: 297 B

View File

@ -0,0 +1 @@
<svg height="600" viewBox="0 0 9 6" width="900" xmlns="http://www.w3.org/2000/svg"><path d="m0 0h9v6h-9z" fill="#21468b"/><path d="m0 0h9v4h-9z" fill="#fff"/><path d="m0 0h9v2h-9z" fill="#ae1c28"/></svg>

After

Width:  |  Height:  |  Size: 203 B

View File

@ -0,0 +1 @@
<svg height="800" viewBox="0 0 16 10" width="1280" xmlns="http://www.w3.org/2000/svg"><path d="m0 0h16v10h-16z" fill="#fff"/><path d="m0 5h16v5h-16z" fill="#dc143c"/></svg>

After

Width:  |  Height:  |  Size: 172 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 12 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -0,0 +1 @@
<svg height="400" viewBox="0 0 3 2" width="600" xmlns="http://www.w3.org/2000/svg"><path d="m0 0h3v2h-3z" fill="#002b7f"/><path d="m1 0h2v2h-2z" fill="#fcd116"/><path d="m2 0h1v2h-1z" fill="#ce1126"/></svg>

After

Width:  |  Height:  |  Size: 206 B

View File

@ -0,0 +1 @@
<svg height="600" viewBox="0 0 9 6" width="900" xmlns="http://www.w3.org/2000/svg"><path d="m0 0h9v3h-9z" fill="#fff"/><path d="m0 3h9v3h-9z" fill="#d52b1e"/><path d="m0 2h9v2h-9z" fill="#0039a6"/></svg>

After

Width:  |  Height:  |  Size: 203 B

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 14 KiB

Some files were not shown because too many files have changed in this diff Show More