xyz 文件重新导入

pull/1/head
剑古敛锋 2024-07-02 16:45:31 +08:00
parent c589144530
commit 1ff83a6c9d
16 changed files with 4133 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,263 @@
//##########################################################################
//# #
//# CLOUDCOMPARE #
//# #
//# This program is free software; you can redistribute it and/or modify #
//# it under the terms of the GNU General Public License as published by #
//# the Free Software Foundation; version 2 or later of the License. #
//# #
//# This program is distributed in the hope that it will be useful, #
//# but WITHOUT ANY WARRANTY; without even the implied warranty of #
//# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
//# GNU General Public License for more details. #
//# #
//# COPYRIGHT: EDF R&D / TELECOM ParisTech (ENST-TSI) #
//# #
//##########################################################################
#ifndef CC_ASCII_OPEN_DIALOG_HEADER
#define CC_ASCII_OPEN_DIALOG_HEADER
#include "meshDataExchangePluginAPI.h"
#include "MainWindow/MainWindow.h"
//local
//#include "qCC_io.h"
//Qt
#include <QDialog>
#include <QString>
#include <QTextStream>
#include <QPushButton>
#include <QComboBox>
//system
#include <vector>
class QComboBox;
class QPushButton;
class QTextStream;
namespace Ui {
class AsciiOpenDialog;
}
namespace GUI{
class MainWindow;
}
namespace MeshData {
const unsigned ASCII_OPEN_DLG_TYPES_COUNT = 20;
const unsigned MAX_NUMBER_OF_POINTS_PER_CLOUD = 2000000000;
enum CC_ASCII_OPEN_DLG_TYPES {
ASCII_OPEN_DLG_None = 0,
ASCII_OPEN_DLG_X = 1,
ASCII_OPEN_DLG_Y = 2,
ASCII_OPEN_DLG_Z = 3,
ASCII_OPEN_DLG_R = 4,
ASCII_OPEN_DLG_G = 5,
ASCII_OPEN_DLG_B = 6,
ASCII_OPEN_DLG_A = 7,
ASCII_OPEN_DLG_Label = 8,
ASCII_OPEN_DLG_Scalar =
ASCII_OPEN_DLG_TYPES_COUNT
- 1, // should always be the last one! (see openAsciiFileDlg::CheckOpenSequence)
};
//! Default ASCII header columns
class AsciiHeaderColumns {
public:
static QString X()
{
return "X";
}
static QString Y()
{
return "Y";
}
static QString Z()
{
return "Z";
}
static QString R()
{
return "R";
}
static QString G()
{
return "G";
}
static QString B()
{
return "B";
}
static QString A()
{
return "A";
}
static QString Label()
{
return "Label";
}
};
const char ASCII_OPEN_DLG_TYPES_NAMES[ASCII_OPEN_DLG_TYPES_COUNT][20] = { "Ignore",
"coord. X",
"coord. Y",
"coord. Z",
"Red (0-255)",
"Green (0-255)",
"Blue (0-255)",
"Alpha (0-255)",
"Label",
"Scalar" };
//! Dialog for configuration of ASCII files opening sequence
class MESHDATAEXCHANGEPLUGINAPI openAsciiFileDlg : public QDialog {
Q_OBJECT
public:
//! Default constructor
/** \param parent parent widget
**/
explicit openAsciiFileDlg(QWidget* parent = nullptr);
//! Default destructor
~openAsciiFileDlg() override;
//! Sets the input filename or text stream
/** \param filename filename
\param stream text stream
**/
void setInput(const QString& filename, QTextStream* stream = nullptr);
//! Restores the previous context ('Apply all' button)
/** \return whether a context was saved or not
**/
bool restorePreviousContext();
//! ASCII open sequence item
struct SequenceItem {
CC_ASCII_OPEN_DLG_TYPES type;
QString header;
//! Default constructor
SequenceItem()
: type(ASCII_OPEN_DLG_None)
, header()
{
}
//! Constructor from parameters
SequenceItem(CC_ASCII_OPEN_DLG_TYPES _type, const QString& _header)
: type(_type)
, header(_header)
{
}
};
//! ASCII open sequence
using Sequence = std::vector<SequenceItem>;
//! Returns the whole "opening" sequence as set by the user
Sequence getOpenSequence() const;
//! Returns number of lines to skip
unsigned getSkippedLinesCount() const
{
return m_skippedLines;
}
//! Returns user selected separator
unsigned char getSeparator() const
{
return m_separator.cell();
}
//! Returns whether comma should be used as decimal point
bool useCommaAsDecimal() const;
//! Returns roughly estimated average line size (in bytes)
double getAverageLineSize() const
{
return m_averageLineSize;
}
//! Returns columns count per line
unsigned getColumnsCount() const
{
return m_columnsCount;
}
//! Returns the max number of points per cloud
unsigned getMaxCloudSize() const;
//! Whether labels should be visible in 2D
bool showLabelsIn2D() const;
//! Returns whether the current sequence is 'safe'
/** A safe sequence is safe if it matches the header (if any)
or if the file has less than 6 columns.
**/
bool safeSequence() const;
//! Checks the "opening" sequence as set by the user
/** \return validity (+ error message if not)
**/
static bool CheckOpenSequence(const Sequence& sequence, QString& errorMessage);
//! Resets the "apply all" flag (if set)
static void ResetApplyAll();
public slots:
//! Slot called when separator changes
void onSeparatorChange(const QString& separator);
//! Forces the table to update itself
void updateTable();
//! Sets the number of lines to skip
void setSkippedLines(int linesCount);
//! Slot called when the 'comma as decimal' checkbox is toggled
void commaDecimalCheckBoxToggled(bool);
protected slots:
bool apply();
void applyAll();
void columnsTypeHasChanged(int index);
void shortcutButtonPressed();
void checkSelectedColumnsValidity();
protected:
//! Tries to guess the best separator automagically
void autoFindBestSeparator();
//! Sets the current separator
void setSeparator(QChar);
// associated UI
Ui::AsciiOpenDialog* m_ui;
unsigned m_skippedLines;
QChar m_separator;
double m_averageLineSize;
QString m_filename;
QTextStream* m_stream;
QString m_headerLine;
enum ColumnType { TEXT = 0, UNKNOWN = 1, IGNORED = 2, VALID = 3 };
//! Identifies columns with numbers only [mandatory]
std::vector<ColumnType> m_columnType;
unsigned m_columnsCount;
};
bool loadXYZImportPCL(QString _filename,GUI::MainWindow* _mw);
}
#endif //CC_ASCII_OPEN_DIALOG_HEADER

View File

@ -0,0 +1,365 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AsciiOpenDialog</class>
<widget class="QDialog" name="AsciiOpenDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1008</width>
<height>657</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string>Open Ascii File</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Source</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEditFileName">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Choose an attribute for each column:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="headerLabel">
<property name="styleSheet">
<string notr="true">color: grey;</string>
</property>
<property name="text">
<string>Header:</string>
</property>
</widget>
</item>
<item>
<widget class="QScrollArea" name="scrollArea">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>990</width>
<height>486</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QTableWidget" name="tableWidget">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::NoSelection</enum>
</property>
<property name="cornerButtonEnabled">
<bool>false</bool>
</property>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Separator</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineEditSeparator">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>30</width>
<height>16777215</height>
</size>
</property>
<property name="maxLength">
<number>1</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="asciiCodeLabel">
<property name="text">
<string>(ASCII code:%i)</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout">
<item>
<widget class="QToolButton" name="toolButtonShortcutSpace">
<property name="toolTip">
<string>space</string>
</property>
<property name="text">
<string>whitespace </string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="toolButtonShortcutComma">
<property name="toolTip">
<string>comma</string>
</property>
<property name="text">
<string notr="true">,</string>
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="toolButtonShortcutSemicolon">
<property name="toolTip">
<string>semicolon</string>
</property>
<property name="text">
<string notr="true">;</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QCheckBox" name="commaDecimalCheckBox">
<property name="text">
<string>use comma as decimal character</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="show2DLabelsCheckBox">
<property name="toolTip">
<string>Show labels in 2D (not recommended over 50).
Otherwise labels are shown in 3D.</string>
</property>
<property name="text">
<string>Show labels in 2D</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>Skip lines</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="spinBoxSkipLines">
<property name="maximum">
<number>999</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="commentLinesSkippedLabel">
<property name="text">
<string>+ comment/header lines skipped: 0</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QCheckBox" name="extractSFNamesFrom1stLineCheckBox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>extract scalar field names from first line</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QWidget" name="buttonWidget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout_5">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="label_5">
<property name="text">
<string>Max number of points per cloud</string>
</property>
</widget>
</item>
<item>
<widget class="QDoubleSpinBox" name="maxCloudSizeDoubleSpinBox">
<property name="suffix">
<string> Million</string>
</property>
<property name="decimals">
<number>2</number>
</property>
<property name="minimum">
<double>0.010000000000000</double>
</property>
<property name="maximum">
<double>1000000.000000000000000</double>
</property>
<property name="value">
<double>128.000000000000000</double>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_5">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>157</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="applyButton">
<property name="text">
<string>Apply</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="applyAllButton">
<property name="text">
<string>Apply all</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="cancelButton">
<property name="text">
<string>Cancel</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

View File

@ -0,0 +1,115 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AutoImportSettings">
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="CMakePresetLoader"><![CDATA[{
"useNewFormat": true
}]]></component>
<component name="CMakeReloadState">
<option name="reloaded" value="true" />
</component>
<component name="CMakeSettings">
<configurations>
<configuration PROFILE_NAME="Debug" ENABLED="true" CONFIG_NAME="Debug" />
</configurations>
</component>
<component name="ChangeListManager">
<list default="true" id="607003e5-e4ae-4518-89ca-e748bf9213a7" name="更改" comment="">
<change beforePath="$PROJECT_DIR$/../../CMakeLists.txt" beforeDir="false" afterPath="$PROJECT_DIR$/../../CMakeLists.txt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../CMakeLists.txt" beforeDir="false" afterPath="$PROJECT_DIR$/../CMakeLists.txt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../GeometryWidgets/dialogCreateCone.ui" beforeDir="false" afterPath="$PROJECT_DIR$/../GeometryWidgets/dialogCreateCone.ui" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../MainWidgets/ControlPanel.cpp" beforeDir="false" afterPath="$PROJECT_DIR$/../MainWidgets/ControlPanel.cpp" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../MainWidgets/ControlPanel.h" beforeDir="false" afterPath="$PROJECT_DIR$/../MainWidgets/ControlPanel.h" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../MainWindow/MainWindow.cpp" beforeDir="false" afterPath="$PROJECT_DIR$/../MainWindow/MainWindow.cpp" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../MainWindow/MainWindow.h" beforeDir="false" afterPath="$PROJECT_DIR$/../MainWindow/MainWindow.h" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../MainWindow/MainWindow.ui" beforeDir="false" afterPath="$PROJECT_DIR$/../MainWindow/MainWindow.ui" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../MainWindow/SubWindowManager.h" beforeDir="false" afterPath="$PROJECT_DIR$/../MainWindow/SubWindowManager.h" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../ModuleBase/graph3DWindow.cpp" beforeDir="false" afterPath="$PROJECT_DIR$/../ModuleBase/graph3DWindow.cpp" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../PluginManager/PluginManageDialog.cpp" beforeDir="false" afterPath="$PROJECT_DIR$/../PluginManager/PluginManageDialog.cpp" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../PluginManager/PluginManager.cpp" beforeDir="false" afterPath="$PROJECT_DIR$/../PluginManager/PluginManager.cpp" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../PluginMeshDataExchange/VTKdataExchange.cpp" beforeDir="false" afterPath="$PROJECT_DIR$/../PluginMeshDataExchange/VTKdataExchange.cpp" afterDir="false" />
<change beforePath="$PROJECT_DIR$/CMakeLists.txt" beforeDir="false" afterPath="$PROJECT_DIR$/CMakeLists.txt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/QGISRasterManager.cpp" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/QGISRasterManager.h" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/RasterToolPlugin.cpp" beforeDir="false" afterPath="$PROJECT_DIR$/RasterToolPlugin.cpp" afterDir="false" />
<change beforePath="$PROJECT_DIR$/RasterToolPlugin.h" beforeDir="false" afterPath="$PROJECT_DIR$/RasterToolPlugin.h" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../PluginWBFZExchangePlugin/CMakeLists.txt" beforeDir="false" afterPath="$PROJECT_DIR$/../PluginWBFZExchangePlugin/CMakeLists.txt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../PluginWBFZExchangePlugin/DialogPCLGPMesh.cpp" beforeDir="false" afterPath="$PROJECT_DIR$/../PluginWBFZExchangePlugin/DialogPCLGPMesh.cpp" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../PluginWBFZExchangePlugin/ImageOperatorBase.cpp" beforeDir="false" afterPath="$PROJECT_DIR$/../PluginWBFZExchangePlugin/ImageOperatorBase.cpp" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../PluginWBFZExchangePlugin/SARBaseTool.cpp" beforeDir="false" afterPath="$PROJECT_DIR$/../PluginWBFZExchangePlugin/SARBaseTool.cpp" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../PluginWBFZExchangePlugin/SARCalibration.cpp" beforeDir="false" afterPath="$PROJECT_DIR$/../PluginWBFZExchangePlugin/SARCalibration.cpp" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../PluginWBFZExchangePlugin/WBFZExchangePlugin.cpp" beforeDir="false" afterPath="$PROJECT_DIR$/../PluginWBFZExchangePlugin/WBFZExchangePlugin.cpp" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../PluginWBFZExchangePlugin/WBFZExchangePlugin.h" beforeDir="false" afterPath="$PROJECT_DIR$/../PluginWBFZExchangePlugin/WBFZExchangePlugin.h" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../llqgisbaselib/CMakeLists.txt" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/../llqgisbaselib/ld_geometry.h" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/../llqgisbaselib/ld_symbol_property.h" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/../llqgisbaselib/ldcommon.h" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/../llqgisbaselib/ll_qgis_base_lib.cpp" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/../llqgisbaselib/ll_qgis_base_lib.h" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/../llqgisbaselib/ll_qgis_base_lib_global.h" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/../llqgisbaselib/ll_qgis_base_lib_layerhandling.cpp" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/../llqgisbaselib/ll_qgis_base_lib_layerhandling.h" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/../llqgisbaselib/ll_qgis_base_lib_layertreeview_menu.cpp" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/../llqgisbaselib/ll_qgis_base_lib_layertreeview_menu.h" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/../llqgisbaselib/ll_qgis_base_lib_singleton.h" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/../llqgisbaselib/llqgisbaselibAPI.h" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/../llqgisbaselib/qgsstatusbarcoordinateswidget.cpp" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/../llqgisbaselib/qgsstatusbarcoordinateswidget.h" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/../llqgisbaselib/qgsstatusbarscalewidget.cpp" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/../llqgisbaselib/qgsstatusbarscalewidget.h" beforeDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="ClangdSettings">
<option name="formatViaClangd" value="false" />
</component>
<component name="Git.Settings">
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$/../.." />
</component>
<component name="ProjectApplicationVersion">
<option name="ide" value="CLion" />
<option name="majorVersion" value="2024" />
<option name="minorVersion" value="1.3" />
<option name="productBranch" value="Classic" />
</component>
<component name="ProjectColorInfo"><![CDATA[{
"associatedIndex": 6
}]]></component>
<component name="ProjectId" id="2i5gnwJYXI7tcU7hbUz4EYTkZT6" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent"><![CDATA[{
"keyToString": {
"RunOnceActivity.ShowReadmeOnStart": "true",
"RunOnceActivity.cidr.known.project.marker": "true",
"RunOnceActivity.readMode.enableVisualFormatting": "true",
"cf.first.check.clang-format": "false",
"cidr.known.project.marker": "true",
"git-widget-placeholder": "LAMPCAE-dev",
"last_opened_file_path": "D:/WBFZCPP/source/LAMPCAE/src/PluginRasterTool",
"nodejs_package_manager_path": "npm",
"vue.rearranger.settings.migration": "true"
}
}]]></component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="应用程序级" UseSingleDictionary="true" transferred="true" />
<component name="TaskManager">
<task active="true" id="Default" summary="默认任务">
<changelist id="607003e5-e4ae-4518-89ca-e748bf9213a7" name="更改" comment="" />
<created>1718786023013</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1718786023013</updated>
<workItem from="1718786024775" duration="3000" />
</task>
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="3" />
</component>
</project>

View File

@ -0,0 +1,280 @@
/**
* @file DEM2PointCloud.cpp
* @brief None
* @author (3045316072@qq.com)
* @version 2.5.0
* @date 24-6-4
* @copyright Copyright (c) Since 2024 All rights reserved.
*/
// You may need to build the project (run Qt uic code generator) to get "ui_DEM2PointCloud.h"
// resolved
#include <QFileDialog>
#include "DEM2PointCloud.h"
#include "ui_DEM2PointCloud.h"
#include "Settings/BusAPI.h"
#include "PythonModule/PyAgent.h"
#include "Common/DebugLogger.h"
#include "ModuleBase/messageWindowBase.h"
#include "ModuleBase/ProcessWindowBase.h"
#include "ModuleBase/ThreadTask.h"
#include "MainWindow/MainWindow.h"
#include "ModuleBase/ThreadControl.h"
#include <QDebug>
#include <QMessageBox>
#include "RasterToolBase.h"
#include "RasterDataClass.h"
#include "DEM2PointCloudTemplateFun.h"
namespace LAMPToolBox {
DEM2PointCloud::DEM2PointCloud(GUI::MainWindow* parent)
: QDialog(parent)
,_mw(parent)
, ui(new Ui::DEM2PointCloud)
{
ui->setupUi(this);
connect(ui->pushButton_selectDEM,SIGNAL(clicked()),this,SLOT(on_push_selectDEM_clicked()));
connect(ui->pushButton_selectPointCloud,SIGNAL(clicked()),this,SLOT(on_push_selectPointCloud_clicked()));
}
DEM2PointCloud::~DEM2PointCloud()
{
delete ui;
}
void DEM2PointCloud::on_push_selectDEM_clicked() {
QString workDir = Setting::BusAPI::instance()->getWorkingDir();
QFileDialog dlg(this, tr("Select DEM TiFF"), workDir, "TIFF (*.tif *.tiff)");
dlg.setAcceptMode(QFileDialog::AcceptOpen);
if (dlg.exec() != QFileDialog::FileName)
return;
QString aSuffix = dlg.selectedNameFilter();
QString aFileName = dlg.selectedFiles().join(",");
if (!(aFileName.isEmpty())) {
this->ui->lineEdit_inDEM->setText(aFileName);
// 检查 坐标系统
if(RasterToolBase::GetEPSGFromRasterFile(aFileName)==-1){
QMessageBox::warning(nullptr, u8"warning", "the Coordination System do not match with EPSG");
this->ui->lineEdit_inDEM->clear();
}
} else {}
}
void DEM2PointCloud::on_push_selectPointCloud_clicked() {
QString workDir = Setting::BusAPI::instance()->getWorkingDir();
QFileDialog dlg(this, tr("save DEM polong cloud"), workDir, "polong cloud files (*.xyz)");
dlg.setAcceptMode(QFileDialog::AcceptSave);
if (dlg.exec() != QFileDialog::FileName)
return;
QString aSuffix = dlg.selectedNameFilter();
QString aFileName = dlg.selectedFiles().join(",");
if (!(aFileName.isEmpty())) {
this->ui->lineEdit_outPointCloud->setText(aFileName);
} else {}
}
void DEM2PointCloud::accept()
{
if(QFile(this->ui->lineEdit_inDEM->text()).exists()) {
_DEMPath=this->ui->lineEdit_inDEM->text();
_PclPath=this->ui->lineEdit_outPointCloud->text();
QFile outxyzfile(this->ui->lineEdit_outPointCloud->text());
if(outxyzfile.exists()){
outxyzfile.remove();
}
auto algthead = new DEM2PointCloudAlgThread(_DEMPath, _PclPath, _mw);
ModuleBase::ThreadControl* tc = new ModuleBase::ThreadControl(algthead);
emit tc->threadStart();
}else{
QMessageBox::warning(nullptr, u8"warning", "please set DEM ");
}
QDialog::accept();
}
DEM2PointCloudAlgThread::DEM2PointCloudAlgThread(const QString& inDEMPath, const QString& _outPlyPath, GUI::MainWindow* mw) :
ModuleBase::ThreadTask(mw)
,_inDEMPath(inDEMPath)
,_outPlyPath(_outPlyPath)
{
}
DEM2PointCloudAlgThread::~DEM2PointCloudAlgThread() {
}
void DEM2PointCloudAlgThread::run() {
ModuleBase::ThreadTask::run();
bool result = false;
result=DEM2PointCloudAlg();
setThreadRunState(result);
DebugInfo("run ok _success %d _threadRuning %d \n", _success, _threadRuning);
defaultMeshFinished();
}
void DEM2PointCloudAlgThread::defaultMeshFinished() {
ModuleBase::ThreadTask::threadTaskFinished();
Py::PythonAgent::getInstance()->unLock();
if (_threadRuning) {
QString information="DEM->PointCloud Sucessfully!!!";
ModuleBase::Message msg;
msg.type = Common::Message::Normal;
msg.message = information;
emit showInformation(information);
emit _mainwindow->printMessageToMessageWindow(msg);
}
qDebug()<<"PCLGPMesh::defaultMeshFinished ModuleBase::ThreadTask::threadTaskFinished";
}
void DEM2PointCloudAlgThread::setThreadRunState(bool flag) {
_success = flag;
}
bool DEM2PointCloudAlgThread::DEM2PointCloudAlg()
{
// DEM --> PointCloud
// 1. 判断坐标系类型
long EPSGCode=-1;
EPSGCode = RasterToolBase::GetEPSGFromRasterFile(_inDEMPath);
qDebug()<<QString("raster file path : %1, epsg : %2 ").arg(_inDEMPath).arg(EPSGCode);
if(EPSGCode == -1) {
emit _mainwindow->printMessage(Common::Message::Error,
QString("do not find coordinateSystem in EPSG !"));
return false;
} else {}
RasterToolBase::CoordinateSystemType coordinateSystemType=RasterToolBase::getCoordinateSystemTypeByEPSGCode(EPSGCode);
switch(coordinateSystemType) {
case(RasterToolBase::CoordinateSystemType::ProjectCoordinateSystem): { // 投影坐标系
return this->DEM2PointCloudAlg_Pro();
}
case(RasterToolBase::CoordinateSystemType::GeoCoordinateSystem): { // 地理坐标系
return this->DEM2PointCloudAlg_Geo();
}
default: { // 未能识别坐标系
emit _mainwindow->printMessage(Common::Message::Error,QString("do not find coordinateSystem in EPSG !"));
return false;
}
}
return false;
}
bool DEM2PointCloudAlgThread::DEM2PointCloudAlg_Geo()
{
qDebug()<<"bool DEM2PointCloudAlgThread::DEM2PointCloudAlg_Geo()";
// 直接根据坐标采样计算
RasterToolBase::RasterDataClass rasterdatades(_inDEMPath);
if(rasterdatades.isReadSuccessfully()){}else{return false;}
switch(rasterdatades.getDataType()) {
case(GDALDataType::GDT_Unknown):{
qDebug()<<"GDALDataType::GDT_Unknown";
return false;
}
case(GDALDataType::GDT_Byte):{
qDebug()<<"GDALDataType::GDT_Unknown";
return LAMPToolBox::DEM2PointCloud_Geo<bool>(rasterdatades,_outPlyPath);
}
case(GDALDataType::GDT_Int8):{
qDebug()<<"GDALDataType::GDT_Unknown";
return LAMPToolBox::DEM2PointCloud_Geo<unsigned char>(rasterdatades,_outPlyPath);
}
case(GDALDataType::GDT_UInt16):{
qDebug()<<"GDALDataType::GDT_UInt16";
return LAMPToolBox::DEM2PointCloud_Geo<unsigned short>(rasterdatades,_outPlyPath);
}
case(GDALDataType::GDT_Int16):{
qDebug()<<"GDALDataType::GDT_Int16";
return LAMPToolBox::DEM2PointCloud_Geo<short int>(rasterdatades,_outPlyPath);
}
case(GDALDataType::GDT_UInt32):{
qDebug()<<"GDALDataType::GDT_UInt32";
return LAMPToolBox::DEM2PointCloud_Geo<unsigned int>(rasterdatades,_outPlyPath);
}
case(GDALDataType::GDT_Int32):{
qDebug()<<"GDALDataType::GDT_Int32";
return LAMPToolBox::DEM2PointCloud_Geo<int>(rasterdatades,_outPlyPath);
}
case(GDALDataType::GDT_UInt64):{
qDebug()<<"GDALDataType::GDT_UInt64";
return LAMPToolBox::DEM2PointCloud_Geo<unsigned long>(rasterdatades,_outPlyPath);
}
case(GDALDataType::GDT_Int64):{
qDebug()<<"GDALDataType::GDT_Int64";
return LAMPToolBox::DEM2PointCloud_Geo<long>(rasterdatades,_outPlyPath);
}
case(GDALDataType::GDT_Float32):{
qDebug()<<"GDALDataType::GDT_Float32";
return LAMPToolBox::DEM2PointCloud_Geo<float>(rasterdatades,_outPlyPath);
}
case(GDALDataType::GDT_Float64):{
qDebug()<<"GDALDataType::GDT_Float64";
return LAMPToolBox::DEM2PointCloud_Geo<double>(rasterdatades,_outPlyPath);
}
default:{
qDebug()<<"GDALDataType::GDT_Unknown";
return false;
}
}
return false;
}
bool DEM2PointCloudAlgThread::DEM2PointCloudAlg_Pro()
{
qDebug()<<"bool DEM2PointCloudAlgThread::DEM2PointCloudAlg_Pro()";
// 直接根据坐标采样计算
RasterToolBase::RasterDataClass rasterdatades(_inDEMPath);
if(rasterdatades.isReadSuccessfully()){}else{return false;}
switch(rasterdatades.getDataType()) {
case(GDALDataType::GDT_Unknown):{
qDebug()<<"GDALDataType::GDT_Unknown";
return false;
}
case(GDALDataType::GDT_Byte):{
qDebug()<<"GDALDataType::GDT_Byte";
return LAMPToolBox::DEM2PointCloud_project<bool>(rasterdatades,_outPlyPath);
}
case(GDALDataType::GDT_Int8):{
qDebug()<<"GDALDataType::GDT_Int8";
return LAMPToolBox::DEM2PointCloud_project<unsigned char>(rasterdatades,_outPlyPath);
}
case(GDALDataType::GDT_UInt16):{
qDebug()<<"GDALDataType::GDT_UInt16";
return LAMPToolBox::DEM2PointCloud_project<unsigned short>(rasterdatades,_outPlyPath);
}
case(GDALDataType::GDT_Int16):{
qDebug()<<"GDALDataType::GDT_Int16";
return LAMPToolBox::DEM2PointCloud_project<short int>(rasterdatades,_outPlyPath);
}
case(GDALDataType::GDT_UInt32):{
qDebug()<<"GDALDataType::GDT_UInt32";
return LAMPToolBox::DEM2PointCloud_project<unsigned int>(rasterdatades,_outPlyPath);
}
case(GDALDataType::GDT_Int32):{
qDebug()<<"GDALDataType::GDT_Int32";
return LAMPToolBox::DEM2PointCloud_project<int>(rasterdatades,_outPlyPath);
}
case(GDALDataType::GDT_UInt64):{
qDebug()<<"GDALDataType::GDT_UInt64";
return LAMPToolBox::DEM2PointCloud_project<unsigned long>(rasterdatades,_outPlyPath);
}
case(GDALDataType::GDT_Int64):{
qDebug()<<"GDALDataType::GDT_Int64";
return LAMPToolBox::DEM2PointCloud_project<long>(rasterdatades,_outPlyPath);
}
case(GDALDataType::GDT_Float32):{
qDebug()<<"GDALDataType::GDT_Float32";
return LAMPToolBox::DEM2PointCloud_project<float>(rasterdatades,_outPlyPath);
}
case(GDALDataType::GDT_Float64):{
qDebug()<<"GDALDataType::GDT_Float64";
return LAMPToolBox::DEM2PointCloud_project<double>(rasterdatades,_outPlyPath);
}
default:{
qDebug()<<"GDALDataType::GDT_Unknown";
return false;
}
}
return false;
}
} // namespace LAMPToolBox

View File

@ -0,0 +1,71 @@
/**
* @file DEM2PointCloud.h
* @brief None
* @author (3045316072@qq.com)
* @version 2.5.0
* @date 24-6-4
* @copyright Copyright (c) Since 2024 All rights reserved.
*/
#ifndef LAMPCAE_DEM2POINTCLOUD_H
#define LAMPCAE_DEM2POINTCLOUD_H
#include "RasterToolPluginAPI.h"
#include "ModuleBase/ThreadTask.h"
#include <QDialog>
#include <QString>
#include "MainWindow/MainWindow.h"
#include "ModuleBase/ThreadTask.h"
#include "RasterDataClass.h"
namespace LAMPToolBox {
QT_BEGIN_NAMESPACE
namespace Ui {
class DEM2PointCloud;
}
QT_END_NAMESPACE
class DEM2PointCloudAlgThread : public ModuleBase::ThreadTask{
public:
DEM2PointCloudAlgThread(const QString &inDEMPath,const QString& _outPlyPath,GUI::MainWindow *mw );
~DEM2PointCloudAlgThread();
public:
virtual void run();
void defaultMeshFinished();
void setThreadRunState(bool);
public:
bool DEM2PointCloudAlg();
bool DEM2PointCloudAlg_Geo();
bool DEM2PointCloudAlg_Pro();
private:
bool _success{false};
QString _inDEMPath;
QString _outPlyPath;
};
class DEM2PointCloud : public QDialog {
Q_OBJECT
public:
explicit DEM2PointCloud(GUI::MainWindow* mw = nullptr);
~DEM2PointCloud() override;
public slots:
void on_push_selectDEM_clicked();
void on_push_selectPointCloud_clicked();
virtual void accept();
private:
Ui::DEM2PointCloud* ui;
GUI::MainWindow* _mw;
QString _DEMPath;
QString _PclPath;
};
} // namespace LAMPToolBox
#endif // LAMPCAE_DEM2POINTCLOUD_H

View File

@ -0,0 +1,179 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>LAMPToolBox::DEM2PointCloud</class>
<widget class="QDialog" name="LAMPToolBox::DEM2PointCloud">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>822</width>
<height>200</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>200</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>200</height>
</size>
</property>
<property name="windowTitle">
<string>DEM2PointCloud</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string/>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="minimumSize">
<size>
<width>0</width>
<height>40</height>
</size>
</property>
<property name="text">
<string>InputDEM</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="lineEdit_inDEM">
<property name="minimumSize">
<size>
<width>0</width>
<height>40</height>
</size>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QPushButton" name="pushButton_selectDEM">
<property name="minimumSize">
<size>
<width>0</width>
<height>40</height>
</size>
</property>
<property name="text">
<string>select</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="minimumSize">
<size>
<width>0</width>
<height>40</height>
</size>
</property>
<property name="text">
<string>outPointCloud</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="lineEdit_outPointCloud">
<property name="minimumSize">
<size>
<width>0</width>
<height>40</height>
</size>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="pushButton_selectPointCloud">
<property name="minimumSize">
<size>
<width>0</width>
<height>40</height>
</size>
</property>
<property name="text">
<string>select</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string/>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QDialogButtonBox" name="btBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>btBox</sender>
<signal>accepted()</signal>
<receiver>LAMPToolBox::DEM2PointCloud</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>410</x>
<y>162</y>
</hint>
<hint type="destinationlabel">
<x>410</x>
<y>99</y>
</hint>
</hints>
</connection>
<connection>
<sender>btBox</sender>
<signal>accepted()</signal>
<receiver>LAMPToolBox::DEM2PointCloud</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>410</x>
<y>162</y>
</hint>
<hint type="destinationlabel">
<x>410</x>
<y>99</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -0,0 +1,307 @@
/**
* @file DialogRasterProjectConvert.cpp
* @brief None
* @author (3045316072@qq.com)
* @version 2.5.0
* @date 24-6-5
* @copyright Copyright (c) Since 2024 All rights reserved.
*/
// You may need to build the project (run Qt uic code generator) to get
// "ui_DialogRasterProjectConvert.h" resolved
#include <QFileDialog>
#include <QWidget>
#include "DialogRasterProjectConvert.h"
#include "ui_DialogRasterProjectConvert.h"
#include "Settings/BusAPI.h"
#include "RasterToolBase.h"
#include "Common/Types.h"
#include "PythonModule/PyAgent.h"
#include "ModuleBase/messageWindowBase.h"
#include <QMessageBox>
#include <memory>
#include <QDebug>
#include <gdalwarper.h>
#include "MainWindow/MainWindow.h"
#include "Common/DebugLogger.h"
#include "ModuleBase/ThreadControl.h"
namespace RasterToolBase {
DialogRasterProjectConvert::DialogRasterProjectConvert(GUI::MainWindow* _mw)
: QDialog(_mw)
, _mw(_mw)
, ui(new Ui::DialogRasterProjectConvert)
{
ui->setupUi(this);
EPSGCode_to = -1;
EPSGCode_Source = -1;
connect(ui->pushButton_In, SIGNAL(clicked()), this, SLOT(on_push_selectIn_clicked()));
connect(ui->pushButton_Out, SIGNAL(clicked()), this, SLOT(on_push_selectOut_clicked()));
}
DialogRasterProjectConvert::~DialogRasterProjectConvert()
{
delete ui;
}
void DialogRasterProjectConvert::on_push_selectIn_clicked()
{
QString workDir = Setting::BusAPI::instance()->getWorkingDir();
QFileDialog dlg(this, tr("Select DEM TiFF"), workDir, "TIFF (*.tif *.tiff)");
dlg.setAcceptMode(QFileDialog::AcceptOpen);
if(dlg.exec() != QFileDialog::FileName)
return;
QString aSuffix = dlg.selectedNameFilter();
QString aFileName = dlg.selectedFiles().join(",");
if(!(aFileName.isEmpty())) {
qDebug() << aFileName;
this->ui->lineEdit_In->setText(aFileName);
} else {
}
CheckDEMSourceEPSG();
CheckDEMToEPSG();
}
void DialogRasterProjectConvert::on_push_selectOut_clicked()
{
QString workDir = Setting::BusAPI::instance()->getWorkingDir();
QFileDialog dlg(this, tr("out DEM TiFF"), workDir, "TIFF (*.tif *.tiff)");
dlg.setAcceptMode(QFileDialog::AcceptSave);
if(dlg.exec() != QFileDialog::FileName)
return;
QString aSuffix = dlg.selectedNameFilter();
QString aFileName = dlg.selectedFiles().join(",");
if(!(aFileName.isEmpty())) {
this->ui->lineEdit_Out->setText(aFileName);
} else {
}
}
void DialogRasterProjectConvert::accept()
{
QString in_tiff_path = this->ui->lineEdit_In->text();
QString out_tiff_path = this->ui->lineEdit_Out->text();
size_t in_epsgCode = this->EPSGCode_Source;
size_t out_epsgCode = this->EPSGCode_to;
// 启动线程
auto algthead = new RasterProjectConvertAlgThread(in_tiff_path, out_tiff_path, in_epsgCode,
out_epsgCode, _mw);
ModuleBase::ThreadControl* tc = new ModuleBase::ThreadControl(algthead);
emit tc->threadStart();
QDialog::accept();
}
void DialogRasterProjectConvert::CheckDEMSourceEPSG()
{
qDebug() << "DialogRasterProjectConvert::CheckDEMSourceEPSG";
size_t EPSGCode = RasterToolBase::GetEPSGFromRasterFile(this->ui->lineEdit_In->text());
if(EPSGCode <= 0) {
QMessageBox::warning(this, tr("Warning"), tr("No coordinate system detected !"));
return;
} else {
qDebug() << QString("EPSG Code %1").arg(EPSGCode);
QString corsystemStr = RasterToolBase::GetProjectionNameFromEPSG(EPSGCode);
qDebug() << corsystemStr;
ui->lineEdit_SourceEPSG->setText(corsystemStr);
}
EPSGCode_Source = EPSGCode;
}
void DialogRasterProjectConvert::CheckDEMToEPSG()
{
qDebug() << "DialogRasterProjectConvert::CheckDEMToEPSG";
if(EPSGCode_Source <= 0) {
return;
}
std::shared_ptr<RasterToolBase::PointRaster> centerPoint =
RasterToolBase::GetCenterPointInRaster(this->ui->lineEdit_In->text());
if(nullptr == centerPoint) {
return;
}
size_t EPSGCode =
RasterToolBase::getProjectEPSGCodeByLon_Lat_inStrip6(
centerPoint->x, centerPoint->y);
EPSGCode_to = EPSGCode;
if(EPSGCode_to <= 0) {
QMessageBox::warning(this, tr("Warning"), tr("No coordinate system do not match !"));
return;
} else {
QString CordSystemStr = RasterToolBase::GetProjectionNameFromEPSG(EPSGCode_to);
ui->lineEdit_TOEPSG->setText(CordSystemStr);
}
}
RasterProjectConvertAlgThread::RasterProjectConvertAlgThread(const QString& inTIFFPath,
const QString& outTIFFPath,
size_t in_epsgCode,
size_t out_epsgCode,
GUI::MainWindow* mw)
: ModuleBase::ThreadTask(mw)
, _inTIFFPath(inTIFFPath)
, _outTIFFPath(outTIFFPath)
, _in_epsgCode(in_epsgCode)
, _out_epsgCode(out_epsgCode)
{
}
RasterProjectConvertAlgThread::~RasterProjectConvertAlgThread() {}
void RasterProjectConvertAlgThread::run()
{
ModuleBase::ThreadTask::run();
bool result = false;
result = RasterProjectConvert();
setThreadRunState(result);
DebugInfo("run ok _success %d _threadRuning %d \n", _success, _threadRuning);
defaultMeshFinished();
}
void RasterProjectConvertAlgThread::defaultMeshFinished()
{
ModuleBase::ThreadTask::threadTaskFinished();
Py::PythonAgent::getInstance()->unLock();
if(_threadRuning) {
QString information = "Raster PointCloud Sucessfully!!!";
ModuleBase::Message msg;
msg.type = Common::Message::Normal;
msg.message = information;
emit showInformation(information);
emit _mainwindow->printMessageToMessageWindow(msg);
}
qDebug() << "RasterProjectConvertAlgThread::defaultMeshFinished ModuleBase::ThreadTask::threadTaskFinished";
}
void RasterProjectConvertAlgThread::setThreadRunState(bool flag)
{
_success = flag;
}
bool RasterProjectConvertAlgThread::RasterProjectConvert()
{
GDALAllRegister();
CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
GDALDriverH hDriver;
GDALDataType eDT;
GDALDatasetH hDstDS; // 输出图像
GDALDatasetH hSrcDS; // 源图像
// 1. 创建目标图像
{
// 打开源文件
hSrcDS = GDALOpen(_inTIFFPath.toUtf8().data(), GA_ReadOnly);
if(hSrcDS == NULL) {
emit _mainwindow->printMessage(Common::Message::Error,
"open file fail :\t " + _inTIFFPath);
qDebug() << "open file fail :\t " + _inTIFFPath;
return false;
} else {
}
// 创建输出图像的数据类型和输入图像第一个波段类型一致
eDT = GDALGetRasterDataType(GDALGetRasterBand(hSrcDS, 1));
hDriver = GDALGetDriverByName("GTiff"); // 获取输出图像的驱动GeoTIFF格式
CPLAssert(hDriver != NULL);
// 获取源图像的坐标系统
const char* pszSrcWKT = NULL;
pszSrcWKT = GDALGetProjectionRef(hSrcDS);
CPLAssert(pszSrcWKT != NULL && strlen(pszSrcWKT) > 0);
// 设置输出图像的坐标系统为UTM 11 WGS84
char* pszDstWKT = NULL;
OGRSpatialReference oSRS;
oSRS.SetUTM(11, TRUE);
oSRS.importFromEPSG(_out_epsgCode);
oSRS.exportToWkt(&pszDstWKT);
// 创建一个变换参数从源图像的行列号坐标到结果图像的地理坐标没有结果行列的句柄初始值设置为NULL。
void* hTransformArg;
hTransformArg =
GDALCreateGenImgProjTransformer(hSrcDS, pszSrcWKT, NULL, pszDstWKT, FALSE, 0, 1);
if(hTransformArg == NULL) {
emit _mainwindow->printMessage(Common::Message::Error,
"create hTransform fail \t ");
qDebug() << "create hTransform fail :\t " + _inTIFFPath;
GDALClose(hSrcDS);
return false;
} else {
}
// 获取输出文件的近似地理范围和分辨率
double adfDstGeoTransform[6];
int nPixels = 0, nLines = 0;
CPLErr eErr;
eErr = GDALSuggestedWarpOutput(hSrcDS, GDALGenImgProjTransform, hTransformArg,
adfDstGeoTransform, &nPixels, &nLines);
if(eErr != CE_None) {
emit _mainwindow->printMessage(Common::Message::Error,
"create geo Extend and Resolution fail \t ");
qDebug() << "create geo Extend and Resolution :\t " + _outTIFFPath;
return false;
}
GDALDestroyGenImgProjTransformer(hTransformArg);
// 创建输出文件
hDstDS = GDALCreate(hDriver, _outTIFFPath.toUtf8().data(), nPixels, nLines,
GDALGetRasterCount(hSrcDS), eDT, NULL);
if(hDstDS == NULL) {
emit _mainwindow->printMessage(Common::Message::Error,
"create out Raster fail \t ");
qDebug() << "create out Raster fail :\t " + _outTIFFPath;
return false;
}
// 写入投影
GDALSetProjection(hDstDS, pszDstWKT);
GDALSetGeoTransform(hDstDS, adfDstGeoTransform);
// 复制颜色表,如果有的话
GDALColorTableH hCT;
hCT = GDALGetRasterColorTable(GDALGetRasterBand(hSrcDS, 1));
if(hCT != NULL) {
GDALSetRasterColorTable(GDALGetRasterBand(hDstDS, 1), hCT);
}
}
emit _mainwindow->printMessage(Common::Message::Normal, "[1/2]create out Raster successfully \t ");
qDebug() << "[1/2]create out Raster successfully \t " ;
// 2. 执行变换
{
// Setup warp options.
GDALWarpOptions* psWarpOptions = GDALCreateWarpOptions();
psWarpOptions->hSrcDS = hSrcDS;
psWarpOptions->hDstDS = hDstDS;
psWarpOptions->nBandCount = 1;
psWarpOptions->panSrcBands = (int*)CPLMalloc(sizeof(int) * psWarpOptions->nBandCount);
psWarpOptions->panSrcBands[0] = 1;
psWarpOptions->panDstBands = (int*)CPLMalloc(sizeof(int) * psWarpOptions->nBandCount);
psWarpOptions->panDstBands[0] = 1;
psWarpOptions->pfnProgress = GDALTermProgress;
// Establish reprojection transformer.
psWarpOptions->pTransformerArg =
GDALCreateGenImgProjTransformer(hSrcDS, GDALGetProjectionRef(hSrcDS), hDstDS,
GDALGetProjectionRef(hDstDS), FALSE, 0.0, 1);
psWarpOptions->pfnTransformer = GDALGenImgProjTransform;
// Initialize and execute the warp operation.
GDALWarpOperation oOperation;
oOperation.Initialize(psWarpOptions);
oOperation.ChunkAndWarpImage(0, 0, GDALGetRasterXSize(hDstDS),
GDALGetRasterYSize(hDstDS));
GDALDestroyGenImgProjTransformer(psWarpOptions->pTransformerArg);
GDALDestroyWarpOptions(psWarpOptions);
}
emit _mainwindow->printMessage(Common::Message::Normal, "[2/2]ReProject successfully \t ");
qDebug() << "[2/2]ReProject successfully :\t " ;
if(hDstDS!=NULL){GDALClose(hDstDS);}
if(hSrcDS!=NULL){GDALClose(hSrcDS);}
return true;
}
} // namespace RasterProjectConvertor

View File

@ -0,0 +1,72 @@
/**
* @file DialogRasterProjectConvert.h
* @brief None
* @author (3045316072@qq.com)
* @version 2.5.0
* @date 24-6-5
* @copyright Copyright (c) Since 2024 All rights reserved.
*/
#ifndef LAMPCAE_DIALOGRASTERPROJECTCONVERT_H
#define LAMPCAE_DIALOGRASTERPROJECTCONVERT_H
#include <QDialog>
#include "ModuleBase/ThreadTask.h"
namespace RasterToolBase {
QT_BEGIN_NAMESPACE
namespace Ui {
class DialogRasterProjectConvert;
}
QT_END_NAMESPACE
// 处理线程
class RasterProjectConvertAlgThread : public ModuleBase::ThreadTask{
public:
RasterProjectConvertAlgThread(const QString &inTIFFPath ,const QString& outTIFFPath,size_t in_epsgCode,size_t out_epsgCode,GUI::MainWindow *mw );
~RasterProjectConvertAlgThread();
public:
virtual void run();
void defaultMeshFinished();
void setThreadRunState(bool);
public:
bool RasterProjectConvert();
private:
bool _success{false};
QString _inTIFFPath;
QString _outTIFFPath;
size_t _in_epsgCode; // 原始影像的 epsg 代码
size_t _out_epsgCode;// 目标影像的 epsg 代码
};
// 界面处理
class DialogRasterProjectConvert : public QDialog {
Q_OBJECT
public:
explicit DialogRasterProjectConvert(GUI::MainWindow* _mw);
~DialogRasterProjectConvert() override;
public slots:
void on_push_selectIn_clicked();
void on_push_selectOut_clicked();
virtual void accept();
public:
// 检查原始数据的坐标系
void CheckDEMSourceEPSG();
void CheckDEMToEPSG();
private:
Ui::DialogRasterProjectConvert* ui;
size_t EPSGCode_Source;
size_t EPSGCode_to;
GUI::MainWindow* _mw;
};
} // namespace RasterProjectConvertor
#endif // LAMPCAE_DIALOGRASTERPROJECTCONVERT_H

View File

@ -0,0 +1,240 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>RasterToolBase::DialogRasterProjectConvert</class>
<widget class="QDialog" name="RasterToolBase::DialogRasterProjectConvert">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1035</width>
<height>293</height>
</rect>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>293</height>
</size>
</property>
<property name="windowTitle">
<string>DialogRasterProjectConvert</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string/>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="2">
<widget class="QPushButton" name="pushButton_In">
<property name="minimumSize">
<size>
<width>0</width>
<height>40</height>
</size>
</property>
<property name="text">
<string>select</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="lineEdit_Out">
<property name="minimumSize">
<size>
<width>0</width>
<height>40</height>
</size>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="lineEdit_TOEPSG">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>40</height>
</size>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="minimumSize">
<size>
<width>0</width>
<height>40</height>
</size>
</property>
<property name="text">
<string>InRaster</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="minimumSize">
<size>
<width>0</width>
<height>40</height>
</size>
</property>
<property name="text">
<string>OutRaster</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="pushButton_Out">
<property name="minimumSize">
<size>
<width>0</width>
<height>40</height>
</size>
</property>
<property name="text">
<string>select</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="lineEdit_In">
<property name="minimumSize">
<size>
<width>0</width>
<height>40</height>
</size>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_3">
<property name="minimumSize">
<size>
<width>0</width>
<height>40</height>
</size>
</property>
<property name="text">
<string>Target Porject Coordinate system</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_4">
<property name="minimumSize">
<size>
<width>0</width>
<height>40</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>40</height>
</size>
</property>
<property name="text">
<string>Source Coordinate system</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLineEdit" name="lineEdit_SourceEPSG">
<property name="enabled">
<bool>false</bool>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>40</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>40</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string/>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>RasterToolBase::DialogRasterProjectConvert</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>381</x>
<y>208</y>
</hint>
<hint type="destinationlabel">
<x>381</x>
<y>122</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>RasterToolBase::DialogRasterProjectConvert</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>381</x>
<y>208</y>
</hint>
<hint type="destinationlabel">
<x>381</x>
<y>122</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -0,0 +1,240 @@
/**
* @file RasterDataClass.cpp
* @brief None
* @author (3045316072@qq.com)
* @version 2.5.0
* @date 24-6-7
* @copyright Copyright (c) Since 2024 All rights reserved.
*/
#include <QFile>
#include "RasterDataClass.h"
#include "gdal.h"
#include "gdal_priv.h"
#include <QDebug>
namespace RasterToolBase {
RasterDataClass::RasterDataClass(QObject* parent)
: QObject(parent)
{
}
RasterDataClass::~RasterDataClass() {
}
RasterDataClass::RasterDataClass(QString filePath, QObject* parent)
: QObject(parent)
{
this->setFilepath(filePath);
this->readFileAttribution();
}
long RasterDataClass::getHeight() const
{
return _height;
}
long RasterDataClass::getWidth() const
{
return _width;
}
long RasterDataClass::getBandnum() const
{
return _bandnum;
}
long RasterDataClass::getEpsgCode() const
{
return _epsgCode;
}
GDALDataType RasterDataClass::getDataType() const
{
return _dataType;
}
const QString& RasterDataClass::getFilepath() const
{
return _filepath;
}
void RasterDataClass::setFilepath(const QString& filepath)
{
_filepath = filepath;
}
void RasterDataClass::readFileAttribution() {
GDALAllRegister();
CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); // 注册GDAL驱动
GDALDataset *poDataset;
poDataset = (GDALDataset *)GDALOpen(_filepath.toUtf8().data(), GA_ReadOnly);
if (NULL==poDataset ) {
qDebug()<<QString("do not open file : %1").arg(_filepath);
_readSuccessfully=false;
return;
}
qDebug()<<u8"1. 读取宽、高、波段数";
{
this->_width = poDataset->GetRasterXSize(); // 图像宽度
this->_height = poDataset->GetRasterYSize(); // 图像高度
this->_bandnum = poDataset->GetRasterCount(); // 波段数量
qDebug()<<QString("h,w,b :%1 , %2 , %3 ").arg(this->_height ).arg(this->_width ).arg(this->_bandnum);
}
qDebug()<<u8"2. 读取数据类型";
{
GDALRasterBand* poBand= nullptr;
poBand = poDataset->GetRasterBand(1);
if(nullptr==poBand||NULL==poBand ) {
qDebug()<<"read raster band";
_readSuccessfully = false;
return;
}
this->_dataType = poBand->GetRasterDataType();
GDALClose(poBand); // 关闭波段
}
qDebug()<<u8"3. 读取坐标系";
{
OGRSpatialReference *poSRS = new OGRSpatialReference();
const char *pszWkt = poDataset->GetProjectionRef();
if (NULL!=pszWkt && poSRS->importFromWkt((char **)&pszWkt) == OGRERR_NONE) {
this->_epsgCode = atoi(poSRS->GetAuthorityCode(nullptr)); // 获取EPSG代码
} else {
this->_epsgCode=-1;
}
delete poSRS;
}
qDebug()<<u8"4. 获取仿射矩阵 与 逆矩阵";
{
double* adfGeoTransform=new double[6];
poDataset->GetGeoTransform(adfGeoTransform);
this->gt=Eigen::MatrixXd::Zero(2,3);
this->gt(0,0)=adfGeoTransform[0];// -> 左上角 x 坐标
this->gt(0,1)=adfGeoTransform[1];// -> 横向分辨率
this->gt(0,2)=adfGeoTransform[2];// -> 旋转参数通常为0
this->gt(1,0)=adfGeoTransform[3];// -> 左上角 y 坐标
this->gt(1,1)=adfGeoTransform[4];// -> 旋转参数通常为0
this->gt(1,2)=adfGeoTransform[5];// -> 纵向分辨率(通常为负数)
delete adfGeoTransform;
this->gt_enable=true;
double a = this->gt(0, 0);
double b = this->gt(0, 1);
double c = this->gt(0, 2);
double d = this->gt(1, 0);
double e = this->gt(1, 1);
double f = this->gt(1, 2);
double g = 1;
double det_gt = b * f - c * e;
if (det_gt == 0) {
this->inv_gt_enable=false;
}else {
this->inv_gt(0, 0) = (c * d - a * f) / det_gt; // 2
this->inv_gt(0, 1) = f / det_gt; // lon
this->inv_gt(0, 2) = -c / det_gt; // lat
this->inv_gt(1, 0) = (a * e - b * d) / det_gt; // 1
this->inv_gt(1, 1) = -e / det_gt; // lon
this->inv_gt(1, 2) = b / det_gt; // lat
this->inv_gt_enable= true;
}
}
GDALClose(poDataset); // 关闭波段
qDebug()<<"close file";
_readSuccessfully=true;
}
bool RasterDataClass::isReadSuccessfully() const
{
return _readSuccessfully;
}
bool RasterDataClass::Image2GeoPionts(double x_img, double y_img,double& x_geo,double& y_geo )
{
x_geo = this->gt(0,0) + this->gt(0,1) * x_img + this->gt(0,2) * y_img;
y_geo = this->gt(1,0) + this->gt(1,1) * x_img + this->gt(1,2) * y_img;
return true;
}
bool RasterDataClass::Geo2ImagePoints(double x_geo, double y_geo, double& x_img, double& y_img)
{
x_img = this->inv_gt(0, 0) + x_geo * this->inv_gt(0, 1) + y_geo * this->inv_gt(0, 2); //x
y_img = this->inv_gt(1, 0) + x_geo * this->inv_gt(1, 1) + y_geo * this->inv_gt(1, 2); //y
return true;
}
RasterDataClass::RasterDataClass(const RasterDataClass& obj) {
QString filePath=obj.getFilepath();
this->setFilepath(filePath);
this->readFileAttribution();
}
std::shared_ptr<RasterToolBase::RasterDataClass> RasterDataClassFactory::OpenRaster(QString filepath)
{
if(QFile(filepath).exists()){
std::shared_ptr<RasterToolBase::RasterDataClass> raster(new RasterToolBase::RasterDataClass(filepath));
if(raster->isReadSuccessfully()){
return raster;
}else{
return nullptr;
}
}else{
return nullptr;
}
}
std::shared_ptr<RasterToolBase::RasterDataClass>
RasterDataClassFactory::CreateRaster(QString filepath, long height, long width,
long bandnum, long epsgCode, GDALDataType dataType)
{
return RasterDataClassFactory::OpenRaster(filepath);
}
RasterDataSplitBlockParams::RasterDataSplitBlockParams(long rowCount, long colCount, long stepRowLen,
long stepColLen):
_rowCount(rowCount)
,_colCount(colCount)
,_stepRowLen(stepRowLen)
,_stepColLen(stepColLen)
{
// 计算分块
long block_row_count = floor(rowCount / stepRowLen);
if(block_row_count * stepRowLen < rowCount) {
block_row_count = block_row_count + 1;
} else {
}
long block_col_count = floor(colCount / stepColLen);
if(block_col_count * stepColLen < colCount) {
block_col_count = block_col_count + 1;
} else {
}
_rowStepCount=block_row_count;
_colStepCount=block_col_count;
_blockCount=block_row_count*block_col_count;
_current_idx=0;
}
RasterDataSplitBlockParams::~RasterDataSplitBlockParams() {}
bool RasterDataSplitBlockParams::getNextParams(long& start_row, long& start_col, long& RowLen,
long& ColLen, long& currentId)
{
currentId=_current_idx+1;
return this->getBlockParams(start_row,start_col,RowLen,ColLen,currentId);
}
bool RasterDataSplitBlockParams::getBlockParams(long& start_row, long& start_col, long& RowLen,
long& ColLen, long& searchId)
{
if(searchId<_blockCount){}else{return false;}
long rowid=floor(searchId/_rowStepCount); // 取整
long colid= searchId%_rowStepCount; // 取余
start_row=rowid*_stepRowLen;
start_col=colid*_stepColLen;
if(start_row+_stepRowLen<_rowCount){RowLen=_stepRowLen;}
else{RowLen=_rowCount-start_row;}
if(start_col+_colStepCount<_colCount){RowLen=_colStepCount;}
else{ColLen=_colCount-start_col;}
return true;
}
long RasterDataSplitBlockParams::getBlockCount()
{
return _blockCount;
}
} // namespace RasterToolBase

View File

@ -0,0 +1,99 @@
/**
* @file RasterDataClass.h
* @brief None
* @author (3045316072@qq.com)
* @version 2.5.0
* @date 24-6-7
* @copyright Copyright (c) Since 2024 All rights reserved.
*/
#ifndef LAMPCAE_RASTERDATACLASS_H
#define LAMPCAE_RASTERDATACLASS_H
#include "RasterToolBase.h"
#include <QString>
#include <QObject>
#include <memory>
#include <Eigen/Dense>
namespace RasterToolBase {
class RasterDataClass:public QObject {
Q_OBJECT
public: // 构造函数
RasterDataClass(const RasterToolBase::RasterDataClass & obj);
RasterDataClass(QObject* parent=nullptr);
RasterDataClass(QString filePath,QObject* parent=nullptr);
~RasterDataClass();
private:
void readFileAttribution();
public:
bool Image2GeoPionts(double x_img, double y_img,double& x_geo,double& y_geo );
bool Geo2ImagePoints(double x_geo, double y_geo,double& x_img,double& y_img );
std::shared_ptr<void> getDataBlock(long band_id,long start_rowm);
private:
bool _readSuccessfully;
QString _filepath;// 文件地址
long _height;
long _width;
long _bandnum;
long _epsgCode;
GDALDataType _dataType;
Eigen::MatrixXd gt;
Eigen::MatrixXd inv_gt;
bool gt_enable{false};
bool inv_gt_enable{false};
public: // 属性操作
bool isReadSuccessfully() const;
const QString& getFilepath() const;
void setFilepath(const QString& filepath);
long getHeight() const;
long getWidth() const;
long getBandnum() const;
long getEpsgCode() const;
GDALDataType getDataType() const;
};
class RasterDataClassFactory {
public:
static std::shared_ptr<RasterToolBase::RasterDataClass> OpenRaster(QString filepath);
static std::shared_ptr<RasterToolBase::RasterDataClass> CreateRaster(QString filepath, long height, long width,
long bandnum, long epsgCode,GDALDataType dataType=GDALDataType::GDT_Float32);
};
// 数据分块参数计算
class RasterDataSplitBlockParams{
public:
RasterDataSplitBlockParams(long rowCount,long colCount,long stepRowLen,long stepColLen);
~RasterDataSplitBlockParams();
bool getNextParams(long& start_row,long& start_col,long& RowLen,long& ColLen,long& currentId);
bool getBlockParams(long& start_row,long& start_col,long& RowLen,long& ColLen,long& searchId);
long getBlockCount();
private:
long _rowCount;
long _colCount;
long _stepRowLen;
long _stepColLen;
long _rowStepCount;
long _colStepCount;
long _current_idx;
long _blockCount;
};
} // namespace RasterToolBase
#endif // LAMPCAE_RASTERDATACLASS_H

View File

@ -0,0 +1,268 @@
/**
* @file RasterProjectBase.cpp
* @brief None
* @author (3045316072@qq.com)
* @version 2.5.0
* @date 24-6-4
* @copyright Copyright (c) Since 2024 All rights reserved.
*/
#include <QDebug>
#include "RasterToolBase.h"
#include "gdal_priv.h"
#include "ogr_spatialref.h"
#include "cpl_conv.h" // for CPLMalloc()
#include <QTextCodec>
#include <iostream>
#include <QFile>
namespace RasterToolBase {
long getProjectEPSGCodeByLon_Lat(double lon, double lat, ProjectStripDelta stripState)
{
long EPSGCode = 0;
switch(stripState) {
case ProjectStripDelta::Strip_3: {
break;
};
case ProjectStripDelta::Strip_6: {
break;
}
default: {
EPSGCode = -1;
break;
}
}
qDebug() << QString(" EPSG code : %1").arg(EPSGCode);
return EPSGCode;
}
long getProjectEPSGCodeByLon_Lat_inStrip3(double lon, double lat)
{
// EPSG 4534 ~ 4554 3 度带
// 首先判断是否是在 中国带宽范围
// 中心经度范围 75E ~ 135E 实际范围 73.5E ~ 136.5E,
// 纬度范围 3N ~ 54N放宽到 0N~ 60N
if(73.5 <= lon && lon <= 136.5 && 0 <= lat && lat <= 60) { // 中国境内
long code = trunc((lon - 73.5) / 3) + 4534;
return code;
} else { // 非中国境内 使用 高斯克吕格
bool isSouth = lat < 0; // 简单判断南北半球,这里仅为示例,实际应用可能需要更细致的逻辑
long prefix = isSouth ? 327000 : 326000;
// std::string prefix = isSouth ? "327" : "326";
lon = fmod(lon + 360.0, 360.0);
long zone = std::floor((lon + 180.0) / 3.0);
prefix = prefix + zone;
return prefix;
}
return 0;
}
long getProjectEPSGCodeByLon_Lat_inStrip6(double lon, double lat)
{
// EPSG 4502 ~ 4512 6度带
// 首先判断是否是在 中国带宽范围
// 中心经度范围 75E ~ 135E 实际范围 72.0E ~ 138E,
// 纬度范围 3N ~ 54N放宽到 0N~ 60N
if(73.5 <= lon && lon <= 136.5 && 0 <= lat && lat <= 60) { // 中国境内
long code = trunc((lon - 72.0) / 6) + 4502;
return code;
} else { // 非中国境内 使用 UTM// 确定带号6度带从1开始到60每6度一个带
int zone = static_cast<int>((lon + 180.0) / 6.0) + 1;
bool isSouth = lon < 0; // 判断是否在南半球
long epsgCodeBase = isSouth ? 32700 : 32600; // 计算EPSG代码
long prefix = static_cast<int>(epsgCodeBase + zone);
return prefix;
}
return 0;
}
QString GetProjectionNameFromEPSG(long epsgCode)
{
qDebug() << "============= GetProjectionNameFromEPSG ======================";
OGRSpatialReference oSRS;
// 设置EPSG代码
if(oSRS.importFromEPSG(epsgCode) != OGRERR_NONE) {
qDebug() << "epsgcode not recognition";
return "";
}
// 获取并输出坐标系的描述(名称)
const char* pszName = oSRS.GetAttrValue("GEOGCS");
if(pszName) {
qDebug() << "Coordinate system name for EPSG " + QString::number(epsgCode)
<< " is: " + QString::fromStdString(pszName);
return QString::fromStdString(pszName);
} else {
qDebug() << "Unable to retrieve the name for EPSG " + QString::number(epsgCode);
return "";
}
// char* wkt = NULL;
// // 转换为WKT格式
// oSRS.exportToWkt(&wkt);
//
// qDebug() << wkt;
//
// // 从WKT中解析投影名称这里简化处理实际可能需要更复杂的逻辑来准确提取名称
// std::string wktStr(wkt);
// long start = wktStr.find("PROJCS[\"") + 8; // 找到"PROJCS["后的第一个双引号位置
// // 从start位置开始找下一个双引号这之间的内容即为投影名称
// int end = wktStr.find('\"', start);
// QString projName = QString::fromStdString(wktStr.substr(start, end - start));
//
// // 释放WKT字符串内存
// CPLFree(wkt);
// return projName;
}
long GetEPSGFromRasterFile(QString filepath)
{
qDebug() << "============= GetEPSGFromRasterFile ======================";
// QTextCodec* codec = QTextCodec::codecForLocale(); // 获取系统默认编码的文本编解码器
// QByteArray byteArray = codec->fromUnicode(filepath); // 将QString转换为QByteArray
//,这个应该会自动释放 const char* charArray = byteArray.constData(); //
// 获取QByteArray的const char*指针
{
if(QFile(filepath).exists()){
qDebug() << "info: the image found.\n";
}else{
return -1;
}
GDALAllRegister();
CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); // 注册GDAL驱动
// std::cout<<filepath.toLocal8Bit().constData()<<std::endl;
// 打开影像文件
GDALDataset* poDataset;
poDataset = (GDALDataset*)GDALOpen(filepath.toUtf8().data(), GA_ReadOnly);
if(NULL==poDataset) {
qDebug() << "Error: Unable to open the image.\n";
return -1;
}
// 获取影像的投影信息
const char* pszProjection = poDataset->GetProjectionRef();
qDebug() << QString::fromUtf8(pszProjection);
// 创建SpatialReference对象
OGRSpatialReference oSRS;
if(oSRS.importFromWkt((char**)&pszProjection) != OGRERR_NONE) {
qDebug() << ("Error: Unable to import projection information.\n");
GDALClose(poDataset);
return -1;
}
long epsgCode = atoi(oSRS.GetAuthorityCode(nullptr)); // 获取EPSG代码
if(epsgCode != 0) {
GDALClose(poDataset);
qDebug() << QString("file %1 :epsg Code %2").arg(filepath).arg(epsgCode);
return epsgCode;
} else {
qDebug() << "EPSG code could not be determined from the spatial reference.";
GDALClose(poDataset);
return -1;
}
}
}
std::shared_ptr<PointRaster> GetCenterPointInRaster(QString filepath)
{
qDebug() << "============= GetCenterPointInRaster ======================";
// QTextCodec* codec = QTextCodec::codecForLocale(); // 获取系统默认编码的文本编解码器
// QByteArray byteArray = codec->fromUnicode(filepath); // 将QString转换为QByteArray
//,这个应该会自动释放 const char* charArray = byteArray.constData(); //
// 获取QByteArray的const char*指针
GDALAllRegister();
CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
// std::cout<<filepath.toLocal8Bit().constData()<<std::endl;
GDALDataset* poDataset = (GDALDataset*)GDALOpen(filepath.toUtf8().data(), GA_ReadOnly);
if(nullptr==poDataset||NULL==poDataset) {
qDebug() << "Could not open dataset";
return nullptr; // 表示读取失败
}
double x, y, z;
bool flag = false;
{
double adfGeoTransform[6];
if(poDataset->GetGeoTransform(adfGeoTransform) != CE_None) {
qDebug() << "Failed to get GeoTransform";
return nullptr;
}
double dfWidth = poDataset->GetRasterXSize();
double dfHeight = poDataset->GetRasterYSize();
// 计算中心点坐标(像素坐标)
double dfCenterX = adfGeoTransform[0] + dfWidth * adfGeoTransform[1] / 2.0
+ dfHeight * adfGeoTransform[2] / 2.0;
double dfCenterY = adfGeoTransform[3] + dfWidth * adfGeoTransform[4] / 2.0
+ dfHeight * adfGeoTransform[5] / 2.0;
OGRSpatialReference oSRS;
oSRS.importFromWkt(poDataset->GetProjectionRef());
if(oSRS.IsGeographic()) {
qDebug() << "Center coords (already in geographic): (" + QString::number(dfCenterX)
+ ", " + QString::number(dfCenterY) + ")";
flag = true;
x = dfCenterX;
y = dfCenterY;
} else {
// 如果不是地理坐标系转换到WGS84
OGRSpatialReference oSRS_WGS84;
oSRS_WGS84.SetWellKnownGeogCS("WGS84");
OGRCoordinateTransformation* poCT =
OGRCreateCoordinateTransformation(&oSRS, &oSRS_WGS84);
if(poCT == nullptr) {
qDebug() << "Failed to create coordinate transformation";
return nullptr;
}
// double dfLon, dfLat;
if(poCT->Transform(1, &dfCenterX, &dfCenterY)) {
qDebug() << "Center coords (transformed to WGS84): ("
+ QString::number(dfCenterX) + ", " + QString::number(dfCenterY)
<< ")";
flag = true;
x = dfCenterX;
y = dfCenterY;
} else {
qDebug() << "Transformation failed.";
}
OGRCoordinateTransformation::DestroyCT(poCT);
}
}
if(nullptr==poDataset||NULL==poDataset){}else{
GDALClose(poDataset);
}
if(flag) {
std::shared_ptr<PointRaster> RasterCenterPoint = std::make_shared<PointRaster>();
RasterCenterPoint->x = x;
RasterCenterPoint->y = y;
RasterCenterPoint->z = 0;
return RasterCenterPoint;
} else {
return nullptr;
}
}
CoordinateSystemType getCoordinateSystemTypeByEPSGCode(long epsg_code)
{
OGRSpatialReference oSRS;
if(oSRS.importFromEPSG(epsg_code) == OGRERR_NONE) {
if(oSRS.IsGeographic()) {
return CoordinateSystemType::GeoCoordinateSystem;
} else if(oSRS.IsProjected()) {
return CoordinateSystemType::ProjectCoordinateSystem;
}
} else {
return CoordinateSystemType::UNKNOW;
}
}
} // namespace RasterToolBase

View File

@ -0,0 +1,79 @@
/**
* @file RasterProjectBase.h
* @brief None
* @author (3045316072@qq.com)
* @version 2.5.0
* @date 24-6-4
* @copyright Copyright (c) Since 2024 All rights reserved.
*/
#ifndef LAMPCAE_RASTERTOOLBASE_H
#define LAMPCAE_RASTERTOOLBASE_H
#include "gdal_priv.h"
#include <memory>
namespace RasterToolBase {
static bool GDALAllRegisterEnable=false;
enum ProjectStripDelta{
Strip_6, // 6度带
Strip_3
};
enum CoordinateSystemType{ // 坐标系类型
GeoCoordinateSystem,
ProjectCoordinateSystem,
UNKNOW
};
struct PointRaster{ // 影像坐标点
double x;
double y;
double z;
};
struct PointXYZ{
double x,y,z;
};
struct PointGeo{
double lon,lat,ati;
};
struct PointImage{
double pixel_x,pixel_y;
};
/// 根据经纬度获取
/// EPSG代码根据经纬度返回对应投影坐标系统其中如果在中华人民共和国境内默认使用
/// CGCS2000坐标系统(EPSG 4502 ~ 4512 6度带,EPSG 4534 ~ 4554 3度带)其余地方使用WGS坐标系统
/// 投影方法 高斯克吕格(国内), 高斯克吕格
/// \param long 经度
/// \param lat 纬度
/// \return 对应投影坐标系统的 EPSG编码,-1 表示计算错误
long getProjectEPSGCodeByLon_Lat(double long, double lat,
ProjectStripDelta stripState = ProjectStripDelta::Strip_3);
long getProjectEPSGCodeByLon_Lat_inStrip3(double lon, double lat);
long getProjectEPSGCodeByLon_Lat_inStrip6(double lon, double lat);
QString GetProjectionNameFromEPSG(long epsgCode) ;
long GetEPSGFromRasterFile(QString filepath);
std::shared_ptr<PointRaster> GetCenterPointInRaster(QString filepath);
CoordinateSystemType getCoordinateSystemTypeByEPSGCode(long EPSGCODE);
} // namespace RasterProjectConvertor
#endif // LAMPCAE_RASTERTOOLBASE_H

View File

@ -0,0 +1,59 @@
/**
* @file ConvertDEMAndMesh.cpp
* @brief None
* @author (3045316072@qq.com)
* @version 2.5.0
* @date 24-6-4
* @copyright Copyright (c) Since 2024 All rights reserved.
*/
#include "RasterToolBoxActions.h"
#include "DialogRasterProjectConvert.h"
#include "DEM2PointCloud.h"
namespace LAMPToolBox {
bool RasterToolBox::initMainWindows(GUI::MainWindow* _mainwindows) {
if(nullptr==_mainwindows||nullptr==_mainwindows->menuBar()){
return false;
}else {
this->_mainwindows = _mainwindows;
this->menuBar = _mainwindows->menuBar();
}
// 添加 命令
_toolboxMenu=new QMenu("RasterToolBox");
// 增加菜单
QAction* action_RasterProjectMenu=_toolboxMenu->addAction("Raster_ProjectSystem");
QAction* action_DEM2PointCloud=_toolboxMenu->addAction("DEM->PointCloud");
QAction* action_DEM2Mesh=_toolboxMenu->addAction("DEM->Mesh");
// 事件绑定
connect(action_RasterProjectMenu, SIGNAL(triggered()),this, SLOT(on_RasterProject_trigged()));
connect(action_DEM2PointCloud, SIGNAL(triggered()),this, SLOT(on_DEM2PointCloud_trigged()));
connect(action_DEM2Mesh, SIGNAL(triggered()),this, SLOT(on_DEM2Mesh_trigged()));
// 添加菜单
this->menuBar->addMenu(_toolboxMenu);
return true;
}
RasterToolBox::~RasterToolBox() {}
RasterToolBox::RasterToolBox(QObject* parent)
: QObject(parent)
{
}
void RasterToolBox::on_DEM2PointCloud_trigged() {
emit _mainwindows->printMessageToMessageWindow("DEM->PointCloud");
LAMPToolBox::DEM2PointCloud* dlg=new LAMPToolBox::DEM2PointCloud(_mainwindows);
dlg->show();
}
void RasterToolBox::on_DEM2Mesh_trigged() {
emit _mainwindows->printMessageToMessageWindow("DEM->mesh");
}
void RasterToolBox::on_RasterProject_trigged() {
emit _mainwindows->printMessageToMessageWindow("Raster Projector");
RasterToolBase::DialogRasterProjectConvert* dlg=new RasterToolBase::DialogRasterProjectConvert(_mainwindows);
dlg->show();
}
} // namespace LAMPToolBox

View File

@ -0,0 +1,41 @@
/**
* @file ConvertDEMAndMesh.h
* @brief None
* @author (3045316072@qq.com)
* @version 2.5.0
* @date 24-6-4
* @copyright Copyright (c) Since 2024 All rights reserved.
*/
#ifndef LAMPCAE_RASTERTOOLBOXACTIONS_H
#define LAMPCAE_RASTERTOOLBOXACTIONS_H
#include "RasterToolPluginAPI.h"
#include <QObject>
#include "MainWindow/MainWindow.h"
#include <QMenu>
#include <QMenuBar>
namespace LAMPToolBox {
class RASTERTOOLPLUGINAPI RasterToolBox:public QObject {
Q_OBJECT
public:
RasterToolBox(QObject* parent= nullptr);
~RasterToolBox();
signals:
public slots:
void on_DEM2PointCloud_trigged();
void on_DEM2Mesh_trigged();
void on_RasterProject_trigged();
public:
bool initMainWindows(GUI::MainWindow* _mainwindows);
private:
GUI::MainWindow* _mainwindows= nullptr;
QMenuBar* menuBar= nullptr;
QMenu* _toolboxMenu=nullptr;
};
} // namespace LAMPToolBox
#endif // LAMPCAE_RASTERTOOLBOXACTIONS_H