/*------------------------------------------------------------------------------ * Copyright (c) 2023 by Bai Bing (seread@163.com) * See COPYING file for copying and redistribution conditions. * * Alians IT Studio. *----------------------------------------------------------------------------*/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "params.h" #include "version.h" #include "SurfaceGridWrapper.h" #include "utils/pystring.h" void parse_args(int argc, char **argv, ais::Settings &settings) { // parse params char c; int optIndex = 0; std::set onParams = {"on", "1", "true", "yes"}; while (-1 != (c = ais::getopt_long_2(argc, argv, ais::shortopts, ais::longopts, &optIndex, &ais::optarg2))) { switch (c) { case 's': settings.randomsFilename = ais::optarg2; break; case 't': settings.concernPointsFilename = ais::optarg2; break; case 'c': { int count = atoi(ais::optarg2); // only use mock random points when specified this option settings.useMockRandoms = true; settings.mockRandomCount = count ? count : 200; // default is 200 break; } case 'd': { std::string strArea = ais::optarg2; std::vector vec = pystring::split(strArea, ","); if (vec.size() >= 4) { settings.area.xMin = std::atof(vec[0].c_str()); settings.area.yMin = std::atof(vec[1].c_str()); settings.area.xMax = std::atof(vec[2].c_str()); settings.area.yMax = std::atof(vec[3].c_str()); } } break; case 'b': settings.breaklinesFilename = ais::optarg2; break; case 'a': settings.faultsFilename = ais::optarg2; break; case 'x': settings.xCount = atoi(ais::optarg2); break; case 'y': settings.yCount = atoi(ais::optarg2); break; case 'X': settings.targetXGridSize = atof(ais::optarg2); break; case 'Y': settings.targetYGridSize = atof(ais::optarg2); break; case 'i': settings.maxIteration = atoi(ais::optarg2); break; case 'r': settings.residual = atof(ais::optarg2); break; case 'f': settings.fillValue = atof(ais::optarg2); break; case 'e': settings.estimateFactor = atoi(ais::optarg2); break; case 'n': settings.contourStep = atof(ais::optarg2); break; case 'u': settings.contourMarkStep = atoi(ais::optarg2); break; case 'g': settings.insertTimes = atoi(ais::optarg2); break; case 'p': settings.smoothTimes = atoi(ais::optarg2); break; case 'w': { // corner weight should between 4~256 int v = atoi(ais::optarg2); if (v < 4) v = 4; if (v > 256) v = 256; settings.cornerWeight = v; break; } case 'm': { std::string value = ais::optarg2; value = ais::tolower(value); settings.useMultiThread = onParams.find(value.c_str()) != onParams.end(); break; } case 'o': { settings.outputFilename = ais::optarg2; if (settings.outputFilename.empty()) settings.outputFilename = "output.grd"; break; } case 'l': { // 0 add fault point with out any constrict, default is 0 // 1-4 add fault point with different constrict level, 1-less 4-more auto faultEdgeLevel = (ais::optarg2 != NULL) ? atoi(ais::optarg2) : 0; if (faultEdgeLevel < 0 || faultEdgeLevel > 4) { std::cout << "Invalid param, the fault edge level must between 0 and 4, default is 0" << std::endl; exit(-1); } settings.faultEdgeLevel = faultEdgeLevel; break; } case '?': case 'h': ais::usage(argv[0]); exit(EXIT_SUCCESS); case 'v': std::cout << ais::VERSION << std::endl; exit(EXIT_SUCCESS); } } } static std::vector WideArgsToNarrow(int wargc, LPWSTR* wargv) { std::vector result; for (int i = 0; i < wargc; i++) { result.push_back(WstringToString(wargv[i])); } return result; } static std::vector VectorToArgv(const std::vector &argv) { std::vector argvPointers; for (auto &arg : argv) { argvPointers.push_back(const_cast(arg.c_str())); } return argvPointers; } int WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, PSTR cmdline, int cmdshow) { ais::Settings settings; // MFC 不采用传统的 main 作入口,而且命令行参数是宽字符, // 但是 parse_args 需要传统的 int argc, char **argv 作为参数 // 这里进行转换 int wargc = 0; LPWSTR *wargv = CommandLineToArgvW(GetCommandLineW(), &wargc); std::vector narrowArgs = WideArgsToNarrow(wargc, wargv); std::vector argvPointers = VectorToArgv(narrowArgs); int argc = static_cast(argvPointers.size()); char **argv = argvPointers.data(); parse_args(argc, argv, settings); std::wstring sourcePointFile = StringToWstring(settings.randomsFilename); std::wstring faultFile = StringToWstring(settings.faultsFilename); std::wstring borderFile = StringToWstring(settings.breaklinesFilename); size_t xNodeCount = settings.xCount; int maxIteration = settings.maxIteration; double residual = settings.residual; double fillValue = settings.fillValue; int faultEdgeLevel = settings.faultEdgeLevel; std::wstring outputFile = StringToWstring(settings.outputFilename); int estimateFactor = settings.estimateFactor; double cornerWeight = settings.cornerWeight; double contourStep = settings.contourStep; int contourMarkStep = settings.contourMarkStep; int insertTimes = settings.insertTimes; int smoothTimes = settings.smoothTimes; double xMin = settings.area.xMin; double yMin = settings.area.yMin; double xMax = settings.area.xMax; double yMax = settings.area.yMax; if (BuildMinCurvatureGrid3Impl(sourcePointFile.c_str(), faultFile.c_str(), borderFile.c_str(), xNodeCount, maxIteration, residual, fillValue, faultEdgeLevel, outputFile.c_str(), estimateFactor, cornerWeight, contourStep, contourMarkStep, insertTimes, smoothTimes, xMin, yMin, xMax, yMax)) { return EXIT_SUCCESS; } return EXIT_FAILURE; }