diff options
| author | Even Rouault <even.rouault@spatialys.com> | 2018-12-19 12:25:33 +0100 |
|---|---|---|
| committer | Even Rouault <even.rouault@spatialys.com> | 2018-12-26 10:08:54 +0100 |
| commit | e6de172371ea203f6393d745641d66c82b5b13e2 (patch) | |
| tree | 791fa07f431a2d1db6f6e813ab984db982587278 /src/projinfo.cpp | |
| parent | ce8075076b4e4ffebd32afaba419e1d9ab27cd03 (diff) | |
| download | PROJ-e6de172371ea203f6393d745641d66c82b5b13e2.tar.gz PROJ-e6de172371ea203f6393d745641d66c82b5b13e2.zip | |
cpp conversion: move source files in apps/ iso19111/ conversions/ projections/ transformations/ tests/ subdirectories
Diffstat (limited to 'src/projinfo.cpp')
| -rw-r--r-- | src/projinfo.cpp | 1067 |
1 files changed, 0 insertions, 1067 deletions
diff --git a/src/projinfo.cpp b/src/projinfo.cpp deleted file mode 100644 index d604365a..00000000 --- a/src/projinfo.cpp +++ /dev/null @@ -1,1067 +0,0 @@ -/****************************************************************************** - * - * Project: PROJ - * Purpose: projinfo utility - * Author: Even Rouault <even dot rouault at spatialys dot com> - * - ****************************************************************************** - * Copyright (c) 2018, Even Rouault <even dot rouault at spatialys dot com> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - ****************************************************************************/ - -//! @cond Doxygen_Suppress - -#define FROM_PROJ_CPP - -#include <cstdlib> -#include <fstream> // std::ifstream -#include <iostream> -#include <utility> - -#include "projects.h" - -#include <proj/common.hpp> -#include <proj/coordinateoperation.hpp> -#include <proj/crs.hpp> -#include <proj/io.hpp> -#include <proj/metadata.hpp> -#include <proj/util.hpp> - -#include "proj/internal/internal.hpp" // for split - -using namespace NS_PROJ::common; -using namespace NS_PROJ::crs; -using namespace NS_PROJ::io; -using namespace NS_PROJ::metadata; -using namespace NS_PROJ::operation; -using namespace NS_PROJ::util; -using namespace NS_PROJ::internal; - -// --------------------------------------------------------------------------- - -namespace { // anonymous namespace -struct OutputOptions { - bool quiet = false; - bool PROJ5 = false; - bool PROJ4 = false; - bool WKT2_2018 = false; - bool WKT2_2018_SIMPLIFIED = false; - bool WKT2_2015 = false; - bool WKT2_2015_SIMPLIFIED = false; - bool WKT1_GDAL = false; - bool WKT1_ESRI = false; - bool c_ify = false; - bool singleLine = false; -}; -} // anonymous namespace - -// --------------------------------------------------------------------------- - -static void usage() { - std::cerr - << "usage: projinfo [-o formats] [-k crs|operation] [--summary] [-q]" - << std::endl - << " ([--area name_or_code] | " - "[--bbox min_long,min_lat,max_long,max_lat]) " - << std::endl - << " [--spatial-test contains|intersects]" << std::endl - << " [--crs-extent-use none|both|intersection|smallest]" - << std::endl - << " [--grid-check none|discard_missing|sort] " - "[--show-superseded]" - << std::endl - << " [--pivot-crs none|{auth:code[,auth:code]*}]" - << std::endl - << " [--boundcrs-to-wgs84]" << std::endl - << " [--main-db-path path] [--aux-db-path path]*" - << std::endl - << " [--identify]" << std::endl - << " [--c-ify] [--single-line]" << std::endl - << " {object_definition} | (-s {srs_def} -t {srs_def})" - << std::endl; - std::cerr << std::endl; - std::cerr << "-o: formats is a comma separated combination of: " - "all,default,PROJ4,PROJ,WKT_ALL,WKT2_2015,WKT2_2018,WKT1_GDAL," - "WKT1_ESRI" - << std::endl; - std::cerr << " Except 'all' and 'default', other format can be preceded " - "by '-' to disable them" - << std::endl; - std::cerr << std::endl; - std::cerr << "{object_definition} might be a PROJ string, a WKT string, " - " a AUTHORITY:CODE, or urn:ogc:def:OBJECT_TYPE:AUTHORITY::CODE" - << std::endl; - std::exit(1); -} - -// --------------------------------------------------------------------------- - -static std::string un_c_ify_string(const std::string &str) { - std::string out(str); - out = out.substr(1, out.size() - 2); - out = replaceAll(out, "\\\"", "{ESCAPED_DOUBLE_QUOTE}"); - out = replaceAll(out, "\\n\"", ""); - out = replaceAll(out, "\"", ""); - out = replaceAll(out, "{ESCAPED_DOUBLE_QUOTE}", "\""); - return out; -} - -// --------------------------------------------------------------------------- - -static std::string c_ify_string(const std::string &str) { - std::string out(str); - out = replaceAll(out, "\"", "{DOUBLE_QUOTE}"); - out = replaceAll(out, "\n", "\\n\"\n\""); - out = replaceAll(out, "{DOUBLE_QUOTE}", "\\\""); - return "\"" + out + "\""; -} - -// --------------------------------------------------------------------------- - -static BaseObjectNNPtr buildObject(DatabaseContextPtr dbContext, - const std::string &user_string, - bool kindIsCRS, const std::string &context, - bool buildBoundCRSToWGS84, bool allowPivots, - bool quiet) { - BaseObjectPtr obj; - - std::string l_user_string(user_string); - if (!user_string.empty() && user_string[0] == '@') { - std::ifstream fs; - auto filename = user_string.substr(1); - fs.open(filename, std::fstream::in | std::fstream::binary); - if (!fs.is_open()) { - std::cerr << context << ": cannot open " << filename << std::endl; - std::exit(1); - } - l_user_string.clear(); - while (!fs.eof()) { - char buffer[256]; - fs.read(buffer, sizeof(buffer)); - l_user_string.append(buffer, static_cast<size_t>(fs.gcount())); - if (l_user_string.size() > 100 * 1000) { - fs.close(); - std::cerr << context << ": too big file" << std::endl; - std::exit(1); - } - } - fs.close(); - } - if (!l_user_string.empty() && l_user_string.back() == '\n') { - l_user_string.resize(l_user_string.size() - 1); - } - if (!l_user_string.empty() && l_user_string.back() == '\r') { - l_user_string.resize(l_user_string.size() - 1); - } - - try { - auto tokens = split(l_user_string, ':'); - if (!kindIsCRS && tokens.size() == 2) { - auto urn = "urn:ogc:def:coordinateOperation:" + tokens[0] + "::" + - tokens[1]; - obj = createFromUserInput(urn, dbContext).as_nullable(); - } else { - // Convenience to be able to use C escaped strings... - if (l_user_string.size() > 2 && l_user_string[0] == '"' && - l_user_string.back() == '"' && - l_user_string.find("\\\"") != std::string::npos) { - l_user_string = un_c_ify_string(l_user_string); - } - WKTParser wktParser; - if (wktParser.guessDialect(l_user_string) != - WKTParser::WKTGuessedDialect::NOT_WKT) { - wktParser.setStrict(false); - wktParser.attachDatabaseContext(dbContext); - obj = wktParser.createFromWKT(l_user_string).as_nullable(); - if (!quiet) { - auto warnings = wktParser.warningList(); - if (!warnings.empty()) { - for (const auto &str : warnings) { - std::cerr << "Warning: " << str << std::endl; - } - } - } - } else { - obj = - createFromUserInput(l_user_string, dbContext).as_nullable(); - } - } - } catch (const std::exception &e) { - std::cerr << context << ": parsing of user string failed: " << e.what() - << std::endl; - std::exit(1); - } - - if (buildBoundCRSToWGS84) { - auto crs = std::dynamic_pointer_cast<CRS>(obj); - if (crs) { - obj = crs->createBoundCRSToWGS84IfPossible(dbContext, allowPivots) - .as_nullable(); - } - } - - return NN_NO_CHECK(obj); -} - -// --------------------------------------------------------------------------- - -static void outputObject(DatabaseContextPtr dbContext, BaseObjectNNPtr obj, - bool allowPivots, const OutputOptions &outputOpt) { - - auto identified = dynamic_cast<const IdentifiedObject *>(obj.get()); - if (!outputOpt.quiet && identified && identified->isDeprecated()) { - std::cout << "Warning: object is deprecated" << std::endl; - auto crs = dynamic_cast<const CRS *>(obj.get()); - if (crs && dbContext) { - try { - auto list = crs->getNonDeprecated(NN_NO_CHECK(dbContext)); - if (!list.empty()) { - std::cout << "Alternative non-deprecated CRS:" << std::endl; - } - for (const auto &altCRS : list) { - const auto &ids = altCRS->identifiers(); - if (!ids.empty()) { - std::cout << " " << *(ids[0]->codeSpace()) << ":" - << ids[0]->code() << std::endl; - } - } - } catch (const std::exception &) { - } - } - std::cout << std::endl; - } - - auto projStringExportable = - nn_dynamic_pointer_cast<IPROJStringExportable>(obj); - bool alreadyOutputed = false; - if (projStringExportable) { - if (outputOpt.PROJ5) { - try { - if (!outputOpt.quiet) { - std::cout << "PROJ string:" << std::endl; - } - std::cout << projStringExportable->exportToPROJString( - PROJStringFormatter::create( - PROJStringFormatter::Convention::PROJ_5, - dbContext) - .get()) - << std::endl; - } catch (const std::exception &e) { - std::cerr << "Error when exporting to PROJ string: " << e.what() - << std::endl; - } - alreadyOutputed = true; - } - - if (outputOpt.PROJ4) { - try { - if (alreadyOutputed) { - std::cout << std::endl; - } - if (!outputOpt.quiet) { - std::cout << "PROJ.4 string:" << std::endl; - } - - auto crs = nn_dynamic_pointer_cast<CRS>(obj); - std::shared_ptr<IPROJStringExportable> objToExport; - if (crs) { - objToExport = - nn_dynamic_pointer_cast<IPROJStringExportable>( - crs->createBoundCRSToWGS84IfPossible(dbContext, - allowPivots)); - } - if (!objToExport) { - objToExport = projStringExportable; - } - - std::cout << objToExport->exportToPROJString( - PROJStringFormatter::create( - PROJStringFormatter::Convention::PROJ_4, - dbContext) - .get()) - << std::endl; - } catch (const std::exception &e) { - std::cerr << "Error when exporting to PROJ string: " << e.what() - << std::endl; - } - alreadyOutputed = true; - } - } - - auto wktExportable = nn_dynamic_pointer_cast<IWKTExportable>(obj); - if (wktExportable) { - if (outputOpt.WKT2_2015) { - try { - if (alreadyOutputed) { - std::cout << std::endl; - } - if (!outputOpt.quiet) { - std::cout << "WKT2_2015 string:" << std::endl; - } - auto formatter = - WKTFormatter::create(WKTFormatter::Convention::WKT2_2015); - if (outputOpt.singleLine) { - formatter->setMultiLine(false); - } - auto wkt = wktExportable->exportToWKT(formatter.get()); - if (outputOpt.c_ify) { - wkt = c_ify_string(wkt); - } - std::cout << wkt << std::endl; - } catch (const std::exception &e) { - std::cerr << "Error when exporting to WKT2_2015: " << e.what() - << std::endl; - } - alreadyOutputed = true; - } - - if (outputOpt.WKT2_2015_SIMPLIFIED) { - try { - if (alreadyOutputed) { - std::cout << std::endl; - } - if (!outputOpt.quiet) { - std::cout << "WKT2_2015_SIMPLIFIED string:" << std::endl; - } - auto formatter = WKTFormatter::create( - WKTFormatter::Convention::WKT2_2015_SIMPLIFIED); - if (outputOpt.singleLine) { - formatter->setMultiLine(false); - } - auto wkt = wktExportable->exportToWKT(formatter.get()); - if (outputOpt.c_ify) { - wkt = c_ify_string(wkt); - } - std::cout << wkt << std::endl; - } catch (const std::exception &e) { - std::cerr << "Error when exporting to WKT2_2015_SIMPLIFIED: " - << e.what() << std::endl; - } - alreadyOutputed = true; - } - - if (outputOpt.WKT2_2018) { - try { - if (alreadyOutputed) { - std::cout << std::endl; - } - if (!outputOpt.quiet) { - std::cout << "WKT2_2018 string:" << std::endl; - } - auto formatter = - WKTFormatter::create(WKTFormatter::Convention::WKT2_2018); - if (outputOpt.singleLine) { - formatter->setMultiLine(false); - } - auto wkt = wktExportable->exportToWKT(formatter.get()); - if (outputOpt.c_ify) { - wkt = c_ify_string(wkt); - } - std::cout << wkt << std::endl; - } catch (const std::exception &e) { - std::cerr << "Error when exporting to WKT2_2018: " << e.what() - << std::endl; - } - alreadyOutputed = true; - } - - if (outputOpt.WKT2_2018_SIMPLIFIED) { - try { - if (alreadyOutputed) { - std::cout << std::endl; - } - if (!outputOpt.quiet) { - std::cout << "WKT2_2018_SIMPLIFIED string:" << std::endl; - } - auto formatter = WKTFormatter::create( - WKTFormatter::Convention::WKT2_2018_SIMPLIFIED); - if (outputOpt.singleLine) { - formatter->setMultiLine(false); - } - auto wkt = wktExportable->exportToWKT(formatter.get()); - if (outputOpt.c_ify) { - wkt = c_ify_string(wkt); - } - std::cout << wkt << std::endl; - } catch (const std::exception &e) { - std::cerr << "Error when exporting to WKT2_2018_SIMPLIFIED: " - << e.what() << std::endl; - } - alreadyOutputed = true; - } - - if (outputOpt.WKT1_GDAL && !nn_dynamic_pointer_cast<Conversion>(obj)) { - try { - if (alreadyOutputed) { - std::cout << std::endl; - } - if (!outputOpt.quiet) { - std::cout << "WKT1_GDAL:" << std::endl; - } - - auto crs = nn_dynamic_pointer_cast<CRS>(obj); - std::shared_ptr<IWKTExportable> objToExport; - if (crs) { - objToExport = nn_dynamic_pointer_cast<IWKTExportable>( - crs->createBoundCRSToWGS84IfPossible(dbContext, - allowPivots)); - } - if (!objToExport) { - objToExport = wktExportable; - } - - auto formatter = - WKTFormatter::create(WKTFormatter::Convention::WKT1_GDAL); - if (outputOpt.singleLine) { - formatter->setMultiLine(false); - } - auto wkt = objToExport->exportToWKT(formatter.get()); - if (outputOpt.c_ify) { - wkt = c_ify_string(wkt); - } - std::cout << wkt << std::endl; - std::cout << std::endl; - } catch (const std::exception &e) { - std::cerr << "Error when exporting to WKT1_GDAL: " << e.what() - << std::endl; - } - alreadyOutputed = true; - } - - if (outputOpt.WKT1_ESRI && !nn_dynamic_pointer_cast<Conversion>(obj)) { - try { - if (alreadyOutputed) { - std::cout << std::endl; - } - if (!outputOpt.quiet) { - std::cout << "WKT1_ESRI:" << std::endl; - } - - auto wkt = wktExportable->exportToWKT( - WKTFormatter::create(WKTFormatter::Convention::WKT1_ESRI, - dbContext) - .get()); - if (outputOpt.c_ify) { - wkt = c_ify_string(wkt); - } - std::cout << wkt << std::endl; - std::cout << std::endl; - } catch (const std::exception &e) { - std::cerr << "Error when exporting to WKT1_ESRI: " << e.what() - << std::endl; - } - } - } -} - -// --------------------------------------------------------------------------- - -static void outputOperationSummary(const CoordinateOperationNNPtr &op) { - auto ids = op->identifiers(); - if (!ids.empty()) { - std::cout << *(ids[0]->codeSpace()) << ":" << ids[0]->code(); - } else { - std::cout << "unknown id"; - } - - std::cout << ", "; - - auto name = op->nameStr(); - if (!name.empty()) { - std::cout << name; - } else { - std::cout << "unknown name"; - } - - std::cout << ", "; - - auto accuracies = op->coordinateOperationAccuracies(); - if (!accuracies.empty()) { - std::cout << accuracies[0]->value() << " m"; - } else { - if (std::dynamic_pointer_cast<Conversion>(op.as_nullable())) { - std::cout << "0 m"; - } else { - std::cout << "unknown accuracy"; - } - } - - std::cout << ", "; - - auto domains = op->domains(); - if (!domains.empty() && domains[0]->domainOfValidity() && - domains[0]->domainOfValidity()->description().has_value()) { - std::cout << *(domains[0]->domainOfValidity()->description()); - } else { - std::cout << "unknown domain of validity"; - } - - std::cout << std::endl; -} - -// --------------------------------------------------------------------------- - -static void outputOperations( - DatabaseContextPtr dbContext, const std::string &sourceCRSStr, - const std::string &targetCRSStr, const ExtentPtr &bboxFilter, - CoordinateOperationContext::SpatialCriterion spatialCriterion, - CoordinateOperationContext::SourceTargetCRSExtentUse crsExtentUse, - CoordinateOperationContext::GridAvailabilityUse gridAvailabilityUse, - bool allowPivots, - const std::vector<std::pair<std::string, std::string>> &pivots, - const std::string &authority, bool usePROJGridAlternatives, - bool showSuperseded, const OutputOptions &outputOpt, bool summary) { - auto sourceObj = buildObject(dbContext, sourceCRSStr, true, "source CRS", - false, false, outputOpt.quiet); - auto sourceCRS = nn_dynamic_pointer_cast<CRS>(sourceObj); - if (!sourceCRS) { - std::cerr << "source CRS string is not a CRS" << std::endl; - std::exit(1); - } - - auto targetObj = buildObject(dbContext, targetCRSStr, true, "target CRS", - false, false, outputOpt.quiet); - auto targetCRS = nn_dynamic_pointer_cast<CRS>(targetObj); - if (!targetCRS) { - std::cerr << "target CRS string is not a CRS" << std::endl; - std::exit(1); - } - - std::vector<CoordinateOperationNNPtr> list; - try { - auto authFactory = - dbContext - ? AuthorityFactory::create(NN_NO_CHECK(dbContext), authority) - .as_nullable() - : nullptr; - auto ctxt = - CoordinateOperationContext::create(authFactory, bboxFilter, 0); - ctxt->setSpatialCriterion(spatialCriterion); - ctxt->setSourceAndTargetCRSExtentUse(crsExtentUse); - ctxt->setGridAvailabilityUse(gridAvailabilityUse); - ctxt->setAllowUseIntermediateCRS(allowPivots); - ctxt->setIntermediateCRS(pivots); - ctxt->setUsePROJAlternativeGridNames(usePROJGridAlternatives); - ctxt->setDiscardSuperseded(!showSuperseded); - list = CoordinateOperationFactory::create()->createOperations( - NN_NO_CHECK(sourceCRS), NN_NO_CHECK(targetCRS), ctxt); - } catch (const std::exception &e) { - std::cerr << "createOperations() failed with: " << e.what() - << std::endl; - std::exit(1); - } - if (outputOpt.quiet && !list.empty()) { - outputObject(dbContext, list[0], allowPivots, outputOpt); - return; - } - if (summary) { - std::cout << "Candidate operations found: " << list.size() << std::endl; - for (const auto &op : list) { - outputOperationSummary(op); - } - } else { - bool first = true; - for (size_t i = 0; i < list.size(); ++i) { - const auto &op = list[i]; - if (list.size() > 1) { - if (!first) { - std::cout << std::endl; - } - first = false; - std::cout << "-------------------------------------" - << std::endl; - std::cout << "Operation n" - "\xC2\xB0" - << (i + 1) << ":" << std::endl - << std::endl; - } - outputOperationSummary(op); - std::cout << std::endl; - outputObject(dbContext, op, allowPivots, outputOpt); - } - } -} - -// --------------------------------------------------------------------------- - -int main(int argc, char **argv) { - - if (argc == 1) { - std::cerr << pj_get_release() << std::endl; - usage(); - } - - std::string user_string; - bool user_string_specified = false; - std::string sourceCRSStr; - std::string targetCRSStr; - bool outputSwithSpecified = false; - OutputOptions outputOpt; - bool kindIsCRS = true; - bool summary = false; - ExtentPtr bboxFilter = nullptr; - std::string area; - CoordinateOperationContext::SpatialCriterion spatialCriterion = - CoordinateOperationContext::SpatialCriterion::STRICT_CONTAINMENT; - CoordinateOperationContext::SourceTargetCRSExtentUse crsExtentUse = - CoordinateOperationContext::SourceTargetCRSExtentUse::SMALLEST; - bool buildBoundCRSToWGS84 = false; - CoordinateOperationContext::GridAvailabilityUse gridAvailabilityUse = - CoordinateOperationContext::GridAvailabilityUse::USE_FOR_SORTING; - bool allowPivots = true; - std::vector<std::pair<std::string, std::string>> pivots; - bool usePROJGridAlternatives = true; - std::string mainDBPath; - std::vector<std::string> auxDBPath; - bool guessDialect = false; - std::string authority; - bool identify = false; - bool showSuperseded = false; - - for (int i = 1; i < argc; i++) { - std::string arg(argv[i]); - if (arg == "-o" && i + 1 < argc) { - outputSwithSpecified = true; - i++; - auto formats(split(argv[i], ',')); - for (auto format : formats) { - if (ci_equal(format, "all")) { - outputOpt.PROJ5 = true; - outputOpt.PROJ4 = true; - outputOpt.WKT2_2018 = true; - outputOpt.WKT2_2015 = true; - outputOpt.WKT1_GDAL = true; - outputOpt.WKT1_ESRI = true; - } else if (ci_equal(format, "default")) { - outputOpt.PROJ5 = true; - outputOpt.PROJ4 = false; - outputOpt.WKT2_2018 = false; - outputOpt.WKT2_2015 = true; - outputOpt.WKT1_GDAL = false; - } else if (ci_equal(format, "PROJ4") || - ci_equal(format, "PROJ.4")) { - outputOpt.PROJ4 = true; - } else if (ci_equal(format, "-PROJ4") || - ci_equal(format, "-PROJ.4")) { - outputOpt.PROJ4 = false; - } else if (ci_equal(format, "PROJ")) { - outputOpt.PROJ5 = true; - } else if (ci_equal(format, "-PROJ")) { - outputOpt.PROJ5 = false; - } else if (ci_equal(format, "WKT_ALL") || - ci_equal(format, "WKT-ALL")) { - outputOpt.WKT2_2018 = true; - outputOpt.WKT2_2015 = true; - outputOpt.WKT1_GDAL = true; - } else if (ci_equal(format, "-WKT_ALL") || - ci_equal(format, "-WKT-ALL")) { - outputOpt.WKT2_2018 = false; - outputOpt.WKT2_2015 = false; - outputOpt.WKT1_GDAL = false; - } else if (ci_equal(format, "WKT2_2018") || - ci_equal(format, "WKT2-2018") || - ci_equal(format, "WKT2:2018")) { - outputOpt.WKT2_2018 = true; - } else if (ci_equal(format, "WKT2_2018_SIMPLIFIED") || - ci_equal(format, "WKT2-2018_SIMPLIFIED") || - ci_equal(format, "WKT2:2018_SIMPLIFIED")) { - outputOpt.WKT2_2018_SIMPLIFIED = true; - } else if (ci_equal(format, "-WKT2_2018") || - ci_equal(format, "-WKT2-2018") || - ci_equal(format, "-WKT2:2018")) { - outputOpt.WKT2_2018 = false; - } else if (ci_equal(format, "WKT2_2015") || - ci_equal(format, "WKT2-2015") || - ci_equal(format, "WKT2:2015")) { - outputOpt.WKT2_2015 = true; - } else if (ci_equal(format, "WKT2_2015_SIMPLIFIED") || - ci_equal(format, "WKT2-2015_SIMPLIFIED") || - ci_equal(format, "WKT2:2015_SIMPLIFIED")) { - outputOpt.WKT2_2015_SIMPLIFIED = true; - } else if (ci_equal(format, "-WKT2_2015") || - ci_equal(format, "-WKT2-2015") || - ci_equal(format, "-WKT2:2015")) { - outputOpt.WKT2_2015 = false; - } else if (ci_equal(format, "WKT1_GDAL") || - ci_equal(format, "WKT1-GDAL") || - ci_equal(format, "WKT1:GDAL")) { - outputOpt.WKT1_GDAL = true; - } else if (ci_equal(format, "-WKT1_GDAL") || - ci_equal(format, "-WKT1-GDAL") || - ci_equal(format, "-WKT1:GDAL")) { - outputOpt.WKT1_GDAL = false; - } else if (ci_equal(format, "WKT1_ESRI") || - ci_equal(format, "WKT1-ESRI") || - ci_equal(format, "WKT1:ESRI")) { - outputOpt.WKT1_ESRI = true; - } else if (ci_equal(format, "-WKT1_ESRI") || - ci_equal(format, "-WKT1-ESRI") || - ci_equal(format, "-WKT1:ESRI")) { - outputOpt.WKT1_ESRI = false; - } else { - std::cerr << "Unrecognized value for option -o: " << format - << std::endl; - usage(); - } - } - } else if (arg == "--bbox" && i + 1 < argc) { - i++; - auto bboxStr(argv[i]); - auto bbox(split(bboxStr, ',')); - if (bbox.size() != 4) { - std::cerr << "Incorrect number of values for option --bbox: " - << bboxStr << std::endl; - usage(); - } - try { - bboxFilter = Extent::createFromBBOX( - c_locale_stod(bbox[0]), c_locale_stod(bbox[1]), - c_locale_stod(bbox[2]), c_locale_stod(bbox[3])) - .as_nullable(); - } catch (const std::exception &e) { - std::cerr << "Invalid value for option --bbox: " << bboxStr - << ", " << e.what() << std::endl; - usage(); - } - } else if (arg == "--area" && i + 1 < argc) { - i++; - area = argv[i]; - } else if (arg == "-k" && i + 1 < argc) { - i++; - std::string kind(argv[i]); - if (ci_equal(kind, "crs") || ci_equal(kind, "srs")) { - kindIsCRS = true; - } else if (ci_equal(kind, "operation")) { - kindIsCRS = false; - } else { - std::cerr << "Unrecognized value for option -k: " << kind - << std::endl; - usage(); - } - } else if ((arg == "-s" || arg == "--ssource-crs") && i + 1 < argc) { - i++; - sourceCRSStr = argv[i]; - } else if ((arg == "-t" || arg == "--target-crs") && i + 1 < argc) { - i++; - targetCRSStr = argv[i]; - } else if (arg == "-q" || arg == "--quiet") { - outputOpt.quiet = true; - } else if (arg == "--c-ify") { - outputOpt.c_ify = true; - } else if (arg == "--single-line") { - outputOpt.singleLine = true; - } else if (arg == "--summary") { - summary = true; - } else if (ci_equal(arg, "--boundcrs-to-wgs84")) { - buildBoundCRSToWGS84 = true; - - // undocumented: only for debugging purposes - } else if (ci_equal(arg, "--no-proj-grid-alternatives")) { - usePROJGridAlternatives = false; - - } else if (arg == "--spatial-test" && i + 1 < argc) { - i++; - std::string value(argv[i]); - if (ci_equal(value, "contains")) { - spatialCriterion = CoordinateOperationContext:: - SpatialCriterion::STRICT_CONTAINMENT; - } else if (ci_equal(value, "intersects")) { - spatialCriterion = CoordinateOperationContext:: - SpatialCriterion::PARTIAL_INTERSECTION; - } else { - std::cerr << "Unrecognized value for option --spatial-test: " - << value << std::endl; - usage(); - } - } else if (arg == "--crs-extent-use" && i + 1 < argc) { - i++; - std::string value(argv[i]); - if (ci_equal(value, "NONE")) { - crsExtentUse = - CoordinateOperationContext::SourceTargetCRSExtentUse::NONE; - } else if (ci_equal(value, "BOTH")) { - crsExtentUse = - CoordinateOperationContext::SourceTargetCRSExtentUse::BOTH; - } else if (ci_equal(value, "INTERSECTION")) { - crsExtentUse = CoordinateOperationContext:: - SourceTargetCRSExtentUse::INTERSECTION; - } else if (ci_equal(value, "SMALLEST")) { - crsExtentUse = CoordinateOperationContext:: - SourceTargetCRSExtentUse::SMALLEST; - } else { - std::cerr << "Unrecognized value for option --crs-extent-use: " - << value << std::endl; - usage(); - } - } else if (arg == "--grid-check" && i + 1 < argc) { - i++; - std::string value(argv[i]); - if (ci_equal(value, "none")) { - gridAvailabilityUse = CoordinateOperationContext:: - GridAvailabilityUse::IGNORE_GRID_AVAILABILITY; - } else if (ci_equal(value, "discard_missing")) { - gridAvailabilityUse = CoordinateOperationContext:: - GridAvailabilityUse::DISCARD_OPERATION_IF_MISSING_GRID; - } else if (ci_equal(value, "sort")) { - gridAvailabilityUse = CoordinateOperationContext:: - GridAvailabilityUse::USE_FOR_SORTING; - } else { - std::cerr << "Unrecognized value for option --grid-check: " - << value << std::endl; - usage(); - } - } else if (arg == "--pivot-crs" && i + 1 < argc) { - i++; - auto value(argv[i]); - if (ci_equal(std::string(value), "none")) { - allowPivots = false; - } else { - auto splitValue(split(value, ',')); - for (const auto &v : splitValue) { - auto auth_code = split(v, ':'); - if (auth_code.size() != 2) { - std::cerr - << "Unrecognized value for option --grid-check: " - << value << std::endl; - usage(); - } - pivots.emplace_back( - std::make_pair(auth_code[0], auth_code[1])); - } - } - } else if (arg == "--main-db-path" && i + 1 < argc) { - i++; - mainDBPath = argv[i]; - } else if (arg == "--aux-db-path" && i + 1 < argc) { - i++; - auxDBPath.push_back(argv[i]); - } else if (arg == "--guess-dialect") { - guessDialect = true; - } else if (arg == "--authority" && i + 1 < argc) { - i++; - authority = argv[i]; - } else if (arg == "--identify") { - identify = true; - } else if (arg == "--show-superseded") { - showSuperseded = true; - } else if (arg == "-?" || arg == "--help") { - usage(); - } else if (arg[0] == '-') { - std::cerr << "Unrecognized option: " << arg << std::endl; - usage(); - } else { - if (!user_string_specified) { - user_string_specified = true; - user_string = arg; - } else { - std::cerr << "Too many parameters: " << arg << std::endl; - usage(); - } - } - } - - if (bboxFilter && !area.empty()) { - std::cerr << "ERROR: --bbox and --area are exclusive" << std::endl; - std::exit(1); - } - - DatabaseContextPtr dbContext; - try { - dbContext = - DatabaseContext::create(mainDBPath, auxDBPath).as_nullable(); - } catch (const std::exception &e) { - if (!mainDBPath.empty() || !auxDBPath.empty() || !area.empty()) { - std::cerr << "ERROR: Cannot create database connection: " - << e.what() << std::endl; - std::exit(1); - } - std::cerr << "WARNING: Cannot create database connection: " << e.what() - << std::endl; - } - - if (!sourceCRSStr.empty() && targetCRSStr.empty()) { - std::cerr << "Source CRS specified, but missing target CRS" - << std::endl; - usage(); - } else if (sourceCRSStr.empty() && !targetCRSStr.empty()) { - std::cerr << "Target CRS specified, but missing source CRS" - << std::endl; - usage(); - } else if (!sourceCRSStr.empty() && !targetCRSStr.empty()) { - if (user_string_specified) { - std::cerr << "Unused extra value" << std::endl; - usage(); - } - } else if (!user_string_specified) { - std::cerr << "Missing user string" << std::endl; - usage(); - } - - if (!outputSwithSpecified) { - outputOpt.PROJ5 = true; - outputOpt.WKT2_2015 = true; - } - - if (outputOpt.quiet && - (outputOpt.PROJ5 + outputOpt.PROJ4 + outputOpt.WKT2_2018 + - outputOpt.WKT2_2015 + outputOpt.WKT1_GDAL) != 1) { - std::cerr << "-q can only be used with a single output format" - << std::endl; - usage(); - } - - if (!user_string.empty()) { - auto obj(buildObject(dbContext, user_string, kindIsCRS, "input string", - buildBoundCRSToWGS84, allowPivots, - outputOpt.quiet)); - if (guessDialect) { - auto dialect = WKTParser().guessDialect(user_string); - std::cout << "Guessed WKT dialect: "; - if (dialect == WKTParser::WKTGuessedDialect::WKT2_2018) { - std::cout << "WKT2_2018"; - } else if (dialect == WKTParser::WKTGuessedDialect::WKT2_2015) { - std::cout << "WKT2_2015"; - } else if (dialect == WKTParser::WKTGuessedDialect::WKT1_GDAL) { - std::cout << "WKT1_GDAL"; - } else if (dialect == WKTParser::WKTGuessedDialect::WKT1_ESRI) { - std::cout << "WKT1_ESRI"; - } else { - std::cout << "Not WKT / unknown"; - } - std::cout << std::endl; - } - outputObject(dbContext, obj, allowPivots, outputOpt); - if (identify) { - auto crs = dynamic_cast<CRS *>(obj.get()); - if (crs) { - try { - auto res = crs->identify( - dbContext - ? AuthorityFactory::create(NN_NO_CHECK(dbContext), - authority) - .as_nullable() - : nullptr); - std::cout << std::endl; - std::cout << "Identification match count: " << res.size() - << std::endl; - for (const auto &pair : res) { - const auto &identifiedCRS = pair.first; - const auto &ids = identifiedCRS->identifiers(); - if (!ids.empty()) { - std::cout << *ids[0]->codeSpace() << ":" - << ids[0]->code() << ": " << pair.second - << " %" << std::endl; - } else { - auto boundCRS = - dynamic_cast<BoundCRS *>(identifiedCRS.get()); - if (boundCRS && - !boundCRS->baseCRS()->identifiers().empty()) { - const auto &idsBase = - boundCRS->baseCRS()->identifiers(); - std::cout << "BoundCRS of " - << *idsBase[0]->codeSpace() << ":" - << idsBase[0]->code() << ": " - << pair.second << " %" << std::endl; - } else { - std::cout - << "un-identifier CRS: " << pair.second - << " %" << std::endl; - } - } - } - } catch (const std::exception &e) { - std::cerr << "Identification failed: " << e.what() - << std::endl; - } - } - } - } else { - - if (!area.empty()) { - assert(dbContext); - try { - if (area.find(' ') == std::string::npos && - area.find(':') != std::string::npos) { - auto tokens = split(area, ':'); - if (tokens.size() == 2) { - const std::string &areaAuth = tokens[0]; - const std::string &areaCode = tokens[1]; - bboxFilter = AuthorityFactory::create( - NN_NO_CHECK(dbContext), areaAuth) - ->createExtent(areaCode) - .as_nullable(); - } - } - if (!bboxFilter) { - auto authFactory = AuthorityFactory::create( - NN_NO_CHECK(dbContext), std::string()); - auto res = authFactory->listAreaOfUseFromName(area, false); - if (res.size() == 1) { - bboxFilter = - AuthorityFactory::create(NN_NO_CHECK(dbContext), - res.front().first) - ->createExtent(res.front().second) - .as_nullable(); - } else { - res = authFactory->listAreaOfUseFromName(area, true); - if (res.size() == 1) { - bboxFilter = - AuthorityFactory::create(NN_NO_CHECK(dbContext), - res.front().first) - ->createExtent(res.front().second) - .as_nullable(); - } else if (res.empty()) { - std::cerr << "No area of use matching provided name" - << std::endl; - std::exit(1); - } else { - std::cerr << "Several candidates area of use " - "matching provided name :" - << std::endl; - for (const auto &candidate : res) { - auto obj = - AuthorityFactory::create( - NN_NO_CHECK(dbContext), candidate.first) - ->createExtent(candidate.second); - std::cerr << " " << candidate.first << ":" - << candidate.second << " : " - << *obj->description() << std::endl; - } - std::exit(1); - } - } - } - } catch (const std::exception &e) { - std::cerr << "Area of use retrieval failed: " << e.what() - << std::endl; - std::exit(1); - } - } - - outputOperations( - dbContext, sourceCRSStr, targetCRSStr, bboxFilter, spatialCriterion, - crsExtentUse, gridAvailabilityUse, allowPivots, pivots, authority, - usePROJGridAlternatives, showSuperseded, outputOpt, summary); - } - - return 0; -} - -//! @endcond |
