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.

380 lines
16 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.

/*------------------------------------------------------------------------------
* Copyright (c) 2023 by Bai Bing (seread@163.com)
* See COPYING file for copying and redistribution conditions.
*
* Alians IT Studio.
*----------------------------------------------------------------------------*/
#pragma once
#include <algorithm>
#include <any>
#include <array>
#include <chrono>
#include <list>
#include <memory>
#include <numeric>
#include <queue>
#include <utility>
#include <vector>
#include <stdexcept>
#include <mutex>
#include "_Define.h"
#include "core/ComplexOperators.h"
#include "core/Endian.h"
#include "core/Enums.h"
#include "core/Error.h"
#include "core/FileSystem.h"
#include "core/StaticAsserts.h"
#include "core/String.h"
#include "core/TypeTraits.h"
#include "ASBreakLine.h"
#include "ASFault.h"
#include "ASGridInterpolatorBlock.h"
#include "ASIterators.h"
#include "ASMatrix.h"
#include "ASShape.h"
#include "ASSlice.h"
#include "ASPoint.h"
#include "interpolator/ASInterpolator.h"
namespace ais
{
using PMatrix = AIS_EXPORT Matrix<PointXYZ>;
enum class EdgeNodeValueMethod : int
{
FILL = 0,
NEAREST,
};
enum class InitTargetMatrixMethod : int
{
LINEAR = 0,
LOG,
};
class AIS_EXPORT GridInterpolator
{
public:
GridInterpolator();
~GridInterpolator();
GridInterpolator(const std::vector<ais::PointXYZ> &randomPoints, // random sample points
const std::vector<ais::Point> &areaPoints, // result grid area corners points
std::shared_ptr<ais::FMatrix> targetMatrix, // output target matrix
const std::vector<ais::BreakLine> &breaklines = {}, // break lines
const std::vector<ais::Fault> &faults = {} // faults
);
//============================================================================
// Method Description:
/// Set the random sample points
///
/// @param points
///
void set_random_points(const std::vector<ais::PointXYZ> &points);
//============================================================================
// Method Description:
/// Set the area points which limit the grid
///
/// @param points
///
void set_area_points(const std::vector<ais::Point> &points);
//============================================================================
// Method Description:
/// Set the grid matrix by corner points and step, for output target
///
/// @param areaPoints
///
void set_result_matrix(ais::Matrix<double> &result, std::vector<ais::Point> &areaPoints);
std::shared_ptr<ais::Matrix<double>> matrix();
//============================================================================
// Method Description:
/// get the interpolation params
///
/// @return params
///
std::map<std::string, std::any> params();
//============================================================================
// Method Description:
/// dump grid interpolation params to string
std::string params_info();
//============================================================================
// Method Description:
/// dump origin data statistics to string
std::string dump_data_statistics();
//============================================================================
// Method Description:
/// update grid interpolation params
void update_grid_params(const std::map<std::string, std::any> &params);
//============================================================================
// Method Description:
/// update grid interpolation for special area
///
/// void update(std::vector<ais::PointXYZ> &changedArea);
//============================================================================
// Method Description:
/// start grid interpolation
///
/// @param interpolator, select specific interpolator to complete the interpolation
///
void start(InterpolationMethod method = InterpolationMethod::MINIMUM_CURVATURE);
//============================================================================
// Method Description:
/// abort grid interpolation
///
inline void abort() { flagRunning_ = false; };
//============================================================================
// Method Description:
/// Get total progress of grid interpolation
///
std::string get_progress_msg();
//============================================================================
// Method Description:
/// output statistics report for original data
///
std::string report();
//============================================================================
// Method Description:
/// dump points data to string
std::string points_info();
//============================================================================
// Method Description:
/// dump grid header info to string
std::string header_info(std::shared_ptr<ais::FMatrix> dataMatrixPtr = {});
//============================================================================
// Method Description:
/// dump grid data info to string
std::string data_info(std::shared_ptr<ais::FMatrix> dataMatrixPtr = {});
//============================================================================
// Method Description:
/// dump total iteration time info to string
std::string iteration_time();
//============================================================================
// Method Description:
/// dump result to file
void dump_result(const char *filename, std::shared_ptr<ais::FMatrix> dataMatrixPtr = {});
void dump_result_async(const std::string &filename, std::shared_ptr<ais::FMatrix> dataMatrixPtr = {}, int8_t detailLevel = 0);
inline bool is_end() { return flagEnd_; }
inline bool is_succeeded() { return flagSucceed_; }
private:
// params from constructor or set functions
std::vector<ais::PointXYZ> randomPoints_;
std::vector<ais::PointXYZ> randomPointPositions_;
std::map<size_t, ais::PointXYZ> randomPointPositionsHash_;
std::vector<ais::Point> areaPoints_; // points list to limit the interpolate area
std::shared_ptr<ais::FMatrix> targetMatrixPtr_; // matrix = col points * row points
// matrix which used to estimate surface, which dx/dy size is too smell to get smooth result
std::shared_ptr<ais::FMatrix> estimateMatrixPtr_;
size_t estimateFactor_ = 0;
// corner smooth weight, which used to get smooth result on corner while there is no simple data
// weight should between 4~256, default is 64
size_t cornerWeight_ = 64;
// breaklines & faults
std::vector<ais::BreakLine> breaklines_;
std::vector<ais::Fault> faults_;
// grid attributes
// constrain matrixsame shape and size as target matrix
std::shared_ptr<ais::PMatrix> constrainMatrixPtr_;
// matrix which storage the points in fault, used to add fault line on output matrix
std::shared_ptr<ais::FMatrix> pointInFaultMatrixPtr_;
// matrix which storage the fault affect block values, used to iteration the points value
std::shared_ptr<ais::FMatrix> faultAffectMatrixPtr_;
bool flagRunning_{false};
bool flagMultiThread_{true};
uint64_t iteration_{0}; // current iteration count
double relaxationFactor_{1}; // relaxation factor, default 1 (0 Slowest~2 Fast)
uint64_t maxIteration_{2000}; // max iteration, suggest 1~2 * total grids, default 2000
double residual_{0.0001}; // residual, default 0.0001
double epsMax_{std::nan("1")}; // epsMax = residual_ * (zMax - zMin)
double fillValue_{0}; // fill value, default 0
std::vector<double> x_;
std::vector<double> y_;
std::pair<double, double> xMinMax_, yMinMax_; // grid coordinates
std::pair<double, double> zMinMax_;
double zMean_;
double dxSize_, dySize_; // grid spacing size
double alpha_; // alpha = dxSize_ / dySize_
double beta_; // beta = dySize_ / dxSize_
size_t faultNodesCount_{0};
std::atomic<bool> flagSucceed_{false}; // reach the max iterator or iteration output eps < maxResidual
std::atomic<bool> flagEnd_{false};
std::chrono::system_clock::time_point startTime_;
std::chrono::system_clock::time_point endTime_;
std::mutex dataMutex_;
std::mutex msgMutex_;
std::vector<std::string> interpolationMsgs_;
std::mutex mapMutex_;
std::map<size_t, ais::GridInterpolatorBlock<>> faultEdgePointExpandBoxes_;
// output option
int8_t faultEdgeLevel_{-1};
int8_t detailLevel_{ 0 };
// origin random points statistics
std::map<std::string, double> dataStatistics_;
//============================================================================
// Method Description:
/// generate suggestions for grid interpolation params
void generate_grid_params(std::shared_ptr<ais::FMatrix> targetMatrixPtr);
//============================================================================
// Method Description:
/// generate origin data statistics
void generate_data_statistics();
//============================================================================
// Method Description:
/// setup constraint point
void setup_constraint_point(std::shared_ptr<ais::PMatrix> &cmp, size_t xi, size_t yi, double xGap, double yGap, const ais::PointXYZ &point);
//============================================================================
// Method Description:
/// generate constraint points for breakline
std::vector<PointXYZ> generate_constraint_points(const ais::BreakLine &breakline);
//============================================================================
// Method Description:
/// generate constraint points for fault
std::vector<PointXYZ> generate_constraint_points(const ais::Fault &fault);
//============================================================================
// Method Description:
/// get nearest sample points for specified point
std::vector<PointXYZ> get_nearest_samples(size_t x, size_t y, size_t min_count = 3, size_t max_count = 6);
//============================================================================
// Method Description:
/// get range sample points for specified point, while radius == 0 or > max(x)
std::vector<PointXYZ> get_range_samples(size_t xIndex, size_t yIndex, double xGridSize, double yGridSize, const std::vector<PointXYZ> &randoms, double radius = 0);
//============================================================================
// Method Description:
/// convert sample points position to coordinates, simple calculating
std::vector<PointXYZ> coordinates_points(const std::vector<PointXYZ> &points);
//============================================================================
// Method Description:
/// get point hash map
std::map<size_t, PointXYZ> points_hash_map(const std::vector<PointXYZ> &points);
//============================================================================
// Method Description:
/// build the constraint matrix by input parameters
///
void build_constraint_matrix(std::shared_ptr<ais::FMatrix> targetMatrixPtr, std::shared_ptr<ais::PMatrix> &constrainMatrixPtr);
//============================================================================
// Method Description:
/// build the fault impact points matrix by input parameters
///
/// @param in targetMatrixPtr: source matrix which used to build fault matrix
/// @param in/out pointInFaultMatrixPtr: storage the point information which in matrix
/// @param in/out faultAffectMatrixPtr: storage the fault affect matrix
void build_fault_impact_matrix(std::shared_ptr<ais::FMatrix> targetMatrixPtr,
std::shared_ptr<ais::FMatrix> &pointInFaultMatrixPtr,
std::shared_ptr<ais::FMatrix> &faultAffectMatrixPtr);
//============================================================================
// Method Description:
/// update edge node
///
void update_edge_node(std::shared_ptr<ais::FMatrix> &targetMatrixPtr, EdgeNodeValueMethod method = EdgeNodeValueMethod::FILL);
//============================================================================
// Method Description:
/// update nan node with fill value
///
void update_nan_node(std::shared_ptr<ais::FMatrix> &targetMatrixPtr);
//============================================================================
// Method Description:
/// detect estimate factor by input params
///
size_t detect_estimate_factor();
//============================================================================
// Method Description:
/// estimate matrix node if the estimate > 1
///
void scale_estimate();
//============================================================================
// Method Description:
/// estimate target matrix node with special method
///
void estimate_gradients_surface(std::shared_ptr<ais::FMatrix> &targetMatrixPtr);
void estimate_gradients_surface_2(InitTargetMatrixMethod method = InitTargetMatrixMethod::LINEAR);
//============================================================================
// Method Description:
/// start interpolation in detached thread
///
void start_interpolation(std::shared_ptr<ais::FMatrix> &targetMatrixPtr, std::shared_ptr<ais::PMatrix> &constrictMatrixPtr,
std::shared_ptr<ais::FMatrix> &pointInFaultMatrixPtr, std::shared_ptr<ais::FMatrix> &faultAffectMatrixPtr,
InterpolationMethod method = InterpolationMethod::MINIMUM_CURVATURE);
//============================================================================
// Method Description:
/// minimum curvature interpolation main function
///
bool update_min_curv_interpolation(std::shared_ptr<ais::FMatrix> &targetMatrixPtr, std::shared_ptr<ais::PMatrix> &constrictMatrixPtr,
std::shared_ptr<ais::FMatrix> &pointInFaultMatrixPtr, std::shared_ptr<ais::FMatrix> &faultAffectMatrixPtr,
const std::vector<ais::Point> &targetArea = {});
//============================================================================
// Method Description:
/// update Minimum Curvature boundary
///
/// @param update matrix for minimum curvature grid iteration
/// @param column target matrix column
/// @param row target matrix row
/// @param alpha = dx/dy = x grid space size / y grid space size
///
void update_min_curv_boundary(std::shared_ptr<ais::FMatrix> &ump, size_t column, size_t row, double alpha);
//============================================================================
// Method Description:
/// interpolate the estimate matrix data to target matrix
///
void interpolate_estimate_2_target();
};
}