1102 lines
30 KiB
C++
1102 lines
30 KiB
C++
/********************************************************
|
|
* ██████╗ ██████╗████████╗██╗
|
|
* ██╔════╝ ██╔════╝╚══██╔══╝██║
|
|
* ██║ ███╗██║ ██║ ██║
|
|
* ██║ ██║██║ ██║ ██║
|
|
* ╚██████╔╝╚██████╗ ██║ ███████╗
|
|
* ╚═════╝ ╚═════╝ ╚═╝ ╚══════╝
|
|
* Geophysical Computational Tools & Library (GCTL)
|
|
*
|
|
* Copyright (c) 2023 Yi Zhang (yizhang-geo@zju.edu.cn)
|
|
*
|
|
* GCTL is distributed under a dual licensing scheme. You can redistribute
|
|
* it and/or modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation, either version 2
|
|
* of the License, or (at your option) any later version. You should have
|
|
* received a copy of the GNU Lesser General Public License along with this
|
|
* program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
* If the terms and conditions of the LGPL v.2. would prevent you from using
|
|
* the GCTL, please consider the option to obtain a commercial license for a
|
|
* fee. These licenses are offered by the GCTL's original author. As a rule,
|
|
* licenses are provided "as-is", unlimited in time for a one time fee. Please
|
|
* send corresponding requests to: yizhang-geo@zju.edu.cn. Please do not forget
|
|
* to include some tcription of your company and the realm of its activities.
|
|
* Also add information on how to contact you by electronic and paper mail.
|
|
******************************************************/
|
|
|
|
#include "dsv_io.h"
|
|
|
|
gctl::dsv_io::dsv_io()
|
|
{
|
|
att_sym_ = '#';
|
|
tag_sym_ = '!';
|
|
deli_sym_ = ' ';
|
|
head_num_ = 0;
|
|
row_num_ = 0;
|
|
col_num_ = 0;
|
|
}
|
|
|
|
gctl::dsv_io::~dsv_io()
|
|
{
|
|
clear();
|
|
}
|
|
|
|
gctl::dsv_io::dsv_io(std::string filename, std::string file_exten, int t)
|
|
{
|
|
att_sym_ = '#';
|
|
tag_sym_ = '!';
|
|
deli_sym_ = ' ';
|
|
head_num_ = 0;
|
|
row_num_ = 0;
|
|
col_num_ = 0;
|
|
|
|
if (file_exten == ".csv") load_csv(filename, t);
|
|
else load_text(filename, file_exten, t);
|
|
}
|
|
|
|
void gctl::dsv_io::clear()
|
|
{
|
|
att_sym_ = '#';
|
|
tag_sym_ = '!';
|
|
deli_sym_ = ' ';
|
|
head_num_ = 0;
|
|
row_num_ = 0;
|
|
col_num_ = 0;
|
|
|
|
destroy_vector(heads_);
|
|
destroy_vector(annotates_);
|
|
destroy_vector(tags_);
|
|
destroy_vector(table_);
|
|
return;
|
|
}
|
|
|
|
std::vector<std::string> gctl::dsv_io::row_names()
|
|
{
|
|
_1s_vector names(row_num_);
|
|
for (size_t i = 1; i <= row_num_; i++)
|
|
{
|
|
names[i - 1] = table_[i][0].str_;
|
|
}
|
|
return names;
|
|
}
|
|
|
|
void gctl::dsv_io::row_names(const std::vector<std::string> &names, const std::vector<int> &idx, std::string corner_name)
|
|
{
|
|
if (!idx.empty())
|
|
{
|
|
if (idx.size() != names.size()) throw std::runtime_error("[gctl::dsv_io] The size of idx and names must be the same.");
|
|
|
|
for (size_t i = 0; i < names.size(); i++)
|
|
{
|
|
table_[idx[i]][0].str_ = names[i];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (size_t i = 1; i <= std::min(row_num_, (int) names.size()); i++)
|
|
{
|
|
table_[i][0].str_ = names[i - 1];
|
|
}
|
|
}
|
|
|
|
table_[0][0].str_ = corner_name;
|
|
return;
|
|
}
|
|
|
|
std::vector<std::string> gctl::dsv_io::column_names()
|
|
{
|
|
_1s_vector names(col_num_);
|
|
for (size_t i = 1; i <= col_num_; i++)
|
|
{
|
|
names[i - 1] = table_[0][i].str_;
|
|
}
|
|
return names;
|
|
}
|
|
|
|
void gctl::dsv_io::column_names(const std::vector<std::string> &names, const std::vector<int> &idx)
|
|
{
|
|
if (!idx.empty())
|
|
{
|
|
if (idx.size() != names.size()) throw std::runtime_error("[gctl::dsv_io] The size of idx and names must be the same.");
|
|
|
|
for (size_t i = 0; i < names.size(); i++)
|
|
{
|
|
table_[0][idx[i]].str_ = names[i];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for (size_t i = 1; i <= std::min(col_num_, (int) names.size()); i++)
|
|
{
|
|
table_[0][i].str_ = names[i - 1];
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
void gctl::dsv_io::row_type(table_cell_type t, int idx)
|
|
{
|
|
if (idx > row_num_ || idx <= 0)
|
|
{
|
|
throw std::runtime_error("[gctl::dsv_io] Invalid row index.");
|
|
}
|
|
|
|
for (size_t i = 0; i <= col_num_; i++)
|
|
{
|
|
table_[idx][i].type_ = t;
|
|
}
|
|
}
|
|
|
|
void gctl::dsv_io::row_type(table_cell_type t, std::string name)
|
|
{
|
|
row_type(t, name_index(name, true));
|
|
}
|
|
|
|
gctl::table_cell_type gctl::dsv_io::row_type(int idx)
|
|
{
|
|
if (idx > row_num_ || idx <= 0)
|
|
{
|
|
throw std::runtime_error("[gctl::dsv_io] Invalid row index.");
|
|
}
|
|
|
|
return table_[idx][0].type_;
|
|
}
|
|
|
|
gctl::table_cell_type gctl::dsv_io::row_type(std::string name)
|
|
{
|
|
return row_type(name_index(name, true));
|
|
}
|
|
|
|
void gctl::dsv_io::column_type(table_cell_type t, int idx)
|
|
{
|
|
if (idx > col_num_ || idx <= 0)
|
|
{
|
|
throw std::runtime_error("[gctl::dsv_io] Invalid column index.");
|
|
}
|
|
|
|
for (size_t i = 0; i <= row_num_; i++)
|
|
{
|
|
table_[i][idx].type_ = t;
|
|
}
|
|
return;
|
|
}
|
|
|
|
void gctl::dsv_io::column_type(table_cell_type t, std::string name)
|
|
{
|
|
column_type(t, name_index(name, false));
|
|
}
|
|
|
|
gctl::table_cell_type gctl::dsv_io::column_type(int idx)
|
|
{
|
|
if (idx > col_num_ || idx <= 0)
|
|
{
|
|
throw std::runtime_error("[gctl::dsv_io] Invalid column index.");
|
|
}
|
|
|
|
return table_[0][idx].type_;
|
|
}
|
|
|
|
gctl::table_cell_type gctl::dsv_io::column_type(std::string name)
|
|
{
|
|
return column_type(name_index(name, false));
|
|
}
|
|
|
|
void gctl::dsv_io::load_text(std::string filename, std::string file_exten, int t)
|
|
{
|
|
std::ifstream infile;
|
|
open_infile(infile, filename, file_exten);
|
|
|
|
int h = 0;
|
|
std::string tmp_line;
|
|
std::vector<std::string> lines;
|
|
while (std::getline(infile, tmp_line))
|
|
{
|
|
if (tmp_line.empty()) continue; // 跳过空行 空行不会并记入头信息计数中
|
|
|
|
// 去掉空格
|
|
tmp_line.erase(0, tmp_line.find_first_not_of(" \t"));
|
|
tmp_line.erase(tmp_line.find_last_not_of(" \t") + 1);
|
|
|
|
if (tmp_line[0] == att_sym_) // 注释行或者标记行 # #!
|
|
{
|
|
if (tmp_line[1] == tag_sym_) // #!
|
|
{
|
|
tmp_line = tmp_line.substr(2); // 去掉前两个字符
|
|
tags_.push_back(tmp_line);
|
|
continue;
|
|
}
|
|
|
|
// #
|
|
tmp_line = tmp_line.substr(1); // 去掉第一个字符
|
|
annotates_.push_back(tmp_line);
|
|
}
|
|
else if (h < head_num_) //读入到头信息中
|
|
{
|
|
heads_.push_back(tmp_line);
|
|
h++;
|
|
}
|
|
else lines.push_back(tmp_line);
|
|
}
|
|
infile.close();
|
|
|
|
table_.resize(lines.size());
|
|
|
|
int cn, cn_max = 0;
|
|
std::vector<std::string> tmp_cols;
|
|
for (size_t i = 0; i < lines.size(); i++)
|
|
{
|
|
tmp_cols.clear();
|
|
parse_string_to_vector(lines[i], deli_sym_, tmp_cols);
|
|
|
|
// 动态调整列数
|
|
cn = tmp_cols.size();
|
|
cn_max = GCTL_MAX(cn, cn_max);
|
|
|
|
table_[i].resize(tmp_cols.size());
|
|
for (size_t j = 0; j < tmp_cols.size(); j++)
|
|
{
|
|
table_[i][j].value(tmp_cols[j]);
|
|
}
|
|
}
|
|
|
|
// 补齐可能的空格
|
|
table_cell empty_cell;
|
|
for (size_t i = 0; i < table_.size(); i++)
|
|
{
|
|
cn = table_[i].size();
|
|
for (size_t j = cn; j < cn_max; j++)
|
|
{
|
|
table_[i].push_back(empty_cell);
|
|
}
|
|
}
|
|
|
|
std::vector<table_cell> empty_line;
|
|
if (t == NoHead) // 无表头 需要补齐空白的列头和行头
|
|
{
|
|
row_num_ = table_.size();
|
|
col_num_ = table_[0].size();
|
|
|
|
table_.emplace(table_.begin(), empty_line);
|
|
table_[0].resize(col_num_);
|
|
|
|
for (size_t i = 0; i < table_.size(); i++)
|
|
{
|
|
table_[i].emplace(table_[i].begin(), empty_cell);
|
|
}
|
|
}
|
|
|
|
if (t == ColHead) // 有列头 需要补齐空白的行头
|
|
{
|
|
row_num_ = table_.size() - 1;
|
|
col_num_ = table_[0].size();
|
|
|
|
for (size_t i = 0; i < table_.size(); i++)
|
|
{
|
|
table_[i].emplace(table_[i].begin(), empty_cell);
|
|
}
|
|
}
|
|
|
|
if (t == RowHead) // 有行头 需要补齐空白的列头
|
|
{
|
|
row_num_ = table_.size();
|
|
col_num_ = table_[0].size() - 1;
|
|
|
|
table_.emplace(table_.begin(), empty_line);
|
|
table_[0].resize(col_num_ + 1);
|
|
}
|
|
|
|
if ((t & RowHead) && (t & ColHead)) // 有行头和列头
|
|
{
|
|
row_num_ = table_.size() - 1;
|
|
col_num_ = table_[0].size() - 1;
|
|
}
|
|
|
|
destroy_vector(lines);
|
|
return;
|
|
}
|
|
|
|
void gctl::dsv_io::load_csv(std::string filename, int t)
|
|
{
|
|
delimeter(',');
|
|
load_text(filename, ".csv", t);
|
|
return;
|
|
}
|
|
|
|
void gctl::dsv_io::save_text(std::string filename, std::string file_exten)
|
|
{
|
|
std::ofstream outfile;
|
|
open_outfile(outfile, filename, file_exten);
|
|
|
|
for (int i = 0; i < heads_.size(); i++)
|
|
{
|
|
outfile << heads_[i] << std::endl;
|
|
}
|
|
|
|
for (int i = 0; i < tags_.size(); i++)
|
|
{
|
|
outfile << "#! " << tags_[i] << std::endl;
|
|
}
|
|
|
|
for (int i = 0; i < annotates_.size(); i++)
|
|
{
|
|
outfile << "# " << annotates_[i] << std::endl;
|
|
}
|
|
|
|
for (int i = 0; i <= row_num_; i++)
|
|
{
|
|
for (size_t j = 0; j <= col_num_; j++)
|
|
{
|
|
if (table_[i][j].out_ok_ && table_[i][j].str_!= "")
|
|
{
|
|
outfile << table_[i][j].str_;
|
|
for (size_t k = j + 1; k <= col_num_; k++)
|
|
{
|
|
if (table_[i][k].out_ok_) outfile << deli_sym_ << table_[i][k].str_;
|
|
}
|
|
outfile << std::endl;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
outfile.close();
|
|
return;
|
|
}
|
|
|
|
void gctl::dsv_io::save_csv(std::string filename)
|
|
{
|
|
delimeter(',');
|
|
save_text(filename, ".csv");
|
|
return;
|
|
}
|
|
|
|
void gctl::dsv_io::init_table(int row, int col)
|
|
{
|
|
if (!table_.empty()) clear();
|
|
|
|
row_num_ = row;
|
|
col_num_ = col;
|
|
|
|
// 初始的列头和行头均为空白
|
|
table_.resize(row_num_ + 1);
|
|
for (size_t i = 0; i < row_num_ + 1; i++)
|
|
{
|
|
table_[i].resize(col_num_ + 1);
|
|
}
|
|
return;
|
|
}
|
|
|
|
gctl::dsv_io gctl::dsv_io::export_table(bool ignore_disabled)
|
|
{
|
|
std::vector<std::string> str_line, row_names, col_names;
|
|
std::vector<std::vector<std::string> > str_table;
|
|
|
|
std::string cor_name = table_[0][0].str_;
|
|
for (size_t j = 1; j <= col_num_; j++)
|
|
{
|
|
if (table_[0][j].out_ok_ || !ignore_disabled)
|
|
col_names.push_back(table_[0][j].str_);
|
|
}
|
|
|
|
for (size_t i = 1; i <= row_num_; i++)
|
|
{
|
|
if (table_[i][0].out_ok_ || !ignore_disabled)
|
|
{
|
|
str_line.clear();
|
|
|
|
for (size_t j = 1; j <= col_num_; j++)
|
|
{
|
|
if (table_[i][j].out_ok_ || !ignore_disabled)
|
|
str_line.push_back(table_[i][j].str_);
|
|
}
|
|
|
|
str_table.push_back(str_line);
|
|
row_names.push_back(table_[i][0].str_);
|
|
}
|
|
}
|
|
|
|
dsv_io out_table;
|
|
out_table.init_table(str_table);
|
|
out_table.row_names(row_names, {}, cor_name);
|
|
out_table.column_names(col_names);
|
|
|
|
destroy_vector(row_names);
|
|
destroy_vector(col_names);
|
|
destroy_vector(str_line);
|
|
destroy_vector(str_table);
|
|
return out_table;
|
|
}
|
|
|
|
void gctl::dsv_io::info(int t, std::ostream &os)
|
|
{
|
|
if (t & HeadInfo)
|
|
{
|
|
os << "Head(s): " << head_num_ << "\n";
|
|
for (size_t i = 0; i < heads_.size(); i++)
|
|
{
|
|
os << heads_[i] << "\n";
|
|
}
|
|
os << "------------\n";
|
|
}
|
|
|
|
if (t & AttInfo)
|
|
{
|
|
os << "Annotation(s): " << annotates_.size() << "\n";
|
|
for (size_t i = 0; i < annotates_.size(); i++)
|
|
{
|
|
os << annotates_[i] << "\n";
|
|
}
|
|
os << "------------\n";
|
|
}
|
|
|
|
if (t & TagInfo)
|
|
{
|
|
os << "Tag(s): " << tags_.size() << "\n";
|
|
for (size_t i = 0; i < tags_.size(); i++)
|
|
{
|
|
os << tags_[i] << "\n";
|
|
}
|
|
os << "------------\n";
|
|
}
|
|
|
|
if (t & ColInfo)
|
|
{
|
|
os << "Columns:\n";
|
|
for (size_t i = 1; i <= col_num_; i++)
|
|
{
|
|
if (table_[0][i].str_ != "")
|
|
{
|
|
os << table_[0][i].str_ << " | ";
|
|
if (table_[0][i].out_ok_) os << "Enabled | ";
|
|
else os << "Disabled | ";
|
|
if (table_[1][i].type_ == String) os << "String | ";
|
|
if (table_[1][i].type_ == Int) os << "Int | ";
|
|
if (table_[1][i].type_ == Float) os << "Float | ";
|
|
os << table_[1][i].str_ << " -> " << table_[row_num_][i].str_;
|
|
}
|
|
else
|
|
{
|
|
os << "C" + std::to_string(i) << " | ";
|
|
if (table_[0][i].out_ok_) os << "Enabled | ";
|
|
else os << "Disabled | ";
|
|
if (table_[1][i].type_ == String) os << "String | ";
|
|
if (table_[1][i].type_ == Int) os << "Int | ";
|
|
if (table_[1][i].type_ == Float) os << "Float | ";
|
|
os << table_[1][i].str_ << " -> " << table_[row_num_][i].str_;
|
|
}
|
|
os << std::endl;
|
|
}
|
|
os << "------------\n";
|
|
}
|
|
|
|
if (t & RowInfo)
|
|
{
|
|
os << "Rows:\n";
|
|
for (size_t i = 1; i <= row_num_; i++)
|
|
{
|
|
if (table_[i][0].str_ != "")
|
|
{
|
|
os << table_[i][0].str_ << " | ";
|
|
if (table_[i][0].out_ok_) os << "Enabled | ";
|
|
else os << "Disabled | ";
|
|
if (table_[i][1].type_ == String) os << "String | ";
|
|
if (table_[i][1].type_ == Int) os << "Int | ";
|
|
if (table_[i][1].type_ == Float) os << "Float | ";
|
|
os << table_[i][1].str_ << " -> " << table_[i][col_num_].str_;
|
|
}
|
|
else
|
|
{
|
|
os << "R" + std::to_string(i) << " | ";
|
|
if (table_[i][0].out_ok_) os << "Enabled | ";
|
|
else os << "Disabled | ";
|
|
if (table_[i][1].type_ == String) os << "String | ";
|
|
if (table_[i][1].type_ == Int) os << "Int | ";
|
|
if (table_[i][1].type_ == Float) os << "Float | ";
|
|
os << table_[i][1].str_ << " -> " << table_[i][col_num_].str_;
|
|
}
|
|
os << std::endl;
|
|
}
|
|
os << "------------\n";
|
|
}
|
|
return;
|
|
}
|
|
|
|
void gctl::dsv_io::display()
|
|
{
|
|
std::string line;
|
|
cli_viewer viewer;
|
|
for (int i = 0; i <= row_num_; i++)
|
|
{
|
|
for (size_t j = 0; j <= col_num_; j++)
|
|
{
|
|
if (table_[i][j].out_ok_ && table_[i][j].str_!= "")
|
|
{
|
|
line = table_[i][j].str_;
|
|
for (size_t k = j + 1; k <= col_num_; k++)
|
|
{
|
|
if (table_[i][k].out_ok_) line += deli_sym_ + table_[i][k].str_;
|
|
}
|
|
|
|
viewer.addData(line);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
viewer.display();
|
|
return;
|
|
}
|
|
|
|
int gctl::dsv_io::name_index(std::string name, bool iter_row)
|
|
{
|
|
// 拾取行号或列号 格式为R<id>和C<id>
|
|
std::smatch ret;
|
|
std::regex patr("R(\\d*)"), patc("C(\\d*)");
|
|
|
|
if (iter_row)
|
|
{
|
|
for (size_t i = 1; i <= row_num_; i++)
|
|
{
|
|
if (table_[i][0].str_ == name) return i;
|
|
}
|
|
|
|
if (regex_search(name, ret, patr))
|
|
{
|
|
int r = atoi(std::string(ret[1]).c_str());
|
|
if (r >= 1 && r <= row_num_) return r;
|
|
else return -1;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
else
|
|
{
|
|
for (size_t i = 1; i <= col_num_; i++)
|
|
{
|
|
if (table_[0][i].str_ == name) return i;
|
|
}
|
|
|
|
if (regex_search(name, ret, patc))
|
|
{
|
|
int c = atoi(std::string(ret[1]).c_str());
|
|
if (c >= 1 && c <= col_num_) return c;
|
|
else return -1;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
void gctl::dsv_io::table_output(switch_type_e s)
|
|
{
|
|
for (size_t i = 0; i <= row_num_; i++)
|
|
{
|
|
for (size_t j = 0; j <= col_num_; j++)
|
|
{
|
|
if (s == Enable) table_[i][j].out_ok_ = true;
|
|
else table_[i][j].out_ok_ = false;
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
void gctl::dsv_io::column_output(int idx, switch_type_e s)
|
|
{
|
|
if (idx > col_num_ || idx <= 0)
|
|
{
|
|
throw std::runtime_error("[gctl::dsv_io] Invalid column index.");
|
|
}
|
|
|
|
for (size_t i = 0; i <= row_num_; i++)
|
|
{
|
|
if (s == Enable) table_[i][idx].out_ok_ = true;
|
|
else table_[i][idx].out_ok_ = false;
|
|
}
|
|
return;
|
|
}
|
|
|
|
void gctl::dsv_io::column_output(std::string name, switch_type_e s)
|
|
{
|
|
column_output(name_index(name), s);
|
|
return;
|
|
}
|
|
|
|
void gctl::dsv_io::row_output(int idx, switch_type_e s)
|
|
{
|
|
if (idx > row_num_ || idx <= 0)
|
|
{
|
|
throw std::runtime_error("[gctl::dsv_io] Invalid row index.");
|
|
}
|
|
|
|
for (size_t i = 0; i <= col_num_; i++)
|
|
{
|
|
if (s == Enable) table_[idx][i].out_ok_ = true;
|
|
else table_[idx][i].out_ok_ = false;
|
|
}
|
|
return;
|
|
}
|
|
|
|
void gctl::dsv_io::row_output(std::string name, switch_type_e s)
|
|
{
|
|
row_output(name_index(name, true), s);
|
|
return;
|
|
}
|
|
|
|
int gctl::dsv_io::add_column(std::string name, int idx)
|
|
{
|
|
if (idx <= 0) throw std::runtime_error("[gctl::dsv_io] Invalid column index.");
|
|
|
|
table_cell empty_cell;
|
|
if (idx > col_num_)
|
|
{
|
|
for (size_t i = 0; i < table_.size(); i++)
|
|
{
|
|
table_[i].push_back(empty_cell);
|
|
}
|
|
|
|
table_[0].back().str_ = name;
|
|
col_num_++;
|
|
return col_num_;
|
|
}
|
|
else
|
|
{
|
|
for (size_t i = 0; i < table_.size(); i++)
|
|
{
|
|
table_[i].insert(table_[i].begin() + idx, empty_cell);
|
|
}
|
|
|
|
table_[0][idx].str_ = name;
|
|
col_num_++;
|
|
return idx;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
int gctl::dsv_io::add_column(std::string name, std::string id_name)
|
|
{
|
|
return add_column(name, name_index(id_name));
|
|
}
|
|
|
|
int gctl::dsv_io::add_row(std::string name, int idx)
|
|
{
|
|
if (idx <= 0) throw std::runtime_error("[gctl::dsv_io] Invalid row index.");
|
|
|
|
std::vector<table_cell> empty_line;
|
|
if (idx > row_num_)
|
|
{
|
|
table_.push_back(empty_line);
|
|
table_.back().resize(col_num_ + 1);
|
|
table_.back().front().str_ = name;
|
|
row_num_++;
|
|
return row_num_;
|
|
}
|
|
else
|
|
{
|
|
table_.insert(table_.begin() + idx, empty_line);
|
|
table_[idx].resize(col_num_ + 1);
|
|
table_[idx].front().str_ = name;
|
|
row_num_++;
|
|
return idx;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
int gctl::dsv_io::add_row(std::string name, std::string id_name)
|
|
{
|
|
return add_row(name, name_index(id_name, true));
|
|
}
|
|
|
|
void gctl::dsv_io::filter(std::string cnd_str, std::string cnd_tar, table_headtype_e thead)
|
|
{
|
|
int idx;
|
|
if (thead == RowHead) idx = name_index(cnd_tar, true);
|
|
else if (thead == ColHead) idx = name_index(cnd_tar);
|
|
else throw std::runtime_error("[gctl::dsv_io::filter] Invalid table head type.");
|
|
|
|
if (idx < 0) throw std::runtime_error("[gctl::dsv_io::filter] Invalid row/column index or name.");
|
|
|
|
std::smatch ret;
|
|
std::regex pat(cnd_str);
|
|
if (thead == RowHead) // cnd_tar是行头 此时为按列过滤
|
|
{
|
|
for (size_t i = 1; i <= col_num_; i++)
|
|
{
|
|
if (!regex_search(table_[idx][i].str_, ret, pat))
|
|
{
|
|
column_output(i, Disable);
|
|
}
|
|
}
|
|
}
|
|
else // cnd_tar是列头 此时为按行过滤
|
|
{
|
|
for (size_t i = 1; i <= row_num_; i++)
|
|
{
|
|
if (!regex_search(table_[i][idx].str_, ret, pat))
|
|
{
|
|
row_output(i, Disable);
|
|
}
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
void gctl::dsv_io::filter(linebool_func_t func, table_headtype_e thead)
|
|
{
|
|
if (thead == RowHead)
|
|
{
|
|
for (size_t i = 1; i <= row_num_; i++)
|
|
{
|
|
if (!func(table_[i])) row_output(i, Disable);
|
|
}
|
|
}
|
|
else if (thead == ColHead)
|
|
{
|
|
std::vector<table_cell> col_cell(row_num_);
|
|
for (size_t i = 1; i <= col_num_; i++)
|
|
{
|
|
for (size_t j = 1; j < row_num_; j++)
|
|
{
|
|
col_cell[j] = table_[j][i];
|
|
}
|
|
|
|
if (!func(col_cell)) column_output(i, Disable);
|
|
}
|
|
}
|
|
else throw std::runtime_error("[gctl::dsv_io::filter] Invalid table head type.");
|
|
return;
|
|
}
|
|
|
|
#ifdef GCTL_EXPRTK
|
|
|
|
void gctl::dsv_io::cal_column(std::string expr_str, const std::vector<std::string> &col_list, int p)
|
|
{
|
|
array<int> idx(col_list.size());
|
|
for (size_t i = 0; i < col_list.size(); i++)
|
|
{
|
|
idx[i] = name_index(col_list[i]);
|
|
|
|
if (idx[i] < 0) throw std::runtime_error("[gctl::dsv_io::] Invalid column index or name.");
|
|
|
|
if (table_[0][idx[i]].type_ != Int && table_[0][idx[i]].type_ != Float)
|
|
{
|
|
throw std::runtime_error("[gctl::dsv_io] Invalid column type for numerical calculating.");
|
|
}
|
|
}
|
|
|
|
exprtk::symbol_table<double> symbol_table;
|
|
array<double> var(col_list.size());
|
|
|
|
for (size_t i = 0; i < var.size(); i++)
|
|
{
|
|
symbol_table.add_variable(col_list[i], var[i]);
|
|
}
|
|
|
|
exprtk::expression<double> expression;
|
|
expression.register_symbol_table(symbol_table);
|
|
|
|
exprtk::parser<double> parser;
|
|
if (!parser.compile(expr_str, expression))
|
|
{
|
|
throw std::runtime_error("[gctl::dsv_io] Fail to compile the math expression.");
|
|
}
|
|
|
|
for (size_t i = 1; i <= row_num_; i++)
|
|
{
|
|
// Remeber we put the output in the first element
|
|
for (size_t j = 1; j < var.size(); j++)
|
|
{
|
|
var[j] = table_[i][idx[j]].value<double>();
|
|
}
|
|
|
|
var[0] = expression.value();
|
|
table_[i][idx[0]].value(var[0], p);
|
|
}
|
|
return;
|
|
}
|
|
|
|
void gctl::dsv_io::filter(std::string cnd_str, const std::vector<std::string> &cnd_tars, table_headtype_e thead)
|
|
{
|
|
array<int> idx(cnd_tars.size());
|
|
if (thead == RowHead)
|
|
{
|
|
for (size_t i = 0; i < cnd_tars.size(); i++)
|
|
{
|
|
idx[i] = name_index(cnd_tars[i], true);
|
|
|
|
if (idx[i] <= 0 || idx[i] > row_num_) throw std::runtime_error("[gctl::dsv_io::filter] Invalid row index or name.");
|
|
|
|
if (table_[idx[i]][0].type_ != Int && table_[idx[i]][0].type_ != Float)
|
|
{
|
|
throw std::runtime_error("[gctl::dsv_io::filter] Invalid row type for numerical calculating.");
|
|
}
|
|
}
|
|
}
|
|
else if (thead == ColHead)
|
|
{
|
|
for (size_t i = 0; i < cnd_tars.size(); i++)
|
|
{
|
|
idx[i] = name_index(cnd_tars[i]);
|
|
|
|
if (idx[i] <= 0 || idx[i] > col_num_) throw std::runtime_error("[gctl::dsv_io::filter] Invalid column index or name.");
|
|
|
|
if (table_[0][idx[i]].type_ != Int && table_[0][idx[i]].type_ != Float)
|
|
{
|
|
throw std::runtime_error("[gctl::dsv_io::filter] Invalid column type for numerical calculating.");
|
|
}
|
|
}
|
|
}
|
|
else throw std::runtime_error("[gctl::dsv_io::filter] Invalid table head type.");
|
|
|
|
exprtk::symbol_table<double> symbol_table;
|
|
array<double> var(cnd_tars.size());
|
|
|
|
for (size_t i = 0; i < var.size(); i++)
|
|
{
|
|
symbol_table.add_variable(cnd_tars[i], var[i]);
|
|
}
|
|
|
|
exprtk::expression<double> expression;
|
|
expression.register_symbol_table(symbol_table);
|
|
|
|
exprtk::parser<double> parser;
|
|
if (!parser.compile(cnd_str, expression))
|
|
{
|
|
throw std::runtime_error("[gctl::dsv_io] Fail to compile the math expression.");
|
|
}
|
|
|
|
if (thead == RowHead) // cnd_tars是行头 此时为按列过滤
|
|
{
|
|
for (size_t i = 1; i <= col_num_; i++)
|
|
{
|
|
for (size_t j = 0; j < var.size(); j++)
|
|
{
|
|
var[j] = table_[idx[j]][i].value<double>();
|
|
}
|
|
|
|
// return 1 if matched or 0 if dismatched
|
|
if (expression.value() < 0.5) column_output(i, Disable);
|
|
}
|
|
}
|
|
else // cnd_tars是列头 此时为按行过滤
|
|
{
|
|
for (size_t i = 1; i <= row_num_; i++)
|
|
{
|
|
for (size_t j = 0; j < var.size(); j++)
|
|
{
|
|
var[j] = table_[i][idx[j]].value<double>();
|
|
}
|
|
|
|
// return 1 if matched or 0 if dismatched
|
|
if (expression.value() < 0.5) row_output(i, Disable);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
#endif // GCTL_EXPRTK
|
|
|
|
gctl::geodsv_io::geodsv_io(){}
|
|
|
|
gctl::geodsv_io::~geodsv_io(){}
|
|
|
|
gctl::geodsv_io::geodsv_io(std::string filename, std::string file_exten, int t)
|
|
{
|
|
att_sym_ = '#';
|
|
tag_sym_ = '!';
|
|
deli_sym_ = ' ';
|
|
head_num_ = 0;
|
|
row_num_ = 0;
|
|
col_num_ = 0;
|
|
|
|
if (file_exten == ".csv") load_csv(filename, t);
|
|
else load_text(filename, file_exten, t);
|
|
}
|
|
|
|
void gctl::geodsv_io::fill_column_point2dc(const array<point2dc> &data, int xid, int yid, int p)
|
|
{
|
|
if (xid > col_num_ || yid > col_num_ || xid == yid || xid <= 0 || yid <= 0)
|
|
{
|
|
throw std::runtime_error("[gctl::geodsv_io] Invalid column index.");
|
|
}
|
|
|
|
std::stringstream ss;
|
|
std::string s;
|
|
for (size_t i = 1; i <= std::min(row_num_, (int) data.size()); i++)
|
|
{
|
|
table_[i][xid].value(data[i - 1].x, p);
|
|
table_[i][yid].value(data[i - 1].y, p);
|
|
}
|
|
return;
|
|
}
|
|
|
|
void gctl::geodsv_io::fill_column_point2dc(const array<point2dc> &data, std::string xname, std::string yname, int p)
|
|
{
|
|
fill_column_point2dc(data, name_index(xname, false), name_index(yname, false), p);
|
|
return;
|
|
}
|
|
|
|
void gctl::geodsv_io::fill_column_point2dp(const array<point2dp> &data, int rid, int cid, int p)
|
|
{
|
|
if (rid > col_num_ || cid > col_num_ || rid == cid || rid <= 0 || cid <= 0)
|
|
{
|
|
throw std::runtime_error("[gctl::geodsv_io] Invalid column index.");
|
|
}
|
|
|
|
std::stringstream ss;
|
|
std::string s;
|
|
for (size_t i = 1; i <= std::min(row_num_, (int) data.size()); i++)
|
|
{
|
|
table_[i][rid].value(data[i - 1].rad, p);
|
|
table_[i][cid].value(data[i - 1].arc, p);
|
|
}
|
|
return;
|
|
}
|
|
|
|
void gctl::geodsv_io::fill_column_point2dp(const array<point2dp> &data, std::string rname, std::string cname, int p)
|
|
{
|
|
fill_column_point2dp(data, name_index(rname, false), name_index(cname, false), p);
|
|
return;
|
|
}
|
|
|
|
void gctl::geodsv_io::fill_column_point3dc(const array<point3dc> &data, int xid, int yid, int zid, int p)
|
|
{
|
|
if (xid > col_num_ || yid > col_num_ || zid > col_num_ || xid == yid || yid == zid || xid == zid
|
|
|| xid <= 0 || yid <= 0 || zid <= 0)
|
|
{
|
|
throw std::runtime_error("[gctl::geodsv_io] Invalid column index.");
|
|
}
|
|
|
|
std::stringstream ss;
|
|
std::string s;
|
|
for (size_t i = 1; i <= std::min(row_num_, (int) data.size()); i++)
|
|
{
|
|
table_[i][xid].value(data[i - 1].x, p);
|
|
table_[i][yid].value(data[i - 1].y, p);
|
|
table_[i][zid].value(data[i - 1].z, p);
|
|
}
|
|
return;
|
|
}
|
|
|
|
void gctl::geodsv_io::fill_column_point3dc(const array<point3dc> &data, std::string xname, std::string yname, std::string zname, int p)
|
|
{
|
|
fill_column_point3dc(data, name_index(xname, false), name_index(yname, false), name_index(zname, false), p);
|
|
return;
|
|
}
|
|
|
|
void gctl::geodsv_io::fill_column_point3ds(const array<point3ds> &data, int rid, int pid, int tid, int p)
|
|
{
|
|
if (rid > col_num_ || pid > col_num_ || tid > col_num_ || rid == pid || pid == tid || tid == rid
|
|
|| rid <= 0 || pid <= 0 || tid <= 0)
|
|
{
|
|
throw std::runtime_error("[gctl::geodsv_io] Invalid column index.");
|
|
}
|
|
|
|
std::stringstream ss;
|
|
std::string s;
|
|
for (size_t i = 1; i <= std::min(row_num_, (int) data.size()); i++)
|
|
{
|
|
table_[i][rid].value(data[i - 1].rad, p);
|
|
table_[i][pid].value(data[i - 1].lon, p);
|
|
table_[i][tid].value(data[i - 1].lat, p);
|
|
}
|
|
return;
|
|
}
|
|
|
|
void gctl::geodsv_io::fill_column_point3ds(const array<point3ds> &data, std::string rname, std::string pname, std::string tname, int p)
|
|
{
|
|
fill_column_point3ds(data, name_index(rname, false), name_index(pname, false), name_index(tname, false), p);
|
|
return;
|
|
}
|
|
|
|
void gctl::geodsv_io::get_column_point2dc(array<point2dc> &data, int xid, int yid)
|
|
{
|
|
if (xid > col_num_ || yid > col_num_ || xid == yid || xid <= 0 || yid <= 0)
|
|
{
|
|
throw std::runtime_error("[gctl::geodsv_io] Invalid column index.");
|
|
}
|
|
|
|
data.resize(row_num_);
|
|
for (size_t i = 1; i <= row_num_; i++)
|
|
{
|
|
data[i - 1].x = table_[i][xid].value<double>();
|
|
data[i - 1].y = table_[i][yid].value<double>();
|
|
}
|
|
return;
|
|
}
|
|
|
|
void gctl::geodsv_io::get_column_point2dc(array<point2dc> &data, std::string xname, std::string yname)
|
|
{
|
|
get_column_point2dc(data, name_index(xname, false), name_index(yname, false));
|
|
return;
|
|
}
|
|
|
|
void gctl::geodsv_io::get_column_point2dp(array<point2dp> &data, int rid, int cid)
|
|
{
|
|
if (rid > col_num_ || cid > col_num_ || rid == cid || rid <= 0 || cid <= 0)
|
|
{
|
|
throw std::runtime_error("[gctl::geodsv_io] Invalid column index.");
|
|
}
|
|
|
|
data.resize(row_num_);
|
|
for (size_t i = 1; i <= row_num_; i++)
|
|
{
|
|
data[i - 1].rad = table_[i][rid].value<double>();
|
|
data[i - 1].arc = table_[i][cid].value<double>();
|
|
}
|
|
return;
|
|
}
|
|
|
|
void gctl::geodsv_io::get_column_point2dp(array<point2dp> &data, std::string rname, std::string cname)
|
|
{
|
|
get_column_point2dp(data, name_index(rname, false), name_index(cname, false));
|
|
return;
|
|
}
|
|
|
|
void gctl::geodsv_io::get_column_point3dc(array<point3dc> &data, int xid, int yid, int zid)
|
|
{
|
|
if (xid > col_num_ || yid > col_num_ || zid > col_num_ || xid == yid || yid == zid || xid == zid
|
|
|| xid <= 0 || yid <= 0 || zid <= 0)
|
|
{
|
|
throw std::runtime_error("[gctl::geodsv_io] Invalid column index.");
|
|
}
|
|
|
|
data.resize(row_num_);
|
|
for (size_t i = 1; i <= row_num_; i++)
|
|
{
|
|
data[i - 1].x = table_[i][xid].value<double>();
|
|
data[i - 1].y = table_[i][yid].value<double>();
|
|
data[i - 1].z = table_[i][zid].value<double>();
|
|
}
|
|
return;
|
|
}
|
|
|
|
void gctl::geodsv_io::get_column_point3dc(array<point3dc> &data, std::string xname, std::string yname, std::string zname)
|
|
{
|
|
get_column_point3dc(data, name_index(xname, false), name_index(yname, false), name_index(zname, false));
|
|
return;
|
|
}
|
|
|
|
void gctl::geodsv_io::get_column_point3ds(array<point3ds> &data, int rid, int pid, int tid)
|
|
{
|
|
if (rid > col_num_ || pid > col_num_ || tid > col_num_ || rid == pid || pid == tid || tid == rid
|
|
|| rid <= 0 || pid <= 0 || tid <= 0)
|
|
{
|
|
throw std::runtime_error("[gctl::geodsv_io] Invalid column index.");
|
|
}
|
|
|
|
data.resize(row_num_);
|
|
for (size_t i = 1; i <= row_num_; i++)
|
|
{
|
|
data[i - 1].rad = table_[i][rid].value<double>();
|
|
data[i - 1].lon = table_[i][pid].value<double>();
|
|
data[i - 1].lat = table_[i][tid].value<double>();
|
|
}
|
|
return;
|
|
}
|
|
|
|
void gctl::geodsv_io::get_column_point3ds(array<point3ds> &data, std::string rname, std::string pname, std::string tname)
|
|
{
|
|
get_column_point3ds(data, name_index(rname, false), name_index(pname, false), name_index(tname, false));
|
|
return;
|
|
} |