initial upload
This commit is contained in:
24
sph2plane/CMakeLists.txt
Normal file
24
sph2plane/CMakeLists.txt
Normal file
@@ -0,0 +1,24 @@
|
||||
set(TOOL_NAME sph2plane)
|
||||
set(BIN_DIR bin)
|
||||
set(INSTALL_DIR sbin)
|
||||
|
||||
find_package(GCTL REQUIRED)
|
||||
include_directories(${GCTL_INC_DIR})
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3")
|
||||
if(WIN32)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
|
||||
else()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
|
||||
endif()
|
||||
|
||||
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/${BIN_DIR})
|
||||
|
||||
aux_source_directory(. TOOL_SRC)
|
||||
add_executable(${TOOL_NAME} ${TOOL_SRC})
|
||||
set_target_properties(${TOOL_NAME} PROPERTIES INSTALL_RPATH /usr/local/lib)
|
||||
set_target_properties(${TOOL_NAME} PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
target_link_libraries(${TOOL_NAME} PUBLIC ${GCTL_LIB})
|
||||
|
||||
install(TARGETS ${TOOL_NAME} RUNTIME DESTINATION ${INSTALL_DIR})
|
235
sph2plane/sph2plane.cpp
Normal file
235
sph2plane/sph2plane.cpp
Normal file
@@ -0,0 +1,235 @@
|
||||
/********************************************************
|
||||
* ██████╗ ██████╗████████╗██╗
|
||||
* ██╔════╝ ██╔════╝╚══██╔══╝██║
|
||||
* ██║ ███╗██║ ██║ ██║
|
||||
* ██║ ██║██║ ██║ ██║
|
||||
* ╚██████╔╝╚██████╗ ██║ ███████╗
|
||||
* ╚═════╝ ╚═════╝ ╚═╝ ╚══════╝
|
||||
* 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("sph2plane");
|
||||
fp.set_proinfo("Project spherical data points to a plane surface with respected to \
|
||||
a reference point. 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('a', "anchor", required_argument, NULL,
|
||||
"The reference point (anchor) for the project.", "<lon>,<lat>", true);
|
||||
fp.add_opt('r', "reference", required_argument, NULL,
|
||||
"Set a reference system for converting the coordinates according to the specified spherical or ellipsoidal surface.", "<r>/<R>|<f>,<R>|WGS84|Earth|Moon", true);
|
||||
fp.add_opt('u', "unit-length", no_argument, NULL,
|
||||
"Use the unit-length at the reference point to project all data points. This is often required to get unified intervals for grid data points.", 0, false);
|
||||
fp.add_opt('c', "column", required_argument, NULL,
|
||||
"Select data columns for the longitudinal and latitudinal coordinates (the default is 0,1).", "<lon-col>,<lat-col>", false);
|
||||
fp.add_opt('p', "precision", required_argument, NULL,
|
||||
"Set the precision of the outputs (the default is 12).", "<precision>", 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;
|
||||
}
|
||||
|
||||
// 查看是否通过强制参数检查
|
||||
if (!fp.pass_mandatory()) return 0;
|
||||
|
||||
bool use_unit = false;
|
||||
if (fp.set_opt('u'))
|
||||
{
|
||||
use_unit = true;
|
||||
}
|
||||
|
||||
std::string err_str, anchor_str, ref_str, col_str, pre_str;
|
||||
std::stringstream tmp_ss;
|
||||
|
||||
fp.get_argv({'a', 'r', 'c', 'p'}, {&anchor_str, &ref_str, &col_str, &pre_str});
|
||||
// 确定参考点
|
||||
double ref_lon = -200.0, ref_lat = -100.0;
|
||||
if (2 != sscanf(anchor_str.c_str(), "%lf,%lf", &ref_lon, &ref_lat) ||
|
||||
ref_lon < -180.0 || ref_lon > 180.0 || ref_lat < -90.0 || ref_lat > 90.0)
|
||||
{
|
||||
err_str = "Wrong entrance: " + anchor_str;
|
||||
throw err_str;
|
||||
}
|
||||
|
||||
// 确定参考球
|
||||
double ref_r, ref_R;
|
||||
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 col_lon, col_lat;
|
||||
if (col_str == "NULL") col_str = "0,1";
|
||||
if (2 != sscanf(col_str.c_str(), "%d,%d", &col_lon, &col_lat))
|
||||
{
|
||||
err_str = "Wrong entrance: " + col_str;
|
||||
throw err_str;
|
||||
}
|
||||
|
||||
// 确定输出精度
|
||||
int pre_int;
|
||||
if (pre_str == "NULL") pre_str = "12";
|
||||
if (1 != sscanf(pre_str.c_str(), "%d", &pre_int))
|
||||
{
|
||||
err_str = "Wrong entrance: " + pre_str;
|
||||
throw err_str;
|
||||
}
|
||||
|
||||
std::string line;
|
||||
std::vector<std::string> line_arr;
|
||||
std::vector<double> line_ele;
|
||||
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 sph2plane. Use -h to see the help information." << std::endl;
|
||||
std::cout << "# reference system: " << ref_str << std::endl;
|
||||
std::cout << "# reference coordinate: lon = " << ref_lon << ", lat = " << ref_lat << std::endl;
|
||||
|
||||
double rad, rad_lat, unit_yl, unit_xl, tmp_d;
|
||||
double point_lon, point_lat;
|
||||
if (use_unit)
|
||||
{
|
||||
// 计算参考点处的经纬向单位长度
|
||||
rad = gctl::ellipse_radius_2d(ref_R, ref_r, ref_lat*GCTL_Pi/180.0);
|
||||
unit_yl = rad*tan(1.0*GCTL_Pi/180.0);
|
||||
|
||||
rad_lat = rad*sin(GCTL_Pi*(90.0 - ref_lat)/180.0);
|
||||
unit_xl = rad_lat*tan(1.0*GCTL_Pi/180.0);
|
||||
|
||||
for (int i = 0; i < line_arr.size(); i++)
|
||||
{
|
||||
if (!line_ele.empty()) line_ele.clear();
|
||||
|
||||
tmp_ss.clear();
|
||||
tmp_ss.str(line_arr[i]);
|
||||
while (tmp_ss.good())
|
||||
{
|
||||
tmp_ss >> tmp_d;
|
||||
line_ele.push_back(tmp_d);
|
||||
}
|
||||
|
||||
if (line_ele.size() <= GCTL_MAX(col_lon, col_lat))
|
||||
{
|
||||
err_str = "Wrong entrance: " + line_arr[i];
|
||||
throw err_str;
|
||||
}
|
||||
|
||||
point_lon = line_ele[col_lon];
|
||||
point_lat = line_ele[col_lat];
|
||||
|
||||
line_ele[col_lon] = (point_lon - ref_lon)*unit_xl;
|
||||
line_ele[col_lat] = (point_lat - ref_lat)*unit_yl;
|
||||
|
||||
std::cout << std::setprecision(pre_int) << line_ele[0];
|
||||
for (int l = 1; l < line_ele.size(); l++)
|
||||
{
|
||||
std::cout << std::setprecision(pre_int) << " " << line_ele[l];
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < line_arr.size(); i++)
|
||||
{
|
||||
if (!line_ele.empty()) line_ele.clear();
|
||||
|
||||
tmp_ss.clear();
|
||||
tmp_ss.str(line_arr[i]);
|
||||
while (tmp_ss.good())
|
||||
{
|
||||
tmp_ss >> tmp_d;
|
||||
line_ele.push_back(tmp_d);
|
||||
}
|
||||
|
||||
if (line_ele.size() <= GCTL_MAX(col_lon, col_lat))
|
||||
{
|
||||
err_str = "Wrong entrance: " + line_arr[i];
|
||||
throw err_str;
|
||||
}
|
||||
|
||||
point_lon = line_ele[col_lon];
|
||||
point_lat = line_ele[col_lat];
|
||||
|
||||
// 计算参考点处的经纬向单位长度
|
||||
rad = gctl::ellipse_radius_2d(ref_R, ref_r, ref_lat*GCTL_Pi/180.0);
|
||||
rad_lat = rad*sin(GCTL_Pi*(90.0 - ref_lat)/180.0);
|
||||
|
||||
line_ele[col_lat] = rad*tan((point_lat - ref_lat)*GCTL_Pi/180.0);
|
||||
line_ele[col_lon] = rad_lat*tan((point_lon - ref_lon)*GCTL_Pi/180.0);
|
||||
|
||||
std::cout << std::setprecision(pre_int) << line_ele[0];
|
||||
for (int l = 1; l < line_ele.size(); l++)
|
||||
{
|
||||
std::cout << std::setprecision(pre_int) << " " << line_ele[l];
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
catch(std::exception &e)
|
||||
{
|
||||
GCTL_ShowWhatError(e.what(), GCTL_ERROR_ERROR, 0, 0, 0);
|
||||
}
|
Reference in New Issue
Block a user