You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kev/Drawer/GVision/SurfaceGrid/lib/SurfaceGridWrapper.cpp

889 lines
22 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <stdexcept>
#include <thread>
#include "utils/pystring.h"
#include "SurfaceGridWrapper.h"
#include <afxext.h>
#include <sstream>
#include "DrawModel\\BaseLib.h"
#include "DrawOperator\\DrawLib.h"
#include "utils/pystring.h"
#include "GridSmooth.h"
std::wstring StringToWstring(const std::string& wstr)
{
std::wstring res;
int len = MultiByteToWideChar(CP_ACP, 0, wstr.c_str(), static_cast<int>(wstr.size()), nullptr, 0);
if (len == 0)
{
return L"";
}
std::vector<wchar_t> buffer(len + 1);
if (MultiByteToWideChar(CP_ACP, 0, wstr.c_str(), static_cast<int>(wstr.size()), buffer.data(), len) == 0)
{
throw std::runtime_error("Failed to convert string to wstring.");
}
res.assign(buffer.begin(), buffer.end());
return res;
}
std::string WstringToString(std::wstring wstr)
{
std::string res;
int len = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), static_cast<int>(wstr.size()), nullptr, 0, nullptr, nullptr);
if (len <= 0)
{
return "";
}
res.resize(len);
WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), static_cast<int>(wstr.size()), &res[0], len, nullptr, nullptr);
return res;
}
template <typename T>
void qDeleteAll(std::vector<T *> &vec)
{
for (auto* p : vec) {
delete p;
}
vec.clear();
}
// Target area
static std::vector<ais::Point> build_area_by_concerns_points(double xMin, double yMin, double xMax, double yMax)
{
std::vector<ais::Point> points;
points.push_back(ais::Point(xMin, yMin));
points.push_back(ais::Point(xMin, yMax));
points.push_back(ais::Point(xMax, yMin));
points.push_back(ais::Point(xMax, yMax));
points.push_back(ais::Point(xMin, yMin));
return points;
}
std::vector<ais::Point> load_area_concerns(const char *filename)
{
std::vector<ais::Point> points;
std::ifstream ifs(filename);
if (!ifs)
{
std::cout << "Failed to opening file " << filename << std::endl;
std::cout << "Use sample points' coordinates value to established target area." << std::endl;
return points;
}
std::string line;
while (std::getline(ifs, line))
{
// skip version number and object name
if (line == "Version 2030" || line.find("Pline") != std::string::npos)
continue;
std::istringstream iss(line);
std::vector<std::string> tokens;
std::string token;
while (std::getline(iss, token, ','))
{
tokens.push_back(token);
}
if (!tokens.empty())
points.push_back(ais::Point(std::stod(tokens[0]), std::stod(tokens[1])));
}
return points;
}
using axisRange = std::pair<double, double>;
/**
*
* \\param points
* \\return x <20><><EFBFBD>ͷ<EFBFBD>Χ <20><> y <20><><EFBFBD>ķ<EFBFBD>Χ
*/
static std::pair<axisRange, axisRange> get_actually_area_concerns(const std::vector<ais::PointXYZ> &points)
{
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD> x <20><>
auto x = ais::getAxisValues(points, ais::Axis3DType::X);
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD> y <20><>
auto y = ais::getAxisValues(points, ais::Axis3DType::Y);
// <20><>ȡ x <20>ķ<EFBFBD>Χ
auto xMinMax = ais::getMinMax(x);
// <20><>ȡ y <20>ķ<EFBFBD>Χ
auto yMinMax = ais::getMinMax(y);
return { xMinMax, yMinMax };
}
/**
* <20>Ƴ<EFBFBD><C6B3>ظ<EFBFBD><D8B8>ĵ<EFBFBD>
* \\param points
* \\return
*/
static std::vector<ais::PointXYZ> drop_duplicated_points(std::vector<ais::PointXYZ> &points)
{
std::vector<ais::PointXYZ> result;
std::sort(points.begin(), points.end());
result.reserve(points.size());
for (auto &p : points)
{
if (std::find(std::execution::par, result.begin(), result.end(), p) == result.end())
result.push_back(p);
}
return result;
}
/**
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>
* \\param gi
* \\param filename Ŀ<><C4BF><EFBFBD>ļ<EFBFBD>
*/
static void dump_to_grd(ais::GridInterpolator &gi, const std::string &filename)
{
std::ofstream outfile;
outfile.open(filename, std::ios::out);
if (!outfile.is_open())
{
std::string errMsg = "Failed to open grd file: " + filename;
throw std::runtime_error(errMsg);
}
// header
outfile << "DSAA" << std::endl;
outfile << gi.header_info().c_str();
// data
outfile << gi.data_info().c_str();
outfile.close();
}
/**
* <20><><EFBFBD>ز<EFBFBD><D8B2><EFBFBD><EFBFBD>ļ<EFBFBD>
* \\param filename
* \\return
*/
static std::vector<ais::PointXYZ> load_sample_points(const std::string &filename)
{
std::vector<ais::PointXYZ> points;
std::ifstream infile;
infile.open(filename, std::ios::in);
if (!infile.is_open())
{
std::string errMsg = "Failed to open sample points file: " + filename;
throw std::runtime_error(errMsg);
}
std::string line;
while (std::getline(infile, line))
{
line = pystring::strip(line);
if (line.empty() || line[0] == '#')
continue;
ais::PointXYZ p(line.c_str());
if (!p.isNan())
points.push_back(p);
}
return points;
}
static void AddContourCurve(CXy* pXy, vector<CCurve*>* curves, vector<CString*>* layer)
{
for (size_t i = 0; i < curves->size(); i++)
{
CCurve* pCurve = curves->at(i);
if (pCurve == NULL) continue;
CString* pName = layer->at(i);
CCurveEx *ce = new CCurveEx(pCurve->num);
for (int i = 0; i < ce->num; i++)
{
ce->x[i] = pCurve->x[i];
ce->y[i] = pCurve->y[i];
ce->z[i] = pCurve->z[i];
}
ce->nPoint = pCurve->nPoint;
ce->GetLocation();
POSITION pos = NULL;
if (pCurve->name)
ce->SetName(pCurve->name);
pos = pXy->AddElement(ce, DOUBLEFOX_CURVE);
pXy->SetElementLayer(pos, *pName);
}
}
/**
* <20>ж<EFBFBD> dx dY <20><><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*
* \\param vec <20><><EFBFBD>򼯺ϣ<F2BCAFBA><CFA3><EFBFBD>Ȼ<EFBFBD><C8BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E0A3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>պϵ<D5BA><CFB5><EFBFBD><EFBFBD><EFBFBD>
* \\param dX
* \\param dY
* \\return
*/
static bool any_contains(std::vector<CCurveEx*> &vec, double dX, double dY)
{
return std::any_of(vec.begin(), vec.end(), [dX, dY](CCurveEx *pBorder) {
return (pBorder->IsInside(dX, dY));
});
}
/**
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> CDimension2D <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>б߿<D0B1><DFBF><EFBFBD><EFBFBD>򽫱߿<F2BDABB1><DFBF><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD>Ϊ<EFBFBD>Ƿ<EFBFBD>ֵ
*
* \\param xMin
* \\param yMin
* \\param matrix
* \\param nCols
* \\param nRows
* \\param dx
* \\param dy
* \\param zMin
* \\param zMax
* \\param insertTimes
* \\param borders <20>߿򼯺ϣ<F2BCAFBA><CFA3>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD>ѡ<EFBFBD>ж<EFBFBD><D0B6><EFBFBD><EFBFBD>߿<EFBFBD>
* \\return
*/
static CDimension2D *CreateGridData(double xMin, double yMin, std::shared_ptr<ais::FMatrix> matrix,
int nCols, int nRows, double dx, double dy,
double zMin, double zMax, int insertTimes,
std::vector<CCurveEx*> &borders,
double fillValue)
{
static const double valueNull = -1E301;
//int nCount = nCols * nRows;
auto *pDfg = new CDimension2D();
pDfg->Create(nCols, nRows, xMin, yMin, dx, dy);
// any_contains <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> CCurveEx::IsInSide<64><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̰߳<DFB3>ȫ<EFBFBD><C8AB>
// <20><>Ҫ<EFBFBD><D2AA><EFBFBD>׶<EFBFBD><D7B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><D1AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̻߳<DFB3> openmp <20><><EFBFBD><EFBFBD>
for (int i = 0; i < nCols; i++)
{
for (int j = 0; j < nRows; j++)
{
double dX = pDfg->x(i);
double dY = pDfg->y(j);
double value = matrix->at(j, i);
if (std::isinf(value) || std::isnan(value)) {
value = valueNull;
}
// <20><><EFBFBD><EFBFBD>value<75>Ƿ<EFBFBD><C7B7><EFBFBD>[zMin, zMax]<5D><>Χ<EFBFBD><CEA7>
if (value < zMin || value > zMax) {
value = valueNull;
}
if (borders.empty()) {
pDfg->SetValue(i, j, value);
continue;
}
if (any_contains(borders, dX, dY)) {
pDfg->SetValue(i, j, value);
}
else {
pDfg->SetValue(i, j, valueNull);
}
}
}
pDfg->range[0] = zMin;
pDfg->range[1] = zMax;
return pDfg;
}
static void CreateBorder(std::shared_ptr<CXy> pXy, std::vector<CCurveEx*> &ccurves)
{
CLayer* pLayerBorder = pXy->FindAddLayer("<EFBFBD>߽<EFBFBD>11");
for (auto *pCurve : ccurves) {
POSITION posNew = pXy->AddElement(pCurve, DOUBLEFOX_CURVE);
pXy->SetElementLayer(posNew, pLayerBorder);
}
}
/**
* <20><><EFBFBD>ɶϲ<C9B6>
*
* \\param faultFile
* \\param pXy
* \\param pDfg
* \\return
*/
static bool CreateFaults(CString faultFile, std::shared_ptr<CXy> pXy, CDimension2D *pDfg)
{
// <20><><EFBFBD>ɶϲ<C9B6>
std::unique_ptr<CXy> pXyFaults = std::make_unique<CXy>();
if (!pXyFaults->ReadWithExtension(faultFile)) {
return false;
}
CLayer* pLayerFault = pXy->FindAddLayer("<EFBFBD>ϲ<EFBFBD>");
CPtrList *pl = pXyFaults->GetValueList();
for (POSITION pos = pl->GetHeadPosition(); pos != nullptr; pl->GetNext(pos)) {
COne *pOne = pXyFaults->GetAt(pos);
if (pOne->GetType() == DOUBLEFOX_CURVE) {
CCurveEx* pCurveFault = (CCurveEx*)(pOne->GetValue());
CCurveEx* pCurveNew = new CCurveEx;
(*pCurveNew) = (*pCurveFault);
POSITION posNew = pXy->AddElement(pCurveNew, DOUBLEFOX_CURVE);
pXy->SetElementLayer(posNew, pLayerFault);
pDfg->Faultage(*(CCurve*)pCurveNew);
}
}
return true;
}
/**
* <20><><EFBFBD>ɵ<EFBFBD>ֵ<EFBFBD><D6B5>
*
* \\param pXy
* \\param pMeshNew
* \\param pDfg
* \\param contourStep
* \\param contourMarkStep
* \\return
*/
static void CreateContourLines(std::shared_ptr<CXy> pXy, CMesh *pMeshNew, CDimension2D *pDfg, double contourStep, int contourMarkStep)
{
if (abs(contourStep) < 1E-5) {
return;
}
CString strLayerMark = _T("Layer:\\<EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD>\\<EFBFBD><EFBFBD>ע");
CString strLayerOther = _T("Layer:\\<EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD>\\<EFBFBD>ޱ<EFBFBD>ע");
CString curLayerName = pXy->GetCurrentLayer()->GetPathName();
CLayer* pMarkLayer = pXy->FindLayer(strLayerMark);
CLayer* pOtherLayer = pXy->FindLayer(strLayerOther);
if (pMarkLayer == nullptr)
{
pMarkLayer = pXy->FindAddLayer(strLayerMark);
pMarkLayer->HowToViewCurve = new CHowToViewCurve();
pMarkLayer->HowToViewCurve->EnableDrawSourceCurve(FALSE);
CCurveInName* pInName = new CCurveInName();
CRect8 rect = pMeshNew->GetRect();
pInName->text_h = rect.Width() / 300;
pInName->m_size.cx = pInName->text_h*0.06;
pInName->color = RGB(0, 0, 0);
pMarkLayer->HowToViewCurve->Add(pInName);
}
if (pOtherLayer == nullptr)
{
pOtherLayer = pXy->FindAddLayer(strLayerOther);
pOtherLayer->HowToViewCurve = new CHowToViewCurve();
pOtherLayer->HowToViewCurve->EnableDrawSourceCurve(FALSE);
CCurveProperties* pview = new CCurveProperties();
pview->color = RGB(0, 0, 0);
pOtherLayer->HowToViewCurve->Add(pview);
}
std::vector<CCurve*> pCurves;
std::vector<CString*> pLayers;
pMeshNew->ContourCreate(&pCurves, &pLayers, contourStep, contourMarkStep,
strLayerMark, strLayerOther, pDfg->range[0], pDfg->range[1]);
AddContourCurve(pXy.get(), &pCurves, &pLayers);
qDeleteAll(pCurves);
qDeleteAll(pLayers);
}
/**
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC>У<EFBFBD><D0A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>׺<EFBFBD><D7BA><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD>ɶ<EFBFBD>Ӧ<EFBFBD><D3A6>ʽ
*
* \\param pXy
* \\param outputFile Ҫ<><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>
* \\param contourStep
* \\param contourMarkStep
* \\param insertTimes
* \\param pDfg Ҫ<><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* \\return
*/
static bool SaveFile(CString outputFile, CString faultFile
, double contourStep, int contourMarkStep, int insertTimes, int smoothTimes
, CDimension2D *pDfg, std::vector<CCurveEx*> &borders)
{
std::shared_ptr<CXy> pXy = std::make_shared<CXy>();
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
CMesh* pMeshNew = new CMesh(); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
CLayer* pLayer = pXy->FindAddLayer("<EFBFBD><EFBFBD><EFBFBD><EFBFBD>");
POSITION posNew = pXy->AddElement(pMeshNew, DOUBLEFOX_MESH);
pXy->SetElementLayer(posNew, pLayer);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
pMeshNew->SetMesh(pDfg, MESH_DFG, FALSE);
pMeshNew->m_nTimes = insertTimes;
// <20><><EFBFBD>ɱ߿<C9B1>
CreateBorder(pXy, borders);
// <20><><EFBFBD>ɶϲ<C9B6>
CreateFaults(faultFile, pXy, pDfg);
for (int i = 0; i < smoothTimes; i++)
{
CGridSmooth::ExcuteSmooth(pXy, pDfg);
}
// <20><><EFBFBD>ɵ<EFBFBD>ֵ<EFBFBD><D6B5>
CreateContourLines(pXy, pMeshNew, pDfg, contourStep, contourMarkStep);
pMeshNew->EnableUpdateRuler(TRUE);
pMeshNew->UpdateColorRuler();
pXy->SaveAsWithExtension(outputFile);
return true;
}
// <20><>ȡ<EFBFBD>߽<EFBFBD><DFBD><EFBFBD>/<2F>߿<EFBFBD>
static std::vector<CCurveEx*> get_border(CString borderFile)
{
if (!CFindFileEx::IsFileExists(borderFile)) {
return {};
}
std::shared_ptr<CXy> pXy = std::make_shared<CXy>();
borderFile = borderFile.Trim();
if (borderFile.GetLength() <= 0 || borderFile == "NULL") {
return {};
}
if (!pXy->ReadWithExtension(borderFile)) {
return {};
}
std::vector<CCurveEx*> result;
CPtrList* pl = pXy->GetValueList();
for (POSITION pos = pl->GetHeadPosition(); pos != nullptr; pl->GetNext(pos)) {
COne* pOne = (COne *)pl->GetAt(pos);
if (pOne->GetType() == DOUBLEFOX_CURVE) {
CCurveEx *pCurve = (CCurveEx*)(pOne->GetValue());
CCurveEx *pCurveNew = new CCurveEx();
*pCurveNew = *pCurve;
result.push_back(pCurveNew);
}
}
return result;
}
static bool get_borderRange(CString borderFile, double& xMin, double& yMin, double& xMax, double& yMax) {
if (!CFindFileEx::IsFileExists(borderFile)) {
return false;
}
std::shared_ptr<CXy> pXy = std::make_shared<CXy>();
borderFile = borderFile.Trim();
if (borderFile.GetLength() <= 0 || borderFile == "NULL") {
return false;
}
if (!pXy->ReadWithExtension(borderFile)) {
return false;
}
xMin = 1e100;
yMin = 1e100;
xMax = -1e100;
yMax = -1e100;
CPtrList* pl = pXy->GetValueList();
for (POSITION pos = pl->GetHeadPosition(); pos != nullptr; pl->GetNext(pos)) {
COne* pOne = (COne *)pl->GetAt(pos);
if (pOne->GetType() == DOUBLEFOX_CURVE) {
CCurveEx *pCurve = (CCurveEx*)(pOne->GetValue());
for (int i = 0; i < pCurve->num; i++) {
if (pCurve->x[i] < xMin) {
xMin = pCurve->x[i];
}
if (pCurve->x[i] > xMax)
{
xMax = pCurve->x[i];
}
if (pCurve->y[i] < yMin) {
yMin = pCurve->y[i];
}
if (pCurve->y[i] > yMax) {
yMax = pCurve->y[i];
}
}
}
}
return true;
}
static void dump_to_cxy(ais::GridInterpolator &gi, double fillValue, CString faultFile, CString borderFile, CString filename
, double contourStep, int contourMarkStep, int insertTimes,int smoothTimes, double zValueMin, double zValueMax)
{
std::map<std::string, any> params = gi.params();
double xMin = std::any_cast<double>(params["x_min"]);
double xMax = std::any_cast<double>(params["x_max"]);
double yMin = std::any_cast<double>(params["y_min"]);
double yMax = std::any_cast<double>(params["y_max"]);
double zMin = zValueMin;// std::any_cast<double>(params["z_min"]);
double zMax = zValueMax;// std::any_cast<double>(params["z_max"]);
size_t nCols = std::any_cast<size_t>(params["x_nodes"]);
size_t nRows = std::any_cast<size_t>(params["y_nodes"]);
double dx = std::any_cast<double>(params["x_grid_size"]);
double dy = std::any_cast<double>(params["y_grid_size"]);
std::shared_ptr<ais::FMatrix> matrix = gi.matrix();
std::vector<CCurveEx*> curves = get_border(borderFile);
auto pDfg = CreateGridData(xMin, yMin, matrix,
(int)nCols, (int)nRows, dx, dy,
zMin, zMax, 0,
curves,
fillValue);
SaveFile(filename, faultFile, contourStep, contourMarkStep, insertTimes, smoothTimes, pDfg, curves);
}
/**
* <20><><EFBFBD>ض<EFBFBD><D8B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>
* \\param filename <20>ļ<EFBFBD><C4BC><EFBFBD>
* \\return
*/
static std::vector<ais::BreakLine> loadBreadLines(const std::string &filename)
{
std::vector<ais::BreakLine> result;
ais::BreakLineFile blf(filename.c_str());
for (auto &kv : blf.lines)
{
result.emplace_back(kv.second);
}
return result;
}
/**
* <20><><EFBFBD>ضϲ<D8B6>
* \\param filename <20>ļ<EFBFBD><C4BC><EFBFBD>
* \\return
*/
static std::vector<ais::Fault> loadFaults(const std::string &filename)
{
std::vector<ais::Fault> result;
ais::FaultFile ff(filename.c_str());
for (auto &kv : ff.faults)
{
result.emplace_back(kv.second);
}
return result;
}
double range(const axisRange &minMax)
{
return minMax.second - minMax.first;
}
size_t calcYNodeCount(const axisRange &xMinMax, const axisRange &yMinMax, size_t xNodeCount)
{
double xRange = range(xMinMax);
double yRange = range(yMinMax);
double step = xRange / xNodeCount;
return std::ceil(yRange / step);
}
bool IsValidGridSize(double gridSize)
{
return !std::isnan(gridSize) && gridSize > 0.0;
}
static void logMessage(const std::string_view& message)
{
std::time_t now = std::time(nullptr);
std::tm* timeinfo = std::localtime(&now);
char buffer[80];
memset(buffer, 0, sizeof(buffer));
std::strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", timeinfo);
std::ofstream logFile("log.txt", std::ios::app);
if (logFile.is_open()) {
// <20><><EFBFBD><EFBFBD>־<EFBFBD><D6BE>Ϣд<CFA2><D0B4><EFBFBD>ļ<EFBFBD>
logFile << "[" << buffer << "] " << message << std::endl;
}
}
static void logMessage(int lineNO)
{
logMessage(std::to_string(lineNO));
}
// <20><><EFBFBD><EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7><EFBFBD>ñ<EFBFBD><C3B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̫<EFBFBD><CCAB><EFBFBD>˲<EFBFBD><CBB2>У<EFBFBD><D0A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܷ<EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> maxIteration =xNodeCount*yNodeCount*2<><32>fillValue<75><65>TODO<44><4F><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7>Ӱ<EFBFBD><D3B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD>ݾ<EFBFBD><DDBE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
bool BuildMinCurvatureGrid3Impl(
const wchar_t* sourcePointFile,
const wchar_t* faultFile,
const wchar_t* borderFile,
size_t xNodeCount,
int maxIteration,
double residual,
double fillValue,
int faultEdgeLevel,
const wchar_t* outputFile,
int estimateFactor,
int cornerWeight,
double contourStep,
int contourMarkStep,
int insertTimes,
int smoothTimes,
double xMin, double yMin, double xMax, double yMax
)
{
if (cornerWeight < 4)
cornerWeight = 4;
if (cornerWeight > 256)
cornerWeight = 256;
// -1 <20><>ʾĬ<CABE><C4AC>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Σ<EFBFBD><CEA3><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD>˱<EFBFBD>֤<EFBFBD><D6A4>ʹ<EFBFBD><CAB9> <= 0 <20>ж<EFBFBD>
if (maxIteration <= 0)
{
maxIteration = 20000;
}
if (faultFile == nullptr)
{
faultFile = L"";
}
if (borderFile == nullptr)
{
borderFile = L"";
}
if (sourcePointFile == nullptr
|| outputFile == nullptr)
{
return false;
}
try
{
std::string sourcePointFileStr = WstringToString(sourcePointFile);
std::string faultFileStr = WstringToString(faultFile);
std::string outputFileStr = WstringToString(outputFile);
sourcePointFileStr = pystring::strip(sourcePointFileStr);
faultFileStr = pystring::strip(faultFileStr);
outputFileStr = pystring::strip(outputFileStr);
std::vector<ais::PointXYZ> samplePoints = load_sample_points(sourcePointFileStr);
auto[xMinMax, yMinMax] = get_actually_area_concerns(samplePoints);
std::vector<ais::Point> areaPoints = build_area_by_concerns_points(xMinMax.first, yMinMax.first, xMinMax.second, yMinMax.second);
if (xMin < xMax && yMin < yMax) {
areaPoints = build_area_by_concerns_points(xMin, yMin, xMax, yMax);
}
CString cstrBorderFile(borderFile);
if (cstrBorderFile.GetLength() > 0 && cstrBorderFile!= "NULL") {
double dXMin = 0, dYMin = 0, dXMax = 0, dYMax = 0;
bool bSuccess = get_borderRange(cstrBorderFile, dXMin, dYMin, dXMax, dYMax);
if (bSuccess) {
areaPoints = build_area_by_concerns_points(dXMin, dYMin, dXMax, dYMax);
}
}
// <20>Ƴ<EFBFBD><C6B3>ظ<EFBFBD><D8B8>ͳ<EFBFBD><CDB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD>
std::vector<ais::PointXYZ> effectivePoints = ais::filter_points(areaPoints, samplePoints);
if (xNodeCount == 0)
{
xNodeCount = 101; // x <20><> Ĭ<><C4AC> 101 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
size_t xCount = xNodeCount;
size_t yCount = calcYNodeCount(xMinMax, yMinMax, xNodeCount);
// <20><><EFBFBD>ñ<EFBFBD><C3B1><EFBFBD><EFBFBD><EFBFBD>С
ais::Shape targetShape = { yCount, xCount };
std::shared_ptr<ais::FMatrix> target = std::make_shared<ais::FMatrix>(targetShape);
// fill target matrix with nan values for next iteration
std::cout << "targetShape.yCount = " << yCount << ", " << "xCount = " << xCount << "\n";
target->zeros();
std::vector<ais::BreakLine> breaklines;
// <20><><EFBFBD>ļ<EFBFBD><C4BC>м<EFBFBD><D0BC>ضϲ<D8B6>
std::vector<ais::Fault> faults;
if (pystring::strip(faultFileStr).length() > 0 && faultFileStr != "NULL")
{
faults = loadFaults(faultFileStr);
}
if (effectivePoints.empty())
{
return false;
}
ais::GridInterpolator gi(effectivePoints, areaPoints, target, breaklines, faults);
std::map<std::string, any> paramsOrigin = gi.params();
double zMin = std::any_cast<double>(paramsOrigin["z_min"]);
double zMax = std::any_cast<double>(paramsOrigin["z_max"]);
if (maxIteration <= 0)
{
maxIteration = static_cast<int>(xCount * yCount * 2); // <20>Ƽ<EFBFBD><C6BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
std::map<std::string, std::any> params
{
{ "max_iteration", (size_t)maxIteration },
{ "residual", residual },
{ "estimate_factor", (int32_t)estimateFactor },
{ "fault_edge_level", (int8_t)faultEdgeLevel },
{ "fill_value", fillValue },
{ "corner_weight", (short)cornerWeight },
{ "use_multi_threads", true },
{ "detail_level", (int8_t)0 },
};
gi.update_grid_params(params);
std::cout << gi.params_info();
// start grid intersection
auto gs = [&gi]()
{
gi.start();
};
std::thread t(gs);
do
{
std::this_thread::sleep_for(std::chrono::milliseconds(500)); // ΪʲôҪ sleep ? <20><><EFBFBD><EFBFBD>ԭ<EFBFBD><D4AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ﲻ sleep <20>ͻ<EFBFBD><CDBB><EFBFBD><EFBFBD><EFBFBD>ȥ<EFBFBD><C8A5>ȡ
std::string msg = gi.get_progress_msg();
if (!msg.empty())
{
std::cout << msg;
}
} while (!gi.is_end());
t.join();
std::cout << "Interpolated result: " << std::endl;
std::cout << "---------------------------------------" << std::endl;
std::cout << gi.report();
std::cout << "---------------------------------------" << std::endl;
std::cout << "Output file: " << outputFileStr << std::endl;
paramsOrigin = gi.params();
zMin = std::any_cast<double>(paramsOrigin["z_min"]);
zMax = std::any_cast<double>(paramsOrigin["z_max"]);
dump_to_cxy(gi, fillValue, faultFile, borderFile, outputFile, contourStep, contourMarkStep, insertTimes, smoothTimes, zMin, zMax);
//dump_to_grd(gi, outputFileStr.c_str());
}
catch (std::exception e) {
std::cout << e.what() << std::endl;
return false;
}
return true;
}
static std::optional<int> ExecuteCommand(LPSTR command)
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
DWORD exitCode = 0;
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
// <20><><EFBFBD><EFBFBD><EFBFBD>µĽ<C2B5><C4BD><EFBFBD>
if (CreateProcess(NULL, command, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
// <20>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD>̽<EFBFBD><CCBD><EFBFBD>
WaitForSingleObject(pi.hProcess, INFINITE);
// <20><>ȡ<EFBFBD><C8A1><EFBFBD>̵ķ<CCB5><C4B7><EFBFBD>ֵ
GetExitCodeProcess(pi.hProcess, &exitCode);
// <20>رս<D8B1><D5BD>̺<EFBFBD><CCBA>̵߳ľ<CCB5><C4BE><EFBFBD>
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
} else {
std::cout << "Failed to create process" << std::endl;
return {};
}
std::cout << "Process exited with code: " << exitCode << std::endl;
return exitCode;
}
/*
bool BuildMinCurvatureGrid3(
const wchar_t * sourcePointFile,
const wchar_t * faultFile,
const wchar_t * borderFile,
size_t xNodeCount,
int maxIteration,
double residual,
double fillValue,
int faultEdgeLevel,
const wchar_t * outputFile,
int estimateFactor,
int cornerWeight,
double contourStep,
int contourMarkStep,
int insertTimes,
double xMin, double yMin, double xMax, double yMax)
{
std::vector<std::string> strArea{ std::to_string(xMin), std::to_string(yMin), std::to_string(xMax), std::to_string(yMax) };
std::map<std::string, std::string> commandArgs
{
{ "--source-point-file", wstringToString(sourcePointFile) },
{ "--fault", wstringToString(faultFile) },
{ "--breakline", wstringToString(borderFile) },
{ "--x-nodes-count", std::to_string(xNodeCount) },
{ "--max-iteration", std::to_string(maxIteration) },
{ "--residual", std::to_string(residual) },
{ "--fill-value", std::to_string(fillValue) },
{ "--fault-edge-level", std::to_string(faultEdgeLevel) },
{ "--output-file", wstringToString(outputFile) },
{ "--estimate-factor", std::to_string(estimateFactor) },
{ "--corner-weight", std::to_string(cornerWeight) },
{ "--contour-step", std::to_string(contourStep) },
{ "--contour-mark-step", std::to_string(contourMarkStep) },
{ "--insert-times", std::to_string(insertTimes) },
{ "--area", pystring::join(",", strArea) },
};
std::stringstream ss;
ss << "SurfaceGrid.exe ";
for (auto &pair : commandArgs)
{
ss << pair.first << " " << pair.second << " ";
}
string command = ss.str();
return ExecuteCommand(const_cast<char *>(command.c_str())) == EXIT_SUCCESS;
}
*/