aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2021-10-05 19:21:05 +0200
committerGitHub <noreply@github.com>2021-10-05 19:21:05 +0200
commitc50ba1b1a7ecde946544c03ab0951727dd87264d (patch)
tree2be4d809980ba1450d6e8a2af29c4e9822c9f2d1 /test
parent6b58adb4b7396b9c2aff2fa26aae2340d5a62d21 (diff)
parent5d6bdadfca419c1d54d455e240743791e6cea44e (diff)
downloadPROJ-c50ba1b1a7ecde946544c03ab0951727dd87264d.tar.gz
PROJ-c50ba1b1a7ecde946544c03ab0951727dd87264d.zip
Merge pull request #2876 from rouault/iau
Add IAU_2015 CRS definitions
Diffstat (limited to 'test')
-rw-r--r--test/cli/testprojinfo_out.dist2
-rw-r--r--test/unit/test_c_api.cpp12
-rw-r--r--test/unit/test_crs.cpp47
-rw-r--r--test/unit/test_factory.cpp90
-rw-r--r--test/unit/test_io.cpp36
-rw-r--r--test/unit/test_operationfactory.cpp132
6 files changed, 308 insertions, 11 deletions
diff --git a/test/cli/testprojinfo_out.dist b/test/cli/testprojinfo_out.dist
index a21e7501..0c9673a0 100644
--- a/test/cli/testprojinfo_out.dist
+++ b/test/cli/testprojinfo_out.dist
@@ -270,7 +270,7 @@ INSERT INTO projected_crs VALUES('HOBU','MY_CRS','unknown','','EPSG','4400','HOB
INSERT INTO usage VALUES('HOBU','USAGE_PROJECTED_CRS_MY_CRS','projected_crs','HOBU','MY_CRS','PROJ','EXTENT_UNKNOWN','PROJ','SCOPE_UNKNOWN');
Testing projinfo "+proj=merc +lat_ts=5 +datum=WGS84 +type=crs" --output-id HOBU:MY_CRS --authority HOBU -o SQL -q
-INSERT INTO ellipsoid VALUES('HOBU','ELLPS_GEODETIC_DATUM_GEODETIC_CRS_MY_CRS','WGS 84','','PROJ','EARTH',6378137,'EPSG','9001',298.257223563,NULL,0);
+INSERT INTO ellipsoid VALUES('HOBU','ELLPS_GEODETIC_DATUM_GEODETIC_CRS_MY_CRS','WGS 84','','IAU_2015','399',6378137,'EPSG','9001',298.257223563,NULL,0);
INSERT INTO prime_meridian VALUES('HOBU','PM_GEODETIC_DATUM_GEODETIC_CRS_MY_CRS','Greenwich',0,'EPSG','9122',0);
INSERT INTO geodetic_datum VALUES('HOBU','GEODETIC_DATUM_GEODETIC_CRS_MY_CRS','World Geodetic System 1984','','HOBU','ELLPS_GEODETIC_DATUM_GEODETIC_CRS_MY_CRS','HOBU','PM_GEODETIC_DATUM_GEODETIC_CRS_MY_CRS',NULL,NULL,NULL,NULL,0);
INSERT INTO usage VALUES('HOBU','USAGE_GEODETIC_DATUM_GEODETIC_CRS_MY_CRS','geodetic_datum','HOBU','GEODETIC_DATUM_GEODETIC_CRS_MY_CRS','PROJ','EXTENT_UNKNOWN','PROJ','SCOPE_UNKNOWN');
diff --git a/test/unit/test_c_api.cpp b/test/unit/test_c_api.cpp
index 1049ce35..aceae656 100644
--- a/test/unit/test_c_api.cpp
+++ b/test/unit/test_c_api.cpp
@@ -1357,14 +1357,16 @@ TEST_F(CApi, proj_get_authorities_from_database) {
ASSERT_TRUE(list[1] != nullptr);
EXPECT_EQ(list[1], std::string("ESRI"));
ASSERT_TRUE(list[2] != nullptr);
- EXPECT_EQ(list[2], std::string("IGNF"));
+ EXPECT_EQ(list[2], std::string("IAU_2015"));
ASSERT_TRUE(list[3] != nullptr);
- EXPECT_EQ(list[3], std::string("NKG"));
+ EXPECT_EQ(list[3], std::string("IGNF"));
ASSERT_TRUE(list[4] != nullptr);
- EXPECT_EQ(list[4], std::string("OGC"));
+ EXPECT_EQ(list[4], std::string("NKG"));
ASSERT_TRUE(list[5] != nullptr);
- EXPECT_EQ(list[5], std::string("PROJ"));
- EXPECT_EQ(list[6], nullptr);
+ EXPECT_EQ(list[5], std::string("OGC"));
+ ASSERT_TRUE(list[6] != nullptr);
+ EXPECT_EQ(list[6], std::string("PROJ"));
+ EXPECT_EQ(list[7], nullptr);
}
// ---------------------------------------------------------------------------
diff --git a/test/unit/test_crs.cpp b/test/unit/test_crs.cpp
index c9c0c9a1..bc42d834 100644
--- a/test/unit/test_crs.cpp
+++ b/test/unit/test_crs.cpp
@@ -747,6 +747,53 @@ TEST(crs, EPSG_4268_geogcrs_deprecated_as_WKT1_GDAL) {
// ---------------------------------------------------------------------------
+TEST(crs, IAU_1000_as_WKT2) {
+ auto dbContext = DatabaseContext::create();
+ auto factory = AuthorityFactory::create(dbContext, "IAU_2015");
+ auto crs = factory->createCoordinateReferenceSystem("1000");
+ WKTFormatterNNPtr f(
+ WKTFormatter::create(WKTFormatter::Convention::WKT2_2019, dbContext));
+ auto wkt = crs->exportToWKT(f.get());
+ // Check that IAU_2015 is split into a authority name and version
+ EXPECT_TRUE(wkt.find("ID[\"IAU\",1000,2015]") != std::string::npos) << wkt;
+
+ auto obj = createFromUserInput(wkt, dbContext);
+ auto crs2 = nn_dynamic_pointer_cast<CRS>(obj);
+ ASSERT_TRUE(crs2 != nullptr);
+ auto wkt2 = crs2->exportToWKT(f.get());
+ // Check that IAU_2015 is split into a authority name and version
+ EXPECT_TRUE(wkt2.find("ID[\"IAU\",1000,2015]") != std::string::npos)
+ << wkt2;
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(crs, IAU_1000_as_PROJJSON) {
+ auto dbContext = DatabaseContext::create();
+ auto factory = AuthorityFactory::create(dbContext, "IAU_2015");
+ auto crs = factory->createCoordinateReferenceSystem("1000");
+ auto projjson = crs->exportToJSON(JSONFormatter::create(dbContext).get());
+ // Check that IAU_2015 is split into a authority name and version
+ EXPECT_TRUE(projjson.find("\"authority\": \"IAU\",") != std::string::npos)
+ << projjson;
+ EXPECT_TRUE(projjson.find("\"code\": 1000,") != std::string::npos)
+ << projjson;
+ EXPECT_TRUE(projjson.find("\"version\": 2015") != std::string::npos)
+ << projjson;
+
+ auto obj = createFromUserInput(projjson, dbContext);
+ auto crs2 = nn_dynamic_pointer_cast<CRS>(obj);
+ ASSERT_TRUE(crs2 != nullptr);
+ WKTFormatterNNPtr f(
+ WKTFormatter::create(WKTFormatter::Convention::WKT2_2019, dbContext));
+ auto wkt2 = crs2->exportToWKT(f.get());
+ // Check that IAU_2015 is split into a authority name and version
+ EXPECT_TRUE(wkt2.find("ID[\"IAU\",1000,2015]") != std::string::npos)
+ << wkt2;
+}
+
+// ---------------------------------------------------------------------------
+
TEST(crs, EPSG_2008_projcrs_deprecated_as_WKT1_GDAL) {
auto dbContext = DatabaseContext::create();
auto factory = AuthorityFactory::create(dbContext, "EPSG");
diff --git a/test/unit/test_factory.cpp b/test/unit/test_factory.cpp
index 9319968d..a3156faf 100644
--- a/test/unit/test_factory.cpp
+++ b/test/unit/test_factory.cpp
@@ -1561,6 +1561,86 @@ TEST(factory, AuthorityFactory_getDescriptionText) {
// ---------------------------------------------------------------------------
+TEST(factory, AuthorityFactory_IAU_2015) {
+ auto factory =
+ AuthorityFactory::create(DatabaseContext::create(), "IAU_2015");
+
+ {
+ auto crs = factory->createGeographicCRS("19900");
+ EXPECT_EQ(crs->nameStr(), "Mercury (2015) - Sphere / Ocentric");
+
+ const auto ellps = crs->ellipsoid();
+ EXPECT_TRUE(ellps->isSphere());
+ EXPECT_NEAR(ellps->semiMajorAxis().value(), 2440530.0, 1e-6);
+
+ const auto &axisList = crs->coordinateSystem()->axisList();
+ EXPECT_EQ(axisList.size(), 2U);
+
+ EXPECT_EQ(*(axisList[0]->name()->description()), "Geodetic latitude");
+ EXPECT_EQ(axisList[0]->abbreviation(), "Lat");
+ EXPECT_EQ(axisList[0]->direction(), AxisDirection::NORTH);
+ EXPECT_EQ(axisList[0]->unit(), UnitOfMeasure::DEGREE);
+
+ EXPECT_EQ(*(axisList[1]->name()->description()), "Geodetic longitude");
+ EXPECT_EQ(axisList[1]->abbreviation(), "Lon");
+ EXPECT_EQ(axisList[1]->direction(), AxisDirection::EAST);
+ EXPECT_EQ(axisList[1]->unit(), UnitOfMeasure::DEGREE);
+ }
+
+ {
+ auto crs = factory->createGeographicCRS("19901");
+ EXPECT_EQ(crs->nameStr(), "Mercury (2015) / Ographic");
+
+ const auto ellps = crs->ellipsoid();
+ EXPECT_TRUE(!ellps->isSphere());
+ EXPECT_NEAR(ellps->semiMajorAxis().value(), 2440530.0, 1e-6);
+ EXPECT_NEAR(ellps->computeSemiMinorAxis().value(), 2438260.0, 1e-6);
+
+ const auto &axisList = crs->coordinateSystem()->axisList();
+ EXPECT_EQ(axisList.size(), 2U);
+
+ EXPECT_EQ(*(axisList[0]->name()->description()), "Geodetic latitude");
+ EXPECT_EQ(axisList[0]->abbreviation(), "Lat");
+ EXPECT_EQ(axisList[0]->direction(), AxisDirection::NORTH);
+ EXPECT_EQ(axisList[0]->unit(), UnitOfMeasure::DEGREE);
+
+ EXPECT_EQ(*(axisList[1]->name()->description()), "Geodetic longitude");
+ EXPECT_EQ(axisList[1]->abbreviation(), "Lon");
+ EXPECT_EQ(axisList[1]->direction(), AxisDirection::WEST); // WEST !
+ EXPECT_EQ(axisList[1]->unit(), UnitOfMeasure::DEGREE);
+ }
+
+ {
+ auto crs = factory->createGeodeticCRS("19902");
+ EXPECT_EQ(crs->nameStr(), "Mercury (2015) / Ocentric");
+ EXPECT_TRUE(dynamic_cast<GeographicCRS *>(crs.get()) == nullptr);
+
+ const auto ellps = crs->ellipsoid();
+ EXPECT_TRUE(!ellps->isSphere());
+ EXPECT_NEAR(ellps->semiMajorAxis().value(), 2440530.0, 1e-6);
+ EXPECT_NEAR(ellps->computeSemiMinorAxis().value(), 2438260.0, 1e-6);
+
+ const auto &cs = crs->coordinateSystem();
+ EXPECT_TRUE(dynamic_cast<SphericalCS *>(cs.get()) != nullptr);
+ const auto &axisList = cs->axisList();
+ EXPECT_EQ(axisList.size(), 2U);
+
+ EXPECT_EQ(*(axisList[0]->name()->description()),
+ "Planetocentric latitude");
+ EXPECT_EQ(axisList[0]->abbreviation(), "U");
+ EXPECT_EQ(axisList[0]->direction(), AxisDirection::NORTH);
+ EXPECT_EQ(axisList[0]->unit(), UnitOfMeasure::DEGREE);
+
+ EXPECT_EQ(*(axisList[1]->name()->description()),
+ "Planetocentric longitude");
+ EXPECT_EQ(axisList[1]->abbreviation(), "V");
+ EXPECT_EQ(axisList[1]->direction(), AxisDirection::EAST);
+ EXPECT_EQ(axisList[1]->unit(), UnitOfMeasure::DEGREE);
+ }
+}
+
+// ---------------------------------------------------------------------------
+
class FactoryWithTmpDatabase : public ::testing::Test {
protected:
void SetUp() override { sqlite3_open(":memory:", &m_ctxt); }
@@ -3950,10 +4030,9 @@ TEST(factory, objectInsertion) {
const auto sql =
ctxt->getInsertStatementsFor(crs, "HOBU", "XXXX", true);
ASSERT_EQ(sql.size(), 5U);
- EXPECT_EQ(
- sql[0],
- "INSERT INTO ellipsoid VALUES('HOBU','1','my "
- "ellipsoid','','PROJ','EARTH',6378137,'EPSG','9001',295,NULL,0);");
+ EXPECT_EQ(sql[0], "INSERT INTO ellipsoid VALUES('HOBU','1','my "
+ "ellipsoid','','IAU_2015','399',6378137,'EPSG','9001'"
+ ",295,NULL,0);");
const auto identified =
crs->identify(AuthorityFactory::create(ctxt, std::string()));
ASSERT_EQ(identified.size(), 1U);
@@ -3986,7 +4065,8 @@ TEST(factory, objectInsertion) {
ASSERT_EQ(sql.size(), 5U);
EXPECT_EQ(sql[0], "INSERT INTO ellipsoid "
"VALUES('HOBU','ELLPS_GEODETIC_DATUM_XXXX','my "
- "ellipsoid','','PROJ','EARTH',6378137,'EPSG','9001',"
+ "ellipsoid','','IAU_2015','399',6378137,"
+ "'EPSG','9001',"
"NULL,6378136,0);");
const auto identified =
crs->identify(AuthorityFactory::create(ctxt, std::string()));
diff --git a/test/unit/test_io.cpp b/test/unit/test_io.cpp
index f9a54f3c..4e888f2c 100644
--- a/test/unit/test_io.cpp
+++ b/test/unit/test_io.cpp
@@ -7881,6 +7881,26 @@ TEST(io, projstringformatter_axisswap_minus_two_one_followed_two_one) {
// ---------------------------------------------------------------------------
+TEST(io, projstringformatter_axisswap_two_minus_one_followed_minus_two_one) {
+ auto fmt = PROJStringFormatter::create();
+ fmt->ingestPROJString("+proj=pipeline "
+ "+step +proj=axisswap +order=2,-1 "
+ "+step +proj=axisswap +order=-2,1");
+ EXPECT_EQ(fmt->toString(), "+proj=noop");
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(io, projstringformatter_axisswap_two_minus_one_followed_one_minus_two) {
+ auto fmt = PROJStringFormatter::create();
+ fmt->ingestPROJString("+proj=pipeline "
+ "+step +proj=axisswap +order=2,-1 "
+ "+step +proj=axisswap +order=1,-2");
+ EXPECT_EQ(fmt->toString(), "+proj=axisswap +order=2,1");
+}
+
+// ---------------------------------------------------------------------------
+
TEST(io, projstringformatter_unmodified) {
const char *const strs[] = {"+proj=pipeline "
"+step +proj=axisswap +order=2,-1 "
@@ -10495,6 +10515,8 @@ TEST(io, createFromUserInput) {
EXPECT_NO_THROW(createFromUserInput("epsg:4326", dbContext));
EXPECT_NO_THROW(
createFromUserInput("urn:ogc:def:crs:EPSG::4326", dbContext));
+ EXPECT_NO_THROW(
+ createFromUserInput("urn:ogc:def:crs:EPSG:10:4326", dbContext));
EXPECT_THROW(createFromUserInput("urn:ogc:def:crs:EPSG::4326", nullptr),
ParsingException);
EXPECT_NO_THROW(createFromUserInput(
@@ -10508,6 +10530,20 @@ TEST(io, createFromUserInput) {
EXPECT_NO_THROW(
createFromUserInput("urn:ogc:def:ellipsoid:EPSG::7030", dbContext));
+ EXPECT_NO_THROW(createFromUserInput("IAU:1000", dbContext));
+ EXPECT_NO_THROW(createFromUserInput("IAU_2015:1000", dbContext));
+ EXPECT_NO_THROW(
+ createFromUserInput("urn:ogc:def:crs:IAU::1000", dbContext));
+ EXPECT_NO_THROW(
+ createFromUserInput("urn:ogc:def:crs:IAU_2015::1000", dbContext));
+ EXPECT_NO_THROW(
+ createFromUserInput("urn:ogc:def:crs:IAU:2015:1000", dbContext));
+
+ EXPECT_THROW(createFromUserInput("urn:ogc:def:crs:IAU_2015::xxxx", nullptr),
+ ParsingException);
+ EXPECT_THROW(createFromUserInput("urn:ogc:def:crs:IAU:xxxx:1000", nullptr),
+ ParsingException);
+
// Found as srsName in some GMLs...
EXPECT_NO_THROW(
createFromUserInput("URN:OGC:DEF:CRS:OGC:1.3:CRS84", dbContext));
diff --git a/test/unit/test_operationfactory.cpp b/test/unit/test_operationfactory.cpp
index 31b23287..2246c60c 100644
--- a/test/unit/test_operationfactory.cpp
+++ b/test/unit/test_operationfactory.cpp
@@ -7010,3 +7010,135 @@ TEST(operation,
"+proj=axisswap +order=1,-2");
}
}
+
+// ---------------------------------------------------------------------------
+
+TEST(
+ operation,
+ createOperation_ellipsoidal_ographic_west_to_projected_of_ellipsoidal_ographic_west) {
+ auto authFactory =
+ AuthorityFactory::create(DatabaseContext::create(), "IAU_2015");
+ auto op = CoordinateOperationFactory::create()->createOperation(
+ authFactory->createCoordinateReferenceSystem("19901"),
+ authFactory->createCoordinateReferenceSystem("19911"));
+ 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=eqc +lat_ts=0 +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 "
+ "+a=2440530 +b=2438260 "
+ "+step +proj=axisswap +order=-1,2");
+
+ // Inverse
+ auto op2 = CoordinateOperationFactory::create()->createOperation(
+ authFactory->createCoordinateReferenceSystem("19911"),
+ authFactory->createCoordinateReferenceSystem("19901"));
+ ASSERT_TRUE(op2 != nullptr);
+ EXPECT_EQ(op2->exportToPROJString(PROJStringFormatter::create().get()),
+ "+proj=pipeline "
+ "+step +inv +proj=axisswap +order=-1,2 "
+ "+step +inv +proj=eqc +lat_ts=0 +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 "
+ "+a=2440530 +b=2438260 "
+ "+step +proj=unitconvert +xy_in=rad +xy_out=deg "
+ "+step +proj=axisswap +order=2,-1");
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(
+ operation,
+ createOperation_ellipsoidal_ographic_west_to_projected_of_ellipsoidal_ocentric) {
+ auto authFactory =
+ AuthorityFactory::create(DatabaseContext::create(), "IAU_2015");
+ auto op = CoordinateOperationFactory::create()->createOperation(
+ authFactory->createCoordinateReferenceSystem("19901"),
+ authFactory->createCoordinateReferenceSystem("19912"));
+ 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=eqc +lat_ts=0 +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 "
+ "+a=2440530 +b=2438260");
+
+ // Inverse
+ auto op2 = CoordinateOperationFactory::create()->createOperation(
+ authFactory->createCoordinateReferenceSystem("19912"),
+ authFactory->createCoordinateReferenceSystem("19901"));
+ ASSERT_TRUE(op2 != nullptr);
+ EXPECT_EQ(op2->exportToPROJString(PROJStringFormatter::create().get()),
+ "+proj=pipeline "
+ "+step +inv +proj=eqc +lat_ts=0 +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 "
+ "+a=2440530 +b=2438260 "
+ "+step +proj=unitconvert +xy_in=rad +xy_out=deg "
+ "+step +proj=axisswap +order=2,-1");
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(
+ operation,
+ createOperation_ellipsoidal_ocentric_to_projected_of_ellipsoidal_ocentric) {
+ auto authFactory =
+ AuthorityFactory::create(DatabaseContext::create(), "IAU_2015");
+ auto op = CoordinateOperationFactory::create()->createOperation(
+ authFactory->createCoordinateReferenceSystem("19902"),
+ authFactory->createCoordinateReferenceSystem("19912"));
+ 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=geoc +a=2440530 +b=2438260 "
+ "+step +proj=eqc +lat_ts=0 +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 "
+ "+a=2440530 +b=2438260");
+
+ // Inverse
+ auto op2 = CoordinateOperationFactory::create()->createOperation(
+ authFactory->createCoordinateReferenceSystem("19912"),
+ authFactory->createCoordinateReferenceSystem("19902"));
+ ASSERT_TRUE(op2 != nullptr);
+ EXPECT_EQ(op2->exportToPROJString(PROJStringFormatter::create().get()),
+ "+proj=pipeline "
+ "+step +inv +proj=eqc +lat_ts=0 +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 "
+ "+a=2440530 +b=2438260 "
+ "+step +proj=geoc +a=2440530 +b=2438260 "
+ "+step +proj=unitconvert +xy_in=rad +xy_out=deg "
+ "+step +proj=axisswap +order=2,1");
+}
+
+// ---------------------------------------------------------------------------
+
+TEST(
+ operation,
+ createOperation_ellipsoidal_ocentric_to_projected_of_ellipsoidal_ographic_west) {
+ auto authFactory =
+ AuthorityFactory::create(DatabaseContext::create(), "IAU_2015");
+ auto op = CoordinateOperationFactory::create()->createOperation(
+ authFactory->createCoordinateReferenceSystem("19902"),
+ authFactory->createCoordinateReferenceSystem("19911"));
+ 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=geoc +a=2440530 +b=2438260 "
+ "+step +proj=eqc +lat_ts=0 +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 "
+ "+a=2440530 +b=2438260 "
+ "+step +proj=axisswap +order=-1,2");
+
+ // Inverse
+ auto op2 = CoordinateOperationFactory::create()->createOperation(
+ authFactory->createCoordinateReferenceSystem("19911"),
+ authFactory->createCoordinateReferenceSystem("19902"));
+ ASSERT_TRUE(op2 != nullptr);
+ EXPECT_EQ(op2->exportToPROJString(PROJStringFormatter::create().get()),
+ "+proj=pipeline "
+ "+step +inv +proj=axisswap +order=-1,2 "
+ "+step +inv +proj=eqc +lat_ts=0 +lat_0=0 +lon_0=0 +x_0=0 +y_0=0 "
+ "+a=2440530 +b=2438260 "
+ "+step +proj=geoc +a=2440530 +b=2438260 "
+ "+step +proj=unitconvert +xy_in=rad +xy_out=deg "
+ "+step +proj=axisswap +order=2,1");
+}