diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/apps/projinfo.cpp | 13 | ||||
| -rw-r--r-- | src/iso19111/c_api.cpp | 31 | ||||
| -rw-r--r-- | src/iso19111/io.cpp | 78 |
3 files changed, 100 insertions, 22 deletions
diff --git a/src/apps/projinfo.cpp b/src/apps/projinfo.cpp index 966de03d..f36674fd 100644 --- a/src/apps/projinfo.cpp +++ b/src/apps/projinfo.cpp @@ -350,11 +350,10 @@ static void outputObject( objToExport = projStringExportable; } - std::cout << objToExport->exportToPROJString( - PROJStringFormatter::create( - PROJStringFormatter::Convention::PROJ_5, - dbContext) - .get()) + auto formatter = PROJStringFormatter::create( + PROJStringFormatter::Convention::PROJ_5, dbContext); + formatter->setMultiLine(!outputOpt.singleLine); + std::cout << objToExport->exportToPROJString(formatter.get()) << std::endl; } catch (const std::exception &e) { std::cerr << "Error when exporting to PROJ string: " << e.what() @@ -376,9 +375,7 @@ static void outputObject( } auto formatter = WKTFormatter::create(WKTFormatter::Convention::WKT2_2015); - if (outputOpt.singleLine) { - formatter->setMultiLine(false); - } + formatter->setMultiLine(!outputOpt.singleLine); formatter->setStrict(outputOpt.strict); auto wkt = wktExportable->exportToWKT(formatter.get()); if (outputOpt.c_ify) { diff --git a/src/iso19111/c_api.cpp b/src/iso19111/c_api.cpp index cad76431..8d77437a 100644 --- a/src/iso19111/c_api.cpp +++ b/src/iso19111/c_api.cpp @@ -1504,9 +1504,16 @@ const char *proj_as_wkt(PJ_CONTEXT *ctx, const PJ *obj, PJ_WKT_TYPE type, * @param obj Object (must not be NULL) * @param type PROJ String version. * @param options NULL-terminated list of strings with "KEY=VALUE" format. or - * NULL. - * The currently recognized option is USE_APPROX_TMERC=YES to add the +approx - * flag to +proj=tmerc or +proj=utm + * NULL. Currently supported options are: + * <ul> + * <li>USE_APPROX_TMERC=YES to add the +approx flag to +proj=tmerc or + * +proj=utm.</li> + * <li>MULTILINE=YES/NO. Defaults to NO</li> + * <li>INDENTATION_WIDTH=number. Defaults to 2 (when multiline output is + * on).</li> + * <li>MAX_LINE_LENGTH=number. Defaults to 80 (when multiline output is + * on).</li> + * </ul> * @return a string, or NULL in case of error. */ const char *proj_as_proj_string(PJ_CONTEXT *ctx, const PJ *obj, @@ -1542,9 +1549,21 @@ const char *proj_as_proj_string(PJ_CONTEXT *ctx, const PJ *obj, auto dbContext = getDBcontextNoException(ctx, __FUNCTION__); try { auto formatter = PROJStringFormatter::create(convention, dbContext); - if (options != nullptr && options[0] != nullptr) { - if (ci_equal(options[0], "USE_APPROX_TMERC=YES")) { - formatter->setUseApproxTMerc(true); + for (auto iter = options; iter && iter[0]; ++iter) { + const char *value; + if ((value = getOptionValue(*iter, "MULTILINE="))) { + formatter->setMultiLine(ci_equal(value, "YES")); + } else if ((value = getOptionValue(*iter, "INDENTATION_WIDTH="))) { + formatter->setIndentationWidth(std::atoi(value)); + } else if ((value = getOptionValue(*iter, "MAX_LINE_LENGTH="))) { + formatter->setMaxLineLength(std::atoi(value)); + } else if ((value = getOptionValue(*iter, "USE_APPROX_TMERC="))) { + formatter->setUseApproxTMerc(ci_equal(value, "YES")); + } else { + std::string msg("Unknown option :"); + msg += *iter; + proj_log_error(ctx, __FUNCTION__, msg.c_str()); + return nullptr; } } obj->lastPROJString = exportable->exportToPROJString(formatter.get()); diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index c464b724..7a107f96 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -6722,6 +6722,10 @@ struct PROJStringFormatter::Private { bool coordOperationOptimizations_ = false; bool crsExport_ = false; bool legacyCRSToCRSContext_ = false; + bool multiLine_ = false; + int indentWidth_ = 2; + int indentLevel_ = 0; + int maxLineLength_ = 80; std::string result_{}; @@ -6780,6 +6784,36 @@ void PROJStringFormatter::setUseApproxTMerc(bool flag) { // --------------------------------------------------------------------------- +/** \brief Whether to use multi line output or not. */ +PROJStringFormatter & +PROJStringFormatter::setMultiLine(bool multiLine) noexcept { + d->multiLine_ = multiLine; + return *this; +} + +// --------------------------------------------------------------------------- + +/** \brief Set number of spaces for each indentation level (defaults to 2). + */ +PROJStringFormatter & +PROJStringFormatter::setIndentationWidth(int width) noexcept { + d->indentWidth_ = width; + return *this; +} + +// --------------------------------------------------------------------------- + +/** \brief Set the maximum size of a line (when multiline output is enable). + * Can be set to 0 for unlimited length. + */ +PROJStringFormatter & +PROJStringFormatter::setMaxLineLength(int maxLineLength) noexcept { + d->maxLineLength_ = maxLineLength; + return *this; +} + +// --------------------------------------------------------------------------- + /** \brief Returns the PROJ string. */ const std::string &PROJStringFormatter::toString() const { @@ -7308,28 +7342,56 @@ const std::string &PROJStringFormatter::toString() const { pj_double_quote_string_param_if_needed(paramValue.value); } } + + if (d->multiLine_) { + d->indentLevel_++; + } } for (const auto &step : d->steps_) { + std::string curLine; if (!d->result_.empty()) { - d->appendToResult("+step"); + if (d->multiLine_) { + curLine = std::string(d->indentLevel_ * d->indentWidth_, ' '); + curLine += "+step"; + } else { + curLine = " +step"; + } } if (step.inverted) { - d->appendToResult("+inv"); + curLine += " +inv"; } if (!step.name.empty()) { - d->appendToResult(step.isInit ? "+init=" : "+proj="); - d->result_ += step.name; + if (!curLine.empty()) + curLine += ' '; + curLine += step.isInit ? "+init=" : "+proj="; + curLine += step.name; } for (const auto ¶mValue : step.paramValues) { - d->appendToResult("+"); - d->result_ += paramValue.key; + std::string newKV = "+"; + newKV += paramValue.key; if (!paramValue.value.empty()) { - d->result_ += '='; - d->result_ += + newKV += '='; + newKV += pj_double_quote_string_param_if_needed(paramValue.value); } + if (d->maxLineLength_ > 0 && d->multiLine_ && + curLine.size() + newKV.size() > + static_cast<size_t>(d->maxLineLength_)) { + if (d->multiLine_ && !d->result_.empty()) + d->result_ += '\n'; + d->result_ += curLine; + curLine = std::string( + d->indentLevel_ * d->indentWidth_ + strlen("+step "), ' '); + } else { + if (!curLine.empty()) + curLine += ' '; + } + curLine += newKV; } + if (d->multiLine_ && !d->result_.empty()) + d->result_ += '\n'; + d->result_ += curLine; } if (d->result_.empty()) { |
