diff options
| -rw-r--r-- | include/proj/crs.hpp | 31 | ||||
| -rw-r--r-- | include/proj/internal/coordinateoperation_constants.hpp | 2 | ||||
| -rw-r--r-- | include/proj/internal/esri_projection_mappings.hpp | 2 | ||||
| -rw-r--r-- | include/proj/io.hpp | 29 | ||||
| -rw-r--r-- | src/apps/projinfo.cpp | 41 | ||||
| -rw-r--r-- | src/iso19111/coordinateoperation.cpp | 64 | ||||
| -rw-r--r-- | src/iso19111/crs.cpp | 237 | ||||
| -rw-r--r-- | src/iso19111/io.cpp | 21 | ||||
| -rwxr-xr-x | test/cli/testprojinfo | 4 | ||||
| -rw-r--r-- | test/cli/testprojinfo_out.dist | 19 | ||||
| -rw-r--r-- | test/unit/proj_angular_io_test.cpp | 36 | ||||
| -rw-r--r-- | test/unit/test_c_api.cpp | 5 | ||||
| -rw-r--r-- | test/unit/test_crs.cpp | 320 | ||||
| -rw-r--r-- | test/unit/test_factory.cpp | 24 | ||||
| -rw-r--r-- | test/unit/test_io.cpp | 215 | ||||
| -rw-r--r-- | test/unit/test_operation.cpp | 72 |
16 files changed, 480 insertions, 642 deletions
diff --git a/include/proj/crs.hpp b/include/proj/crs.hpp index cc9fdeb9..65414d7d 100644 --- a/include/proj/crs.hpp +++ b/include/proj/crs.hpp @@ -502,9 +502,6 @@ class PROJ_GCC_DLL DerivedCRS : virtual public SingleCRS { PROJ_INTERNAL void setDerivingConversionCRS(); - PROJ_INTERNAL void baseExportToPROJString( - io::PROJStringFormatter *formatter) const; // throw(FormattingException) - PROJ_INTERNAL void baseExportToWKT( io::WKTFormatter *&formatter, const std::string &keyword, const std::string &baseKeyword) const; // throw(FormattingException) @@ -977,9 +974,6 @@ class PROJ_GCC_DLL DerivedGeodeticCRS final : public GeodeticCRS, const cs::SphericalCSNNPtr &csIn); PROJ_INTERNAL DerivedGeodeticCRS(const DerivedGeodeticCRS &other); - PROJ_INTERNAL void _exportToPROJString(io::PROJStringFormatter *formatter) - const override; // throw(FormattingException) - PROJ_INTERNAL CRSNNPtr _shallowClone() const override; PROJ_INTERNAL bool @@ -990,6 +984,10 @@ class PROJ_GCC_DLL DerivedGeodeticCRS final : public GeodeticCRS, PROJ_INTERNAL std::list<std::pair<CRSNNPtr, int>> _identify(const io::AuthorityFactoryPtr &authorityFactory) const override; + // cppcheck-suppress functionStatic + PROJ_INTERNAL void _exportToPROJString(io::PROJStringFormatter *formatter) + const override; // throw(FormattingException) + INLINED_MAKE_SHARED private: @@ -1041,9 +1039,6 @@ class PROJ_GCC_DLL DerivedGeographicCRS final : public GeographicCRS, const cs::EllipsoidalCSNNPtr &csIn); PROJ_INTERNAL DerivedGeographicCRS(const DerivedGeographicCRS &other); - PROJ_INTERNAL void _exportToPROJString(io::PROJStringFormatter *formatter) - const override; // throw(FormattingException) - PROJ_INTERNAL CRSNNPtr _shallowClone() const override; PROJ_INTERNAL bool @@ -1054,6 +1049,10 @@ class PROJ_GCC_DLL DerivedGeographicCRS final : public GeographicCRS, PROJ_INTERNAL std::list<std::pair<CRSNNPtr, int>> _identify(const io::AuthorityFactoryPtr &authorityFactory) const override; + // cppcheck-suppress functionStatic + PROJ_INTERNAL void _exportToPROJString(io::PROJStringFormatter *formatter) + const override; // throw(FormattingException) + INLINED_MAKE_SHARED private: @@ -1078,9 +1077,7 @@ using DerivedProjectedCRSNNPtr = util::nn<DerivedProjectedCRSPtr>; * * \remark Implements DerivedProjectedCRS from \ref ISO_19111_2018 */ -class PROJ_GCC_DLL DerivedProjectedCRS final - : public DerivedCRS, - public io::IPROJStringExportable { +class PROJ_GCC_DLL DerivedProjectedCRS final : public DerivedCRS { public: //! @cond Doxygen_Suppress PROJ_DLL ~DerivedProjectedCRS() override; @@ -1106,9 +1103,6 @@ class PROJ_GCC_DLL DerivedProjectedCRS final const cs::CoordinateSystemNNPtr &csIn); PROJ_INTERNAL DerivedProjectedCRS(const DerivedProjectedCRS &other); - PROJ_INTERNAL void _exportToPROJString(io::PROJStringFormatter *formatter) - const override; // throw(FormattingException) - PROJ_INTERNAL CRSNNPtr _shallowClone() const override; PROJ_INTERNAL bool @@ -1164,9 +1158,6 @@ class PROJ_GCC_DLL DerivedVerticalCRS final : public VerticalCRS, const cs::VerticalCSNNPtr &csIn); PROJ_INTERNAL DerivedVerticalCRS(const DerivedVerticalCRS &other); - PROJ_INTERNAL void _exportToPROJString(io::PROJStringFormatter *formatter) - const override; // throw(FormattingException) - PROJ_INTERNAL CRSNNPtr _shallowClone() const override; PROJ_INTERNAL bool @@ -1177,6 +1168,10 @@ class PROJ_GCC_DLL DerivedVerticalCRS final : public VerticalCRS, PROJ_INTERNAL std::list<std::pair<CRSNNPtr, int>> _identify(const io::AuthorityFactoryPtr &authorityFactory) const override; + // cppcheck-suppress functionStatic + PROJ_INTERNAL void _exportToPROJString(io::PROJStringFormatter *formatter) + const override; // throw(FormattingException) + INLINED_MAKE_SHARED private: diff --git a/include/proj/internal/coordinateoperation_constants.hpp b/include/proj/internal/coordinateoperation_constants.hpp index 53a2622e..accb4a1e 100644 --- a/include/proj/internal/coordinateoperation_constants.hpp +++ b/include/proj/internal/coordinateoperation_constants.hpp @@ -1240,7 +1240,7 @@ static const MethodMapping otherMethodMappings[] = { }; // end of anonymous namespace -} +} // namespace // --------------------------------------------------------------------------- diff --git a/include/proj/internal/esri_projection_mappings.hpp b/include/proj/internal/esri_projection_mappings.hpp index 4ceeb300..423f28be 100644 --- a/include/proj/internal/esri_projection_mappings.hpp +++ b/include/proj/internal/esri_projection_mappings.hpp @@ -880,7 +880,7 @@ static const ESRIMethodMapping esriMappings[] = { // --------------------------------------------------------------------------- // end of anonymous namespace -} +} // namespace //! @endcond diff --git a/include/proj/io.hpp b/include/proj/io.hpp index ec3301f8..7f7639cd 100644 --- a/include/proj/io.hpp +++ b/include/proj/io.hpp @@ -373,7 +373,9 @@ class PROJ_GCC_DLL PROJStringFormatter { //! @cond Doxygen_Suppress PROJ_DLL void - startInversion(); + setCRSExport(bool b); + PROJ_INTERNAL bool getCRSExport() const; + PROJ_DLL void startInversion(); PROJ_DLL void stopInversion(); PROJ_INTERNAL bool isInverted() const; PROJ_INTERNAL bool getUseETMercForTMerc(bool &settingSetOut) const; @@ -510,24 +512,15 @@ class PROJ_GCC_DLL IPROJStringExportable { /** \brief Builds a PROJ string representation. * * <ul> - * <li>For PROJStringFormatter::Convention::PROJ_5 (the default), return - * strings that generally express PROJ.5 pipelines. + * <li>For PROJStringFormatter::Convention::PROJ_5 (the default), * <ul> - * <li>For a crs::GeographicCRS, returns a string expressing the - * transformation from geographic coordinates expressed in radian with - * longitude, latitude order, and with respect to the international - * reference meridian, into geographic coordinates expressed in the units - * and axis order of the CRS, taking into account its prime meridian.</li> - * <li>For a geocentric crs::GeodeticCRS, returns a string expressing the - * transformation from geographic coordinates expressed in radian with - * longitude, latitude order, and with respect to the international - * reference meridian, into geocentric coordinates.</li> - * <li>For a - * crs::ProjectedCRS / crs::DerivedGeographicCRS / crs::DerivedProjectedCRS, - * returns a string expressing the transformation from the base CRS to the - * CRS</li> - * <li>For a crs::BoundCRS, throws a FormattingException.</li> - * <li>For operation::CoordinateTransformations, returns a PROJ + * <li>For a crs::CRS, returns the same as + * PROJStringFormatter::Convention::PROJ_4. It should be noted that the + * export of a CRS as a PROJ string may cause loss of many important aspects + * of a CRS definition. Consequently it is discouraged to use it for + * interoperability in newer projects. The choice of a WKT representation + * will be a better option.</li> + * <li>For operation::CoordinateOperation, returns a PROJ * pipeline.</li> * </ul> * diff --git a/src/apps/projinfo.cpp b/src/apps/projinfo.cpp index b418bc57..446a1e9e 100644 --- a/src/apps/projinfo.cpp +++ b/src/apps/projinfo.cpp @@ -61,7 +61,6 @@ 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; @@ -100,7 +99,7 @@ static void usage() { << 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," + "all,default,PROJ,WKT_ALL,WKT2_2015,WKT2_2018,WKT1_GDAL," "WKT1_ESRI" << std::endl; std::cerr << " Except 'all' and 'default', other format can be preceded " @@ -256,32 +255,18 @@ static void outputObject(DatabaseContextPtr dbContext, BaseObjectNNPtr obj, 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; } + auto crs = nn_dynamic_pointer_cast<CRS>(obj); if (!outputOpt.quiet) { - std::cout << "PROJ.4 string:" << std::endl; + if( crs ) { + std::cout << "PROJ.4 string:" << std::endl; + } else { + std::cout << "PROJ string:" << std::endl; + } } - auto crs = nn_dynamic_pointer_cast<CRS>(obj); std::shared_ptr<IPROJStringExportable> objToExport; if (crs) { objToExport = @@ -295,7 +280,7 @@ static void outputObject(DatabaseContextPtr dbContext, BaseObjectNNPtr obj, std::cout << objToExport->exportToPROJString( PROJStringFormatter::create( - PROJStringFormatter::Convention::PROJ_4, + PROJStringFormatter::Convention::PROJ_5, dbContext) .get()) << std::endl; @@ -651,23 +636,15 @@ int main(int argc, char **argv) { 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")) { @@ -929,7 +906,7 @@ int main(int argc, char **argv) { } if (outputOpt.quiet && - (outputOpt.PROJ5 + outputOpt.PROJ4 + outputOpt.WKT2_2018 + + (outputOpt.PROJ5 + outputOpt.WKT2_2018 + outputOpt.WKT2_2015 + outputOpt.WKT1_GDAL) != 1) { std::cerr << "-q can only be used with a single output format" << std::endl; diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index d00be93f..47f10392 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -5377,8 +5377,8 @@ bool Conversion::addWKTExtensionNode(io::WKTFormatter *formatter) const { bool north = true; if (l_method->getPrivate()->projMethodOverride_ == "etmerc" && !isUTM(zone, north)) { - auto projFormatter = io::PROJStringFormatter::create( - io::PROJStringFormatter::Convention::PROJ_4); + auto projFormatter = io::PROJStringFormatter::create(); + projFormatter->setCRSExport(true); projFormatter->setUseETMercForTMerc(true); formatter->startNode(io::WKTConstants::EXTENSION, false); formatter->addQuotedString("PROJ4"); @@ -5391,8 +5391,8 @@ bool Conversion::addWKTExtensionNode(io::WKTFormatter *formatter) const { EPSG_CODE_METHOD_POPULAR_VISUALISATION_PSEUDO_MERCATOR || nameStr() == "Popular Visualisation Mercator") { - auto projFormatter = io::PROJStringFormatter::create( - io::PROJStringFormatter::Convention::PROJ_4); + auto projFormatter = io::PROJStringFormatter::create(); + projFormatter->setCRSExport(true); if (createPROJ4WebMercator(this, projFormatter.get())) { formatter->startNode(io::WKTConstants::EXTENSION, false); formatter->addQuotedString("PROJ4"); @@ -5401,8 +5401,8 @@ bool Conversion::addWKTExtensionNode(io::WKTFormatter *formatter) const { return true; } } else if (starts_with(methodName, "PROJ ")) { - auto projFormatter = io::PROJStringFormatter::create( - io::PROJStringFormatter::Convention::PROJ_4); + auto projFormatter = io::PROJStringFormatter::create(); + projFormatter->setCRSExport(true); if (createPROJExtensionFromCustomProj(this, projFormatter.get(), true)) { formatter->startNode(io::WKTConstants::EXTENSION, false); @@ -5413,8 +5413,8 @@ bool Conversion::addWKTExtensionNode(io::WKTFormatter *formatter) const { } } else if (methodName == PROJ_WKT2_NAME_METHOD_GEOSTATIONARY_SATELLITE_SWEEP_X) { - auto projFormatter = io::PROJStringFormatter::create( - io::PROJStringFormatter::Convention::PROJ_4); + auto projFormatter = io::PROJStringFormatter::create(); + projFormatter->setCRSExport(true); formatter->startNode(io::WKTConstants::EXTENSION, false); formatter->addQuotedString("PROJ4"); _exportToPROJString(projFormatter.get()); @@ -5445,12 +5445,10 @@ void Conversion::_exportToPROJString( const bool applySourceCRSModifiers = !isZUnitConversion && !isAffineParametric && !isAxisOrderReversal(methodEPSGCode) && !isGeographicGeocentric; - const bool applyTargetCRSModifiers = applySourceCRSModifiers; + bool applyTargetCRSModifiers = applySourceCRSModifiers; auto l_sourceCRS = sourceCRS(); - if (l_sourceCRS && applySourceCRSModifiers && - formatter->convention() == - io::PROJStringFormatter::Convention::PROJ_5) { + if (!formatter->getCRSExport() && l_sourceCRS && applySourceCRSModifiers) { auto geogCRS = dynamic_cast<const crs::GeographicCRS *>(l_sourceCRS.get()); if (geogCRS) { @@ -5593,8 +5591,7 @@ void Conversion::_exportToPROJString( EPSG_NAME_PARAMETER_LATITUDE_OF_NATURAL_ORIGIN); } // PROJ.4 specific hack for webmercator - } else if (formatter->convention() == - io::PROJStringFormatter::Convention::PROJ_4 && + } else if (formatter->getCRSExport() && methodEPSGCode == EPSG_CODE_METHOD_POPULAR_VISUALISATION_PSEUDO_MERCATOR) { if (!createPROJ4WebMercator(this, formatter)) { @@ -5605,14 +5602,15 @@ void Conversion::_exportToPROJString( } bConversionDone = true; bEllipsoidParametersDone = true; + applyTargetCRSModifiers = false; } else if (ci_equal(convName, "Popular Visualisation Mercator")) { - if (formatter->convention() == - io::PROJStringFormatter::Convention::PROJ_4) { + if (formatter->getCRSExport()) { if (!createPROJ4WebMercator(this, formatter)) { throw io::FormattingException(concat( "Cannot export ", convName, " as PROJ.4 string outside of a ProjectedCRS context")); } + applyTargetCRSModifiers = false; } else { formatter->addStep("webmerc"); if (l_sourceCRS) { @@ -5717,8 +5715,7 @@ void Conversion::_exportToPROJString( if (!bEllipsoidParametersDone) { auto targetGeogCRS = l_targetCRS->extractGeographicCRS(); if (targetGeogCRS) { - if (formatter->convention() == - io::PROJStringFormatter::Convention::PROJ_4) { + if (formatter->getCRSExport()) { targetGeogCRS->addDatumInfoToPROJString(formatter); } else { targetGeogCRS->ellipsoid()->_exportToPROJString(formatter); @@ -5737,13 +5734,10 @@ void Conversion::_exportToPROJString( auto derivedGeographicCRS = dynamic_cast<const crs::DerivedGeographicCRS *>(l_targetCRS.get()); if (derivedGeographicCRS) { - if (formatter->convention() == - io::PROJStringFormatter::Convention::PROJ_5) { - auto geogCRS = derivedGeographicCRS->baseCRS(); - formatter->setOmitProjLongLatIfPossible(true); - geogCRS->_exportToPROJString(formatter); - formatter->setOmitProjLongLatIfPossible(false); - } + auto baseGeodCRS = derivedGeographicCRS->baseCRS(); + formatter->setOmitProjLongLatIfPossible(true); + baseGeodCRS->_exportToPROJString(formatter); + formatter->setOmitProjLongLatIfPossible(false); } } } @@ -11104,31 +11098,27 @@ CoordinateOperationFactory::Private::createOperations( if (!targetProjExportable) { throw InvalidOperation("Target CRS is not PROJ exportable"); } - auto projFormatter = io::PROJStringFormatter::create( - io::PROJStringFormatter::Convention::PROJ_4); + auto projFormatter = io::PROJStringFormatter::create(); + projFormatter->setCRSExport(true); projFormatter->startInversion(); sourceProjExportable->_exportToPROJString(projFormatter.get()); - auto geogSrc = dynamic_cast<const crs::GeographicCRS *>(sourceCRS.get()); if (geogSrc) { - auto proj5Formatter = io::PROJStringFormatter::create( - io::PROJStringFormatter::Convention::PROJ_5); - geogSrc->addAngularUnitConvertAndAxisSwap(proj5Formatter.get()); - projFormatter->ingestPROJString(proj5Formatter->toString()); + auto tmpFormatter = io::PROJStringFormatter::create(); + geogSrc->addAngularUnitConvertAndAxisSwap(tmpFormatter.get()); + projFormatter->ingestPROJString(tmpFormatter->toString()); } projFormatter->stopInversion(); targetProjExportable->_exportToPROJString(projFormatter.get()); - auto geogDst = dynamic_cast<const crs::GeographicCRS *>(targetCRS.get()); if (geogDst) { - auto proj5Formatter = io::PROJStringFormatter::create( - io::PROJStringFormatter::Convention::PROJ_5); - geogDst->addAngularUnitConvertAndAxisSwap(proj5Formatter.get()); - projFormatter->ingestPROJString(proj5Formatter->toString()); + auto tmpFormatter = io::PROJStringFormatter::create(); + geogDst->addAngularUnitConvertAndAxisSwap(tmpFormatter.get()); + projFormatter->ingestPROJString(tmpFormatter->toString()); } const auto PROJString = projFormatter->toString(); diff --git a/src/iso19111/crs.cpp b/src/iso19111/crs.cpp index 190291de..6776093a 100644 --- a/src/iso19111/crs.cpp +++ b/src/iso19111/crs.cpp @@ -1142,13 +1142,11 @@ void GeodeticCRS::addGeocentricUnitConversionIntoPROJString( const auto &unit = axisList[0]->unit(); if (!unit._isEquivalentTo(common::UnitOfMeasure::METRE, util::IComparable::Criterion::EQUIVALENT)) { - if (formatter->convention() == - io::PROJStringFormatter::Convention::PROJ_4) { - io::FormattingException::Throw("GeodeticCRS::exportToPROJString(): " - "non-meter unit not supported for " - "PROJ.4"); + if (formatter->getCRSExport()) { + io::FormattingException::Throw( + "GeodeticCRS::exportToPROJString() only " + "supports metre unit"); } - formatter->addStep("unitconvert"); formatter->addParam("xy_in", "m"); formatter->addParam("z_in", "m"); @@ -1164,8 +1162,7 @@ void GeodeticCRS::addGeocentricUnitConversionIntoPROJString( const auto &toSI = unit.conversionToSI(); formatter->addParam("xy_out", toSI); formatter->addParam("z_out", toSI); - } else if (formatter->convention() == - io::PROJStringFormatter::Convention::PROJ_4) { + } else if (formatter->getCRSExport()) { formatter->addParam("units", "m"); } } @@ -1177,14 +1174,11 @@ void GeodeticCRS::addGeocentricUnitConversionIntoPROJString( void GeodeticCRS::_exportToPROJString( io::PROJStringFormatter *formatter) const // throw(io::FormattingException) { - if (formatter->convention() == - io::PROJStringFormatter::Convention::PROJ_4) { - const auto &extensionProj4 = CRS::getPrivate()->extensionProj4_; - if (!extensionProj4.empty()) { - formatter->ingestPROJString(extensionProj4); - formatter->addNoDefs(false); - return; - } + const auto &extensionProj4 = CRS::getPrivate()->extensionProj4_; + if (!extensionProj4.empty()) { + formatter->ingestPROJString(extensionProj4); + formatter->addNoDefs(false); + return; } if (!isGeocentric()) { @@ -1193,11 +1187,10 @@ void GeodeticCRS::_exportToPROJString( "supports geocentric coordinate systems"); } - if (formatter->convention() == - io::PROJStringFormatter::Convention::PROJ_4) { - formatter->addStep("geocent"); - } else { + if (!formatter->getCRSExport()) { formatter->addStep("cart"); + } else { + formatter->addStep("geocent"); } addDatumInfoToPROJString(formatter); addGeocentricUnitConversionIntoPROJString(formatter); @@ -1214,9 +1207,8 @@ void GeodeticCRS::addDatumInfoToPROJString( bool datumWritten = false; const auto &nadgrids = formatter->getHDatumExtension(); const auto &l_datum = datum(); - if (formatter->convention() == - io::PROJStringFormatter::Convention::PROJ_4 && - l_datum && TOWGS84Params.empty() && nadgrids.empty()) { + if (formatter->getCRSExport() && l_datum && TOWGS84Params.empty() && + nadgrids.empty()) { if (l_datum->_isEquivalentTo( datum::GeodeticReferenceFrame::EPSG_6326.get(), util::IComparable::Criterion::EQUIVALENT)) { @@ -1857,57 +1849,53 @@ void GeographicCRS::addAngularUnitConvertAndAxisSwap( io::PROJStringFormatter *formatter) const { const auto &axisList = coordinateSystem()->axisList(); - if (formatter->convention() == - io::PROJStringFormatter::Convention::PROJ_5) { - - formatter->addStep("unitconvert"); - formatter->addParam("xy_in", "rad"); - if (axisList.size() == 3 && !formatter->omitZUnitConversion()) { - formatter->addParam("z_in", "m"); - } - { - const auto &unitHoriz = axisList[0]->unit(); - const auto projUnit = unitHoriz.exportToPROJString(); - if (projUnit.empty()) { - formatter->addParam("xy_out", unitHoriz.conversionToSI()); - } else { - formatter->addParam("xy_out", projUnit); - } + formatter->addStep("unitconvert"); + formatter->addParam("xy_in", "rad"); + if (axisList.size() == 3 && !formatter->omitZUnitConversion()) { + formatter->addParam("z_in", "m"); + } + { + const auto &unitHoriz = axisList[0]->unit(); + const auto projUnit = unitHoriz.exportToPROJString(); + if (projUnit.empty()) { + formatter->addParam("xy_out", unitHoriz.conversionToSI()); + } else { + formatter->addParam("xy_out", projUnit); } - if (axisList.size() == 3 && !formatter->omitZUnitConversion()) { - const auto &unitZ = axisList[2]->unit(); - auto projVUnit = unitZ.exportToPROJString(); - if (projVUnit.empty()) { - formatter->addParam("z_out", unitZ.conversionToSI()); - } else { - formatter->addParam("z_out", projVUnit); - } + } + if (axisList.size() == 3 && !formatter->omitZUnitConversion()) { + const auto &unitZ = axisList[2]->unit(); + auto projVUnit = unitZ.exportToPROJString(); + if (projVUnit.empty()) { + formatter->addParam("z_out", unitZ.conversionToSI()); + } else { + formatter->addParam("z_out", projVUnit); } + } - const char *order[2] = {nullptr, nullptr}; - const char *one = "1"; - const char *two = "2"; - for (int i = 0; i < 2; i++) { - const auto &dir = axisList[i]->direction(); - if (&dir == &cs::AxisDirection::WEST) { - order[i] = "-1"; - } else if (&dir == &cs::AxisDirection::EAST) { - order[i] = one; - } else if (&dir == &cs::AxisDirection::SOUTH) { - order[i] = "-2"; - } else if (&dir == &cs::AxisDirection::NORTH) { - order[i] = two; - } - } - if (order[0] && order[1] && (order[0] != one || order[1] != two)) { - formatter->addStep("axisswap"); - char orderStr[10]; - strcpy(orderStr, order[0]); - strcat(orderStr, ","); - strcat(orderStr, order[1]); - formatter->addParam("order", orderStr); + const char *order[2] = {nullptr, nullptr}; + const char *one = "1"; + const char *two = "2"; + for (int i = 0; i < 2; i++) { + const auto &dir = axisList[i]->direction(); + if (&dir == &cs::AxisDirection::WEST) { + order[i] = "-1"; + } else if (&dir == &cs::AxisDirection::EAST) { + order[i] = one; + } else if (&dir == &cs::AxisDirection::SOUTH) { + order[i] = "-2"; + } else if (&dir == &cs::AxisDirection::NORTH) { + order[i] = two; } } + if (order[0] && order[1] && (order[0] != one || order[1] != two)) { + formatter->addStep("axisswap"); + char orderStr[10]; + strcpy(orderStr, order[0]); + strcat(orderStr, ","); + strcat(orderStr, order[1]); + formatter->addParam("order", orderStr); + } } //! @endcond @@ -1917,14 +1905,11 @@ void GeographicCRS::addAngularUnitConvertAndAxisSwap( void GeographicCRS::_exportToPROJString( io::PROJStringFormatter *formatter) const // throw(io::FormattingException) { - if (formatter->convention() == - io::PROJStringFormatter::Convention::PROJ_4) { - const auto &extensionProj4 = CRS::getPrivate()->extensionProj4_; - if (!extensionProj4.empty()) { - formatter->ingestPROJString(extensionProj4); - formatter->addNoDefs(false); - return; - } + const auto &extensionProj4 = CRS::getPrivate()->extensionProj4_; + if (!extensionProj4.empty()) { + formatter->ingestPROJString(extensionProj4); + formatter->addNoDefs(false); + return; } if (!formatter->omitProjLongLatIfPossible() || @@ -1934,8 +1919,9 @@ void GeographicCRS::_exportToPROJString( formatter->addStep("longlat"); addDatumInfoToPROJString(formatter); } - - addAngularUnitConvertAndAxisSwap(formatter); + if (!formatter->getCRSExport()) { + addAngularUnitConvertAndAxisSwap(formatter); + } } //! @endcond @@ -2107,20 +2093,17 @@ void VerticalCRS::addLinearUnitConvert( io::PROJStringFormatter *formatter) const { auto &axisList = coordinateSystem()->axisList(); - if (formatter->convention() == - io::PROJStringFormatter::Convention::PROJ_5) { - if (!axisList.empty()) { - auto projUnit = axisList[0]->unit().exportToPROJString(); - if (axisList[0]->unit().conversionToSI() != 1.0) { - formatter->addStep("unitconvert"); - formatter->addParam("z_in", "m"); - auto projVUnit = axisList[0]->unit().exportToPROJString(); - if (projVUnit.empty()) { - formatter->addParam("z_out", - axisList[0]->unit().conversionToSI()); - } else { - formatter->addParam("z_out", projVUnit); - } + if (!axisList.empty()) { + auto projUnit = axisList[0]->unit().exportToPROJString(); + if (axisList[0]->unit().conversionToSI() != 1.0) { + formatter->addStep("unitconvert"); + formatter->addParam("z_in", "m"); + auto projVUnit = axisList[0]->unit().exportToPROJString(); + if (projVUnit.empty()) { + formatter->addParam("z_out", + axisList[0]->unit().conversionToSI()); + } else { + formatter->addParam("z_out", projVUnit); } } } @@ -2437,14 +2420,6 @@ void DerivedCRS::setDerivingConversionCRS() { // --------------------------------------------------------------------------- -void DerivedCRS::baseExportToPROJString( - io::PROJStringFormatter *formatter) const // throw(io::FormattingException) -{ - d->derivingConversion_->_exportToPROJString(formatter); -} - -// --------------------------------------------------------------------------- - void DerivedCRS::baseExportToWKT(io::WKTFormatter *&formatter, const std::string &keyword, const std::string &baseKeyword) const { @@ -2742,17 +2717,14 @@ void ProjectedCRS::_exportToWKT(io::WKTFormatter *formatter) const { void ProjectedCRS::_exportToPROJString( io::PROJStringFormatter *formatter) const // throw(io::FormattingException) { - if (formatter->convention() == - io::PROJStringFormatter::Convention::PROJ_4) { - const auto &extensionProj4 = CRS::getPrivate()->extensionProj4_; - if (!extensionProj4.empty()) { - formatter->ingestPROJString(extensionProj4); - formatter->addNoDefs(false); - return; - } + const auto &extensionProj4 = CRS::getPrivate()->extensionProj4_; + if (!extensionProj4.empty()) { + formatter->ingestPROJString(extensionProj4); + formatter->addNoDefs(false); + return; } - baseExportToPROJString(formatter); + derivingConversionRef()->_exportToPROJString(formatter); } // --------------------------------------------------------------------------- @@ -2821,8 +2793,7 @@ void ProjectedCRS::addUnitConvertAndAxisSwap(io::PROJStringFormatter *formatter, util::IComparable::Criterion::EQUIVALENT)) { auto projUnit = unit.exportToPROJString(); const double toSI = unit.conversionToSI(); - if (formatter->convention() == - io::PROJStringFormatter::Convention::PROJ_5) { + if (!formatter->getCRSExport()) { formatter->addStep("unitconvert"); formatter->addParam("xy_in", "m"); formatter->addParam("z_in", "m"); @@ -2840,17 +2811,11 @@ void ProjectedCRS::addUnitConvertAndAxisSwap(io::PROJStringFormatter *formatter, formatter->addParam("units", projUnit); } } - } else if (formatter->convention() == - io::PROJStringFormatter::Convention::PROJ_4) { - // could come from the hardcoded def of webmerc - if (!formatter->hasParam("units")) { - formatter->addParam("units", "m"); - } + } else if (formatter->getCRSExport()) { + formatter->addParam("units", "m"); } - if (formatter->convention() == - io::PROJStringFormatter::Convention::PROJ_5 && - !axisSpecFound) { + if (!axisSpecFound && !formatter->getCRSExport()) { const auto &dir0 = axisList[0]->direction(); const auto &dir1 = axisList[1]->direction(); if (!(&dir0 == &cs::AxisDirection::EAST && @@ -3792,13 +3757,6 @@ void BoundCRS::_exportToWKT(io::WKTFormatter *formatter) const { void BoundCRS::_exportToPROJString( io::PROJStringFormatter *formatter) const // throw(io::FormattingException) { - if (formatter->convention() == - io::PROJStringFormatter::Convention::PROJ_5) { - io::FormattingException::Throw( - "BoundCRS cannot be exported as a PROJ.5 string, but its baseCRS " - "might"); - } - auto crs_exportable = dynamic_cast<const io::IPROJStringExportable *>(d->baseCRS_.get()); if (!crs_exportable) { @@ -4086,9 +4044,10 @@ void DerivedGeodeticCRS::_exportToWKT(io::WKTFormatter *formatter) const { // --------------------------------------------------------------------------- void DerivedGeodeticCRS::_exportToPROJString( - io::PROJStringFormatter *formatter) const // throw(io::FormattingException) + io::PROJStringFormatter *) const // throw(io::FormattingException) { - baseExportToPROJString(formatter); + throw io::FormattingException( + "DerivedGeodeticCRS cannot be exported to PROJ string"); } // --------------------------------------------------------------------------- @@ -4223,9 +4182,10 @@ void DerivedGeographicCRS::_exportToWKT(io::WKTFormatter *formatter) const { // --------------------------------------------------------------------------- void DerivedGeographicCRS::_exportToPROJString( - io::PROJStringFormatter *formatter) const // throw(io::FormattingException) + io::PROJStringFormatter *) const // throw(io::FormattingException) { - baseExportToPROJString(formatter); + throw io::FormattingException( + "DerivedGeographicCRS cannot be exported to PROJ string"); } // --------------------------------------------------------------------------- @@ -4377,14 +4337,6 @@ void DerivedProjectedCRS::_exportToWKT(io::WKTFormatter *formatter) const { // --------------------------------------------------------------------------- -void DerivedProjectedCRS::_exportToPROJString( - io::PROJStringFormatter *formatter) const // throw(io::FormattingException) -{ - baseExportToPROJString(formatter); -} - -// --------------------------------------------------------------------------- - bool DerivedProjectedCRS::_isEquivalentTo( const util::IComparable *other, util::IComparable::Criterion criterion) const { @@ -4792,9 +4744,10 @@ void DerivedVerticalCRS::_exportToWKT(io::WKTFormatter *formatter) const { // --------------------------------------------------------------------------- void DerivedVerticalCRS::_exportToPROJString( - io::PROJStringFormatter *formatter) const // throw(io::FormattingException) + io::PROJStringFormatter *) const // throw(io::FormattingException) { - baseExportToPROJString(formatter); + throw io::FormattingException( + "DerivedVerticalCRS cannot be exported to PROJ string"); } // --------------------------------------------------------------------------- diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index cfccd70f..13a8f236 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -4596,15 +4596,19 @@ IPROJStringExportable::~IPROJStringExportable() = default; std::string IPROJStringExportable::exportToPROJString( PROJStringFormatter *formatter) const { + const bool bIsCRS = dynamic_cast<const crs::CRS *>(this) != nullptr; + if (bIsCRS) { + formatter->setCRSExport(true); + } _exportToPROJString(formatter); - if (formatter->getAddNoDefs() && - formatter->convention() == - io::PROJStringFormatter::Convention::PROJ_4 && - dynamic_cast<const crs::CRS *>(this)) { + if (formatter->getAddNoDefs() && bIsCRS) { if (!formatter->hasParam("no_defs")) { formatter->addParam("no_defs"); } } + if (bIsCRS) { + formatter->setCRSExport(false); + } return formatter->toString(); } //! @endcond @@ -4673,6 +4677,7 @@ struct PROJStringFormatter::Private { bool useETMercForTMercSet_ = false; bool addNoDefs_ = true; bool coordOperationOptimizations_ = false; + bool crsExport_ = false; std::string result_{}; @@ -5311,6 +5316,14 @@ void PROJStringFormatter::ingestPROJString( // --------------------------------------------------------------------------- +void PROJStringFormatter::setCRSExport(bool b) { d->crsExport_ = b; } + +// --------------------------------------------------------------------------- + +bool PROJStringFormatter::getCRSExport() const { return d->crsExport_; } + +// --------------------------------------------------------------------------- + void PROJStringFormatter::startInversion() { PROJStringFormatter::Private::InversionStackElt elt; elt.startIter = d->steps_.end(); diff --git a/test/cli/testprojinfo b/test/cli/testprojinfo index bae38482..70e4912f 100755 --- a/test/cli/testprojinfo +++ b/test/cli/testprojinfo @@ -82,6 +82,10 @@ echo "Testing non compliant WKT1" >> ${OUT} $EXE 'GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563]],UNIT["degree",0.0174532925199433]]' >>${OUT} 2>&1 echo "" >>${OUT} +echo "Testing CRS with towgs84: projinfo -o PROJ EPSG:25832" >> ${OUT} +$EXE -o PROJ EPSG:25832 >>${OUT} 2>&1 +echo "" >>${OUT} + # do 'diff' with distribution results echo "diff ${OUT} with testprojinfo_out.dist" diff -u ${OUT} ${TEST_CLI_DIR}/testprojinfo_out.dist diff --git a/test/cli/testprojinfo_out.dist b/test/cli/testprojinfo_out.dist index 1fd3bbbf..23e26975 100644 --- a/test/cli/testprojinfo_out.dist +++ b/test/cli/testprojinfo_out.dist @@ -1,6 +1,6 @@ Testing projinfo EPSG:4326 -PROJ string: -+proj=pipeline +step +proj=longlat +ellps=WGS84 +step +proj=unitconvert +xy_in=rad +xy_out=deg +step +proj=axisswap +order=2,1 +PROJ.4 string: ++proj=longlat +datum=WGS84 +no_defs WKT2_2015 string: GEODCRS["WGS 84", @@ -21,9 +21,6 @@ GEODCRS["WGS 84", ID["EPSG",4326]] Testing projinfo -o ALL EPSG:4326 -PROJ string: -+proj=pipeline +step +proj=longlat +ellps=WGS84 +step +proj=unitconvert +xy_in=rad +xy_out=deg +step +proj=axisswap +order=2,1 - PROJ.4 string: +proj=longlat +datum=WGS84 +no_defs @@ -483,8 +480,8 @@ Warning: object is deprecated Alternative non-deprecated CRS: EPSG:3003 -PROJ string: -+proj=pipeline +step +proj=axisswap +order=2,1 +step +proj=unitconvert +xy_in=deg +xy_out=rad +step +inv +proj=longlat +ellps=intl +pm=rome +step +proj=tmerc +lat_0=0 +lon_0=9 +k=0.9996 +x_0=1500000 +y_0=0 +ellps=intl +pm=rome +PROJ.4 string: ++proj=tmerc +lat_0=0 +lon_0=9 +k=0.9996 +x_0=1500000 +y_0=0 +ellps=intl +pm=rome +units=m +no_defs WKT2_2015 string: PROJCRS["Monte Mario (Rome) / Italy zone 1", @@ -528,8 +525,8 @@ Warning: GEOGCS should have a PRIMEM node Warning: Parsing error : syntax error, unexpected UNIT, expecting PRIMEM. Error occurred around: HEROID["WGS 84",6378137,298.257223563]],UNIT["degree",0.0174532925199433]] ^ -PROJ string: -+proj=pipeline +step +proj=longlat +ellps=WGS84 +step +proj=unitconvert +xy_in=rad +xy_out=deg +PROJ.4 string: ++proj=longlat +datum=WGS84 +no_defs WKT2_2015 string: GEODCRS["WGS 84", @@ -548,3 +545,7 @@ GEODCRS["WGS 84", ORDER[2], ANGLEUNIT["degree",0.0174532925199433]]] +Testing CRS with towgs84: projinfo -o PROJ EPSG:25832 +PROJ.4 string: ++proj=utm +zone=32 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs + diff --git a/test/unit/proj_angular_io_test.cpp b/test/unit/proj_angular_io_test.cpp index fdb44704..dbf09986 100644 --- a/test/unit/proj_angular_io_test.cpp +++ b/test/unit/proj_angular_io_test.cpp @@ -48,7 +48,9 @@ TEST(AngularUnits, Basic) { TEST(AngularUnits, Pipelines) { auto ctx = proj_context_create(); - auto P = proj_create(ctx, "proj=pipeline +step +proj=axisswap +order=2,1 +step +proj=latlong +step +proj=axisswap +order=2,1"); + auto P = + proj_create(ctx, "proj=pipeline +step +proj=axisswap +order=2,1 +step " + "+proj=latlong +step +proj=axisswap +order=2,1"); EXPECT_TRUE(proj_angular_input(P, PJ_FWD)); EXPECT_TRUE(proj_angular_output(P, PJ_FWD)); @@ -57,45 +59,43 @@ TEST(AngularUnits, Pipelines) { proj_destroy(P); proj_context_destroy(ctx); - } TEST(AngularUnits, Pipelines2) { auto ctx = proj_context_create(); auto P = proj_create( - ctx, - "+proj=pipeline " - "+step +proj=axisswap +order=2,1 " - "+step +proj=unitconvert +xy_in=deg +xy_out=rad " - "+step +proj=tmerc +lat_0=0 +lon_0=-81 +k=0.9996 +x_0=500000.001016002 +y_0=0 +ellps=WGS84 " - "+step +proj=axisswap +order=2,1 " - "+step +proj=unitconvert +xy_in=m +z_in=m +xy_out=us-ft +z_out=us-ft"); + ctx, + "+proj=pipeline " + "+step +proj=axisswap +order=2,1 " + "+step +proj=unitconvert +xy_in=deg +xy_out=rad " + "+step +proj=tmerc +lat_0=0 +lon_0=-81 +k=0.9996 +x_0=500000.001016002 " + "+y_0=0 +ellps=WGS84 " + "+step +proj=axisswap +order=2,1 " + "+step +proj=unitconvert +xy_in=m +z_in=m +xy_out=us-ft +z_out=us-ft"); EXPECT_FALSE(proj_angular_input(P, PJ_FWD)); EXPECT_FALSE(proj_angular_output(P, PJ_FWD)); proj_destroy(P); proj_context_destroy(ctx); - } TEST(AngularUnits, Pipelines3) { auto ctx = proj_context_create(); auto P = proj_create( - ctx, - "+proj=pipeline " - "+step +proj=axisswap +order=2,1 " - "+step +proj=tmerc +lat_0=0 +lon_0=-81 +k=0.9996 +x_0=500000.001016002 +y_0=0 +ellps=WGS84 " - "+step +proj=axisswap +order=2,1 " - "+step +proj=unitconvert +xy_in=m +z_in=m +xy_out=us-ft +z_out=us-ft"); + ctx, + "+proj=pipeline " + "+step +proj=axisswap +order=2,1 " + "+step +proj=tmerc +lat_0=0 +lon_0=-81 +k=0.9996 +x_0=500000.001016002 " + "+y_0=0 +ellps=WGS84 " + "+step +proj=axisswap +order=2,1 " + "+step +proj=unitconvert +xy_in=m +z_in=m +xy_out=us-ft +z_out=us-ft"); EXPECT_TRUE(proj_angular_input(P, PJ_FWD)); EXPECT_FALSE(proj_angular_output(P, PJ_FWD)); proj_destroy(P); proj_context_destroy(ctx); - } - } // namespace diff --git a/test/unit/test_c_api.cpp b/test/unit/test_c_api.cpp index 82cb7b75..6353d46f 100644 --- a/test/unit/test_c_api.cpp +++ b/test/unit/test_c_api.cpp @@ -492,10 +492,7 @@ TEST_F(CApi, proj_as_proj_string) { { auto proj_5 = proj_as_proj_string(m_ctxt, obj, PJ_PROJ_5, nullptr); ASSERT_NE(proj_5, nullptr); - EXPECT_EQ(std::string(proj_5), "+proj=pipeline +step +proj=longlat " - "+ellps=WGS84 +step +proj=unitconvert " - "+xy_in=rad +xy_out=deg +step " - "+proj=axisswap +order=2,1"); + EXPECT_EQ(std::string(proj_5), "+proj=longlat +datum=WGS84 +no_defs"); } { auto proj_4 = proj_as_proj_string(m_ctxt, obj, PJ_PROJ_4, nullptr); diff --git a/test/unit/test_crs.cpp b/test/unit/test_crs.cpp index fe0ac7e8..d3309fb2 100644 --- a/test/unit/test_crs.cpp +++ b/test/unit/test_crs.cpp @@ -388,14 +388,7 @@ TEST(crs, EPSG_4326_as_WKT1_ESRI_without_database) { TEST(crs, EPSG_4326_as_PROJ_string) { auto crs = GeographicCRS::EPSG_4326; EXPECT_EQ(crs->exportToPROJString(PROJStringFormatter::create().get()), - "+proj=pipeline +step +proj=longlat +ellps=WGS84 +step " - "+proj=unitconvert +xy_in=rad +xy_out=deg +step +proj=axisswap " - "+order=2,1"); - EXPECT_EQ( - crs->exportToPROJString( - PROJStringFormatter::create(PROJStringFormatter::Convention::PROJ_4) - .get()), - "+proj=longlat +datum=WGS84 +no_defs"); + "+proj=longlat +datum=WGS84 +no_defs"); } // --------------------------------------------------------------------------- @@ -595,14 +588,7 @@ TEST(crs, EPSG_4807_as_WKT1_ESRI_without_database) { TEST(crs, EPSG_4807_as_PROJ_string) { auto crs = GeographicCRS::EPSG_4807; EXPECT_EQ(crs->exportToPROJString(PROJStringFormatter::create().get()), - "+proj=pipeline +step +proj=longlat +ellps=clrk80ign " - "+pm=paris +step +proj=unitconvert +xy_in=rad +xy_out=grad +step " - "+proj=axisswap +order=2,1"); - EXPECT_EQ( - crs->exportToPROJString( - PROJStringFormatter::create(PROJStringFormatter::Convention::PROJ_4) - .get()), - "+proj=longlat +ellps=clrk80ign +pm=paris +no_defs"); + "+proj=longlat +ellps=clrk80ign +pm=paris +no_defs"); } // --------------------------------------------------------------------------- @@ -624,11 +610,8 @@ TEST(crs, EPSG_4267) { " ORDER[2],\n" " ANGLEUNIT[\"degree\",0.0174532925199433]],\n" " ID[\"EPSG\",4267]]"); - EXPECT_EQ( - crs->exportToPROJString( - PROJStringFormatter::create(PROJStringFormatter::Convention::PROJ_4) - .get()), - "+proj=longlat +datum=NAD27 +no_defs"); + EXPECT_EQ(crs->exportToPROJString(PROJStringFormatter::create().get()), + "+proj=longlat +datum=NAD27 +no_defs"); } // --------------------------------------------------------------------------- @@ -663,11 +646,8 @@ TEST(crs, EPSG_4269) { " ORDER[2],\n" " ANGLEUNIT[\"degree\",0.0174532925199433]],\n" " ID[\"EPSG\",4269]]"); - EXPECT_EQ( - crs->exportToPROJString( - PROJStringFormatter::create(PROJStringFormatter::Convention::PROJ_4) - .get()), - "+proj=longlat +datum=NAD83 +no_defs"); + EXPECT_EQ(crs->exportToPROJString(PROJStringFormatter::create().get()), + "+proj=longlat +datum=NAD83 +no_defs"); } // --------------------------------------------------------------------------- @@ -725,15 +705,6 @@ TEST(crs, EPSG_27561_projected_with_geodetic_in_grad_as_PROJ_string_and_WKT1) { ASSERT_TRUE(crs != nullptr); EXPECT_EQ( crs->exportToPROJString(PROJStringFormatter::create().get()), - "+proj=pipeline +step +proj=axisswap +order=2,1 +step " - "+proj=unitconvert +xy_in=grad +xy_out=rad +step +inv +proj=longlat " - "+ellps=clrk80ign +pm=paris +step +proj=lcc +lat_1=49.5 " - "+lat_0=49.5 +lon_0=0 +k_0=0.999877341 +x_0=600000 +y_0=200000 " - "+ellps=clrk80ign +pm=paris"); - EXPECT_EQ( - crs->exportToPROJString( - PROJStringFormatter::create(PROJStringFormatter::Convention::PROJ_4) - .get()), "+proj=lcc +lat_1=49.5 +lat_0=49.5 +lon_0=0 +k_0=0.999877341 " "+x_0=600000 +y_0=200000 +ellps=clrk80ign +pm=paris +units=m +no_defs"); @@ -811,9 +782,7 @@ TEST(crs, EPSG_3040_projected_northing_easting_as_PROJ_string) { auto crs = nn_dynamic_pointer_cast<ProjectedCRS>(obj); ASSERT_TRUE(crs != nullptr); EXPECT_EQ(crs->exportToPROJString(PROJStringFormatter::create().get()), - "+proj=pipeline +step +proj=axisswap +order=2,1 +step " - "+proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=utm " - "+zone=28 +ellps=GRS80 +step +proj=axisswap +order=2,1"); + "+proj=utm +zone=28 +ellps=GRS80 +units=m +no_defs"); } // --------------------------------------------------------------------------- @@ -843,17 +812,8 @@ TEST(crs, EPSG_2222_projected_unit_foot_as_PROJ_string_and_WKT1) { auto crs = nn_dynamic_pointer_cast<ProjectedCRS>(obj); ASSERT_TRUE(crs != nullptr); EXPECT_EQ(crs->exportToPROJString(PROJStringFormatter::create().get()), - "+proj=pipeline +step +proj=axisswap +order=2,1 +step " - "+proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=tmerc " - "+lat_0=31 +lon_0=-110.166666666667 +k=0.9999 +x_0=213360 " - "+y_0=0 +ellps=GRS80 +step +proj=unitconvert +xy_in=m +z_in=m " - "+xy_out=ft +z_out=ft"); - EXPECT_EQ( - crs->exportToPROJString( - PROJStringFormatter::create(PROJStringFormatter::Convention::PROJ_4) - .get()), - "+proj=tmerc +lat_0=31 +lon_0=-110.166666666667 +k=0.9999 " - "+x_0=213360 +y_0=0 +datum=NAD83 +units=ft +no_defs"); + "+proj=tmerc +lat_0=31 +lon_0=-110.166666666667 +k=0.9999 " + "+x_0=213360 +y_0=0 +datum=NAD83 +units=ft +no_defs"); auto wkt1 = crs->exportToWKT( WKTFormatter::create(WKTFormatter::Convention::WKT1_GDAL).get()); @@ -931,22 +891,18 @@ TEST(crs, EPSG_32661_projected_north_pole_north_east) { auto crs = factory->createCoordinateReferenceSystem("32661"); auto proj_crs = nn_dynamic_pointer_cast<ProjectedCRS>(crs); ASSERT_TRUE(proj_crs != nullptr); + auto proj_string = "+proj=pipeline +step +proj=axisswap +order=2,1 +step " "+proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=stere " "+lat_0=90 +lon_0=0 +k=0.994 +x_0=2000000 +y_0=2000000 " "+ellps=WGS84 +step +proj=axisswap +order=2,1"; - EXPECT_EQ(proj_crs->exportToPROJString(PROJStringFormatter::create().get()), - proj_string); - auto obj_from_proj = PROJStringParser().createFromPROJString(proj_string); - auto crs_from_proj = nn_dynamic_pointer_cast<ProjectedCRS>(obj_from_proj); - ASSERT_TRUE(crs_from_proj != nullptr); - EXPECT_EQ( - crs_from_proj->exportToPROJString(PROJStringFormatter::create().get()), - proj_string); - EXPECT_TRUE(crs_from_proj->coordinateSystem()->isEquivalentTo( - proj_crs->coordinateSystem().get())); + auto op = CoordinateOperationFactory::create()->createOperation( + GeographicCRS::EPSG_4326, NN_NO_CHECK(proj_crs)); + ASSERT_TRUE(op != nullptr); + EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), + proj_string); } // --------------------------------------------------------------------------- @@ -962,17 +918,12 @@ TEST(crs, EPSG_5041_projected_north_pole_east_north) { "+proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=stere " "+lat_0=90 +lon_0=0 +k=0.994 +x_0=2000000 +y_0=2000000 " "+ellps=WGS84"; - EXPECT_EQ(proj_crs->exportToPROJString(PROJStringFormatter::create().get()), - proj_string); - auto obj_from_proj = PROJStringParser().createFromPROJString(proj_string); - auto crs_from_proj = nn_dynamic_pointer_cast<ProjectedCRS>(obj_from_proj); - ASSERT_TRUE(crs_from_proj != nullptr); - EXPECT_EQ( - crs_from_proj->exportToPROJString(PROJStringFormatter::create().get()), - proj_string); - EXPECT_TRUE(crs_from_proj->coordinateSystem()->isEquivalentTo( - proj_crs->coordinateSystem().get())); + auto op = CoordinateOperationFactory::create()->createOperation( + GeographicCRS::EPSG_4326, NN_NO_CHECK(proj_crs)); + ASSERT_TRUE(op != nullptr); + EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), + proj_string); } // --------------------------------------------------------------------------- @@ -988,17 +939,12 @@ TEST(crs, EPSG_32761_projected_south_pole_north_east) { "+proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=stere " "+lat_0=-90 +lon_0=0 +k=0.994 +x_0=2000000 +y_0=2000000 " "+ellps=WGS84 +step +proj=axisswap +order=2,1"; - EXPECT_EQ(proj_crs->exportToPROJString(PROJStringFormatter::create().get()), - proj_string); - auto obj_from_proj = PROJStringParser().createFromPROJString(proj_string); - auto crs_from_proj = nn_dynamic_pointer_cast<ProjectedCRS>(obj_from_proj); - ASSERT_TRUE(crs_from_proj != nullptr); - EXPECT_EQ( - crs_from_proj->exportToPROJString(PROJStringFormatter::create().get()), - proj_string); - EXPECT_TRUE(crs_from_proj->coordinateSystem()->isEquivalentTo( - proj_crs->coordinateSystem().get())); + auto op = CoordinateOperationFactory::create()->createOperation( + GeographicCRS::EPSG_4326, NN_NO_CHECK(proj_crs)); + ASSERT_TRUE(op != nullptr); + EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), + proj_string); } // --------------------------------------------------------------------------- @@ -1009,11 +955,17 @@ TEST(crs, EPSG_5042_projected_south_pole_east_north) { auto crs = factory->createCoordinateReferenceSystem("5042"); auto proj_crs = nn_dynamic_pointer_cast<ProjectedCRS>(crs); ASSERT_TRUE(proj_crs != nullptr); - EXPECT_EQ(proj_crs->exportToPROJString(PROJStringFormatter::create().get()), - "+proj=pipeline +step +proj=axisswap +order=2,1 +step " - "+proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=stere " - "+lat_0=-90 +lon_0=0 +k=0.994 +x_0=2000000 +y_0=2000000 " - "+ellps=WGS84"); + auto proj_string = + "+proj=pipeline +step +proj=axisswap +order=2,1 +step " + "+proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=stere " + "+lat_0=-90 +lon_0=0 +k=0.994 +x_0=2000000 +y_0=2000000 " + "+ellps=WGS84"; + + auto op = CoordinateOperationFactory::create()->createOperation( + GeographicCRS::EPSG_4326, NN_NO_CHECK(proj_crs)); + ASSERT_TRUE(op != nullptr); + EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), + proj_string); } // --------------------------------------------------------------------------- @@ -1157,12 +1109,7 @@ TEST(crs, EPSG_4978_as_WKT1_GDAL_with_database) { TEST(crs, geocentricCRS_as_PROJ_string) { auto crs = createGeocentric(); EXPECT_EQ(crs->exportToPROJString(PROJStringFormatter::create().get()), - "+proj=cart +ellps=WGS84"); - EXPECT_EQ( - crs->exportToPROJString( - PROJStringFormatter::create(PROJStringFormatter::Convention::PROJ_4) - .get()), - "+proj=geocent +datum=WGS84 +units=m +no_defs"); + "+proj=geocent +datum=WGS84 +units=m +no_defs"); } // --------------------------------------------------------------------------- @@ -1173,14 +1120,17 @@ TEST(crs, geocentricCRS_non_meter_unit_as_PROJ_string) { CartesianCS::createGeocentric( UnitOfMeasure("kilometre", 1000.0, UnitOfMeasure::Type::LINEAR))); - EXPECT_EQ(crs->exportToPROJString(PROJStringFormatter::create().get()), - "+proj=pipeline +step +proj=cart +ellps=WGS84 +step " - "+proj=unitconvert +xy_in=m +z_in=m +xy_out=km +z_out=km"); - EXPECT_THROW( - crs->exportToPROJString( - PROJStringFormatter::create(PROJStringFormatter::Convention::PROJ_4) - .get()), - FormattingException); + auto op = CoordinateOperationFactory::create()->createOperation( + GeographicCRS::EPSG_4326, crs); + ASSERT_TRUE(op != nullptr); + EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), + "+proj=pipeline +step +proj=axisswap +order=2,1 +step " + "+proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=cart " + "+ellps=WGS84 +step +proj=unitconvert +xy_in=m +z_in=m " + "+xy_out=km +z_out=km"); + + EXPECT_THROW(crs->exportToPROJString(PROJStringFormatter::create().get()), + FormattingException); } // --------------------------------------------------------------------------- @@ -1191,9 +1141,14 @@ TEST(crs, geocentricCRS_unsupported_unit_as_PROJ_string) { CartesianCS::createGeocentric( UnitOfMeasure("my unit", 500.0, UnitOfMeasure::Type::LINEAR))); - EXPECT_EQ(crs->exportToPROJString(PROJStringFormatter::create().get()), - "+proj=pipeline +step +proj=cart +ellps=WGS84 +step " - "+proj=unitconvert +xy_in=m +z_in=m +xy_out=500 +z_out=500"); + auto op = CoordinateOperationFactory::create()->createOperation( + GeographicCRS::EPSG_4326, crs); + ASSERT_TRUE(op != nullptr); + EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), + "+proj=pipeline +step +proj=axisswap +order=2,1 +step " + "+proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=cart " + "+ellps=WGS84 +step +proj=unitconvert +xy_in=m +z_in=m " + "+xy_out=500 +z_out=500"); } // --------------------------------------------------------------------------- @@ -1556,7 +1511,7 @@ TEST(crs, projectedCRS_shallowClone) { } EXPECT_EQ(clone->baseCRS()->exportToPROJString( PROJStringFormatter::create().get()), - "+proj=cart +ellps=WGS84"); + "+proj=geocent +datum=WGS84 +units=m +no_defs"); } } @@ -1785,15 +1740,16 @@ TEST(crs, projectedCRS_from_WKT1_ESRI_as_WKT1_ESRI) { TEST(crs, projectedCRS_as_PROJ_string) { auto crs = createProjected(); - EXPECT_EQ(crs->exportToPROJString(PROJStringFormatter::create().get()), + + auto op = CoordinateOperationFactory::create()->createOperation( + GeographicCRS::EPSG_4326, crs); + ASSERT_TRUE(op != nullptr); + EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), "+proj=pipeline +step +proj=axisswap +order=2,1 +step " "+proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=utm " "+zone=31 +ellps=WGS84"); - EXPECT_EQ( - crs->exportToPROJString( - PROJStringFormatter::create(PROJStringFormatter::Convention::PROJ_4) - .get()), - "+proj=utm +zone=31 +datum=WGS84 +units=m +no_defs"); + EXPECT_EQ(crs->exportToPROJString(PROJStringFormatter::create().get()), + "+proj=utm +zone=31 +datum=WGS84 +units=m +no_defs"); } // --------------------------------------------------------------------------- @@ -1802,7 +1758,10 @@ TEST(crs, projectedCRS_Krovak_EPSG_5221_as_PROJ_string) { auto factory = AuthorityFactory::create(DatabaseContext::create(), "EPSG"); auto crs = factory->createProjectedCRS("5221"); // 30deg 17' 17.30311'' = 30.28813975277777776 - EXPECT_EQ(crs->exportToPROJString(PROJStringFormatter::create().get()), + auto op = CoordinateOperationFactory::create()->createOperation( + crs->baseCRS(), crs); + ASSERT_TRUE(op != nullptr); + EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), "+proj=pipeline +step +proj=axisswap +order=2,1 " "+step +proj=unitconvert +xy_in=deg +xy_out=rad " "+step +inv +proj=longlat +ellps=bessel +pm=ferro " @@ -1819,7 +1778,10 @@ TEST(crs, projectedCRS_Krovak_with_approximate_alpha_as_PROJ_string) { "+proj=krovak +lat_0=49.5 +lon_0=42.5 +alpha=30.28813972222222 " "+k=0.9999 +x_0=0 +y_0=0 +ellps=bessel +pm=ferro +units=m +no_defs"); auto crs = nn_dynamic_pointer_cast<ProjectedCRS>(obj); - EXPECT_EQ(crs->exportToPROJString(PROJStringFormatter::create().get()), + auto op = CoordinateOperationFactory::create()->createOperation( + crs->baseCRS(), NN_NO_CHECK(crs)); + ASSERT_TRUE(op != nullptr); + EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), "+proj=pipeline " "+step +proj=unitconvert +xy_in=deg +xy_out=rad " "+step +inv +proj=longlat +ellps=bessel +pm=ferro " @@ -3159,17 +3121,8 @@ TEST(crs, compoundCRS_as_WKT1_GDAL) { TEST(crs, compoundCRS_as_PROJ_string) { auto crs = createCompoundCRS(); - auto expected = "+proj=pipeline +step +proj=axisswap +order=2,1 +step " - "+proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=utm " - "+zone=31 +ellps=WGS84 +vunits=m"; - EXPECT_EQ(crs->exportToPROJString(PROJStringFormatter::create().get()), - expected); - EXPECT_EQ( - crs->exportToPROJString( - PROJStringFormatter::create(PROJStringFormatter::Convention::PROJ_4) - .get()), - "+proj=utm +zone=31 +datum=WGS84 +units=m +vunits=m +no_defs"); + "+proj=utm +zone=31 +datum=WGS84 +units=m +vunits=m +no_defs"); } // --------------------------------------------------------------------------- @@ -3586,13 +3539,8 @@ TEST(crs, boundCRS_geographicCRS_to_PROJ_string) { auto crs = BoundCRS::createFromTOWGS84( basecrs, std::vector<double>{1, 2, 3, 4, 5, 6, 7}); - EXPECT_THROW(crs->exportToPROJString(PROJStringFormatter::create().get()), - FormattingException); - EXPECT_EQ( - crs->exportToPROJString( - PROJStringFormatter::create(PROJStringFormatter::Convention::PROJ_4) - .get()), - "+proj=longlat +ellps=WGS84 +towgs84=1,2,3,4,5,6,7 +no_defs"); + EXPECT_EQ(crs->exportToPROJString(PROJStringFormatter::create().get()), + "+proj=longlat +ellps=WGS84 +towgs84=1,2,3,4,5,6,7 +no_defs"); } // --------------------------------------------------------------------------- @@ -3611,12 +3559,9 @@ TEST(crs, boundCRS_projectedCRS_to_PROJ_string) { auto crs = BoundCRS::createFromTOWGS84( projcrs, std::vector<double>{1, 2, 3, 4, 5, 6, 7}); - EXPECT_EQ( - crs->exportToPROJString( - PROJStringFormatter::create(PROJStringFormatter::Convention::PROJ_4) - .get()), - "+proj=utm +zone=31 +ellps=WGS84 +towgs84=1,2,3,4,5,6,7 +units=m " - "+no_defs"); + EXPECT_EQ(crs->exportToPROJString(PROJStringFormatter::create().get()), + "+proj=utm +zone=31 +ellps=WGS84 +towgs84=1,2,3,4,5,6,7 +units=m " + "+no_defs"); } // --------------------------------------------------------------------------- @@ -3742,12 +3687,9 @@ TEST(crs, WKT1_DATUM_EXTENSION_to_WKT1_and_PROJ_string) { WKTFormatter::create(WKTFormatter::Convention::WKT1_GDAL).get()), wkt); - EXPECT_EQ( - crs->exportToPROJString( - PROJStringFormatter::create(PROJStringFormatter::Convention::PROJ_4) - .get()), - "+proj=nzmg +lat_0=-41 +lon_0=173 +x_0=2510000 +y_0=6023150 " - "+ellps=intl +nadgrids=nzgd2kgrid0005.gsb +units=m +no_defs"); + EXPECT_EQ(crs->exportToPROJString(PROJStringFormatter::create().get()), + "+proj=nzmg +lat_0=-41 +lon_0=173 +x_0=2510000 +y_0=6023150 " + "+ellps=intl +nadgrids=nzgd2kgrid0005.gsb +units=m +no_defs"); } // --------------------------------------------------------------------------- @@ -3843,11 +3785,8 @@ TEST(crs, WKT1_VERT_DATUM_EXTENSION_to_PROJ_string) { auto crs = nn_dynamic_pointer_cast<BoundCRS>(obj); ASSERT_TRUE(crs != nullptr); - EXPECT_EQ( - crs->exportToPROJString( - PROJStringFormatter::create(PROJStringFormatter::Convention::PROJ_4) - .get()), - "+geoidgrids=egm08_25.gtx +vunits=m +no_defs"); + EXPECT_EQ(crs->exportToPROJString(PROJStringFormatter::create().get()), + "+geoidgrids=egm08_25.gtx +vunits=m +no_defs"); } // --------------------------------------------------------------------------- @@ -4022,8 +3961,11 @@ TEST(crs, derivedGeographicCRS_to_PROJ) { auto obj = WKTParser().createFromWKT(wkt); auto crs = nn_dynamic_pointer_cast<DerivedGeographicCRS>(obj); ASSERT_TRUE(crs != nullptr); + auto op = CoordinateOperationFactory::create()->createOperation( + crs->baseCRS(), NN_NO_CHECK(crs)); + ASSERT_TRUE(op != nullptr); EXPECT_EQ( - crs->exportToPROJString(PROJStringFormatter::create().get()), + op->exportToPROJString(PROJStringFormatter::create().get()), "+proj=pipeline +step +proj=axisswap +order=2,1 +step " "+proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=ob_tran " "+o_proj=longlat +o_lat_p=52 +o_lon_p=-30 +lon_0=-25 +ellps=WGS84 " @@ -4071,7 +4013,10 @@ TEST(crs, derivedGeographicCRS_with_affine_transform_to_PROJ) { auto crs = nn_dynamic_pointer_cast<DerivedGeographicCRS>(obj); ASSERT_TRUE(crs != nullptr); EXPECT_TRUE(crs->derivingConversion()->validateParameters().empty()); - EXPECT_EQ(crs->exportToPROJString(PROJStringFormatter::create().get()), + auto op = CoordinateOperationFactory::create()->createOperation( + crs->baseCRS(), NN_NO_CHECK(crs)); + ASSERT_TRUE(op != nullptr); + EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), "+proj=affine +xoff=0.5 +s11=1 +s12=0 +yoff=2.5 +s21=0 +s22=1"); } @@ -4254,15 +4199,6 @@ TEST(crs, derivedProjectedCRS_WKT2_2015) { // --------------------------------------------------------------------------- -TEST(crs, derivedProjectedCRS_to_PROJ) { - - auto crs = createDerivedProjectedCRS(); - EXPECT_EQ(crs->exportToPROJString(PROJStringFormatter::create().get()), - "+proj=unimplemented"); -} - -// --------------------------------------------------------------------------- - static DateTimeTemporalCSNNPtr createDateTimeTemporalCS() { return DateTimeTemporalCS::create( PropertyMap(), @@ -4806,14 +4742,12 @@ TEST(crs, crs_createBoundCRSToWGS84IfPossible) { bound); auto boundCRS = nn_dynamic_pointer_cast<BoundCRS>(bound); ASSERT_TRUE(boundCRS != nullptr); - EXPECT_EQ(boundCRS->exportToPROJString( - PROJStringFormatter::create( - PROJStringFormatter::Convention::PROJ_4) - .get()), - "+proj=sterea +lat_0=46 +lon_0=25 +k=0.99975 +x_0=500000 " - "+y_0=500000 +ellps=krass " - "+towgs84=2.329,-147.042,-92.08,-0.309,0.325,0.497,5.69 " - "+units=m +no_defs"); + EXPECT_EQ( + boundCRS->exportToPROJString(PROJStringFormatter::create().get()), + "+proj=sterea +lat_0=46 +lon_0=25 +k=0.99975 +x_0=500000 " + "+y_0=500000 +ellps=krass " + "+towgs84=2.329,-147.042,-92.08,-0.309,0.325,0.497,5.69 " + "+units=m +no_defs"); } { // Pulkovo 42 Poland @@ -4825,14 +4759,12 @@ TEST(crs, crs_createBoundCRSToWGS84IfPossible) { bound); auto boundCRS = nn_dynamic_pointer_cast<BoundCRS>(bound); ASSERT_TRUE(boundCRS != nullptr); - EXPECT_EQ(boundCRS->exportToPROJString( - PROJStringFormatter::create( - PROJStringFormatter::Convention::PROJ_4) - .get()), - "+proj=sterea +lat_0=50.625 +lon_0=21.0833333333333 " - "+k=0.9998 +x_0=4637000 +y_0=5647000 +ellps=krass " - "+towgs84=33.4,-146.6,-76.3,-0.359,-0.053,0.844,-0.84 " - "+units=m +no_defs"); + EXPECT_EQ( + boundCRS->exportToPROJString(PROJStringFormatter::create().get()), + "+proj=sterea +lat_0=50.625 +lon_0=21.0833333333333 " + "+k=0.9998 +x_0=4637000 +y_0=5647000 +ellps=krass " + "+towgs84=33.4,-146.6,-76.3,-0.359,-0.053,0.844,-0.84 " + "+units=m +no_defs"); } { // NTF (Paris) @@ -4844,12 +4776,10 @@ TEST(crs, crs_createBoundCRSToWGS84IfPossible) { bound); auto boundCRS = nn_dynamic_pointer_cast<BoundCRS>(bound); ASSERT_TRUE(boundCRS != nullptr); - EXPECT_EQ(boundCRS->exportToPROJString( - PROJStringFormatter::create( - PROJStringFormatter::Convention::PROJ_4) - .get()), - "+proj=longlat +ellps=clrk80ign +pm=paris " - "+towgs84=-168,-60,320,0,0,0,0 +no_defs"); + EXPECT_EQ( + boundCRS->exportToPROJString(PROJStringFormatter::create().get()), + "+proj=longlat +ellps=clrk80ign +pm=paris " + "+towgs84=-168,-60,320,0,0,0,0 +no_defs"); } { // NTF (Paris) / Lambert zone II + NGF-IGN69 height @@ -4861,14 +4791,12 @@ TEST(crs, crs_createBoundCRSToWGS84IfPossible) { bound); auto boundCRS = nn_dynamic_pointer_cast<BoundCRS>(bound); ASSERT_TRUE(boundCRS != nullptr); - EXPECT_EQ(boundCRS->exportToPROJString( - PROJStringFormatter::create( - PROJStringFormatter::Convention::PROJ_4) - .get()), - "+proj=lcc +lat_1=46.8 +lat_0=46.8 +lon_0=0 +k_0=0.99987742 " - "+x_0=600000 +y_0=2200000 +ellps=clrk80ign +pm=paris " - "+towgs84=-168,-60,320,0,0,0,0 +units=m " - "+vunits=m +no_defs"); + EXPECT_EQ( + boundCRS->exportToPROJString(PROJStringFormatter::create().get()), + "+proj=lcc +lat_1=46.8 +lat_0=46.8 +lon_0=0 +k_0=0.99987742 " + "+x_0=600000 +y_0=2200000 +ellps=clrk80ign +pm=paris " + "+towgs84=-168,-60,320,0,0,0,0 +units=m " + "+vunits=m +no_defs"); } { auto crs = createVerticalCRS(); @@ -4882,13 +4810,11 @@ TEST(crs, crs_createBoundCRSToWGS84IfPossible) { EXPECT_NE(bound, crs); auto boundCRS = nn_dynamic_pointer_cast<BoundCRS>(bound); ASSERT_TRUE(boundCRS != nullptr); - EXPECT_EQ(boundCRS->exportToPROJString( - PROJStringFormatter::create( - PROJStringFormatter::Convention::PROJ_4) - .get()), - "+proj=stere +lat_0=-90 +lon_0=140 +k=0.960272946 " - "+x_0=300000 +y_0=-2299363.482 +ellps=intl " - "+towgs84=324.8,153.6,172.1,0,0,0,0 +units=m +no_defs"); + EXPECT_EQ( + boundCRS->exportToPROJString(PROJStringFormatter::create().get()), + "+proj=stere +lat_0=-90 +lon_0=140 +k=0.960272946 " + "+x_0=300000 +y_0=-2299363.482 +ellps=intl " + "+towgs84=324.8,153.6,172.1,0,0,0,0 +units=m +no_defs"); } { auto factoryIGNF = @@ -4898,12 +4824,10 @@ TEST(crs, crs_createBoundCRSToWGS84IfPossible) { EXPECT_NE(bound, crs); auto boundCRS = nn_dynamic_pointer_cast<BoundCRS>(bound); ASSERT_TRUE(boundCRS != nullptr); - EXPECT_EQ(boundCRS->exportToPROJString( - PROJStringFormatter::create( - PROJStringFormatter::Convention::PROJ_4) - .get()), - "+proj=geocent +ellps=intl " - "+towgs84=324.8,153.6,172.1,0,0,0,0 +units=m +no_defs"); + EXPECT_EQ( + boundCRS->exportToPROJString(PROJStringFormatter::create().get()), + "+proj=geocent +ellps=intl " + "+towgs84=324.8,153.6,172.1,0,0,0,0 +units=m +no_defs"); } { auto crs = factory->createCoordinateReferenceSystem("4269"); // NAD83 diff --git a/test/unit/test_factory.cpp b/test/unit/test_factory.cpp index deff6b63..e9b29728 100644 --- a/test/unit/test_factory.cpp +++ b/test/unit/test_factory.cpp @@ -409,9 +409,7 @@ TEST(factory, AuthorityFactory_createGeodeticCRS_geographic2D) { EXPECT_TRUE(extent->isEquivalentTo(factory->createExtent("1262").get())); EXPECT_EQ(crs->exportToPROJString(PROJStringFormatter::create().get()), - "+proj=pipeline +step +proj=longlat +ellps=WGS84 +step " - "+proj=unitconvert +xy_in=rad +xy_out=deg +step +proj=axisswap " - "+order=2,1"); + "+proj=longlat +datum=WGS84 +no_defs"); } // --------------------------------------------------------------------------- @@ -972,11 +970,9 @@ TEST(factory, AuthorityFactory_test_uom_9110) { // This tests conversion from unit of measure EPSG:9110 DDD.MMSSsss auto crs = factory->createProjectedCRS("2172"); EXPECT_EQ(crs->exportToPROJString(PROJStringFormatter::create().get()), - "+proj=pipeline +step +proj=axisswap +order=2,1 +step " - "+proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=sterea " - "+lat_0=53.0019444444444 +lon_0=21.5027777777778 +k=0.9998 " - "+x_0=4603000 +y_0=5806000 +ellps=krass +step +proj=axisswap " - "+order=2,1"); + "+proj=sterea +lat_0=53.0019444444444 +lon_0=21.5027777777778 " + "+k=0.9998 +x_0=4603000 +y_0=5806000 +ellps=krass +units=m " + "+no_defs"); } // --------------------------------------------------------------------------- @@ -2327,10 +2323,8 @@ TEST_F(FactoryWithTmpDatabase, custom_projected_crs) { EXPECT_EQ(*(crs->name()->description()), "my name"); EXPECT_EQ(crs->identifiers().size(), 1); EXPECT_EQ(crs->derivingConversion()->targetCRS().get(), crs.get()); - EXPECT_EQ( - crs->exportToPROJString(PROJStringFormatter::create().get()), - "+proj=pipeline +step +proj=unitconvert +xy_in=deg +xy_out=rad " - "+step +proj=mbt_s +unused_flag +ellps=WGS84"); + EXPECT_EQ(crs->exportToPROJString(PROJStringFormatter::create().get()), + "+proj=mbt_s +unused_flag +datum=WGS84 +units=m +no_defs"); EXPECT_TRUE(crs->canonicalBoundCRS() == nullptr); } { @@ -2338,10 +2332,8 @@ TEST_F(FactoryWithTmpDatabase, custom_projected_crs) { EXPECT_EQ(*(crs->name()->description()), "my name"); EXPECT_EQ(crs->identifiers().size(), 1); EXPECT_EQ(crs->derivingConversion()->targetCRS().get(), crs.get()); - EXPECT_EQ( - crs->exportToPROJString(PROJStringFormatter::create().get()), - "+proj=pipeline +step +proj=unitconvert +xy_in=deg +xy_out=rad " - "+step +proj=mbt_s +unused_flag +ellps=WGS84"); + EXPECT_EQ(crs->exportToPROJString(PROJStringFormatter::create().get()), + "+proj=mbt_s +unused_flag +datum=WGS84 +units=m +no_defs"); EXPECT_TRUE(crs->canonicalBoundCRS() != nullptr); } diff --git a/test/unit/test_io.cpp b/test/unit/test_io.cpp index fc20b08d..3eabfc03 100644 --- a/test/unit/test_io.cpp +++ b/test/unit/test_io.cpp @@ -1253,11 +1253,10 @@ TEST(wkt_parse, wkt1_krovak_south_west) { auto projString = crs->exportToPROJString(PROJStringFormatter::create().get()); - auto expectedPROJString = - "+proj=pipeline +step +proj=unitconvert +xy_in=deg +xy_out=rad " - "+step +proj=krovak +axis=swu +lat_0=49.5 " - "+lon_0=24.8333333333333 +alpha=30.2881397222222 " - "+k=0.9999 +x_0=0 +y_0=0 +ellps=bessel"; + auto expectedPROJString = "+proj=krovak +axis=swu +lat_0=49.5 " + "+lon_0=24.8333333333333 +alpha=30.2881397222222 " + "+k=0.9999 +x_0=0 +y_0=0 +ellps=bessel +units=m " + "+no_defs"; EXPECT_EQ(projString, expectedPROJString); obj = PROJStringParser().createFromPROJString(projString); @@ -1368,9 +1367,9 @@ TEST(wkt_parse, wkt1_krovak_north_oriented) { " ID[\"EPSG\",5514]]"); EXPECT_EQ(crs->exportToPROJString(PROJStringFormatter::create().get()), - "+proj=pipeline +step +proj=unitconvert +xy_in=deg +xy_out=rad " - "+step +proj=krovak +lat_0=49.5 +lon_0=24.8333333333333 " - "+alpha=30.2881397222222 +k=0.9999 +x_0=0 +y_0=0 +ellps=bessel"); + "+proj=krovak +lat_0=49.5 +lon_0=24.8333333333333 " + "+alpha=30.2881397222222 +k=0.9999 +x_0=0 +y_0=0 +ellps=bessel " + "+units=m +no_defs"); } // --------------------------------------------------------------------------- @@ -6892,17 +6891,20 @@ TEST(io, projparse_longlat_pm_overriding_datum) { TEST(io, projparse_longlat_complex) { std::string input = - "+proj=pipeline +step +proj=longlat +ellps=clrk80ign " + "+step +proj=longlat +ellps=clrk80ign " "+pm=paris +step +proj=unitconvert +xy_in=rad +xy_out=grad +step " "+proj=axisswap +order=2,1"; - auto obj = PROJStringParser().createFromPROJString(input); + auto obj = + PROJStringParser().createFromPROJString("+proj=pipeline " + input); auto crs = nn_dynamic_pointer_cast<GeographicCRS>(obj); ASSERT_TRUE(crs != nullptr); - EXPECT_EQ( - crs->exportToPROJString( - PROJStringFormatter::create(PROJStringFormatter::Convention::PROJ_5) - .get()), - input); + auto op = CoordinateOperationFactory::create()->createOperation( + GeographicCRS::EPSG_4326, NN_NO_CHECK(crs)); + ASSERT_TRUE(op != nullptr); + EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), + "+proj=pipeline +step +proj=axisswap +order=2,1 +step " + "+proj=unitconvert +xy_in=deg +xy_out=rad " + + input); } // --------------------------------------------------------------------------- @@ -7069,7 +7071,7 @@ TEST(io, projparse_vunits) { auto crs = nn_dynamic_pointer_cast<VerticalCRS>(obj); ASSERT_TRUE(crs != nullptr); EXPECT_EQ(crs->exportToPROJString(PROJStringFormatter::create().get()), - "+vunits=ft"); + "+vunits=ft +no_defs"); } // --------------------------------------------------------------------------- @@ -7079,7 +7081,7 @@ TEST(io, projparse_vto_meter) { auto crs = nn_dynamic_pointer_cast<VerticalCRS>(obj); ASSERT_TRUE(crs != nullptr); EXPECT_EQ(crs->exportToPROJString(PROJStringFormatter::create().get()), - "+vto_meter=2"); + "+vto_meter=2 +no_defs"); } // --------------------------------------------------------------------------- @@ -7102,9 +7104,11 @@ TEST(io, projparse_longlat_axis_enu) { std::string::npos) << wkt; - EXPECT_EQ(crs->exportToPROJString(PROJStringFormatter::create().get()), - "+proj=pipeline +step +proj=longlat +ellps=GRS80 +step " - "+proj=unitconvert +xy_in=rad +xy_out=deg"); + auto op = CoordinateOperationFactory::create()->createOperation( + GeographicCRS::EPSG_4326, NN_NO_CHECK(crs)); + ASSERT_TRUE(op != nullptr); + EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), + "+proj=axisswap +order=2,1"); } // --------------------------------------------------------------------------- @@ -7127,10 +7131,10 @@ TEST(io, projparse_longlat_axis_neu) { std::string::npos) << wkt; - EXPECT_EQ(crs->exportToPROJString(PROJStringFormatter::create().get()), - "+proj=pipeline +step +proj=longlat +ellps=GRS80 +step " - "+proj=unitconvert +xy_in=rad +xy_out=deg +step +proj=axisswap " - "+order=2,1"); + auto op = CoordinateOperationFactory::create()->createOperation( + GeographicCRS::EPSG_4326, NN_NO_CHECK(crs)); + ASSERT_TRUE(op != nullptr); + EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), ""); } // --------------------------------------------------------------------------- @@ -7153,10 +7157,12 @@ TEST(io, projparse_longlat_axis_swu) { std::string::npos) << wkt; - EXPECT_EQ(crs->exportToPROJString(PROJStringFormatter::create().get()), - "+proj=pipeline +step +proj=longlat +ellps=GRS80 +step " - "+proj=unitconvert +xy_in=rad +xy_out=deg +step +proj=axisswap " - "+order=-2,-1"); + auto op = CoordinateOperationFactory::create()->createOperation( + GeographicCRS::EPSG_4326, NN_NO_CHECK(crs)); + ASSERT_TRUE(op != nullptr); + EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), + "+proj=pipeline +step +proj=axisswap +order=2,1 +step " + "+proj=axisswap +order=-2,-1"); } // --------------------------------------------------------------------------- @@ -7168,9 +7174,11 @@ TEST(io, projparse_longlat_unitconvert_deg) { auto crs = nn_dynamic_pointer_cast<GeographicCRS>(obj); ASSERT_TRUE(crs != nullptr); - EXPECT_EQ(crs->exportToPROJString(PROJStringFormatter::create().get()), - "+proj=pipeline +step +proj=longlat +ellps=GRS80 +step " - "+proj=unitconvert +xy_in=rad +xy_out=deg"); + auto op = CoordinateOperationFactory::create()->createOperation( + GeographicCRS::EPSG_4326, NN_NO_CHECK(crs)); + ASSERT_TRUE(op != nullptr); + EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), + "+proj=axisswap +order=2,1"); } // --------------------------------------------------------------------------- @@ -7182,8 +7190,12 @@ TEST(io, projparse_longlat_unitconvert_grad) { auto crs = nn_dynamic_pointer_cast<GeographicCRS>(obj); ASSERT_TRUE(crs != nullptr); - EXPECT_EQ(crs->exportToPROJString(PROJStringFormatter::create().get()), - "+proj=pipeline +step +proj=longlat +ellps=GRS80 +step " + auto op = CoordinateOperationFactory::create()->createOperation( + GeographicCRS::EPSG_4326, NN_NO_CHECK(crs)); + ASSERT_TRUE(op != nullptr); + EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), + "+proj=pipeline +step +proj=axisswap +order=2,1 +step " + "+proj=unitconvert +xy_in=deg +xy_out=rad +step " "+proj=unitconvert +xy_in=rad +xy_out=grad"); } @@ -7196,9 +7208,12 @@ TEST(io, projparse_longlat_unitconvert_rad) { auto crs = nn_dynamic_pointer_cast<GeographicCRS>(obj); ASSERT_TRUE(crs != nullptr); - EXPECT_EQ(crs->exportToPROJString(PROJStringFormatter::create().get()), - "+proj=pipeline +step +proj=longlat +ellps=GRS80 +step " - "+proj=unitconvert +xy_in=rad +xy_out=rad"); + auto op = CoordinateOperationFactory::create()->createOperation( + GeographicCRS::EPSG_4326, NN_NO_CHECK(crs)); + ASSERT_TRUE(op != nullptr); + EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), + "+proj=pipeline +step +proj=axisswap +order=2,1 +step " + "+proj=unitconvert +xy_in=deg +xy_out=rad"); } // --------------------------------------------------------------------------- @@ -7215,13 +7230,16 @@ TEST(io, projparse_longlat_axisswap) { auto crs = nn_dynamic_pointer_cast<GeographicCRS>(obj); ASSERT_TRUE(crs != nullptr); + auto op = CoordinateOperationFactory::create()->createOperation( + GeographicCRS::EPSG_4326, NN_NO_CHECK(crs)); + ASSERT_TRUE(op != nullptr); EXPECT_EQ( - crs->exportToPROJString( - PROJStringFormatter::create().get()), - "+proj=pipeline +step +proj=longlat +ellps=GRS80 +step " - "+proj=unitconvert +xy_in=rad +xy_out=deg +step " - "+proj=axisswap +order=" + - std::string(order1) + "," + order2); + op->exportToPROJString(PROJStringFormatter::create().get()), + (atoi(order1) == 2 && atoi(order2) == 1) + ? "" + : "+proj=pipeline +step +proj=axisswap +order=2,1 " + "+step +proj=axisswap +order=" + + std::string(order1) + "," + order2); } } } @@ -7870,11 +7888,14 @@ TEST(io, projparse_axisswap_unitconvert_longlat_proj) { auto obj = PROJStringParser().createFromPROJString(input); auto crs = nn_dynamic_pointer_cast<ProjectedCRS>(obj); ASSERT_TRUE(crs != nullptr); - EXPECT_EQ( - crs->exportToPROJString( - PROJStringFormatter::create(PROJStringFormatter::Convention::PROJ_5) - .get()), - input); + auto op = CoordinateOperationFactory::create()->createOperation( + GeographicCRS::EPSG_4326, NN_NO_CHECK(crs)); + ASSERT_TRUE(op != nullptr); + EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), + "+proj=pipeline +step +proj=axisswap +order=2,1 +step " + "+proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=lcc " + "+lat_1=49.5 +lat_0=49.5 +lon_0=0 +k_0=0.999877341 +x_0=600000 " + "+y_0=200000 +ellps=clrk80ign +pm=paris"); } // --------------------------------------------------------------------------- @@ -7887,11 +7908,14 @@ TEST(io, projparse_axisswap_unitconvert_proj_axisswap) { auto obj = PROJStringParser().createFromPROJString(input); auto crs = nn_dynamic_pointer_cast<ProjectedCRS>(obj); ASSERT_TRUE(crs != nullptr); - EXPECT_EQ( - crs->exportToPROJString( - PROJStringFormatter::create(PROJStringFormatter::Convention::PROJ_5) - .get()), - input); + auto op = CoordinateOperationFactory::create()->createOperation( + GeographicCRS::EPSG_4326, NN_NO_CHECK(crs)); + ASSERT_TRUE(op != nullptr); + EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), + "+proj=pipeline +step +proj=axisswap +order=2,1 +step " + "+proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=igh " + "+lon_0=0 +x_0=0 +y_0=0 +ellps=GRS80 +step +proj=axisswap " + "+order=2,1"); } // --------------------------------------------------------------------------- @@ -7905,11 +7929,14 @@ TEST(io, projparse_axisswap_unitconvert_proj_unitconvert) { auto obj = PROJStringParser().createFromPROJString(input); auto crs = nn_dynamic_pointer_cast<ProjectedCRS>(obj); ASSERT_TRUE(crs != nullptr); - EXPECT_EQ( - crs->exportToPROJString( - PROJStringFormatter::create(PROJStringFormatter::Convention::PROJ_5) - .get()), - input); + auto op = CoordinateOperationFactory::create()->createOperation( + GeographicCRS::EPSG_4326, NN_NO_CHECK(crs)); + ASSERT_TRUE(op != nullptr); + EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), + "+proj=pipeline +step +proj=axisswap +order=2,1 +step " + "+proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=igh " + "+lon_0=0 +x_0=0 +y_0=0 +ellps=GRS80 +step +proj=unitconvert " + "+xy_in=m +z_in=m +xy_out=ft +z_out=ft"); } // --------------------------------------------------------------------------- @@ -7923,11 +7950,15 @@ TEST(io, projparse_axisswap_unitconvert_proj_unitconvert_numeric_axisswap) { auto obj = PROJStringParser().createFromPROJString(input); auto crs = nn_dynamic_pointer_cast<ProjectedCRS>(obj); ASSERT_TRUE(crs != nullptr); - EXPECT_EQ( - crs->exportToPROJString( - PROJStringFormatter::create(PROJStringFormatter::Convention::PROJ_5) - .get()), - input); + auto op = CoordinateOperationFactory::create()->createOperation( + GeographicCRS::EPSG_4326, NN_NO_CHECK(crs)); + ASSERT_TRUE(op != nullptr); + EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), + "+proj=pipeline +step +proj=axisswap +order=2,1 +step " + "+proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=igh " + "+lon_0=0 +x_0=0 +y_0=0 +ellps=GRS80 +step +proj=unitconvert " + "+xy_in=m +z_in=m +xy_out=2.5 +z_out=2.5 +step +proj=axisswap " + "+order=-2,-1"); } // --------------------------------------------------------------------------- @@ -8059,20 +8090,9 @@ TEST(io, projparse_projected_unknown) { EXPECT_EQ(wkt, expected_wkt1); } - EXPECT_EQ( - crs->exportToPROJString( - PROJStringFormatter::create(PROJStringFormatter::Convention::PROJ_4) - .get()), - "+proj=mbt_s +unused_flag +lat_0=45 +lon_0=0 +k=1 +x_0=10 " - "+y_0=0 +datum=WGS84 +units=m +no_defs"); - - EXPECT_EQ( - crs->exportToPROJString( - PROJStringFormatter::create(PROJStringFormatter::Convention::PROJ_5) - .get()), - "+proj=pipeline +step +proj=unitconvert +xy_in=deg +xy_out=rad " - "+step +proj=mbt_s +unused_flag +lat_0=45 +lon_0=0 +k=1 " - "+x_0=10 +y_0=0 +ellps=WGS84"); + EXPECT_EQ(crs->exportToPROJString(PROJStringFormatter::create().get()), + "+proj=mbt_s +unused_flag +lat_0=45 +lon_0=0 +k=1 +x_0=10 " + "+y_0=0 +datum=WGS84 +units=m +no_defs"); { auto obj2 = WKTParser().createFromWKT(expected_wkt1); @@ -8160,11 +8180,14 @@ TEST(io, projparse_cart_unit) { auto obj = PROJStringParser().createFromPROJString(input); auto crs = nn_dynamic_pointer_cast<GeodeticCRS>(obj); ASSERT_TRUE(crs != nullptr); - EXPECT_EQ( - crs->exportToPROJString( - PROJStringFormatter::create(PROJStringFormatter::Convention::PROJ_5) - .get()), - input); + auto op = CoordinateOperationFactory::create()->createOperation( + GeographicCRS::EPSG_4326, NN_NO_CHECK(crs)); + ASSERT_TRUE(op != nullptr); + EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), + "+proj=pipeline +step +proj=axisswap +order=2,1 +step " + "+proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=cart " + "+ellps=WGS84 +step +proj=unitconvert +xy_in=m +z_in=m " + "+xy_out=km +z_out=km"); } // --------------------------------------------------------------------------- @@ -8176,11 +8199,14 @@ TEST(io, projparse_cart_unit_numeric) { auto obj = PROJStringParser().createFromPROJString(input); auto crs = nn_dynamic_pointer_cast<GeodeticCRS>(obj); ASSERT_TRUE(crs != nullptr); - EXPECT_EQ( - crs->exportToPROJString( - PROJStringFormatter::create(PROJStringFormatter::Convention::PROJ_5) - .get()), - input); + auto op = CoordinateOperationFactory::create()->createOperation( + GeographicCRS::EPSG_4326, NN_NO_CHECK(crs)); + ASSERT_TRUE(op != nullptr); + EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), + "+proj=pipeline +step +proj=axisswap +order=2,1 +step " + "+proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=cart " + "+ellps=WGS84 +step +proj=unitconvert +xy_in=m +z_in=m " + "+xy_out=500 +z_out=500"); } // --------------------------------------------------------------------------- @@ -8237,11 +8263,15 @@ TEST(io, projparse_ob_tran_longlat) { auto obj = PROJStringParser().createFromPROJString(input); auto crs = nn_dynamic_pointer_cast<DerivedGeographicCRS>(obj); ASSERT_TRUE(crs != nullptr); - EXPECT_EQ( - crs->exportToPROJString( - PROJStringFormatter::create(PROJStringFormatter::Convention::PROJ_5) - .get()), - input); + auto op = CoordinateOperationFactory::create()->createOperation( + GeographicCRS::EPSG_4326, NN_NO_CHECK(crs)); + ASSERT_TRUE(op != nullptr); + EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), + "+proj=pipeline +step +proj=axisswap +order=2,1 +step " + "+proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=ob_tran " + "+o_proj=longlat +o_lat_p=52 +o_lon_p=-30 +lon_0=-25 " + "+ellps=WGS84 +step +proj=unitconvert +xy_in=rad +xy_out=deg " + "+step +proj=axisswap +order=2,1"); } // --------------------------------------------------------------------------- @@ -8651,8 +8681,7 @@ TEST(io, projparse_init) { auto crs = nn_dynamic_pointer_cast<GeographicCRS>(obj); ASSERT_TRUE(crs != nullptr); EXPECT_EQ(crs->exportToPROJString(PROJStringFormatter::create().get()), - "+proj=pipeline +step +proj=longlat +ellps=GRS80 " - "+step +proj=unitconvert +xy_in=rad +xy_out=deg"); + "+proj=longlat +ellps=GRS80 +no_defs"); } } diff --git a/test/unit/test_operation.cpp b/test/unit/test_operation.cpp index 9b9273b5..379ef31a 100644 --- a/test/unit/test_operation.cpp +++ b/test/unit/test_operation.cpp @@ -1377,9 +1377,8 @@ TEST(operation, tmerc_south_oriented_export) { auto crs = nn_dynamic_pointer_cast<ProjectedCRS>(obj); ASSERT_TRUE(crs != nullptr); EXPECT_EQ(crs->exportToPROJString(PROJStringFormatter::create().get()), - "+proj=pipeline +step +proj=axisswap +order=2,1 +step " - "+proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=tmerc " - "+axis=wsu +lat_0=0 +lon_0=29 +k=1 +x_0=0 +y_0=0 +ellps=WGS84"); + "+proj=tmerc +axis=wsu +lat_0=0 +lon_0=29 +k=1 +x_0=0 +y_0=0 " + "+ellps=WGS84 +units=m +no_defs"); } // --------------------------------------------------------------------------- @@ -1630,8 +1629,8 @@ TEST(operation, bonne_export) { auto crs = nn_dynamic_pointer_cast<ProjectedCRS>(obj); ASSERT_TRUE(crs != nullptr); EXPECT_EQ(crs->exportToPROJString(PROJStringFormatter::create().get()), - "+proj=pipeline +step +proj=unitconvert +xy_in=deg +xy_out=rad " - "+step +proj=bonne +lat_1=1 +lon_0=2 +x_0=3 +y_0=4 +ellps=WGS84"); + "+proj=bonne +lat_1=1 +lon_0=2 +x_0=3 +y_0=4 +ellps=WGS84 " + "+units=m +no_defs"); } // --------------------------------------------------------------------------- @@ -3016,12 +3015,6 @@ TEST(operation, webmerc_export) { EXPECT_EQ(conv->exportToPROJString(PROJStringFormatter::create().get()), "+proj=webmerc +lat_0=0 +lon_0=2 +x_0=3 +y_0=4"); - EXPECT_THROW( - conv->exportToPROJString( - PROJStringFormatter::create(PROJStringFormatter::Convention::PROJ_4) - .get()), - FormattingException); - EXPECT_EQ(conv->exportToWKT(WKTFormatter::create().get()), "CONVERSION[\"Popular Visualisation Pseudo Mercator\",\n" " METHOD[\"Popular Visualisation Pseudo Mercator\",\n" @@ -3072,20 +3065,17 @@ TEST(operation, webmerc_export) { "+x_0=3 +y_0=4 +k=1 +units=m " "+nadgrids=@null +wktext +no_defs\"]]"); - EXPECT_EQ( - projCRS->exportToPROJString( - PROJStringFormatter::create(PROJStringFormatter::Convention::PROJ_5) - .get()), - "+proj=pipeline +step +proj=axisswap +order=2,1 +step " - "+proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=webmerc " - "+lat_0=0 +lon_0=2 +x_0=3 +y_0=4 +ellps=WGS84"); + auto op = CoordinateOperationFactory::create()->createOperation( + GeographicCRS::EPSG_4326, projCRS); + ASSERT_TRUE(op != nullptr); + EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), + "+proj=pipeline +step +proj=axisswap +order=2,1 +step " + "+proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=webmerc " + "+lat_0=0 +lon_0=2 +x_0=3 +y_0=4 +ellps=WGS84"); - EXPECT_EQ( - projCRS->exportToPROJString( - PROJStringFormatter::create(PROJStringFormatter::Convention::PROJ_4) - .get()), - "+proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=2 +x_0=3 " - "+y_0=4 +k=1 +units=m +nadgrids=@null +wktext +no_defs"); + EXPECT_EQ(projCRS->exportToPROJString(PROJStringFormatter::create().get()), + "+proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=2 +x_0=3 " + "+y_0=4 +k=1 +units=m +nadgrids=@null +wktext +no_defs"); } // --------------------------------------------------------------------------- @@ -3183,17 +3173,8 @@ TEST(operation, webmerc_import_from_GDAL_wkt1_EPSG_3785_deprecated) { ASSERT_TRUE(crs != nullptr); EXPECT_EQ(crs->exportToPROJString(PROJStringFormatter::create().get()), - "+proj=pipeline +step +proj=axisswap +order=2,1 +step " - "+proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=webmerc " - "+lat_0=0 +lon_0=0 +x_0=0 +y_0=0 " - "+ellps=WGS84"); - - EXPECT_EQ( - crs->exportToPROJString( - PROJStringFormatter::create(PROJStringFormatter::Convention::PROJ_4) - .get()), - "+proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 " - "+y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs"); + "+proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 " + "+y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs"); auto convGot = crs->derivingConversion(); @@ -3257,16 +3238,8 @@ TEST(operation, webmerc_import_from_WKT2_EPSG_3785_deprecated) { ASSERT_TRUE(crs != nullptr); EXPECT_EQ(crs->exportToPROJString(PROJStringFormatter::create().get()), - "+proj=pipeline +step +proj=axisswap +order=2,1 +step " - "+proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=webmerc " - "+ellps=WGS84"); - - EXPECT_EQ( - crs->exportToPROJString( - PROJStringFormatter::create(PROJStringFormatter::Convention::PROJ_4) - .get()), - "+proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 " - "+y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs"); + "+proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 " + "+y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs"); EXPECT_EQ( crs->exportToWKT( @@ -4105,12 +4078,9 @@ TEST(operation, eqearth_export) { TEST(operation, laborde_oblique_mercator) { // Content of EPSG:29701 "Tananarive (Paris) / Laborde Grid" - auto projString = "+proj=pipeline +step +proj=axisswap +order=2,1 +step " - "+proj=unitconvert +xy_in=grad +xy_out=rad +step +inv " - "+proj=longlat +ellps=intl +pm=paris +step +proj=labrd " - "+lat_0=-18.9 +lon_0=44.1 +azi=18.9 +k=0.9995 " - "+x_0=400000 +y_0=800000 +ellps=intl +pm=paris +step " - "+proj=axisswap +order=2,1"; + auto projString = "+proj=labrd +lat_0=-18.9 +lon_0=44.1 +azi=18.9 " + "+k=0.9995 +x_0=400000 +y_0=800000 +ellps=intl +pm=paris " + "+units=m +no_defs"; auto obj = PROJStringParser().createFromPROJString(projString); auto crs = nn_dynamic_pointer_cast<ProjectedCRS>(obj); ASSERT_TRUE(crs != nullptr); |
