aboutsummaryrefslogtreecommitdiff
path: root/src/projinfo.cpp
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2018-12-19 12:25:33 +0100
committerEven Rouault <even.rouault@spatialys.com>2018-12-26 10:08:54 +0100
commite6de172371ea203f6393d745641d66c82b5b13e2 (patch)
tree791fa07f431a2d1db6f6e813ab984db982587278 /src/projinfo.cpp
parentce8075076b4e4ffebd32afaba419e1d9ab27cd03 (diff)
downloadPROJ-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.cpp1067
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