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/ASGridInterpolator.h

380 lines
16 KiB
C

1 month ago
/*------------------------------------------------------------------------------
* 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();
};
}