2024-09-10 20:25:18 +08:00
/********************************************************
* █ █ █ █ █ █ ╗ █ █ █ █ █ █ ╗ █ █ █ █ █ █ █ █ ╗ █ █ ╗
* █ █ ╔ ═ ═ ═ ═ ╝ █ █ ╔ ═ ═ ═ ═ ╝ ╚ ═ ═ █ █ ╔ ═ ═ ╝ █ █ ║
* █ █ ║ █ █ █ ╗ █ █ ║ █ █ ║ █ █ ║
* █ █ ║ █ █ ║ █ █ ║ █ █ ║ █ █ ║
* ╚ █ █ █ █ █ █ ╔ ╝ ╚ █ █ █ █ █ █ ╗ █ █ ║ █ █ █ █ █ █ █ ╗
* ╚ ═ ═ ═ ═ ═ ╝ ╚ ═ ═ ═ ═ ═ ╝ ╚ ═ ╝ ╚ ═ ═ ═ ═ ═ ═ ╝
* Geophysical Computational Tools & Library ( GCTL )
*
* Copyright ( c ) 2022 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 description of your company and the realm of its activities .
* Also add information on how to contact you by electronic and paper mail .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include "gctl/core.h"
# include "gctl/io.h"
# include "gctl/utility.h"
int main ( int argc , char * argv [ ] ) try
{
std : : string v_str = " Treate all input columns as grid values. Set exact specification of incoming column value table(s). \
Append two chars that indicate file organization : ( 1 ) If data is in row format , state if first row is at T ( op ) or B ( ottom ) . \
Then , append L or R to indicate starting point in row . ( 2 ) If data is in column format , state if first columns is \
L ( left ) or R ( ight ) . Then , append T or B to indicate starting point in column . " ;
gctl : : flags_parser fp ;
fp . set_proname ( " xyz2nc " ) ;
fp . set_proinfo ( " Read xyz data table and write the Netcdf .nc grid files. \
This program is a toolkit of the GCTL package . The GCTL comes with ABSOLUTE NO WARRANTY . \
Please see instructions or contact the author for more information . " );
fp . add_opt ( ' t ' , " table " , required_argument , NULL , " Input data table. " , " <table> " , true ) ;
fp . add_opt ( ' r ' , " range " , required_argument , NULL , " Range of the output grid. " , " <xmin>/<xmax>/<ymin>/<ymax> " , true ) ;
fp . add_opt ( ' i ' , " interval " , required_argument , NULL , " Intervals of output grid " , " <dx>/<dy> " , false ) ;
fp . add_opt ( ' s ' , " size " , required_argument , NULL , " Size of the output grid. " , " <x-size>/<y-size> " , false ) ;
fp . add_opt ( ' g ' , " grid " , required_argument , NULL , " Output grid file. The input table name will be used if not set. " , " <grid> " , false ) ;
fp . add_opt ( ' c ' , " column " , required_argument , NULL , " Column index of x, y and data. The defaults are 0,1,2. Append extra columns to save multiple grids in one file. " , " <x-col>,<y-col>,<z-col>,... " , false ) ;
fp . add_opt ( ' v ' , " value-only " , required_argument , NULL , v_str . c_str ( ) , " T|B|L|R " , false ) ;
fp . add_opt ( ' l ' , " label " , required_argument , NULL , " Labels of x, y and data. The defaults are 'x', 'y' and 'z'. " , " <x-label>,<y-label>,<z-label>,... " , false ) ;
fp . add_opt ( ' e ' , " head-record " , required_argument , NULL , " Input file has [0] Header record(s). " , " <size> " , false ) ;
fp . add_opt ( ' a ' , " annotate " , required_argument , NULL , " The starting symbol of an annotate line. The default is '#'. " , " <sym> " , false ) ;
fp . add_opt ( ' d ' , " delimeter " , required_argument , NULL , " Delimeter between different columns. The default is space. " , " <sym> " , false ) ;
fp . add_opt ( ' h ' , " help " , no_argument , NULL , " Show help information. " , 0 , false ) ;
fp . configure ( argc , argv ) ;
if ( argc = = 1 | | fp . set_opt ( ' h ' ) )
{
fp . show_help_page ( ) ;
return 0 ;
}
std : : string table_name , range_str , interval_str , size_str , grid_name , col_str , label_str , head_str , ant_str , del_str , format_str ;
fp . get_argv ( { ' t ' , ' r ' , ' i ' , ' s ' , ' g ' , ' c ' , ' l ' , ' e ' , ' a ' , ' d ' , ' v ' } ,
{ & table_name , & range_str , & interval_str , & size_str , & grid_name , & col_str , & label_str , & head_str , & ant_str , & del_str , & format_str } ) ;
// 查看是否通过强制参数检查
if ( ! fp . pass_mandatory ( ) ) return 0 ;
if ( grid_name = = " NULL " )
{
size_t dpos = table_name . find_last_of ( ' . ' ) ;
if ( dpos ! = std : : string : : npos ) grid_name = table_name . substr ( 0 , dpos ) ;
else grid_name = table_name ;
}
if ( col_str = = " NULL " ) col_str = " 0,1,2 " ;
bool custom_label = false ;
if ( label_str = = " NULL " ) label_str = " x,y,z " ;
else custom_label = true ;
bool value_only = false ;
if ( format_str ! = " NULL " ) value_only = true ;
2024-09-19 11:24:17 +08:00
std : : string file_ext ;
size_t dpos = table_name . find_last_of ( ' . ' ) ;
if ( dpos ! = std : : string : : npos )
{
file_ext = table_name . substr ( dpos ) ;
table_name = table_name . substr ( 0 , dpos ) ;
}
else file_ext = " .txt " ;
2024-09-10 20:25:18 +08:00
gctl : : text_descriptor desc ;
2024-09-19 11:24:17 +08:00
desc . file_name_ = table_name ;
desc . file_ext_ = file_ext ;
2024-09-10 20:25:18 +08:00
if ( head_str ! = " NULL " ) gctl : : str2type ( head_str , desc . head_num_ ) ;
if ( ant_str ! = " NULL " ) gctl : : str2type ( ant_str , desc . att_sym_ ) ;
if ( del_str ! = " NULL " ) gctl : : str2type ( del_str , desc . delimiter_ ) ;
2024-09-19 11:24:17 +08:00
if ( grid_name = = " NULL " ) grid_name = table_name ;
2024-09-10 20:25:18 +08:00
if ( interval_str = = " NULL " & & size_str = = " NULL " )
{
throw gctl : : runtime_error ( " Either the data intervals or table sizes must be set. See the instructions for more information. " ) ;
}
int tmp_int , maxi_col = - 1 ;
std : : string tmp_str ;
gctl : : _1i_vector col_index ;
std : : stringstream tmp_ss ;
gctl : : str2ss ( col_str , tmp_ss , " , " ) ;
while ( tmp_ss > > tmp_int )
{
col_index . push_back ( tmp_int ) ;
maxi_col = GCTL_MAX ( maxi_col , tmp_int ) ;
}
gctl : : _1s_vector label_index ;
gctl : : str2ss ( label_str , tmp_ss , " , " ) ;
while ( tmp_ss > > tmp_str )
{
label_index . push_back ( tmp_str ) ;
}
if ( ! value_only & & col_index . size ( ) < 3 )
{
GCTL_ShowWhatError ( " Not enough column index found: " , GCTL_ERROR_ERROR ,
col_str . c_str ( ) , " Use -h option to see the instruction. " , 0 ) ;
return 0 ;
}
if ( label_index . size ( ) < 3 )
{
GCTL_ShowWhatError ( " Not enough column labels found: " , GCTL_ERROR_ERROR ,
label_str . c_str ( ) , " Use -h option to see the instruction. " , 0 ) ;
return 0 ;
}
if ( custom_label & & col_index . size ( ) ! = label_index . size ( ) )
{
GCTL_ShowWhatError ( " Number of index and labels not match. " , GCTL_ERROR_ERROR ,
0 , " Use -h option to see the instruction. " , 0 ) ;
return 0 ;
}
gctl : : _2d_vector table_data ;
2024-09-19 11:24:17 +08:00
gctl : : read_text2vector2d ( desc , table_data ) ;
2024-09-10 20:25:18 +08:00
// check data
for ( int i = 0 ; i < table_data . size ( ) ; i + + )
{
if ( table_data [ i ] . size ( ) < maxi_col + 1 )
{
GCTL_ShowWhatError ( " Incomplete data set found in: " , GCTL_ERROR_ERROR , table_name . c_str ( ) , 0 , 0 ) ;
return 0 ;
}
}
int xnum , ynum ;
double xmin , xmax , ymin , ymax , dx , dy ;
gctl : : parse_string_to_value ( range_str , ' / ' , true , xmin , xmax , ymin , ymax ) ;
if ( interval_str ! = " NULL " )
{
gctl : : parse_string_to_value ( interval_str , ' / ' , true , dx , dy ) ;
xnum = round ( ( xmax - xmin ) / dx ) + 1 ;
ynum = round ( ( ymax - ymin ) / dy ) + 1 ;
}
else
{
gctl : : parse_string_to_value ( size_str , ' / ' , true , xnum , ynum ) ;
dx = ( xmax - xmin ) / ( xnum - 1.0 ) ;
dy = ( ymax - ymin ) / ( ynum - 1.0 ) ;
}
gctl : : array < double > out_data ( xnum * ynum , GCTL_BDL_MAX ) ;
int tmp_M , tmp_N ;
if ( value_only )
{
gctl : : array < int > val_idx ( table_data . size ( ) ) ;
if ( format_str = = " TL " )
{
for ( int i = 0 ; i < ynum ; i + + )
{
for ( int j = 0 ; j < xnum ; j + + )
{
val_idx [ j + xnum * i ] = xnum * ( ynum - 1 - i ) + j ;
}
}
}
else if ( format_str = = " TR " )
{
for ( int i = 0 ; i < ynum ; i + + )
{
for ( int j = 0 ; j < xnum ; j + + )
{
val_idx [ j + xnum * i ] = xnum * ( ynum - 1 - i ) + xnum - 1 - j ;
}
}
}
else if ( format_str = = " BL " )
{
for ( int i = 0 ; i < val_idx . size ( ) ; i + + )
{
val_idx [ i ] = i ;
}
}
else if ( format_str = = " BR " )
{
for ( int i = 0 ; i < ynum ; i + + )
{
for ( int j = 0 ; j < xnum ; j + + )
{
val_idx [ j + xnum * i ] = xnum * i + xnum - 1 - j ;
}
}
}
else if ( format_str = = " LT " )
{
for ( int j = 0 ; j < xnum ; j + + )
{
for ( int i = 0 ; i < ynum ; i + + )
{
val_idx [ i + ynum * j ] = xnum * ( ynum - 1 - i ) + j ;
}
}
}
else if ( format_str = = " RT " )
{
for ( int j = 0 ; j < xnum ; j + + )
{
for ( int i = 0 ; i < ynum ; i + + )
{
val_idx [ i + ynum * j ] = xnum * ( ynum - 1 - i ) + xnum - 1 - j ;
}
}
}
else if ( format_str = = " LB " )
{
for ( int j = 0 ; j < xnum ; j + + )
{
for ( int i = 0 ; i < ynum ; i + + )
{
val_idx [ i + ynum * j ] = xnum * i + j ;
}
}
}
else if ( format_str = = " RB " )
{
for ( int j = 0 ; j < xnum ; j + + )
{
for ( int i = 0 ; i < ynum ; i + + )
{
val_idx [ i + ynum * j ] = xnum * i + xnum - 1 - j ;
}
}
}
for ( int i = 0 ; i < table_data . size ( ) ; i + + )
{
out_data [ val_idx [ i ] ] = table_data [ i ] [ col_index [ 0 ] ] ;
}
gctl : : save_netcdf_grid ( grid_name , out_data , xnum , ynum , xmin , dx , ymin , dy ,
label_index [ 0 ] , label_index [ 1 ] , label_index [ 2 ] ) ;
std : : string save_dataname ;
if ( col_index . size ( ) > 1 )
{
for ( int c = 1 ; c < col_index . size ( ) ; c + + )
{
2025-02-11 10:43:28 +08:00
out_data . assign ( GCTL_BDL_MAX ) ;
2024-09-10 20:25:18 +08:00
for ( int i = 0 ; i < table_data . size ( ) ; i + + )
{
out_data [ val_idx [ i ] ] = table_data [ i ] [ col_index [ c ] ] ;
}
if ( custom_label )
save_dataname = label_index [ c ] ;
else
save_dataname = label_index [ 2 ] + " _ " + std : : to_string ( c - 1 ) ;
gctl : : append_netcdf_grid ( grid_name , out_data , label_index [ 0 ] , label_index [ 1 ] , save_dataname ) ;
}
}
}
else
{
for ( int i = 0 ; i < table_data . size ( ) ; i + + )
{
if ( table_data [ i ] [ col_index [ 0 ] ] > = xmin & & table_data [ i ] [ col_index [ 0 ] ] < = xmax & &
table_data [ i ] [ col_index [ 1 ] ] > = ymin & & table_data [ i ] [ col_index [ 1 ] ] < = ymax )
{
tmp_N = round ( ( table_data [ i ] [ col_index [ 0 ] ] - xmin ) / dx ) ;
tmp_M = round ( ( table_data [ i ] [ col_index [ 1 ] ] - ymin ) / dy ) ;
out_data [ tmp_M * xnum + tmp_N ] = table_data [ i ] [ col_index [ 2 ] ] ;
}
}
gctl : : save_netcdf_grid ( grid_name , out_data , xnum , ynum , xmin , dx , ymin , dy ,
label_index [ 0 ] , label_index [ 1 ] , label_index [ 2 ] ) ;
std : : string save_dataname ;
if ( col_index . size ( ) > 3 )
{
for ( int c = 3 ; c < col_index . size ( ) ; c + + )
{
2025-02-11 10:43:28 +08:00
out_data . assign ( GCTL_BDL_MAX ) ;
2024-09-10 20:25:18 +08:00
for ( int i = 0 ; i < table_data . size ( ) ; i + + )
{
if ( table_data [ i ] [ col_index [ 0 ] ] > = xmin & & table_data [ i ] [ col_index [ 0 ] ] < = xmax & &
table_data [ i ] [ col_index [ 1 ] ] > = ymin & & table_data [ i ] [ col_index [ 1 ] ] < = ymax )
{
tmp_N = round ( ( table_data [ i ] [ col_index [ 0 ] ] - xmin ) / dx ) ;
tmp_M = round ( ( table_data [ i ] [ col_index [ 1 ] ] - ymin ) / dy ) ;
out_data [ tmp_M * xnum + tmp_N ] = table_data [ i ] [ col_index [ c ] ] ;
}
}
if ( custom_label )
save_dataname = label_index [ c ] ;
else
save_dataname = label_index [ 2 ] + " _ " + std : : to_string ( c - 1 ) ;
gctl : : append_netcdf_grid ( grid_name , out_data , label_index [ 0 ] , label_index [ 1 ] , save_dataname ) ;
}
}
}
return 0 ;
}
catch ( std : : exception & e )
{
GCTL_ShowWhatError ( e . what ( ) , GCTL_ERROR_ERROR , 0 , 0 , 0 ) ;
}