177 lines
6.0 KiB
C++
177 lines
6.0 KiB
C++
/********************************************************
|
|
* ██████╗ ██████╗████████╗██╗
|
|
* ██╔════╝ ██╔════╝╚══██╔══╝██║
|
|
* ██║ ███╗██║ ██║ ██║
|
|
* ██║ ██║██║ ██║ ██║
|
|
* ╚██████╔╝╚██████╗ ██║ ███████╗
|
|
* ╚═════╝ ╚═════╝ ╚═╝ ╚══════╝
|
|
* 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
|
|
{
|
|
gctl::flags_parser fp;
|
|
fp.set_proname("xyz2sph");
|
|
fp.set_proinfo("Convert coordinates of 3-D points from the Cartesian \
|
|
coordinates to the spherical coordinates, or the other way around. 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. The program \
|
|
takes inputs from the standard input and display the results on screen. The coordinates \
|
|
should be separated by spaces and different points should be placed on different lines. \
|
|
The inputting continues until encounter a blank line or 'EOF'. Any lines start with '#' will be skipped.");
|
|
|
|
fp.add_opt('c', "cartesian", no_argument, NULL,
|
|
"The input points are under the Cartesian coordinates. Point format is <x> <y> <z>.", 0, false);
|
|
fp.add_opt('s', "spherical", no_argument, NULL,
|
|
"The input points are under the spherical coordinates (default). Point format is <rad> <lon> <lat>.", 0, false);
|
|
fp.add_opt('p', "precision", required_argument, NULL,
|
|
"Set the precision of the outputs (the default is 12).", "<precision>", false);
|
|
fp.add_opt('r', "reference", required_argument, NULL,
|
|
"Set a reference system for converting coordinates to the given spherical or ellipsoidal surface.", "<r>/<R>|<f>,<R>|WGS84|Earth|Moon", false);
|
|
fp.add_opt('v', "verbose", no_argument, NULL, "Show full outputs.", 0, false);
|
|
fp.add_opt('h', "help", no_argument, NULL, "Show help information.", 0, false);
|
|
fp.configure(argc, argv);
|
|
|
|
if(fp.set_opt('h'))
|
|
{
|
|
fp.show_help_page();
|
|
return 0;
|
|
}
|
|
|
|
bool verbose = false;
|
|
if (fp.set_opt('v'))
|
|
{
|
|
verbose = true;
|
|
}
|
|
|
|
double ref_r, ref_R;
|
|
std::string err_str, pre_str, ref_str;
|
|
std::stringstream tmp_ss;
|
|
|
|
fp.get_argv({'p', 'r'}, {&pre_str, &ref_str});
|
|
if (pre_str == "NULL") pre_str = "12";
|
|
if (ref_str != "NULL")
|
|
{
|
|
if (ref_str == "WGS84")
|
|
{
|
|
ref_r = GCTL_WGS84_PoleRadius;
|
|
ref_R = GCTL_WGS84_EquatorRadius;
|
|
}
|
|
else if (ref_str == "Earth")
|
|
{
|
|
ref_r = GCTL_Earth_Radius;
|
|
ref_R = GCTL_Earth_Radius;
|
|
}
|
|
else if (ref_str == "Moon")
|
|
{
|
|
ref_r = GCTL_Moon_Radius;
|
|
ref_R = GCTL_Moon_Radius;
|
|
}
|
|
else if (2 != sscanf(ref_str.c_str(), "%lf/%lf", &ref_r, &ref_R))
|
|
{
|
|
if (2 == sscanf(ref_str.c_str(), "%lf,%lf", &ref_r, &ref_R))
|
|
{
|
|
ref_r = (1.0-ref_r)*ref_R;
|
|
}
|
|
else
|
|
{
|
|
err_str = "Wrong entrance: " + ref_str;
|
|
throw err_str;
|
|
}
|
|
}
|
|
}
|
|
|
|
int pre_int;
|
|
gctl::str2type(pre_str, pre_int);
|
|
|
|
std::string line;
|
|
std::vector<std::string> line_arr;
|
|
gctl::point3dc pc;
|
|
gctl::point3ds ps;
|
|
while (true)
|
|
{
|
|
std::getline(std::cin, line);
|
|
if (line[0] == '#') continue;
|
|
if (line.empty() || line == "EOF") break;
|
|
else line_arr.push_back(line);
|
|
}
|
|
|
|
std::cout << "# Outputs from the xyz2sph. Use -h to see the help information." << std::endl;
|
|
if (verbose) std::cout << "# reference system: " << ref_str << std::endl;
|
|
|
|
if (fp.set_opt('c'))
|
|
{
|
|
if (verbose) std::cout << "x,y,z,rad,lon,lat" << std::endl;
|
|
for (int i = 0; i < line_arr.size(); i++)
|
|
{
|
|
tmp_ss.clear();
|
|
tmp_ss.str(line_arr[i]);
|
|
tmp_ss >> pc.x >> pc.y >> pc.z;
|
|
if (tmp_ss.fail())
|
|
{
|
|
err_str = "Wrong entrance: " + line_arr[i];
|
|
throw err_str;
|
|
}
|
|
|
|
ps = pc.c2s();
|
|
if (ref_str != "NULL")
|
|
{
|
|
ps.rad = gctl::ellipse_radius_2d(ref_R, ref_r, ps.lat*GCTL_Pi/180.0);
|
|
pc = ps.s2c();
|
|
}
|
|
|
|
if (verbose) std::cout << std::setprecision(pre_int) << pc.x << "," << pc.y << "," << pc.z << ",";
|
|
std::cout << std::setprecision(pre_int) << ps.rad << "," << ps.lon << "," << ps.lat << std::endl;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (verbose) std::cout << "rad,lon,lat,x,y,z" << std::endl;
|
|
for (int i = 0; i < line_arr.size(); i++)
|
|
{
|
|
tmp_ss.clear();
|
|
tmp_ss.str(line_arr[i]);
|
|
tmp_ss >> ps.rad >> ps.lon >> ps.lat;
|
|
if (tmp_ss.fail())
|
|
{
|
|
err_str = "Wrong entrance: " + line_arr[i];
|
|
throw err_str;
|
|
}
|
|
|
|
if (ref_str != "NULL")
|
|
{
|
|
ps.rad = gctl::ellipse_radius_2d(ref_R, ref_r, ps.lat*GCTL_Pi/180.0);
|
|
}
|
|
pc = ps.s2c();
|
|
|
|
if (verbose) std::cout << std::setprecision(pre_int) << ps.rad << "," << ps.lon << "," << ps.lat << ",";
|
|
std::cout << std::setprecision(pre_int) << pc.x << "," << pc.y << "," << pc.z << std::endl;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
catch(std::exception &e)
|
|
{
|
|
GCTL_ShowWhatError(e.what(), GCTL_ERROR_ERROR, 0, 0, 0);
|
|
} |