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/io.h"
# include "gctl/utility.h"
int main ( int argc , char * argv [ ] ) try
{
gctl : : flags_parser fp ;
fp . set_proname ( " nc2other " ) ;
fp . set_proinfo ( " Extract data sets from a Netcdf's .nc file and save to a text file. \
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 ( ' i ' , " in-file " , required_argument , NULL , " Input file name. " , " <file-name> " , true ) ;
fp . add_opt ( ' o ' , " out-file " , required_argument , NULL , " Output file name. The input file name will be used if this option was not set. " , " <file-name> " , false ) ;
fp . add_opt ( ' d ' , " data-set " , required_argument , NULL , " Names of the target data set separated by commas. The default is 'z'. " , " <data-name>,<data-name>,... " , false ) ;
fp . add_opt ( ' x ' , " x-axis " , required_argument , NULL , " Name of the x-axis. The default is 'x'. " , " <axis-name> " , false ) ;
fp . add_opt ( ' y ' , " y-axis " , required_argument , NULL , " Name of the y-axis. The default is 'y'. " , " <axis-name> " , false ) ;
fp . add_opt ( ' l ' , " delimiter " , required_argument , NULL , " Delimiter of the output data table. The default is space. " , " <delimiter> " , false ) ;
fp . add_opt ( ' t ' , " out-type " , required_argument , NULL , " Output file type. 'txt' for ASCII text file (default), 'grd6' for Surface 6 text grid, 'grd7' for Surface 7 binary grid. " , " <id> " , false ) ;
fp . add_opt ( ' u ' , " upper-left " , no_argument , NULL , " Output the grid data from the upper-left corner to the down-right corner. The default is from the down-left corner to the upper-right corner. " , 0 , 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 in_name , out_name , data_name , x_name , y_name , del_str , type_str ;
fp . get_argv (
{ ' i ' , ' o ' , ' d ' , ' x ' , ' y ' , ' l ' , ' t ' } ,
{ & in_name , & out_name , & data_name , & x_name , & y_name , & del_str , & type_str }
) ;
// 查看是否通过强制参数检查
if ( ! fp . pass_mandatory ( ) ) return 0 ;
if ( out_name = = " NULL " ) out_name = in_name . substr ( 0 , in_name . length ( ) - 3 ) ;
if ( x_name = = " NULL " ) x_name = " x " ;
if ( y_name = = " NULL " ) y_name = " y " ;
if ( data_name = = " NULL " ) data_name = " z " ;
if ( del_str = = " NULL " ) del_str = " " ;
if ( type_str = = " NULL " ) type_str = " txt " ;
bool from_tl = false ;
if ( fp . set_opt ( ' u ' ) ) from_tl = true ;
gctl : : _1s_vector name_vec ;
gctl : : parse_string_to_vector ( data_name , ' , ' , name_vec ) ;
gctl : : _1d_array out_x , out_y , one_data ;
gctl : : _2d_vector out_data ;
out_data . resize ( name_vec . size ( ) + 2 ) ; // 预留网格节点坐标所在的列
for ( int i = 0 ; i < name_vec . size ( ) ; i + + )
{
gctl : : read_netcdf_axis ( in_name . substr ( 0 , in_name . length ( ) - 3 ) , out_x , x_name ) ;
gctl : : read_netcdf_axis ( in_name . substr ( 0 , in_name . length ( ) - 3 ) , out_y , y_name ) ;
gctl : : read_netcdf_grid ( in_name . substr ( 0 , in_name . length ( ) - 3 ) , one_data , x_name , y_name , name_vec [ i ] ) ;
out_data [ 2 + i ] . resize ( one_data . size ( ) ) ;
for ( int j = 0 ; j < one_data . size ( ) ; j + + )
{
out_data [ 2 + i ] [ j ] = one_data [ j ] ;
}
}
// 添加网格节点坐标
int xsize = out_x . size ( ) ;
int ysize = out_y . size ( ) ;
out_data [ 0 ] . resize ( xsize * ysize ) ;
out_data [ 1 ] . resize ( xsize * ysize ) ;
for ( int j = 0 ; j < ysize ; j + + )
{
for ( int i = 0 ; i < xsize ; i + + )
{
out_data [ 0 ] [ i + j * xsize ] = out_x [ i ] ;
out_data [ 1 ] [ i + j * xsize ] = out_y [ j ] ;
}
}
if ( from_tl )
{
double tmp_data ;
int half_y = ysize / 2 ;
// swap y corrdinates and data
for ( size_t j = 0 ; j < half_y ; j + + )
{
for ( size_t i = 0 ; i < xsize ; i + + )
{
tmp_data = out_data [ 1 ] [ i + j * xsize ] ; out_data [ 1 ] [ i + j * xsize ] = out_data [ 1 ] [ i + ( ysize - 1 - j ) * xsize ] ; out_data [ 1 ] [ i + ( ysize - 1 - j ) * xsize ] = tmp_data ;
for ( int k = 2 ; k < name_vec . size ( ) + 2 ; k + + )
{
tmp_data = out_data [ k ] [ i + j * xsize ] ; out_data [ k ] [ i + j * xsize ] = out_data [ k ] [ i + ( ysize - 1 - j ) * xsize ] ; out_data [ k ] [ i + ( ysize - 1 - j ) * xsize ] = tmp_data ;
}
}
}
}
std : : vector < std : : string > head_info ( 1 ) ;
head_info [ 0 ] = x_name + del_str + y_name ;
for ( int i = 0 ; i < name_vec . size ( ) ; i + + )
{
head_info [ 0 ] + = del_str + name_vec [ i ] ;
}
// 保存文本文件
if ( type_str = = " txt " )
{
2024-09-19 11:24:17 +08:00
gctl : : text_descriptor desc ;
desc . file_name_ = out_name ;
desc . delimiter_ = del_str [ 0 ] ;
desc . head_strs_ = head_info ;
if ( del_str = = " , " ) desc . file_ext_ = " .csv " ;
2024-09-10 20:25:18 +08:00
2024-09-19 11:24:17 +08:00
gctl : : save_vector2d2text ( desc , out_data , gctl : : ColMajor ) ;
2024-09-10 20:25:18 +08:00
return 0 ;
}
double xmin = GCTL_BDL_MAX , xmax = GCTL_BDL_MIN ;
for ( int i = 0 ; i < xsize ; i + + )
{
xmin = std : : min ( xmin , out_x [ i ] ) ;
xmax = std : : max ( xmax , out_x [ i ] ) ;
}
double ymin = GCTL_BDL_MAX , ymax = GCTL_BDL_MIN ;
for ( int i = 0 ; i < ysize ; i + + )
{
ymin = std : : min ( ymin , out_y [ i ] ) ;
ymax = std : : max ( ymax , out_y [ i ] ) ;
}
double dx = ( xmax - xmin ) / ( xsize - 1 ) ;
double dy = ( ymax - ymin ) / ( ysize - 1 ) ;
gctl : : array < double > tmp_data ( xsize * ysize ) ;
if ( type_str = = " grd6 " )
{
for ( int i = 0 ; i < name_vec . size ( ) ; i + + )
{
for ( size_t j = 0 ; j < xsize * ysize ; j + + )
{
tmp_data [ j ] = out_data [ i + 2 ] [ j ] ;
}
gctl : : save_surfer6_grid ( out_name + " _ " + name_vec [ i ] , tmp_data , xsize , ysize , xmin , xmax , ymin , ymax ) ;
}
}
else if ( type_str = = " grd7 " )
{
for ( int i = 0 ; i < name_vec . size ( ) ; i + + )
{
for ( size_t j = 0 ; j < xsize * ysize ; j + + )
{
tmp_data [ j ] = out_data [ i + 2 ] [ j ] ;
}
gctl : : save_surfer7_grid ( out_name + " _ " + name_vec [ i ] , tmp_data , xsize , ysize , xmin , ymin , dx , dy ) ;
}
}
else throw std : : runtime_error ( " Invalid output file type. " ) ;
return 0 ;
}
catch ( std : : exception & e )
{
GCTL_ShowWhatError ( e . what ( ) , GCTL_ERROR_ERROR , 0 , 0 , 0 ) ;
}