From f6232db745af1acd2473f51f82d006372c04fc55 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 20 Feb 2019 10:36:14 +0100 Subject: Add VERTCON grid name alternatives in database, and handle filename substitution for VERTCON method --- test/unit/test_operation.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'test/unit') diff --git a/test/unit/test_operation.cpp b/test/unit/test_operation.cpp index 90deb661..58b740b6 100644 --- a/test/unit/test_operation.cpp +++ b/test/unit/test_operation.cpp @@ -6174,6 +6174,25 @@ TEST(operation, vertCRS_to_vertCRS) { // --------------------------------------------------------------------------- +TEST(operation, vertCRS_to_vertCRS_context) { + auto authFactory = + AuthorityFactory::create(DatabaseContext::create(), "EPSG"); + auto ctxt = CoordinateOperationContext::create(authFactory, nullptr, 0.0); + ctxt->setSpatialCriterion( + CoordinateOperationContext::SpatialCriterion::PARTIAL_INTERSECTION); + auto list = CoordinateOperationFactory::create()->createOperations( + // NGVD29 height (m) + authFactory->createCoordinateReferenceSystem("7968"), + // NAVD88 height (1) + authFactory->createCoordinateReferenceSystem("5703"), ctxt); + ASSERT_EQ(list.size(), 3U); + EXPECT_EQ(list[0]->nameStr(), "NGVD29 height (m) to NAVD88 height (3)"); + EXPECT_EQ(list[0]->exportToPROJString(PROJStringFormatter::create().get()), + "+proj=vgridshift +grids=vertcone.gtx +multiplier=0.001"); +} + +// --------------------------------------------------------------------------- + TEST(operation, compoundCRS_to_geogCRS_3D) { auto compoundcrs_ft_obj = PROJStringParser().createFromPROJString( -- cgit v1.2.3 From 3664cb546811146c588cab6db41b1ccef6fcee7a Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 20 Feb 2019 11:12:38 +0100 Subject: compoundCRS to compoundCRS: avoid emitting dummy 'Null geographic offset from X to X' in transformation name --- test/unit/gie_self_tests.cpp | 6 ++++-- test/unit/test_operation.cpp | 26 ++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) (limited to 'test/unit') diff --git a/test/unit/gie_self_tests.cpp b/test/unit/gie_self_tests.cpp index ad637786..3c5ffa86 100644 --- a/test/unit/gie_self_tests.cpp +++ b/test/unit/gie_self_tests.cpp @@ -421,9 +421,11 @@ TEST(gie, info_functions) { /* check a few key characteristics of the Mercator projection */ EXPECT_NEAR(factors.angular_distortion, 0.0, 1e-7) << factors.angular_distortion; /* angular distortion should be 0 */ + + /* Meridian/parallel angle should be 90 deg */ EXPECT_NEAR(factors.meridian_parallel_angle, M_PI_2, 1e-7) - << factors.meridian_parallel_angle; /* Meridian/parallel angle should be - 90 deg */ + << factors.meridian_parallel_angle; + EXPECT_EQ(factors.meridian_convergence, 0.0); /* meridian convergence should be 0 */ diff --git a/test/unit/test_operation.cpp b/test/unit/test_operation.cpp index 58b740b6..9a968378 100644 --- a/test/unit/test_operation.cpp +++ b/test/unit/test_operation.cpp @@ -6125,6 +6125,32 @@ TEST(operation, compoundCRS_to_compoundCRS_with_vertical_transform) { // --------------------------------------------------------------------------- +TEST(operation, compoundCRS_to_compoundCRS_context) { + auto authFactory = + AuthorityFactory::create(DatabaseContext::create(), "EPSG"); + auto ctxt = CoordinateOperationContext::create(authFactory, nullptr, 0.0); + ctxt->setSpatialCriterion( + CoordinateOperationContext::SpatialCriterion::PARTIAL_INTERSECTION); + auto list = CoordinateOperationFactory::create()->createOperations( + // NAD27 + NGVD29 height (ftUS) + authFactory->createCoordinateReferenceSystem("7406"), + // NAD83(NSRS2007) + NAVD88 height + authFactory->createCoordinateReferenceSystem("5500"), ctxt); + ASSERT_EQ(list.size(), 88U); + EXPECT_EQ(list[0]->nameStr(), "NGVD29 height (ftUS) to NAVD88 height (3) + " + "NAD27 to WGS 84 (79) + Inverse of " + "NAD83(NSRS2007) to WGS 84 (1)"); + EXPECT_EQ(list[0]->exportToPROJString(PROJStringFormatter::create().get()), + "+proj=pipeline +step +proj=axisswap +order=2,1 +step " + "+proj=unitconvert +xy_in=deg +z_in=us-ft +xy_out=rad +z_out=m " + "+step +proj=vgridshift +grids=vertcone.gtx +multiplier=0.001 " + "+step +proj=hgridshift +grids=conus +step +proj=push +v_3 +step " + "+proj=unitconvert +xy_in=rad +xy_out=deg +step +proj=axisswap " + "+order=2,1 +step +proj=pop +v_3"); +} + +// --------------------------------------------------------------------------- + TEST(operation, vertCRS_to_vertCRS) { auto vertcrs_m_obj = PROJStringParser().createFromPROJString("+vunits=m"); -- cgit v1.2.3 From 70bc293a43def169fa34ed8e97a5cb06b336f247 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 20 Feb 2019 12:18:16 +0100 Subject: Vertical CRS transformation: synthetize a vertical unit change transformation when needed, and also sort Null geographic offset transformation in last --- test/unit/test_c_api.cpp | 4 ++-- test/unit/test_operation.cpp | 40 ++++++++++++++++++++++++++++++++-------- 2 files changed, 34 insertions(+), 10 deletions(-) (limited to 'test/unit') diff --git a/test/unit/test_c_api.cpp b/test/unit/test_c_api.cpp index 6205a9b8..8cfed9ad 100644 --- a/test/unit/test_c_api.cpp +++ b/test/unit/test_c_api.cpp @@ -1421,7 +1421,7 @@ TEST_F(CApi, proj_create_operations_with_pivot) { ASSERT_NE(res, nullptr); ObjListKeeper keeper_res(res); EXPECT_EQ(proj_list_get_count(res), 7); - auto op = proj_list_get(m_ctxt, res, 1); + auto op = proj_list_get(m_ctxt, res, 0); ASSERT_NE(op, nullptr); ObjectKeeper keeper_op(op); @@ -1451,7 +1451,7 @@ TEST_F(CApi, proj_create_operations_with_pivot) { ASSERT_NE(res, nullptr); ObjListKeeper keeper_res(res); // includes results from ESRI - EXPECT_EQ(proj_list_get_count(res), 5); + EXPECT_EQ(proj_list_get_count(res), 4); auto op = proj_list_get(m_ctxt, res, 0); ASSERT_NE(op, nullptr); ObjectKeeper keeper_op(op); diff --git a/test/unit/test_operation.cpp b/test/unit/test_operation.cpp index 9a968378..42f8fe76 100644 --- a/test/unit/test_operation.cpp +++ b/test/unit/test_operation.cpp @@ -4362,7 +4362,7 @@ TEST(operation, geogCRS_to_geogCRS_context_inverse_needed) { authFactory->createCoordinateReferenceSystem("4275"), // NTF authFactory->createCoordinateReferenceSystem("4258"), // ETRS89 ctxt); - ASSERT_EQ(list.size(), 3U); + ASSERT_EQ(list.size(), 2U); EXPECT_EQ( list[0]->exportToPROJString(PROJStringFormatter::create().get()), "+proj=pipeline +step +proj=push +v_3 +step +proj=axisswap " @@ -4376,12 +4376,6 @@ TEST(operation, geogCRS_to_geogCRS_context_inverse_needed) { PROJStringFormatter::Convention::PROJ_5, authFactory->databaseContext()) .get()), - ""); - EXPECT_EQ(list[2]->exportToPROJString( - PROJStringFormatter::create( - PROJStringFormatter::Convention::PROJ_5, - authFactory->databaseContext()) - .get()), "+proj=pipeline +step +proj=axisswap +order=2,1 +step " "+proj=unitconvert +xy_in=deg +xy_out=rad +step " "+proj=hgridshift +grids=ntf_r93.gsb +step +proj=unitconvert " @@ -6136,7 +6130,8 @@ TEST(operation, compoundCRS_to_compoundCRS_context) { authFactory->createCoordinateReferenceSystem("7406"), // NAD83(NSRS2007) + NAVD88 height authFactory->createCoordinateReferenceSystem("5500"), ctxt); - ASSERT_EQ(list.size(), 88U); + // 152 or 155 depending if the VERTCON grids are there + ASSERT_GE(list.size(), 152U); EXPECT_EQ(list[0]->nameStr(), "NGVD29 height (ftUS) to NAVD88 height (3) + " "NAD27 to WGS 84 (79) + Inverse of " "NAD83(NSRS2007) to WGS 84 (1)"); @@ -6147,6 +6142,35 @@ TEST(operation, compoundCRS_to_compoundCRS_context) { "+step +proj=hgridshift +grids=conus +step +proj=push +v_3 +step " "+proj=unitconvert +xy_in=rad +xy_out=deg +step +proj=axisswap " "+order=2,1 +step +proj=pop +v_3"); + + bool foundApprox = false; + for (size_t i = 0; i < list.size(); i++) { + auto projString = + list[i]->exportToPROJString(PROJStringFormatter::create().get()); + EXPECT_TRUE( + projString.find("+proj=pipeline +step +proj=axisswap +order=2,1 " + "+step +proj=unitconvert +xy_in=deg +z_in=us-ft " + "+xy_out=rad +z_out=m") == 0) + << list[i]->nameStr(); + if (list[i]->nameStr().find("Transformation from NGVD29 height (ftUS) " + "to NAVD88 height (approximate " + "transformation)") == 0) { + EXPECT_EQ(list[i]->nameStr(), + "Transformation from NGVD29 height (ftUS) to NAVD88 " + "height (approximate transformation) + NAD27 to WGS 84 " + "(79) + Inverse of NAD83(NSRS2007) to WGS 84 (1)"); + EXPECT_EQ(projString, + "+proj=pipeline +step +proj=axisswap +order=2,1 +step " + "+proj=unitconvert +xy_in=deg +z_in=us-ft +xy_out=rad " + "+z_out=m +step +proj=hgridshift +grids=conus +step " + "+proj=push +v_3 +step +proj=unitconvert +xy_in=rad " + "+xy_out=deg +step +proj=axisswap +order=2,1 +step " + "+proj=pop +v_3"); + foundApprox = true; + break; + } + } + EXPECT_TRUE(foundApprox); } // --------------------------------------------------------------------------- -- cgit v1.2.3 From 0d8600e46b20fba28eb0cf0cabbbb4c6b586c6bf Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 20 Feb 2019 13:18:20 +0100 Subject: PROJStringFormatter: remove useless push/pop in another case --- test/unit/test_operation.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'test/unit') diff --git a/test/unit/test_operation.cpp b/test/unit/test_operation.cpp index 42f8fe76..bcf3e043 100644 --- a/test/unit/test_operation.cpp +++ b/test/unit/test_operation.cpp @@ -6139,9 +6139,9 @@ TEST(operation, compoundCRS_to_compoundCRS_context) { "+proj=pipeline +step +proj=axisswap +order=2,1 +step " "+proj=unitconvert +xy_in=deg +z_in=us-ft +xy_out=rad +z_out=m " "+step +proj=vgridshift +grids=vertcone.gtx +multiplier=0.001 " - "+step +proj=hgridshift +grids=conus +step +proj=push +v_3 +step " + "+step +proj=hgridshift +grids=conus +step " "+proj=unitconvert +xy_in=rad +xy_out=deg +step +proj=axisswap " - "+order=2,1 +step +proj=pop +v_3"); + "+order=2,1"); bool foundApprox = false; for (size_t i = 0; i < list.size(); i++) { @@ -6162,10 +6162,9 @@ TEST(operation, compoundCRS_to_compoundCRS_context) { EXPECT_EQ(projString, "+proj=pipeline +step +proj=axisswap +order=2,1 +step " "+proj=unitconvert +xy_in=deg +z_in=us-ft +xy_out=rad " - "+z_out=m +step +proj=hgridshift +grids=conus +step " - "+proj=push +v_3 +step +proj=unitconvert +xy_in=rad " - "+xy_out=deg +step +proj=axisswap +order=2,1 +step " - "+proj=pop +v_3"); + "+z_out=m +step +proj=hgridshift +grids=conus " + "+step +proj=unitconvert +xy_in=rad " + "+xy_out=deg +step +proj=axisswap +order=2,1"); foundApprox = true; break; } -- cgit v1.2.3 From ca8f21ecbcc404b9e9c648784216846c048a3d69 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 20 Feb 2019 15:29:38 +0100 Subject: PROJStringFormatting: change order of emission of push/pop w.r.t axis swap/unitconvert to avoid useless simplification rules --- test/unit/gie_self_tests.cpp | 24 +++-- test/unit/test_c_api.cpp | 12 ++- test/unit/test_factory.cpp | 54 +++++----- test/unit/test_operation.cpp | 246 +++++++++++++++++++++---------------------- 4 files changed, 170 insertions(+), 166 deletions(-) (limited to 'test/unit') diff --git a/test/unit/gie_self_tests.cpp b/test/unit/gie_self_tests.cpp index 3c5ffa86..3f99b1b3 100644 --- a/test/unit/gie_self_tests.cpp +++ b/test/unit/gie_self_tests.cpp @@ -703,13 +703,16 @@ TEST(gie, proj_create_crs_to_crs_PULKOVO42_ETRS89) { EXPECT_NEAR(c.xy.x, 44.999701238, 1e-9); EXPECT_NEAR(c.xy.y, 24.998474948, 1e-9); EXPECT_EQ(std::string(proj_pj_info(P).definition), - "proj=pipeline step proj=push v_3 step proj=axisswap order=2,1 " - "step proj=unitconvert xy_in=deg xy_out=rad step proj=cart " + "proj=pipeline step proj=axisswap order=2,1 " + "step proj=unitconvert xy_in=deg xy_out=rad " + "step proj=push v_3 " + "step proj=cart " "ellps=krass step proj=helmert x=2.3287 y=-147.0425 z=-92.0802 " "rx=0.3092483 ry=-0.32482185 rz=-0.49729934 s=5.68906266 " - "convention=coordinate_frame step inv proj=cart ellps=GRS80 step " - "proj=unitconvert xy_in=rad xy_out=deg step proj=axisswap " - "order=2,1 step proj=pop v_3"); + "convention=coordinate_frame step inv proj=cart ellps=GRS80 " + "step proj=pop v_3 " + "step proj=unitconvert xy_in=rad xy_out=deg step proj=axisswap " + "order=2,1"); c = proj_trans(P, PJ_INV, c); EXPECT_NEAR(c.xy.x, 45, 1e-8); @@ -732,12 +735,15 @@ TEST(gie, proj_create_crs_to_crs_PULKOVO42_ETRS89) { EXPECT_NEAR(c.xy.x, 51.999714150, 1e-9); EXPECT_NEAR(c.xy.y, 19.998187811, 1e-9); EXPECT_EQ(std::string(proj_pj_info(P).definition), - "proj=pipeline step proj=push v_3 step proj=axisswap order=2,1 " - "step proj=unitconvert xy_in=deg xy_out=rad step proj=cart " + "proj=pipeline step proj=axisswap order=2,1 " + "step proj=unitconvert xy_in=deg xy_out=rad " + "step proj=push v_3 " + "step proj=cart " "ellps=krass step proj=helmert x=33.4 y=-146.6 z=-76.3 rx=-0.359 " "ry=-0.053 rz=0.844 s=-0.84 convention=position_vector step inv " - "proj=cart ellps=GRS80 step proj=unitconvert xy_in=rad " - "xy_out=deg step proj=axisswap order=2,1 step proj=pop v_3"); + "proj=cart ellps=GRS80 step proj=pop v_3 " + "step proj=unitconvert xy_in=rad " + "xy_out=deg step proj=axisswap order=2,1"); proj_destroy(P); } diff --git a/test/unit/test_c_api.cpp b/test/unit/test_c_api.cpp index 8cfed9ad..69472a58 100644 --- a/test/unit/test_c_api.cpp +++ b/test/unit/test_c_api.cpp @@ -838,14 +838,16 @@ TEST_F(CApi, proj_create_from_database) { ASSERT_NE(info.definition, nullptr); EXPECT_EQ( info.definition, - std::string("proj=pipeline step proj=push v_3 step proj=axisswap " + std::string("proj=pipeline step proj=axisswap " "order=2,1 step proj=unitconvert xy_in=deg xy_out=rad " + "step proj=push v_3 " "step proj=cart ellps=bessel step proj=helmert " "x=601.705 y=84.263 z=485.227 rx=-4.7354 ry=-1.3145 " - "rz=-5.393 s=-2.3887 convention=coordinate_frame step " - "inv proj=cart ellps=GRS80 step proj=unitconvert " - "xy_in=rad xy_out=deg step proj=axisswap order=2,1 " - "step proj=pop v_3")); + "rz=-5.393 s=-2.3887 convention=coordinate_frame " + "step inv proj=cart ellps=GRS80 " + "step proj=pop v_3 " + "step proj=unitconvert xy_in=rad xy_out=deg " + "step proj=axisswap order=2,1")); EXPECT_EQ(info.accuracy, 1); } } diff --git a/test/unit/test_factory.cpp b/test/unit/test_factory.cpp index 80de017f..944e0ebe 100644 --- a/test/unit/test_factory.cpp +++ b/test/unit/test_factory.cpp @@ -660,13 +660,13 @@ TEST(factory, AuthorityFactory_createCoordinateOperation_helmert_3) { NoSuchAuthorityCodeException); auto op = factory->createCoordinateOperation("1113", false); EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), - "+proj=pipeline +step +proj=push +v_3 +step +proj=axisswap " - "+order=2,1 +step +proj=unitconvert +xy_in=deg +xy_out=rad +step " - "+inv +proj=longlat +a=6378249.145 +rf=293.4663077 +step " - "+proj=cart +a=6378249.145 +rf=293.4663077 +step +proj=helmert " - "+x=-143 +y=-90 +z=-294 +step +inv +proj=cart +ellps=WGS84 +step " - "+proj=unitconvert +xy_in=rad +xy_out=deg +step +proj=axisswap " - "+order=2,1 +step +proj=pop +v_3"); + "+proj=pipeline +step +proj=axisswap +order=2,1 +step " + "+proj=unitconvert +xy_in=deg +xy_out=rad +step +inv " + "+proj=longlat +a=6378249.145 +rf=293.4663077 +step +proj=push " + "+v_3 +step +proj=cart +a=6378249.145 +rf=293.4663077 +step " + "+proj=helmert +x=-143 +y=-90 +z=-294 +step +inv +proj=cart " + "+ellps=WGS84 +step +proj=pop +v_3 +step +proj=unitconvert " + "+xy_in=rad +xy_out=deg +step +proj=axisswap +order=2,1"); } // --------------------------------------------------------------------------- @@ -675,13 +675,13 @@ TEST(factory, AuthorityFactory_createCoordinateOperation_helmert_7_CF) { auto factory = AuthorityFactory::create(DatabaseContext::create(), "EPSG"); auto op = factory->createCoordinateOperation("7676", false); EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), - "+proj=pipeline +step +proj=push +v_3 +step +proj=axisswap " - "+order=2,1 +step +proj=unitconvert +xy_in=deg +xy_out=rad +step " - "+proj=cart +ellps=bessel +step +proj=helmert +x=577.88891 " + "+proj=pipeline +step +proj=axisswap +order=2,1 +step " + "+proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=push +v_3 " + "+step +proj=cart +ellps=bessel +step +proj=helmert +x=577.88891 " "+y=165.22205 +z=391.18289 +rx=-4.9145 +ry=0.94729 +rz=13.05098 " "+s=7.78664 +convention=coordinate_frame +step +inv +proj=cart " - "+ellps=WGS84 +step +proj=unitconvert +xy_in=rad +xy_out=deg " - "+step +proj=axisswap +order=2,1 +step +proj=pop +v_3"); + "+ellps=WGS84 +step +proj=pop +v_3 +step +proj=unitconvert " + "+xy_in=rad +xy_out=deg +step +proj=axisswap +order=2,1"); } // --------------------------------------------------------------------------- @@ -852,15 +852,15 @@ TEST(factory, EXPECT_TRUE(so->validateParameters().empty()); EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), - "+proj=pipeline +step +proj=push +v_3 +step +proj=axisswap " - "+order=2,1 +step +proj=unitconvert +xy_in=deg +xy_out=rad +step " - "+proj=cart +ellps=bessel +step +proj=molobadekas +x=593.032 " - "+y=26 +z=478.741 +rx=0.409394387439237 +ry=-0.359705195614311 " - "+rz=1.86849100035057 +s=4.0772 +px=3903453.148 +py=368135.313 " - "+pz=5012970.306 +convention=coordinate_frame +step +inv " - "+proj=cart +ellps=GRS80 +step +proj=unitconvert +xy_in=rad " - "+xy_out=deg +step +proj=axisswap +order=2,1 +step +proj=pop " - "+v_3"); + "+proj=pipeline +step +proj=axisswap +order=2,1 +step " + "+proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=push +v_3 " + "+step +proj=cart +ellps=bessel +step +proj=molobadekas " + "+x=593.032 +y=26 +z=478.741 +rx=0.409394387439237 " + "+ry=-0.359705195614311 +rz=1.86849100035057 +s=4.0772 " + "+px=3903453.148 +py=368135.313 +pz=5012970.306 " + "+convention=coordinate_frame +step +inv +proj=cart +ellps=GRS80 " + "+step +proj=pop +v_3 +step +proj=unitconvert +xy_in=rad " + "+xy_out=deg +step +proj=axisswap +order=2,1"); } // --------------------------------------------------------------------------- @@ -2071,12 +2071,12 @@ TEST_F(FactoryWithTmpDatabase, AuthorityFactory_wkt_based_transformation) { ASSERT_EQ(res.size(), 1U); EXPECT_EQ(res[0]->nameStr(), "My WKT string based op"); EXPECT_EQ(res[0]->exportToPROJString(PROJStringFormatter::create().get()), - "+proj=pipeline +step +proj=push +v_3 +step +proj=axisswap " - "+order=2,1 +step +proj=unitconvert +xy_in=deg +xy_out=rad +step " - "+proj=cart +ellps=WGS84 +step +proj=helmert +x=1 +y=2 +z=3 " - "+step +inv +proj=cart +ellps=WGS84 +step +proj=unitconvert " - "+xy_in=rad +xy_out=deg +step +proj=axisswap +order=2,1 +step " - "+proj=pop +v_3"); + "+proj=pipeline +step +proj=axisswap +order=2,1 +step " + "+proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=push +v_3 " + "+step +proj=cart +ellps=WGS84 +step +proj=helmert +x=1 +y=2 " + "+z=3 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 " + "+step +proj=unitconvert +xy_in=rad +xy_out=deg +step " + "+proj=axisswap +order=2,1"); } // --------------------------------------------------------------------------- diff --git a/test/unit/test_operation.cpp b/test/unit/test_operation.cpp index bcf3e043..8f1caecd 100644 --- a/test/unit/test_operation.cpp +++ b/test/unit/test_operation.cpp @@ -565,12 +565,12 @@ TEST(operation, transformation_createGeocentricTranslations) { EXPECT_EQ(inv_transf_as_transf->getTOWGS84Parameters(), expected_inv); EXPECT_EQ(transf->exportToPROJString(PROJStringFormatter::create().get()), - "+proj=pipeline +step +proj=push +v_3 +step +proj=axisswap " - "+order=2,1 +step +proj=unitconvert +xy_in=deg +xy_out=rad +step " - "+proj=cart +ellps=GRS80 +step +proj=helmert +x=1 +y=2 +z=3 " - "+step +inv +proj=cart +ellps=WGS84 +step +proj=unitconvert " - "+xy_in=rad +xy_out=deg +step +proj=axisswap +order=2,1 +step " - "+proj=pop +v_3"); + "+proj=pipeline +step +proj=axisswap +order=2,1 +step " + "+proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=push +v_3 " + "+step +proj=cart +ellps=GRS80 +step +proj=helmert +x=1 +y=2 " + "+z=3 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 " + "+step +proj=unitconvert +xy_in=rad +xy_out=deg +step " + "+proj=axisswap +order=2,1"); } // --------------------------------------------------------------------------- @@ -673,13 +673,13 @@ TEST(operation, transformation_createPositionVector) { EXPECT_EQ(transf->getTOWGS84Parameters(), expected); EXPECT_EQ(transf->exportToPROJString(PROJStringFormatter::create().get()), - "+proj=pipeline +step +proj=push +v_3 +step +proj=axisswap " - "+order=2,1 +step +proj=unitconvert +xy_in=deg +xy_out=rad +step " - "+proj=cart +ellps=GRS80 +step +proj=helmert +x=1 +y=2 +z=3 " - "+rx=4 +ry=5 +rz=6 +s=7 +convention=position_vector +step +inv " - "+proj=cart +ellps=WGS84 +step +proj=unitconvert +xy_in=rad " - "+xy_out=deg +step +proj=axisswap +order=2,1 +step +proj=pop " - "+v_3"); + "+proj=pipeline +step +proj=axisswap +order=2,1 +step " + "+proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=push +v_3 " + "+step +proj=cart +ellps=GRS80 +step +proj=helmert +x=1 +y=2 " + "+z=3 +rx=4 +ry=5 +rz=6 +s=7 +convention=position_vector +step " + "+inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step " + "+proj=unitconvert +xy_in=rad +xy_out=deg +step +proj=axisswap " + "+order=2,1"); auto inv_transf = transf->inverse(); ASSERT_EQ(inv_transf->coordinateOperationAccuracies().size(), 1U); @@ -696,12 +696,12 @@ TEST(operation, transformation_createPositionVector) { #else EXPECT_EQ( inv_transf->exportToPROJString(PROJStringFormatter::create().get()), - "+proj=pipeline +step +proj=push +v_3 +step +proj=axisswap +order=2,1 " - "+step +proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=cart " - "+ellps=WGS84 +step +inv +proj=helmert +x=1 +y=2 +z=3 +rx=4 +ry=5 " - "+rz=6 +s=7 +convention=position_vector +step +inv +proj=cart " - "+ellps=GRS80 +step +proj=unitconvert +xy_in=rad +xy_out=deg +step " - "+proj=axisswap +order=2,1 +step +proj=pop +v_3"); + "+proj=pipeline +step +proj=axisswap +order=2,1 +step " + "+proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=push +v_3 +step " + "+proj=cart +ellps=WGS84 +step +inv +proj=helmert +x=1 +y=2 +z=3 +rx=4 " + "+ry=5 +rz=6 +s=7 +convention=position_vector +step +inv +proj=cart " + "+ellps=GRS80 +step +proj=pop +v_3 +step +proj=unitconvert +xy_in=rad " + "+xy_out=deg +step +proj=axisswap +order=2,1"); // In WKT, use approximate formula auto wkt = inv_transf->exportToWKT(WKTFormatter::create().get()); @@ -742,13 +742,13 @@ TEST(operation, transformation_createCoordinateFrameRotation) { EXPECT_EQ(params, expected); EXPECT_EQ(transf->exportToPROJString(PROJStringFormatter::create().get()), - "+proj=pipeline +step +proj=push +v_3 +step +proj=axisswap " - "+order=2,1 +step +proj=unitconvert +xy_in=deg +xy_out=rad +step " - "+proj=cart +ellps=GRS80 +step +proj=helmert +x=1 +y=2 +z=3 " - "+rx=-4 +ry=-5 +rz=-6 +s=7 +convention=coordinate_frame +step " - "+inv +proj=cart +ellps=WGS84 +step +proj=unitconvert +xy_in=rad " - "+xy_out=deg +step +proj=axisswap +order=2,1 +step +proj=pop " - "+v_3"); + "+proj=pipeline +step +proj=axisswap +order=2,1 +step " + "+proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=push +v_3 " + "+step +proj=cart +ellps=GRS80 +step +proj=helmert +x=1 +y=2 " + "+z=3 +rx=-4 +ry=-5 +rz=-6 +s=7 +convention=coordinate_frame " + "+step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step " + "+proj=unitconvert +xy_in=rad +xy_out=deg +step +proj=axisswap " + "+order=2,1"); auto inv_transf = transf->inverse(); ASSERT_EQ(inv_transf->coordinateOperationAccuracies().size(), 0U); @@ -765,12 +765,12 @@ TEST(operation, transformation_createCoordinateFrameRotation) { #else EXPECT_EQ( inv_transf->exportToPROJString(PROJStringFormatter::create().get()), - "+proj=pipeline +step +proj=push +v_3 +step +proj=axisswap +order=2,1 " - "+step +proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=cart " - "+ellps=WGS84 +step +inv +proj=helmert +x=1 +y=2 +z=3 +rx=-4 +ry=-5 " - "+rz=-6 +s=7 +convention=coordinate_frame +step +inv +proj=cart " - "+ellps=GRS80 +step +proj=unitconvert +xy_in=rad +xy_out=deg +step " - "+proj=axisswap +order=2,1 +step +proj=pop +v_3"); + "+proj=pipeline +step +proj=axisswap +order=2,1 +step " + "+proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=push +v_3 +step " + "+proj=cart +ellps=WGS84 +step +inv +proj=helmert +x=1 +y=2 +z=3 " + "+rx=-4 +ry=-5 +rz=-6 +s=7 +convention=coordinate_frame +step +inv " + "+proj=cart +ellps=GRS80 +step +proj=pop +v_3 +step +proj=unitconvert " + "+xy_in=rad +xy_out=deg +step +proj=axisswap +order=2,1"); // In WKT, use approximate formula auto wkt = inv_transf->exportToWKT(WKTFormatter::create().get()); @@ -4203,13 +4203,14 @@ TEST(operation, geogCRS_to_geogCRS_context_default) { EXPECT_EQ( list[0]->exportToPROJString(PROJStringFormatter::create().get()), - "+proj=pipeline +step +proj=push +v_3 +step +proj=axisswap " - "+order=2,1 +step +proj=unitconvert +xy_in=deg +xy_out=rad +step " - "+proj=cart +ellps=krass +step +proj=helmert +x=2.3287 " + "+proj=pipeline +step +proj=axisswap +order=2,1 +step " + "+proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=push +v_3 " + "+step +proj=cart +ellps=krass +step +proj=helmert +x=2.3287 " "+y=-147.0425 +z=-92.0802 +rx=0.3092483 +ry=-0.32482185 " "+rz=-0.49729934 +s=5.68906266 +convention=coordinate_frame +step " - "+inv +proj=cart +ellps=GRS80 +step +proj=unitconvert +xy_in=rad " - "+xy_out=deg +step +proj=axisswap +order=2,1 +step +proj=pop +v_3"); + "+inv +proj=cart +ellps=GRS80 +step +proj=pop +v_3 +step " + "+proj=unitconvert +xy_in=rad +xy_out=deg +step +proj=axisswap " + "+order=2,1"); } // Reverse case @@ -4224,13 +4225,14 @@ TEST(operation, geogCRS_to_geogCRS_context_default) { EXPECT_EQ( list[0]->exportToPROJString(PROJStringFormatter::create().get()), - "+proj=pipeline +step +proj=push +v_3 +step +proj=axisswap " - "+order=2,1 +step +proj=unitconvert +xy_in=deg +xy_out=rad +step " - "+proj=cart +ellps=GRS80 +step +inv +proj=helmert +x=2.3287 " + "+proj=pipeline +step +proj=axisswap +order=2,1 +step " + "+proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=push +v_3 " + "+step +proj=cart +ellps=GRS80 +step +inv +proj=helmert +x=2.3287 " "+y=-147.0425 +z=-92.0802 +rx=0.3092483 +ry=-0.32482185 " "+rz=-0.49729934 +s=5.68906266 +convention=coordinate_frame +step " - "+inv +proj=cart +ellps=krass +step +proj=unitconvert +xy_in=rad " - "+xy_out=deg +step +proj=axisswap +order=2,1 +step +proj=pop +v_3"); + "+inv +proj=cart +ellps=krass +step +proj=pop +v_3 +step " + "+proj=unitconvert +xy_in=rad +xy_out=deg +step +proj=axisswap " + "+order=2,1"); } } @@ -4365,12 +4367,12 @@ TEST(operation, geogCRS_to_geogCRS_context_inverse_needed) { ASSERT_EQ(list.size(), 2U); EXPECT_EQ( list[0]->exportToPROJString(PROJStringFormatter::create().get()), - "+proj=pipeline +step +proj=push +v_3 +step +proj=axisswap " - "+order=2,1 +step +proj=unitconvert +xy_in=deg +xy_out=rad +step " - "+proj=cart +ellps=clrk80ign +step +proj=helmert +x=-168 +y=-60 " - "+z=320 +step +inv +proj=cart +ellps=GRS80 +step +proj=unitconvert " - "+xy_in=rad +xy_out=deg +step +proj=axisswap +order=2,1 +step " - "+proj=pop +v_3"); + "+proj=pipeline +step +proj=axisswap +order=2,1 +step " + "+proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=push +v_3 " + "+step +proj=cart +ellps=clrk80ign +step +proj=helmert +x=-168 " + "+y=-60 +z=320 +step +inv +proj=cart +ellps=GRS80 +step +proj=pop " + "+v_3 +step +proj=unitconvert +xy_in=rad +xy_out=deg +step " + "+proj=axisswap +order=2,1"); EXPECT_EQ(list[1]->exportToPROJString( PROJStringFormatter::create( PROJStringFormatter::Convention::PROJ_5, @@ -5318,14 +5320,14 @@ TEST(operation, boundCRS_of_geogCRS_to_geogCRS) { boundCRS, GeographicCRS::EPSG_4326); ASSERT_TRUE(op != nullptr); EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), - "+proj=pipeline +step +proj=push +v_3 +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=cart +ellps=clrk80ign +step +proj=helmert +x=1 +y=2 +z=3 " - "+rx=4 +ry=5 +rz=6 +s=7 +convention=position_vector +step +inv " - "+proj=cart +ellps=WGS84 +step +proj=unitconvert +xy_in=rad " - "+xy_out=deg +step +proj=axisswap +order=2,1 +step +proj=pop " - "+v_3"); + "+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=push +v_3 " + "+step +proj=cart +ellps=clrk80ign +step +proj=helmert +x=1 +y=2 " + "+z=3 +rx=4 +ry=5 +rz=6 +s=7 +convention=position_vector +step " + "+inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step " + "+proj=unitconvert +xy_in=rad +xy_out=deg +step +proj=axisswap " + "+order=2,1"); } // --------------------------------------------------------------------------- @@ -5339,13 +5341,13 @@ TEST(operation, boundCRS_of_geogCRS_to_geogCRS_with_area) { boundCRS, authFactory->createCoordinateReferenceSystem("4326")); ASSERT_TRUE(op != nullptr); EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), - "+proj=pipeline +step +proj=push +v_3 +step +proj=axisswap " - "+order=2,1 +step +proj=unitconvert +xy_in=deg +xy_out=rad +step " - "+proj=cart +ellps=clrk66 +step +proj=helmert +x=1 +y=2 +z=3 " - "+rx=4 +ry=5 +rz=6 +s=7 +convention=position_vector +step +inv " - "+proj=cart +ellps=WGS84 +step +proj=unitconvert +xy_in=rad " - "+xy_out=deg +step +proj=axisswap +order=2,1 +step +proj=pop " - "+v_3"); + "+proj=pipeline +step +proj=axisswap +order=2,1 +step " + "+proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=push +v_3 " + "+step +proj=cart +ellps=clrk66 +step +proj=helmert +x=1 +y=2 " + "+z=3 +rx=4 +ry=5 +rz=6 +s=7 +convention=position_vector +step " + "+inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step " + "+proj=unitconvert +xy_in=rad +xy_out=deg +step +proj=axisswap " + "+order=2,1"); } // --------------------------------------------------------------------------- @@ -5381,8 +5383,8 @@ TEST(operation, createOperation_boundCRS_identified_by_datum) { NN_CHECK_ASSERT(src), NN_CHECK_ASSERT(dest)); ASSERT_TRUE(op != nullptr); EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), - "+proj=pipeline +step +proj=push +v_3 +step +proj=unitconvert " - "+xy_in=deg +xy_out=rad +step +proj=cart +ellps=WGS84 +step " + "+proj=pipeline +step +proj=unitconvert +xy_in=deg +xy_out=rad " + "+step +proj=push +v_3 +step +proj=cart +ellps=WGS84 +step " "+proj=helmert +x=263 +y=-6 +z=-431 +step +inv +proj=cart " "+ellps=clrk80ign +step +proj=pop +v_3 +step +proj=utm +zone=32 " "+ellps=clrk80ign"); @@ -5455,13 +5457,11 @@ TEST(operation, boundCRS_of_projCRS_to_geogCRS) { ASSERT_TRUE(op != nullptr); EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), "+proj=pipeline +step +inv +proj=utm +zone=31 +ellps=clrk80ign " - "+pm=paris +step +proj=longlat +ellps=clrk80ign +pm=paris +step " - "+proj=push +v_3 +step +inv +proj=longlat +ellps=clrk80ign " - "+pm=paris +step +proj=cart +ellps=clrk80ign +step +proj=helmert " - "+x=1 +y=2 +z=3 +rx=4 +ry=5 +rz=6 +s=7 " - "+convention=position_vector +step +inv +proj=cart +ellps=WGS84 " - "+step +proj=unitconvert +xy_in=rad +xy_out=deg +step " - "+proj=axisswap +order=2,1 +step +proj=pop +v_3"); + "+pm=paris +step +proj=push +v_3 +step +proj=cart " + "+ellps=clrk80ign +step +proj=helmert +x=1 +y=2 +z=3 +rx=4 +ry=5 " + "+rz=6 +s=7 +convention=position_vector +step +inv +proj=cart " + "+ellps=WGS84 +step +proj=pop +v_3 +step +proj=unitconvert " + "+xy_in=rad +xy_out=deg +step +proj=axisswap +order=2,1"); } // --------------------------------------------------------------------------- @@ -5477,13 +5477,13 @@ TEST(operation, boundCRS_of_geogCRS_to_projCRS) { CoordinateOperationFactory::create()->createOperation(boundCRS, utm31); ASSERT_TRUE(op != nullptr); EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), - "+proj=pipeline +step +proj=push +v_3 +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=cart +ellps=clrk80ign +step +proj=helmert +x=1 +y=2 +z=3 " - "+rx=4 +ry=5 +rz=6 +s=7 +convention=position_vector +step +inv " - "+proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step +proj=utm " - "+zone=31 +ellps=WGS84"); + "+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=push +v_3 " + "+step +proj=cart +ellps=clrk80ign +step +proj=helmert +x=1 +y=2 " + "+z=3 +rx=4 +ry=5 +rz=6 +s=7 +convention=position_vector +step " + "+inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step " + "+proj=utm +zone=31 +ellps=WGS84"); } // --------------------------------------------------------------------------- @@ -5495,14 +5495,14 @@ TEST(operation, geogCRS_to_boundCRS_of_geogCRS) { GeographicCRS::EPSG_4326, boundCRS); ASSERT_TRUE(op != nullptr); EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), - "+proj=pipeline +step +proj=push +v_3 +step +proj=axisswap " - "+order=2,1 +step +proj=unitconvert +xy_in=deg +xy_out=rad +step " - "+proj=cart +ellps=WGS84 +step +inv +proj=helmert +x=1 +y=2 +z=3 " - "+rx=4 +ry=5 +rz=6 +s=7 +convention=position_vector +step +inv " - "+proj=cart +ellps=clrk80ign +step +proj=longlat " - "+ellps=clrk80ign +pm=paris +step +proj=unitconvert +xy_in=rad " - "+xy_out=grad +step +proj=axisswap +order=2,1 +step +proj=pop " - "+v_3"); + "+proj=pipeline +step +proj=axisswap +order=2,1 +step " + "+proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=push +v_3 " + "+step +proj=cart +ellps=WGS84 +step +inv +proj=helmert +x=1 " + "+y=2 +z=3 +rx=4 +ry=5 +rz=6 +s=7 +convention=position_vector " + "+step +inv +proj=cart +ellps=clrk80ign +step +proj=pop +v_3 " + "+step +proj=longlat +ellps=clrk80ign +pm=paris +step " + "+proj=unitconvert +xy_in=rad +xy_out=grad +step +proj=axisswap " + "+order=2,1"); } // --------------------------------------------------------------------------- @@ -5525,14 +5525,12 @@ TEST(operation, boundCRS_to_boundCRS) { ASSERT_TRUE(op != nullptr); EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), "+proj=pipeline +step +inv +proj=utm +zone=31 +ellps=clrk80ign " - "+pm=paris +step +proj=longlat +ellps=clrk80ign +pm=paris +step " - "+proj=push +v_3 +step +inv +proj=longlat +ellps=clrk80ign " - "+pm=paris +step +proj=cart +ellps=clrk80ign +step +proj=helmert " - "+x=1 +y=2 +z=3 +rx=4 +ry=5 +rz=6 +s=7 " - "+convention=position_vector +step +inv +proj=helmert +x=8 +y=9 " - "+z=10 +rx=11 +ry=12 +rz=13 +s=14 +convention=position_vector " - "+step +inv +proj=cart +ellps=GRS80 +step +proj=pop +v_3 +step " - "+proj=utm +zone=32 +ellps=GRS80"); + "+pm=paris +step +proj=push +v_3 +step +proj=cart " + "+ellps=clrk80ign +step +proj=helmert +x=1 +y=2 +z=3 +rx=4 +ry=5 " + "+rz=6 +s=7 +convention=position_vector +step +inv +proj=helmert " + "+x=8 +y=9 +z=10 +rx=11 +ry=12 +rz=13 +s=14 " + "+convention=position_vector +step +inv +proj=cart +ellps=GRS80 " + "+step +proj=pop +v_3 +step +proj=utm +zone=32 +ellps=GRS80"); } // --------------------------------------------------------------------------- @@ -5546,12 +5544,12 @@ TEST(operation, boundCRS_to_boundCRS_noop_for_TOWGS84) { boundCRS2); ASSERT_TRUE(op != nullptr); EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), - "+proj=pipeline +step +proj=push +v_3 +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=cart +ellps=clrk80ign +step +inv +proj=cart +ellps=GRS80 " - "+step +proj=unitconvert +xy_in=rad +xy_out=deg +step " - "+proj=axisswap +order=2,1 +step +proj=pop +v_3"); + "+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=push +v_3 " + "+step +proj=cart +ellps=clrk80ign +step +inv +proj=cart " + "+ellps=GRS80 +step +proj=pop +v_3 +step +proj=unitconvert " + "+xy_in=rad +xy_out=deg +step +proj=axisswap +order=2,1"); } // --------------------------------------------------------------------------- @@ -5949,13 +5947,13 @@ TEST(operation, compoundCRS_with_boundGeogCRS_to_geogCRS) { compound, GeographicCRS::EPSG_4979); ASSERT_TRUE(op != nullptr); EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), - "+proj=pipeline +step +proj=push +v_3 +step +proj=axisswap " - "+order=2,1 +step +proj=unitconvert +xy_in=deg +xy_out=rad +step " - "+proj=cart +ellps=WGS84 +step +proj=helmert +x=1 +y=2 +z=3 " - "+rx=4 +ry=5 +rz=6 +s=7 +convention=position_vector +step +inv " - "+proj=cart +ellps=WGS84 +step +proj=unitconvert +xy_in=rad " - "+xy_out=deg +step +proj=axisswap +order=2,1 +step +proj=pop " - "+v_3"); + "+proj=pipeline +step +proj=axisswap +order=2,1 +step " + "+proj=unitconvert +xy_in=deg +xy_out=rad +step +proj=push +v_3 " + "+step +proj=cart +ellps=WGS84 +step +proj=helmert +x=1 +y=2 " + "+z=3 +rx=4 +ry=5 +rz=6 +s=7 +convention=position_vector +step " + "+inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step " + "+proj=unitconvert +xy_in=rad +xy_out=deg +step +proj=axisswap " + "+order=2,1"); } // --------------------------------------------------------------------------- @@ -5973,12 +5971,12 @@ TEST(operation, compoundCRS_with_boundGeogCRS_and_boundVerticalCRS_to_geogCRS) { // Not completely sure the order of horizontal and vertical operations // makes sense EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), - "+proj=pipeline +step +proj=push +v_3 +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=cart +ellps=clrk80ign +step +proj=helmert +x=1 +y=2 +z=3 " - "+rx=4 +ry=5 +rz=6 +s=7 +convention=position_vector +step +inv " - "+proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step " + "+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=push +v_3 " + "+step +proj=cart +ellps=clrk80ign +step +proj=helmert +x=1 +y=2 " + "+z=3 +rx=4 +ry=5 +rz=6 +s=7 +convention=position_vector +step " + "+inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 +step " "+proj=vgridshift +grids=egm08_25.gtx +multiplier=1 +step " "+proj=unitconvert +xy_in=rad +xy_out=deg +step +proj=axisswap " "+order=2,1"); @@ -6012,14 +6010,12 @@ TEST(operation, compoundCRS_with_boundProjCRS_and_boundVerticalCRS_to_geogCRS) { // makes sense EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), "+proj=pipeline +step +inv +proj=utm +zone=31 +ellps=clrk80ign " - "+pm=paris +step +proj=longlat +ellps=clrk80ign +pm=paris +step " - "+proj=push +v_3 +step +inv +proj=longlat +ellps=clrk80ign " - "+pm=paris +step +proj=cart +ellps=clrk80ign +step +proj=helmert " - "+x=1 +y=2 +z=3 +rx=4 +ry=5 +rz=6 +s=7 " - "+convention=position_vector +step +inv +proj=cart +ellps=WGS84 " - "+step +proj=pop +v_3 +step +proj=vgridshift +grids=egm08_25.gtx " - "+multiplier=1 +step +proj=unitconvert +xy_in=rad +xy_out=deg " - "+step +proj=axisswap +order=2,1"); + "+pm=paris +step +proj=push +v_3 +step +proj=cart " + "+ellps=clrk80ign +step +proj=helmert +x=1 +y=2 +z=3 +rx=4 +ry=5 " + "+rz=6 +s=7 +convention=position_vector +step +inv +proj=cart " + "+ellps=WGS84 +step +proj=pop +v_3 +step +proj=vgridshift " + "+grids=egm08_25.gtx +multiplier=1 +step +proj=unitconvert " + "+xy_in=rad +xy_out=deg +step +proj=axisswap +order=2,1"); auto opInverse = CoordinateOperationFactory::create()->createOperation( GeographicCRS::EPSG_4979, compound); @@ -6303,9 +6299,9 @@ TEST(operation, IGNF_LAMB1_TO_EPSG_4326) { "+lon_0=0 +k_0=0.99987734 +x_0=600000 +y_0=200000 " "+ellps=clrk80ign +pm=paris +step +proj=push +v_3 +step " "+proj=cart +ellps=clrk80ign +step +proj=helmert +x=-168 +y=-60 " - "+z=320 +step +inv +proj=cart +ellps=WGS84 +step " - "+proj=unitconvert +xy_in=rad +xy_out=deg +step +proj=axisswap " - "+order=2,1 +step +proj=pop +v_3"); + "+z=320 +step +inv +proj=cart +ellps=WGS84 +step +proj=pop +v_3 " + "+step +proj=unitconvert +xy_in=rad +xy_out=deg +step " + "+proj=axisswap +order=2,1"); auto list2 = CoordinateOperationFactory::create()->createOperations( AuthorityFactory::create(DatabaseContext::create(), "EPSG") -- cgit v1.2.3 From 374cc258510428fa3bfb9d8ca61ad7ac83a00db1 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 20 Feb 2019 16:13:24 +0100 Subject: CompoundCRS to Geog3DCRS: in synthetised transformation, document in the name we are lacking an ellipsoid height to vertCRS height correction --- test/unit/test_operation.cpp | 56 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) (limited to 'test/unit') diff --git a/test/unit/test_operation.cpp b/test/unit/test_operation.cpp index 8f1caecd..c0cb0b95 100644 --- a/test/unit/test_operation.cpp +++ b/test/unit/test_operation.cpp @@ -6273,6 +6273,62 @@ TEST(operation, compoundCRS_to_geogCRS_3D) { // --------------------------------------------------------------------------- +TEST(operation, compoundCRS_to_geogCRS_3D_context) { + auto authFactory = + AuthorityFactory::create(DatabaseContext::create(), "EPSG"); + // CompoundCRS to Geog3DCRS, with vertical unit change, but without + // ellipsoid height <--> vertical height correction + { + auto ctxt = + CoordinateOperationContext::create(authFactory, nullptr, 0.0); + auto list = CoordinateOperationFactory::create()->createOperations( + authFactory->createCoordinateReferenceSystem( + "7406"), // NAD27 + NGVD29 height (ftUS) + authFactory->createCoordinateReferenceSystem("4979"), // WGS 84 + ctxt); + ASSERT_GE(list.size(), 1U); + EXPECT_EQ(list[0]->nameStr(), + "NAD27 to WGS 84 (79) + Transformation from NGVD29 height " + "(ftUS) to WGS 84 (approximate transformation, without " + "ellipsoid height to vertical height correction)"); + EXPECT_EQ(list[0]->exportToPROJString( + PROJStringFormatter::create( + PROJStringFormatter::Convention::PROJ_5, + authFactory->databaseContext()) + .get()), + "+proj=pipeline +step +proj=axisswap +order=2,1 +step " + "+proj=unitconvert +xy_in=deg +xy_out=rad +step " + "+proj=hgridshift +grids=conus +step +proj=unitconvert " + "+xy_in=rad +z_in=us-ft +xy_out=deg +z_out=m +step " + "+proj=axisswap +order=2,1"); + } + + // CompoundCRS to Geog3DCRS, with same vertical unit, but without + // ellipsoid height <--> vertical height correction + { + auto ctxt = + CoordinateOperationContext::create(authFactory, nullptr, 0.0); + auto list = CoordinateOperationFactory::create()->createOperations( + authFactory->createCoordinateReferenceSystem( + "5500"), // NAD83(NSRS2007) + NAVD88 height + authFactory->createCoordinateReferenceSystem("4979"), // WGS 84 + ctxt); + ASSERT_GE(list.size(), 1U); + EXPECT_EQ(list[0]->nameStr(), + "NAD83(NSRS2007) to WGS 84 (1) + Transformation from NAVD88 " + "height to WGS 84 (approximate transformation, without " + "ellipsoid height to vertical height correction)"); + EXPECT_EQ(list[0]->exportToPROJString( + PROJStringFormatter::create( + PROJStringFormatter::Convention::PROJ_5, + authFactory->databaseContext()) + .get()), + ""); + } +} + +// --------------------------------------------------------------------------- + TEST(operation, IGNF_LAMB1_TO_EPSG_4326) { auto authFactory = AuthorityFactory::create(DatabaseContext::create(), std::string()); -- cgit v1.2.3 From 94578ea8ff38f4bc6b1f6f52b80ecf7359f5dfc2 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 20 Feb 2019 18:04:35 +0100 Subject: CoordinateOperation: add a hasBallparkTransformation() method that can be used to know if it includes a very approximative transformation term --- test/unit/test_c_api.cpp | 6 ++++-- test/unit/test_operation.cpp | 34 ++++++++++++++++++++++------------ 2 files changed, 26 insertions(+), 14 deletions(-) (limited to 'test/unit') diff --git a/test/unit/test_c_api.cpp b/test/unit/test_c_api.cpp index 69472a58..7682c072 100644 --- a/test/unit/test_c_api.cpp +++ b/test/unit/test_c_api.cpp @@ -1345,6 +1345,7 @@ TEST_F(CApi, proj_create_operations) { auto op = proj_list_get(m_ctxt, res, 0); ASSERT_NE(op, nullptr); ObjectKeeper keeper_op(op); + EXPECT_FALSE(proj_coordoperation_has_ballpark_transformation(m_ctxt, op)); EXPECT_EQ(proj_get_name(op), std::string("NAD27 to NAD83 (3)")); } @@ -1401,8 +1402,9 @@ TEST_F(CApi, proj_create_operations_with_pivot) { ASSERT_NE(op, nullptr); ObjectKeeper keeper_op(op); - EXPECT_EQ(proj_get_name(op), - std::string("Null geographic offset from WGS 84 to JGD2011")); + EXPECT_EQ( + proj_get_name(op), + std::string("Ballpark geographic offset from WGS 84 to JGD2011")); } // Restrict pivot to Tokyo CRS diff --git a/test/unit/test_operation.cpp b/test/unit/test_operation.cpp index c0cb0b95..06c230b0 100644 --- a/test/unit/test_operation.cpp +++ b/test/unit/test_operation.cpp @@ -4199,7 +4199,7 @@ TEST(operation, geogCRS_to_geogCRS_context_default) { EXPECT_EQ(list[0]->getEPSGCode(), 15994); // Romania - 3m EXPECT_EQ(list[1]->getEPSGCode(), 1644); // Poland - 1m EXPECT_EQ(list[2]->nameStr(), - "Null geographic offset from Pulkovo 1942(58) to ETRS89"); + "Ballpark geographic offset from Pulkovo 1942(58) to ETRS89"); EXPECT_EQ( list[0]->exportToPROJString(PROJStringFormatter::create().get()), @@ -4507,7 +4507,8 @@ TEST(operation, geogCRS_to_geogCRS_noop) { auto op = CoordinateOperationFactory::create()->createOperation( GeographicCRS::EPSG_4326, GeographicCRS::EPSG_4326); ASSERT_TRUE(op != nullptr); - EXPECT_EQ(op->nameStr(), "Null geographic offset from WGS 84 to WGS 84"); + EXPECT_EQ(op->nameStr(), + "Ballpark geographic offset from WGS 84 to WGS 84"); EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), ""); EXPECT_EQ(op->inverse()->nameStr(), op->nameStr()); } @@ -4768,9 +4769,10 @@ TEST(operation, geocentricCRS_to_geogCRS_different_datum) { auto op = CoordinateOperationFactory::create()->createOperation( createGeocentricDatumWGS84(), GeographicCRS::EPSG_4269); ASSERT_TRUE(op != nullptr); - EXPECT_EQ(op->nameStr(), "Null geocentric translation from WGS 84 to NAD83 " - "(geocentric) + Conversion from NAD83 " - "(geocentric) to NAD83"); + EXPECT_EQ(op->nameStr(), + "Ballpark geocentric translation from WGS 84 to NAD83 " + "(geocentric) + Conversion from NAD83 " + "(geocentric) to NAD83"); EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), "+proj=pipeline +step +inv +proj=cart +ellps=GRS80 +step " "+proj=unitconvert +xy_in=rad +xy_out=deg +step +proj=axisswap " @@ -4785,7 +4787,7 @@ TEST(operation, geogCRS_to_geocentricCRS_different_datum) { GeographicCRS::EPSG_4269, createGeocentricDatumWGS84()); ASSERT_TRUE(op != nullptr); EXPECT_EQ(op->nameStr(), "Conversion from NAD83 to NAD83 (geocentric) + " - "Null geocentric translation from NAD83 " + "Ballpark geocentric translation from NAD83 " "(geocentric) to WGS 84"); EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), "+proj=pipeline +step +proj=axisswap +order=2,1 +step " @@ -4801,7 +4803,7 @@ TEST(operation, geocentricCRS_to_geocentricCRS_noop) { createGeocentricDatumWGS84(), createGeocentricDatumWGS84()); ASSERT_TRUE(op != nullptr); EXPECT_EQ(op->nameStr(), - "Null geocentric translation from WGS 84 to WGS 84"); + "Ballpark geocentric translation from WGS 84 to WGS 84"); EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), ""); EXPECT_EQ(op->inverse()->nameStr(), op->nameStr()); } @@ -6128,6 +6130,7 @@ TEST(operation, compoundCRS_to_compoundCRS_context) { authFactory->createCoordinateReferenceSystem("5500"), ctxt); // 152 or 155 depending if the VERTCON grids are there ASSERT_GE(list.size(), 152U); + EXPECT_FALSE(list[0]->hasBallparkTransformation()); EXPECT_EQ(list[0]->nameStr(), "NGVD29 height (ftUS) to NAVD88 height (3) + " "NAD27 to WGS 84 (79) + Inverse of " "NAD83(NSRS2007) to WGS 84 (1)"); @@ -6149,12 +6152,13 @@ TEST(operation, compoundCRS_to_compoundCRS_context) { "+xy_out=rad +z_out=m") == 0) << list[i]->nameStr(); if (list[i]->nameStr().find("Transformation from NGVD29 height (ftUS) " - "to NAVD88 height (approximate " + "to NAVD88 height (ballpark vertical " "transformation)") == 0) { + EXPECT_TRUE(list[i]->hasBallparkTransformation()); EXPECT_EQ(list[i]->nameStr(), "Transformation from NGVD29 height (ftUS) to NAVD88 " - "height (approximate transformation) + NAD27 to WGS 84 " - "(79) + Inverse of NAD83(NSRS2007) to WGS 84 (1)"); + "height (ballpark vertical transformation) + NAD27 to " + "WGS 84 (79) + Inverse of NAD83(NSRS2007) to WGS 84 (1)"); EXPECT_EQ(projString, "+proj=pipeline +step +proj=axisswap +order=2,1 +step " "+proj=unitconvert +xy_in=deg +z_in=us-ft +xy_out=rad " @@ -6254,6 +6258,7 @@ TEST(operation, compoundCRS_to_geogCRS_3D) { auto op = CoordinateOperationFactory::create()->createOperation( NN_CHECK_ASSERT(compoundcrs_ft), NN_CHECK_ASSERT(geogcrs_m)); ASSERT_TRUE(op != nullptr); + EXPECT_TRUE(op->hasBallparkTransformation()); EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), "+proj=pipeline +step +inv +proj=merc +lon_0=0 +k=1 +x_0=0 " "+y_0=0 +ellps=WGS84 +step +proj=unitconvert +xy_in=rad " @@ -6264,6 +6269,7 @@ TEST(operation, compoundCRS_to_geogCRS_3D) { auto op = CoordinateOperationFactory::create()->createOperation( NN_CHECK_ASSERT(geogcrs_m), NN_CHECK_ASSERT(compoundcrs_ft)); ASSERT_TRUE(op != nullptr); + EXPECT_TRUE(op->hasBallparkTransformation()); EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), "+proj=pipeline +step +proj=unitconvert +xy_in=deg +z_in=m " "+xy_out=rad +z_out=ft +step +proj=merc +lon_0=0 +k=1 +x_0=0 " @@ -6287,9 +6293,10 @@ TEST(operation, compoundCRS_to_geogCRS_3D_context) { authFactory->createCoordinateReferenceSystem("4979"), // WGS 84 ctxt); ASSERT_GE(list.size(), 1U); + EXPECT_TRUE(list[0]->hasBallparkTransformation()); EXPECT_EQ(list[0]->nameStr(), "NAD27 to WGS 84 (79) + Transformation from NGVD29 height " - "(ftUS) to WGS 84 (approximate transformation, without " + "(ftUS) to WGS 84 (ballpark vertical transformation, without " "ellipsoid height to vertical height correction)"); EXPECT_EQ(list[0]->exportToPROJString( PROJStringFormatter::create( @@ -6314,9 +6321,10 @@ TEST(operation, compoundCRS_to_geogCRS_3D_context) { authFactory->createCoordinateReferenceSystem("4979"), // WGS 84 ctxt); ASSERT_GE(list.size(), 1U); + EXPECT_TRUE(list[0]->hasBallparkTransformation()); EXPECT_EQ(list[0]->nameStr(), "NAD83(NSRS2007) to WGS 84 (1) + Transformation from NAVD88 " - "height to WGS 84 (approximate transformation, without " + "height to WGS 84 (ballpark vertical transformation, without " "ellipsoid height to vertical height correction)"); EXPECT_EQ(list[0]->exportToPROJString( PROJStringFormatter::create( @@ -6343,6 +6351,7 @@ TEST(operation, IGNF_LAMB1_TO_EPSG_4326) { ctxt); ASSERT_EQ(list.size(), 2U); + EXPECT_FALSE(list[0]->hasBallparkTransformation()); EXPECT_EQ(list[0]->exportToPROJString(PROJStringFormatter::create().get()), "+proj=pipeline +step +inv +proj=lcc +lat_1=49.5 +lat_0=49.5 " "+lon_0=0 +k_0=0.99987734 +x_0=600000 +y_0=200000 " @@ -6350,6 +6359,7 @@ TEST(operation, IGNF_LAMB1_TO_EPSG_4326) { "+grids=ntf_r93.gsb +step +proj=unitconvert +xy_in=rad " "+xy_out=deg +step +proj=axisswap +order=2,1"); + EXPECT_FALSE(list[1]->hasBallparkTransformation()); EXPECT_EQ(list[1]->exportToPROJString(PROJStringFormatter::create().get()), "+proj=pipeline +step +inv +proj=lcc +lat_1=49.5 +lat_0=49.5 " "+lon_0=0 +k_0=0.99987734 +x_0=600000 +y_0=200000 " -- cgit v1.2.3 From 69ef7449f5f26453a8b6cab1ba02cb870055615f Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 20 Feb 2019 20:42:26 +0100 Subject: typo fixes: s/Explictly/Explicitly/ and s/instanciat/instantiat/ --- test/unit/test_c_api.cpp | 4 ++-- test/unit/test_operation.cpp | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'test/unit') diff --git a/test/unit/test_c_api.cpp b/test/unit/test_c_api.cpp index 7682c072..486ab0c7 100644 --- a/test/unit/test_c_api.cpp +++ b/test/unit/test_c_api.cpp @@ -1302,13 +1302,13 @@ TEST_F(CApi, proj_coordoperation_get_grid_used) { // --------------------------------------------------------------------------- -TEST_F(CApi, proj_coordoperation_is_instanciable) { +TEST_F(CApi, proj_coordoperation_is_instantiable) { auto op = proj_create_from_database(m_ctxt, "EPSG", "1671", PJ_CATEGORY_COORDINATE_OPERATION, true, nullptr); ASSERT_NE(op, nullptr); ObjectKeeper keeper(op); - EXPECT_EQ(proj_coordoperation_is_instanciable(m_ctxt, op), 1); + EXPECT_EQ(proj_coordoperation_is_instantiable(m_ctxt, op), 1); } // --------------------------------------------------------------------------- diff --git a/test/unit/test_operation.cpp b/test/unit/test_operation.cpp index 06c230b0..112b46e3 100644 --- a/test/unit/test_operation.cpp +++ b/test/unit/test_operation.cpp @@ -6394,14 +6394,14 @@ TEST(operation, IGNF_LAMB1_TO_EPSG_4326) { // --------------------------------------------------------------------------- -TEST(operation, isPROJInstanciable) { +TEST(operation, isPROJInstantiable) { { auto transformation = Transformation::createGeocentricTranslations( PropertyMap(), GeographicCRS::EPSG_4269, GeographicCRS::EPSG_4326, 1.0, 2.0, 3.0, {}); EXPECT_TRUE( - transformation->isPROJInstanciable(DatabaseContext::create())); + transformation->isPROJInstantiable(DatabaseContext::create())); } // Missing grid @@ -6410,7 +6410,7 @@ TEST(operation, isPROJInstanciable) { PropertyMap(), GeographicCRS::EPSG_4807, GeographicCRS::EPSG_4326, "foo.gsb", std::vector()); EXPECT_FALSE( - transformation->isPROJInstanciable(DatabaseContext::create())); + transformation->isPROJInstantiable(DatabaseContext::create())); } // Unsupported method @@ -6422,7 +6422,7 @@ TEST(operation, isPROJInstanciable) { std::vector{}, std::vector{}); EXPECT_FALSE( - transformation->isPROJInstanciable(DatabaseContext::create())); + transformation->isPROJInstantiable(DatabaseContext::create())); } } -- cgit v1.2.3 From 287230f86d89a26574c777bb5e5b498084a84897 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Thu, 21 Feb 2019 13:48:28 +0100 Subject: Transformation: reintroduce the term of 'Null geographic offset' for transformations between geographic CRS of same datum (typically 3D to 2D) --- test/unit/test_operation.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'test/unit') diff --git a/test/unit/test_operation.cpp b/test/unit/test_operation.cpp index 112b46e3..e71ac716 100644 --- a/test/unit/test_operation.cpp +++ b/test/unit/test_operation.cpp @@ -4507,8 +4507,7 @@ TEST(operation, geogCRS_to_geogCRS_noop) { auto op = CoordinateOperationFactory::create()->createOperation( GeographicCRS::EPSG_4326, GeographicCRS::EPSG_4326); ASSERT_TRUE(op != nullptr); - EXPECT_EQ(op->nameStr(), - "Ballpark geographic offset from WGS 84 to WGS 84"); + EXPECT_EQ(op->nameStr(), "Null geographic offset from WGS 84 to WGS 84"); EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), ""); EXPECT_EQ(op->inverse()->nameStr(), op->nameStr()); } -- cgit v1.2.3 From d95b0cb8b317d0a8142b664c42928083145194ed Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 16 Mar 2019 15:14:55 +0100 Subject: createOperation(): fix geocent <--> nadgrids+geoidgrids case (fixes #1323) --- test/unit/test_operation.cpp | 45 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'test/unit') diff --git a/test/unit/test_operation.cpp b/test/unit/test_operation.cpp index e71ac716..615cbd67 100644 --- a/test/unit/test_operation.cpp +++ b/test/unit/test_operation.cpp @@ -6026,6 +6026,51 @@ TEST(operation, compoundCRS_with_boundProjCRS_and_boundVerticalCRS_to_geogCRS) { // --------------------------------------------------------------------------- +TEST(operation, geocent_to_compoundCRS) { + auto objSrc = PROJStringParser().createFromPROJString( + "+proj=geocent +datum=WGS84 +units=m +type=crs"); + auto src = nn_dynamic_pointer_cast(objSrc); + ASSERT_TRUE(src != nullptr); + auto objDst = PROJStringParser().createFromPROJString( + "+proj=longlat +ellps=GRS67 +nadgrids=@foo.gsb +geoidgrids=@foo.gtx " + "+type=crs"); + auto dst = nn_dynamic_pointer_cast(objDst); + ASSERT_TRUE(dst != nullptr); + auto op = CoordinateOperationFactory::create()->createOperation( + NN_CHECK_ASSERT(src), NN_CHECK_ASSERT(dst)); + ASSERT_TRUE(op != nullptr); + EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), + "+proj=pipeline +step +inv +proj=cart +ellps=WGS84 +step +inv " + "+proj=vgridshift +grids=@foo.gtx +multiplier=1 +step +inv " + "+proj=hgridshift +grids=@foo.gsb +step +proj=unitconvert " + "+xy_in=rad +xy_out=deg"); +} + +// --------------------------------------------------------------------------- + +TEST(operation, geocent_to_compoundCRS_context) { + auto authFactory = + AuthorityFactory::create(DatabaseContext::create(), "EPSG"); + // WGS84 geocentric + auto src = authFactory->createCoordinateReferenceSystem("4978"); + auto objDst = PROJStringParser().createFromPROJString( + "+proj=longlat +ellps=GRS67 +nadgrids=@foo.gsb +geoidgrids=@foo.gtx " + "+type=crs"); + auto dst = nn_dynamic_pointer_cast(objDst); + ASSERT_TRUE(dst != nullptr); + auto ctxt = CoordinateOperationContext::create(authFactory, nullptr, 0.0); + auto list = CoordinateOperationFactory::create()->createOperations( + src, NN_CHECK_ASSERT(dst), ctxt); + ASSERT_EQ(list.size(), 1U); + EXPECT_EQ(list[0]->exportToPROJString(PROJStringFormatter::create().get()), + "+proj=pipeline +step +inv +proj=cart +ellps=WGS84 +step +inv " + "+proj=vgridshift +grids=@foo.gtx +multiplier=1 +step +inv " + "+proj=hgridshift +grids=@foo.gsb +step +proj=unitconvert " + "+xy_in=rad +xy_out=deg"); +} + +// --------------------------------------------------------------------------- + TEST(operation, compoundCRS_to_compoundCRS) { auto compound1 = CompoundCRS::create( PropertyMap(), -- cgit v1.2.3 From 70c9d0f75c9ecbb6f1ae9b5c7cefbe3a6fdbd5b9 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 16 Mar 2019 17:26:17 +0100 Subject: createOperations(): fix nadgrids+geoidgrids -> nadgrids+geoidgrids --- test/unit/test_operation.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'test/unit') diff --git a/test/unit/test_operation.cpp b/test/unit/test_operation.cpp index 615cbd67..c7811b02 100644 --- a/test/unit/test_operation.cpp +++ b/test/unit/test_operation.cpp @@ -6161,6 +6161,31 @@ TEST(operation, compoundCRS_to_compoundCRS_with_vertical_transform) { // --------------------------------------------------------------------------- +TEST(operation, compoundCRS_to_compoundCRS_with_bound_crs_in_horiz_and_vert) { + auto objSrc = PROJStringParser().createFromPROJString( + "+proj=longlat +ellps=GRS67 +nadgrids=@foo.gsb +geoidgrids=@foo.gtx " + "+type=crs"); + auto src = nn_dynamic_pointer_cast(objSrc); + ASSERT_TRUE(src != nullptr); + auto objDst = PROJStringParser().createFromPROJString( + "+proj=longlat +ellps=GRS80 +nadgrids=@bar.gsb +geoidgrids=@bar.gtx " + "+type=crs"); + auto dst = nn_dynamic_pointer_cast(objDst); + ASSERT_TRUE(dst != nullptr); + auto op = CoordinateOperationFactory::create()->createOperation( + NN_CHECK_ASSERT(src), NN_CHECK_ASSERT(dst)); + ASSERT_TRUE(op != nullptr); + EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), + "+proj=pipeline +step +proj=unitconvert +xy_in=deg +xy_out=rad " + "+step +proj=hgridshift +grids=@foo.gsb " + "+step +proj=vgridshift +grids=@foo.gtx +multiplier=1 " + "+step +inv +proj=vgridshift +grids=@bar.gtx +multiplier=1 " + "+step +inv +proj=hgridshift +grids=@bar.gsb " + "+step +proj=unitconvert +xy_in=rad +xy_out=deg"); +} + +// --------------------------------------------------------------------------- + TEST(operation, compoundCRS_to_compoundCRS_context) { auto authFactory = AuthorityFactory::create(DatabaseContext::create(), "EPSG"); -- cgit v1.2.3 From b5fb5f070793c29bb9b60faec9d221b25e7017d4 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 16 Mar 2019 23:11:25 +0100 Subject: createOperations(): fix nadgrids -> nadgrids+geoidgrids --- test/unit/test_operation.cpp | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'test/unit') diff --git a/test/unit/test_operation.cpp b/test/unit/test_operation.cpp index c7811b02..9111b862 100644 --- a/test/unit/test_operation.cpp +++ b/test/unit/test_operation.cpp @@ -6406,6 +6406,36 @@ TEST(operation, compoundCRS_to_geogCRS_3D_context) { // --------------------------------------------------------------------------- +TEST(operation, boundCRS_to_compoundCRS) { + auto objSrc = PROJStringParser().createFromPROJString( + "+proj=longlat +ellps=GRS67 +nadgrids=@foo.gsb +type=crs"); + auto src = nn_dynamic_pointer_cast(objSrc); + ASSERT_TRUE(src != nullptr); + auto objDst = PROJStringParser().createFromPROJString( + "+proj=longlat +ellps=GRS80 +nadgrids=@bar.gsb +geoidgrids=@bar.gtx " + "+type=crs"); + auto dst = nn_dynamic_pointer_cast(objDst); + ASSERT_TRUE(dst != nullptr); + + auto op = CoordinateOperationFactory::create()->createOperation( + NN_CHECK_ASSERT(src), NN_CHECK_ASSERT(dst)); + ASSERT_TRUE(op != nullptr); + EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), + "+proj=pipeline " + "+step +proj=unitconvert +xy_in=deg +xy_out=rad " + "+step +proj=hgridshift +grids=@foo.gsb " + "+step +inv +proj=vgridshift +grids=@bar.gtx +multiplier=1 " + "+step +inv +proj=hgridshift +grids=@bar.gsb " + "+step +proj=unitconvert +xy_in=rad +xy_out=deg"); + + auto opInverse = CoordinateOperationFactory::create()->createOperation( + NN_CHECK_ASSERT(dst), NN_CHECK_ASSERT(src)); + ASSERT_TRUE(opInverse != nullptr); + EXPECT_TRUE(opInverse->inverse()->_isEquivalentTo(op.get())); +} + +// --------------------------------------------------------------------------- + TEST(operation, IGNF_LAMB1_TO_EPSG_4326) { auto authFactory = AuthorityFactory::create(DatabaseContext::create(), std::string()); -- cgit v1.2.3 From 2622d3851573cd44fc7b36bfd15f07215f434d4b Mon Sep 17 00:00:00 2001 From: Mike Taves Date: Mon, 18 Mar 2019 23:58:41 +1300 Subject: Normalize CMake with cmakelint, 2-space indent --- test/unit/CMakeLists.txt | 55 ++++++++++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 27 deletions(-) (limited to 'test/unit') diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index 58638fa4..9b160be8 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -2,12 +2,12 @@ option(USE_EXTERNAL_GTEST "Compile against external GTest" OFF) -if (USE_EXTERNAL_GTEST) +if(USE_EXTERNAL_GTEST) message(STATUS "Using external GTest") find_package(GTest 1.8.1 CONFIG REQUIRED) -else (USE_EXTERNAL_GTEST) +else() message(STATUS "Using internal GTest") @@ -23,11 +23,11 @@ string(REGEX REPLACE "\\-W[a-z\\-]+" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) # Source https://github.com/google/googletest/blob/master/googletest/README.md # Download and unpack googletest at configure time configure_file( - ${CMAKE_SOURCE_DIR}/test/googletest/CMakeLists.txt.in - ${CMAKE_BINARY_DIR}/googletest-download/CMakeLists.txt) + ${CMAKE_SOURCE_DIR}/test/googletest/CMakeLists.txt.in + ${CMAKE_BINARY_DIR}/googletest-download/CMakeLists.txt) execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" . RESULT_VARIABLE result - WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/googletest-download ) + WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/googletest-download) if(result) message(FATAL_ERROR "CMake step for googletest failed: ${result}") endif() @@ -43,9 +43,10 @@ set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) # Add googletest directly to our build. This defines # the gtest and gtest_main targets. option(INSTALL_GTEST "Enable installation of googletest" OFF) -add_subdirectory(${CMAKE_BINARY_DIR}/googletest-src - ${CMAKE_BINARY_DIR}/googletest-build - EXCLUDE_FROM_ALL) +add_subdirectory( + ${CMAKE_BINARY_DIR}/googletest-src + ${CMAKE_BINARY_DIR}/googletest-build + EXCLUDE_FROM_ALL) # FIXME: Deal with our old-school CMakeLists.txt behaving badly set(CMAKE_C_FLAGS "${_save_c_flags}") @@ -56,14 +57,14 @@ unset(_save_cxx_flags) # Provide the same target name as find_package(GTest) add_library(GTest::gtest ALIAS gtest) -endif(USE_EXTERNAL_GTEST) +endif() # USE_EXTERNAL_GTEST # # Build PROJ unit tests # if("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC" AND BUILD_LIBPROJ_SHARED) -add_definitions(-DPROJ_MSVC_DLL_IMPORT=1) + add_definitions(-DPROJ_MSVC_DLL_IMPORT=1) endif() include_directories(${CMAKE_SOURCE_DIR}/include) @@ -86,31 +87,31 @@ target_link_libraries(proj_errno_string_test add_test(NAME proj_errno_string_test COMMAND proj_errno_string_test) add_executable(proj_angular_io_test - main.cpp - proj_angular_io_test.cpp) + main.cpp + proj_angular_io_test.cpp) target_link_libraries(proj_angular_io_test - GTest::gtest - ${PROJ_LIBRARIES}) + GTest::gtest + ${PROJ_LIBRARIES}) add_test(NAME proj_angular_io_test COMMAND proj_angular_io_test) add_executable(proj_context_test - main.cpp - proj_context_test.cpp) + main.cpp + proj_context_test.cpp) target_link_libraries(proj_context_test - GTest::gtest - ${PROJ_LIBRARIES}) + GTest::gtest + ${PROJ_LIBRARIES}) add_test(NAME proj_context_test COMMAND proj_context_test) -if (MSVC AND BUILD_LIBPROJ_SHARED) -# ph_phi2_test not compatible of a .dll build +if(MSVC AND BUILD_LIBPROJ_SHARED) + # ph_phi2_test not compatible of a .dll build else() -add_executable(pj_phi2_test - main.cpp - pj_phi2_test.cpp) -target_link_libraries(pj_phi2_test - GTest::gtest - ${PROJ_LIBRARIES}) -add_test(NAME pj_phi2_test COMMAND pj_phi2_test) + add_executable(pj_phi2_test + main.cpp + pj_phi2_test.cpp) + target_link_libraries(pj_phi2_test + GTest::gtest + ${PROJ_LIBRARIES}) + add_test(NAME pj_phi2_test COMMAND pj_phi2_test) endif() add_executable(proj_test_cpp_api -- cgit v1.2.3 From 1b8b720bb742a50815b70f2025d9e1d5378899b2 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 19 Mar 2019 12:56:33 +0100 Subject: proj_create_crs_to_crs: better deal with coordinates outside of bbox (fixes #1329) In case several coordinate operations are returned for a CRS to CRS transformation, we currently determine the one to use by selecting the first operation whose bounding box contains the input point. This commit adds a fallback case where after doing that first iteration and finding no appropriate candidate, we try again by selecting the first operation available that does not involve grid based transformations. --- test/unit/gie_self_tests.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'test/unit') diff --git a/test/unit/gie_self_tests.cpp b/test/unit/gie_self_tests.cpp index 3f99b1b3..399f51e5 100644 --- a/test/unit/gie_self_tests.cpp +++ b/test/unit/gie_self_tests.cpp @@ -748,4 +748,27 @@ TEST(gie, proj_create_crs_to_crs_PULKOVO42_ETRS89) { proj_destroy(P); } +// --------------------------------------------------------------------------- + +TEST(gie, proj_create_crs_to_crs_outside_area_of_use) { + + // See https://github.com/OSGeo/proj.4/issues/1329 + auto P = proj_create_crs_to_crs(PJ_DEFAULT_CTX, "EPSG:4275", "EPSG:4807", + nullptr); + ASSERT_TRUE(P != nullptr); + PJ_COORD c; + + EXPECT_EQ(P->fwd, nullptr); + + // Test point outside area of use of both candidate coordinate operations + c.xyz.x = 58; // Lat in deg + c.xyz.y = 5; // Long in deg + c.xyz.z = 0; + c = proj_trans(P, PJ_FWD, c); + EXPECT_NEAR(c.xy.x, 64.44444444444444, 1e-9); // Lat in grad + EXPECT_NEAR(c.xy.y, 2.958634259259258, 1e-9); // Long in grad + + proj_destroy(P); +} + } // namespace -- cgit v1.2.3 From 8763ea7f01bd349df29c5c4ce3b4edd6252eff37 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 24 Mar 2019 20:01:45 +0100 Subject: WKT2 parser: update to OGC 18-010r6 - Allow ID[] in base CRS of Derived CRS - Allow VERSION[] in non-conversion coordinate operations - Use VERSION[] to set operationVersion member of CoordinateOperation - Export operationVersion in WKT2:2018 --- test/unit/test_io.cpp | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) (limited to 'test/unit') diff --git a/test/unit/test_io.cpp b/test/unit/test_io.cpp index 3d015e0c..1d097d9b 100644 --- a/test/unit/test_io.cpp +++ b/test/unit/test_io.cpp @@ -1640,6 +1640,33 @@ TEST(wkt_parse, wkt2_projected) { // --------------------------------------------------------------------------- +TEST(wkt_parse, wkt2_2018_projected_with_id_in_basegeodcrs) { + auto wkt = "PROJCRS[\"WGS 84 / UTM zone 31N\",\n" + " BASEGEOGCRS[\"WGS 84\",\n" + " DATUM[\"World Geodetic System 1984\",\n" + " ELLIPSOID[\"WGS 84\",6378137,298.257223563]],\n" + " ID[\"EPSG\",4326]],\n" + " CONVERSION[\"UTM zone 31N\",\n" + " METHOD[\"Transverse Mercator\"],\n" + " PARAMETER[\"Latitude of natural origin\",0],\n" + " PARAMETER[\"Longitude of natural origin\",3],\n" + " PARAMETER[\"Scale factor at natural origin\",0.9996],\n" + " PARAMETER[\"False easting\",500000],\n" + " PARAMETER[\"False northing\",0]],\n" + " CS[Cartesian,2],\n" + " AXIS[\"(E)\",east],\n" + " AXIS[\"(N)\",north],\n" + " UNIT[\"metre\",1],\n" + " ID[\"EPSG\",32631]]"; + auto obj = WKTParser().createFromWKT(wkt); + auto crs = nn_dynamic_pointer_cast(obj); + ASSERT_TRUE(crs != nullptr); + ASSERT_EQ(crs->baseCRS()->identifiers().size(), 1U); + EXPECT_EQ(crs->baseCRS()->identifiers().front()->code(), "4326"); +} + +// --------------------------------------------------------------------------- + TEST(wkt_parse, wkt2_2018_simplified_projected) { auto wkt = "PROJCRS[\"WGS 84 / UTM zone 31N\",\n" " BASEGEOGCRS[\"WGS 84\",\n" @@ -2280,6 +2307,95 @@ TEST(wkt_parse, COORDINATEOPERATION) { GeographicCRS::EPSG_4979->nameStr()); EXPECT_EQ(transf->method()->nameStr(), "operationMethodName"); EXPECT_EQ(transf->parameterValues().size(), 1U); + + { + auto outWkt = transf->exportToWKT(WKTFormatter::create().get()); + EXPECT_EQ(replaceAll(replaceAll(outWkt, "\n", ""), " ", ""), + replaceAll(replaceAll(wkt, "\n", ""), " ", "")); + } +} + +// --------------------------------------------------------------------------- + +TEST(wkt_parse, COORDINATEOPERATION_wkt2018) { + + std::string src_wkt; + { + auto formatter = + WKTFormatter::create(WKTFormatter::Convention::WKT2_2018); + formatter->setOutputId(false); + src_wkt = GeographicCRS::EPSG_4326->exportToWKT(formatter.get()); + } + + std::string dst_wkt; + { + auto formatter = + WKTFormatter::create(WKTFormatter::Convention::WKT2_2018); + formatter->setOutputId(false); + dst_wkt = GeographicCRS::EPSG_4807->exportToWKT(formatter.get()); + } + + std::string interpolation_wkt; + { + auto formatter = + WKTFormatter::create(WKTFormatter::Convention::WKT2_2018); + formatter->setOutputId(false); + interpolation_wkt = + GeographicCRS::EPSG_4979->exportToWKT(formatter.get()); + } + + auto wkt = + "COORDINATEOPERATION[\"transformationName\",\n" + " VERSION[\"my version\"],\n" + " SOURCECRS[" + + src_wkt + "],\n" + " TARGETCRS[" + + dst_wkt + + "],\n" + " METHOD[\"operationMethodName\",\n" + " ID[\"codeSpaceOperationMethod\",\"codeOperationMethod\"]],\n" + " PARAMETERFILE[\"paramName\",\"foo.bin\"],\n" + " INTERPOLATIONCRS[" + + interpolation_wkt + + "],\n" + " OPERATIONACCURACY[0.1],\n" + " ID[\"codeSpaceTransformation\",\"codeTransformation\"],\n" + " REMARK[\"my remarks\"]]"; + + auto obj = WKTParser().createFromWKT(wkt); + auto transf = nn_dynamic_pointer_cast(obj); + ASSERT_TRUE(transf != nullptr); + EXPECT_EQ(transf->nameStr(), "transformationName"); + EXPECT_EQ(*transf->operationVersion(), "my version"); + ASSERT_EQ(transf->identifiers().size(), 1U); + EXPECT_EQ(transf->identifiers()[0]->code(), "codeTransformation"); + EXPECT_EQ(*(transf->identifiers()[0]->codeSpace()), + "codeSpaceTransformation"); + ASSERT_EQ(transf->coordinateOperationAccuracies().size(), 1U); + EXPECT_EQ(transf->coordinateOperationAccuracies()[0]->value(), "0.1"); + EXPECT_EQ(transf->sourceCRS()->nameStr(), + GeographicCRS::EPSG_4326->nameStr()); + EXPECT_EQ(transf->targetCRS()->nameStr(), + GeographicCRS::EPSG_4807->nameStr()); + ASSERT_TRUE(transf->interpolationCRS() != nullptr); + EXPECT_EQ(transf->interpolationCRS()->nameStr(), + GeographicCRS::EPSG_4979->nameStr()); + EXPECT_EQ(transf->method()->nameStr(), "operationMethodName"); + EXPECT_EQ(transf->parameterValues().size(), 1U); + + { + auto outWkt = transf->exportToWKT( + WKTFormatter::create(WKTFormatter::Convention::WKT2_2018).get()); + EXPECT_EQ(replaceAll(replaceAll(outWkt, "\n", ""), " ", ""), + replaceAll(replaceAll(wkt, "\n", ""), " ", "")); + } + + { + auto outWkt = transf->exportToWKT( + WKTFormatter::create(WKTFormatter::Convention::WKT2_2015).get()); + EXPECT_FALSE(outWkt.find("VERSION[\"my version\"],") != + std::string::npos); + } } // --------------------------------------------------------------------------- @@ -2339,6 +2455,7 @@ TEST(wkt_parse, CONCATENATEDOPERATION) { auto concat = nn_dynamic_pointer_cast(obj); ASSERT_TRUE(concat != nullptr); EXPECT_EQ(concat->nameStr(), "name"); + EXPECT_FALSE(concat->operationVersion().has_value()); ASSERT_EQ(concat->identifiers().size(), 1U); EXPECT_EQ(concat->identifiers()[0]->code(), "code"); EXPECT_EQ(*(concat->identifiers()[0]->codeSpace()), "codeSpace"); @@ -2487,6 +2604,7 @@ TEST(wkt_parse, auto wkt = "CONCATENATEDOPERATION[\"Inverse of UTM zone 11N + NAD27 to WGS 84 " "(79) + UTM zone 11N\",\n" + " VERSION[\"my version\"],\n" " SOURCECRS[\n" " PROJCRS[\"NAD27 / UTM zone 11N\",\n" " BASEGEOGCRS[\"NAD27\",\n" @@ -2639,6 +2757,7 @@ TEST(wkt_parse, auto obj = WKTParser().createFromWKT(wkt); auto concat = nn_dynamic_pointer_cast(obj); ASSERT_TRUE(concat != nullptr); + EXPECT_EQ(*concat->operationVersion(), "my version"); EXPECT_EQ(concat->exportToPROJString(PROJStringFormatter::create().get()), "+proj=pipeline +step +inv +proj=utm +zone=11 +ellps=clrk66 " -- cgit v1.2.3 From d53911f100cfd64a77ed8aa783c0538003dbfa2d Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 25 Mar 2019 11:35:31 +0100 Subject: test: test exporting ENSEMBLE with ID in MEMBER --- test/unit/test_crs.cpp | 90 ++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 65 insertions(+), 25 deletions(-) (limited to 'test/unit') diff --git a/test/unit/test_crs.cpp b/test/unit/test_crs.cpp index 4953529c..02586877 100644 --- a/test/unit/test_crs.cpp +++ b/test/unit/test_crs.cpp @@ -148,32 +148,72 @@ TEST(crs, GeographicCRS_datum_ensemble) { std::vector{GeodeticReferenceFrame::EPSG_6326, GeodeticReferenceFrame::EPSG_6326}, PositionalAccuracy::create("100")); - auto crs = GeographicCRS::create( - PropertyMap().set(IdentifiedObject::NAME_KEY, "unnamed"), nullptr, - ensemble_vdatum, - EllipsoidalCS::createLatitudeLongitude(UnitOfMeasure::DEGREE)); - WKTFormatterNNPtr f( - WKTFormatter::create(WKTFormatter::Convention::WKT2_2018)); - f->simulCurNodeHasId(); - crs->exportToWKT(f.get()); - auto expected = "GEOGCRS[\"unnamed\",\n" - " ENSEMBLE[\"unnamed\",\n" - " MEMBER[\"World Geodetic System 1984\"],\n" - " MEMBER[\"World Geodetic System 1984\"],\n" - " ELLIPSOID[\"WGS 84\",6378137,298.257223563,\n" - " LENGTHUNIT[\"metre\",1]],\n" - " ENSEMBLEACCURACY[100]],\n" - " PRIMEM[\"Greenwich\",0,\n" - " ANGLEUNIT[\"degree\",0.0174532925199433]],\n" - " CS[ellipsoidal,2],\n" - " AXIS[\"latitude\",north,\n" - " ORDER[1],\n" - " ANGLEUNIT[\"degree\",0.0174532925199433]],\n" - " AXIS[\"longitude\",east,\n" - " ORDER[2],\n" - " ANGLEUNIT[\"degree\",0.0174532925199433]]]"; + { + auto crs = GeographicCRS::create( + PropertyMap() + .set(IdentifiedObject::NAME_KEY, "unnamed") + .set(Identifier::CODESPACE_KEY, "MY_CODESPACE") + .set(Identifier::CODE_KEY, "MY_ID"), + nullptr, ensemble_vdatum, + EllipsoidalCS::createLatitudeLongitude(UnitOfMeasure::DEGREE)); + WKTFormatterNNPtr f( + WKTFormatter::create(WKTFormatter::Convention::WKT2_2018)); + crs->exportToWKT(f.get()); + auto expected = + "GEOGCRS[\"unnamed\",\n" + " ENSEMBLE[\"unnamed\",\n" + " MEMBER[\"World Geodetic System 1984\"],\n" + " MEMBER[\"World Geodetic System 1984\"],\n" + " ELLIPSOID[\"WGS 84\",6378137,298.257223563,\n" + " LENGTHUNIT[\"metre\",1]],\n" + " ENSEMBLEACCURACY[100]],\n" + " PRIMEM[\"Greenwich\",0,\n" + " ANGLEUNIT[\"degree\",0.0174532925199433]],\n" + " CS[ellipsoidal,2],\n" + " AXIS[\"latitude\",north,\n" + " ORDER[1],\n" + " ANGLEUNIT[\"degree\",0.0174532925199433]],\n" + " AXIS[\"longitude\",east,\n" + " ORDER[2],\n" + " ANGLEUNIT[\"degree\",0.0174532925199433]],\n" + " ID[\"MY_CODESPACE\",\"MY_ID\"]]"; - EXPECT_EQ(f->toString(), expected); + EXPECT_EQ(f->toString(), expected); + } + + { + auto crs = GeographicCRS::create( + PropertyMap().set(IdentifiedObject::NAME_KEY, "unnamed"), nullptr, + ensemble_vdatum, + EllipsoidalCS::createLatitudeLongitude(UnitOfMeasure::DEGREE)); + WKTFormatterNNPtr f( + WKTFormatter::create(WKTFormatter::Convention::WKT2_2018)); + crs->exportToWKT(f.get()); + auto expected = "GEOGCRS[\"unnamed\",\n" + " ENSEMBLE[\"unnamed\",\n" + " MEMBER[\"World Geodetic System 1984\",\n" + " ID[\"EPSG\",6326]],\n" + " MEMBER[\"World Geodetic System 1984\",\n" + " ID[\"EPSG\",6326]],\n" + " ELLIPSOID[\"WGS 84\",6378137,298.257223563,\n" + " LENGTHUNIT[\"metre\",1],\n" + " ID[\"EPSG\",7030]],\n" + " ENSEMBLEACCURACY[100]],\n" + " PRIMEM[\"Greenwich\",0,\n" + " ANGLEUNIT[\"degree\",0.0174532925199433],\n" + " ID[\"EPSG\",8901]],\n" + " CS[ellipsoidal,2],\n" + " AXIS[\"latitude\",north,\n" + " ORDER[1],\n" + " ANGLEUNIT[\"degree\",0.0174532925199433,\n" + " ID[\"EPSG\",9122]]],\n" + " AXIS[\"longitude\",east,\n" + " ORDER[2],\n" + " ANGLEUNIT[\"degree\",0.0174532925199433,\n" + " ID[\"EPSG\",9122]]]]"; + + EXPECT_EQ(f->toString(), expected); + } } // --------------------------------------------------------------------------- -- cgit v1.2.3 From d4fd50f10ecabb9e9642cb4f877262e082677be4 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 25 Mar 2019 12:07:35 +0100 Subject: WKT2_2018: export ID in base crs node, when there is none on top of upper node This is the standard logic, that is now possible since ID is allowed in BASEGEOGCRS and similar node --- test/unit/test_crs.cpp | 3 ++- test/unit/test_io.cpp | 29 +++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) (limited to 'test/unit') diff --git a/test/unit/test_crs.cpp b/test/unit/test_crs.cpp index 02586877..bfd6ee66 100644 --- a/test/unit/test_crs.cpp +++ b/test/unit/test_crs.cpp @@ -4562,7 +4562,8 @@ TEST(crs, DerivedVerticalCRS_WKT2) { auto expected = "VERTCRS[\"Derived vertCRS\",\n" " BASEVERTCRS[\"ODN height\",\n" - " VDATUM[\"Ordnance Datum Newlyn\"]],\n" + " VDATUM[\"Ordnance Datum Newlyn\",\n" + " ID[\"EPSG\",5101]]],\n" " DERIVINGCONVERSION[\"unnamed\",\n" " METHOD[\"PROJ unimplemented\"]],\n" " CS[vertical,1],\n" diff --git a/test/unit/test_io.cpp b/test/unit/test_io.cpp index 1d097d9b..2181b321 100644 --- a/test/unit/test_io.cpp +++ b/test/unit/test_io.cpp @@ -1667,6 +1667,35 @@ TEST(wkt_parse, wkt2_2018_projected_with_id_in_basegeodcrs) { // --------------------------------------------------------------------------- +TEST(wkt_parse, wkt2_2018_projected_no_id_but_id_in_basegeodcrs) { + auto wkt = "PROJCRS[\"WGS 84 / UTM zone 31N\",\n" + " BASEGEOGCRS[\"WGS 84\",\n" + " DATUM[\"World Geodetic System 1984\",\n" + " ELLIPSOID[\"WGS 84\",6378137,298.257223563]],\n" + " ID[\"EPSG\",4326]],\n" + " CONVERSION[\"UTM zone 31N\",\n" + " METHOD[\"Transverse Mercator\"],\n" + " PARAMETER[\"Latitude of natural origin\",0],\n" + " PARAMETER[\"Longitude of natural origin\",3],\n" + " PARAMETER[\"Scale factor at natural origin\",0.9996],\n" + " PARAMETER[\"False easting\",500000],\n" + " PARAMETER[\"False northing\",0]],\n" + " CS[Cartesian,2],\n" + " AXIS[\"(E)\",east],\n" + " AXIS[\"(N)\",north],\n" + " UNIT[\"metre\",1]]"; + auto obj = WKTParser().createFromWKT(wkt); + auto crs = nn_dynamic_pointer_cast(obj); + ASSERT_TRUE(crs != nullptr); + + auto got_wkt = crs->exportToWKT( + WKTFormatter::create(WKTFormatter::Convention::WKT2_2018).get()); + EXPECT_TRUE(got_wkt.find("ID[\"EPSG\",4326]]") != std::string::npos) + << got_wkt; +} + +// --------------------------------------------------------------------------- + TEST(wkt_parse, wkt2_2018_simplified_projected) { auto wkt = "PROJCRS[\"WGS 84 / UTM zone 31N\",\n" " BASEGEOGCRS[\"WGS 84\",\n" -- cgit v1.2.3 From 46f08f1434f66a4160d7c74923efcfb81505b398 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 25 Mar 2019 12:44:05 +0100 Subject: WKT2_2018: always export ID in base crs node, even if there is one on upper node This is a particular logic allowed by paragraph 7.3.3 Identifier of OGC 18-010r6 --- test/unit/test_crs.cpp | 46 ++++++++++++++++++++++++++++++++++++++++++++++ test/unit/test_io.cpp | 15 +++++++++++++++ 2 files changed, 61 insertions(+) (limited to 'test/unit') diff --git a/test/unit/test_crs.cpp b/test/unit/test_crs.cpp index bfd6ee66..d7303df9 100644 --- a/test/unit/test_crs.cpp +++ b/test/unit/test_crs.cpp @@ -1601,6 +1601,52 @@ TEST(crs, projectedCRS_as_WKT2) { // --------------------------------------------------------------------------- +TEST(crs, projectedCRS_as_WKT2_2018) { + auto crs = createProjected(); + + auto expected = + "PROJCRS[\"WGS 84 / UTM zone 31N\",\n" + " BASEGEOGCRS[\"WGS 84\",\n" + " DATUM[\"World Geodetic System 1984\",\n" + " ELLIPSOID[\"WGS 84\",6378137,298.257223563,\n" + " LENGTHUNIT[\"metre\",1]]],\n" + " PRIMEM[\"Greenwich\",0,\n" + " ANGLEUNIT[\"degree\",0.0174532925199433]],\n" + " ID[\"EPSG\",4326]],\n" + " CONVERSION[\"UTM zone 31N\",\n" + " METHOD[\"Transverse Mercator\",\n" + " ID[\"EPSG\",9807]],\n" + " PARAMETER[\"Latitude of natural origin\",0,\n" + " ANGLEUNIT[\"degree\",0.0174532925199433],\n" + " ID[\"EPSG\",8801]],\n" + " PARAMETER[\"Longitude of natural origin\",3,\n" + " ANGLEUNIT[\"degree\",0.0174532925199433],\n" + " ID[\"EPSG\",8802]],\n" + " PARAMETER[\"Scale factor at natural origin\",0.9996,\n" + " SCALEUNIT[\"unity\",1],\n" + " ID[\"EPSG\",8805]],\n" + " PARAMETER[\"False easting\",500000,\n" + " LENGTHUNIT[\"metre\",1],\n" + " ID[\"EPSG\",8806]],\n" + " PARAMETER[\"False northing\",0,\n" + " LENGTHUNIT[\"metre\",1],\n" + " ID[\"EPSG\",8807]]],\n" + " CS[Cartesian,2],\n" + " AXIS[\"(E)\",east,\n" + " ORDER[1],\n" + " LENGTHUNIT[\"metre\",1]],\n" + " AXIS[\"(N)\",north,\n" + " ORDER[2],\n" + " LENGTHUNIT[\"metre\",1]],\n" + " ID[\"EPSG\",32631]]"; + + EXPECT_EQ( + crs->exportToWKT( + WKTFormatter::create(WKTFormatter::Convention::WKT2_2018).get()), + expected); +} +// --------------------------------------------------------------------------- + TEST(crs, projectedCRS_as_WKT2_simplified) { auto crs = createProjected(); diff --git a/test/unit/test_io.cpp b/test/unit/test_io.cpp index 2181b321..17b3c334 100644 --- a/test/unit/test_io.cpp +++ b/test/unit/test_io.cpp @@ -1663,6 +1663,21 @@ TEST(wkt_parse, wkt2_2018_projected_with_id_in_basegeodcrs) { ASSERT_TRUE(crs != nullptr); ASSERT_EQ(crs->baseCRS()->identifiers().size(), 1U); EXPECT_EQ(crs->baseCRS()->identifiers().front()->code(), "4326"); + + { + auto got_wkt = crs->exportToWKT( + WKTFormatter::create(WKTFormatter::Convention::WKT2_2018).get()); + EXPECT_TRUE(got_wkt.find("ID[\"EPSG\",4326]]") != std::string::npos) + << got_wkt; + } + + { + auto got_wkt = crs->exportToWKT( + WKTFormatter::create(WKTFormatter::Convention::WKT2_2018_SIMPLIFIED) + .get()); + EXPECT_TRUE(got_wkt.find("ID[\"EPSG\",4326]]") == std::string::npos) + << got_wkt; + } } // --------------------------------------------------------------------------- -- cgit v1.2.3 From 09db4826d4a1e5df900cb4b93a4b3eae2c487cb9 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 25 Mar 2019 13:56:43 +0100 Subject: WKT2_2018: always export ID of SOURCECRS/TARGETCRS and STEPs even if there is one on upper node This is a particular logic allowed by paragraph 7.3.3 Identifier of OGC 18-010r6 --- test/unit/test_factory.cpp | 18 ++++++++++++------ test/unit/test_operation.cpp | 4 ---- 2 files changed, 12 insertions(+), 10 deletions(-) (limited to 'test/unit') diff --git a/test/unit/test_factory.cpp b/test/unit/test_factory.cpp index 944e0ebe..f4c560d5 100644 --- a/test/unit/test_factory.cpp +++ b/test/unit/test_factory.cpp @@ -734,7 +734,8 @@ TEST(factory, AuthorityFactory_createCoordinateOperation_helmert_15_CF) { " LENGTHUNIT[\"metre\",1]],\n" " AXIS[\"(Z)\",geocentricZ,\n" " ORDER[3],\n" - " LENGTHUNIT[\"metre\",1]]]],\n" + " LENGTHUNIT[\"metre\",1]],\n" + " ID[\"EPSG\",5332]]],\n" " TARGETCRS[\n" " GEODCRS[\"GDA94\",\n" " DATUM[\"Geocentric Datum of Australia 1994\",\n" @@ -751,7 +752,8 @@ TEST(factory, AuthorityFactory_createCoordinateOperation_helmert_15_CF) { " LENGTHUNIT[\"metre\",1]],\n" " AXIS[\"(Z)\",geocentricZ,\n" " ORDER[3],\n" - " LENGTHUNIT[\"metre\",1]]]],\n" + " LENGTHUNIT[\"metre\",1]],\n" + " ID[\"EPSG\",4938]]],\n" " METHOD[\"Time-dependent Coordinate Frame rotation (geocen)\",\n" " ID[\"EPSG\",1056]],\n" " PARAMETER[\"X-axis translation\",-84.68,\n" @@ -885,7 +887,8 @@ TEST( " ANGLEUNIT[\"degree\",0.0174532925199433]],\n" " AXIS[\"geodetic longitude (Lon)\",east,\n" " ORDER[2],\n" - " ANGLEUNIT[\"degree\",0.0174532925199433]]]],\n" + " ANGLEUNIT[\"degree\",0.0174532925199433]],\n" + " ID[\"EPSG\",4749]]],\n" " TARGETCRS[\n" " GEOGCRS[\"NEA74 Noumea\",\n" " DATUM[\"NEA74 Noumea\",\n" @@ -899,7 +902,8 @@ TEST( " ANGLEUNIT[\"degree\",0.0174532925199433]],\n" " AXIS[\"geodetic longitude (Lon)\",east,\n" " ORDER[2],\n" - " ANGLEUNIT[\"degree\",0.0174532925199433]]]],\n" + " ANGLEUNIT[\"degree\",0.0174532925199433]],\n" + " ID[\"EPSG\",4644]]],\n" " METHOD[\"NTv2\",\n" " ID[\"EPSG\",9615]],\n" " PARAMETERFILE[\"Latitude and longitude difference " @@ -953,7 +957,8 @@ TEST(factory, AuthorityFactory_createCoordinateOperation_other_transformation) { " ANGLEUNIT[\"degree\",0.0174532925199433]],\n" " AXIS[\"geodetic longitude (Lon)\",east,\n" " ORDER[2],\n" - " ANGLEUNIT[\"degree\",0.0174532925199433]]]],\n" + " ANGLEUNIT[\"degree\",0.0174532925199433]],\n" + " ID[\"EPSG\",4818]]],\n" " TARGETCRS[\n" " GEOGCRS[\"S-JTSK\",\n" " DATUM[\"System of the Unified Trigonometrical Cadastral " @@ -968,7 +973,8 @@ TEST(factory, AuthorityFactory_createCoordinateOperation_other_transformation) { " ANGLEUNIT[\"degree\",0.0174532925199433]],\n" " AXIS[\"geodetic longitude (Lon)\",east,\n" " ORDER[2],\n" - " ANGLEUNIT[\"degree\",0.0174532925199433]]]],\n" + " ANGLEUNIT[\"degree\",0.0174532925199433]],\n" + " ID[\"EPSG\",4156]]],\n" " METHOD[\"Longitude rotation\",\n" " ID[\"EPSG\",9601]],\n" " PARAMETER[\"Longitude offset\",-17.6666666666667,\n" diff --git a/test/unit/test_operation.cpp b/test/unit/test_operation.cpp index 9111b862..848fb23b 100644 --- a/test/unit/test_operation.cpp +++ b/test/unit/test_operation.cpp @@ -442,7 +442,6 @@ TEST(operation, concatenated_operation) { { auto formatter = WKTFormatter::create(WKTFormatter::Convention::WKT2_2018); - formatter->setOutputId(false); src_wkt = GeographicCRS::EPSG_4326->exportToWKT(formatter.get()); } @@ -450,7 +449,6 @@ TEST(operation, concatenated_operation) { { auto formatter = WKTFormatter::create(WKTFormatter::Convention::WKT2_2018); - formatter->setOutputId(false); dst_wkt = GeographicCRS::EPSG_4979->exportToWKT(formatter.get()); } @@ -458,7 +456,6 @@ TEST(operation, concatenated_operation) { { auto formatter = WKTFormatter::create(WKTFormatter::Convention::WKT2_2018); - formatter->setOutputId(false); step1_wkt = transf_1->exportToWKT(formatter.get()); } @@ -466,7 +463,6 @@ TEST(operation, concatenated_operation) { { auto formatter = WKTFormatter::create(WKTFormatter::Convention::WKT2_2018); - formatter->setOutputId(false); step2_wkt = transf_2->exportToWKT(formatter.get()); } -- cgit v1.2.3 From e6f8030a51a8e8882695c2ee415609662a3078a3 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 25 Mar 2019 15:35:34 +0100 Subject: Database: update to EPSG v9.6.1 --- test/unit/test_factory.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'test/unit') diff --git a/test/unit/test_factory.cpp b/test/unit/test_factory.cpp index f4c560d5..0ff49fc5 100644 --- a/test/unit/test_factory.cpp +++ b/test/unit/test_factory.cpp @@ -150,7 +150,8 @@ TEST(factory, AuthorityFactory_createPrimeMeridian) { EXPECT_THROW(factory->createPrimeMeridian("-1"), NoSuchAuthorityCodeException); EXPECT_TRUE(nn_dynamic_pointer_cast( - factory->createObject("8903")) != nullptr); + AuthorityFactory::create(DatabaseContext::create(), "ESRI") + ->createObject("108900")) != nullptr); auto pm = factory->createPrimeMeridian("8903"); ASSERT_EQ(pm->identifiers().size(), 1U); EXPECT_EQ(pm->identifiers()[0]->code(), "8903"); -- cgit v1.2.3 From c0312858f7621bde4568d98e6ea43fd45bd57a83 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 25 Mar 2019 16:54:28 +0100 Subject: Database: update to IGNF v3.0.3 --- test/unit/test_factory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test/unit') diff --git a/test/unit/test_factory.cpp b/test/unit/test_factory.cpp index 0ff49fc5..12f58fd3 100644 --- a/test/unit/test_factory.cpp +++ b/test/unit/test_factory.cpp @@ -2799,7 +2799,7 @@ TEST(factory, getMetadata) { EXPECT_EQ(ctxt->getMetadata("i_do_not_exist"), nullptr); const char *IGNF_VERSION = ctxt->getMetadata("IGNF.VERSION"); ASSERT_TRUE(IGNF_VERSION != nullptr); - EXPECT_EQ(std::string(IGNF_VERSION), "3.0.2"); + EXPECT_EQ(std::string(IGNF_VERSION), "3.0.3"); } // --------------------------------------------------------------------------- -- cgit v1.2.3 From 054d02760db6fc2c33889d577cd671baa8807909 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 25 Mar 2019 17:00:04 +0100 Subject: Database: add operation_version column to coordinate operation tables --- test/unit/test_factory.cpp | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) (limited to 'test/unit') diff --git a/test/unit/test_factory.cpp b/test/unit/test_factory.cpp index 12f58fd3..1ceef475 100644 --- a/test/unit/test_factory.cpp +++ b/test/unit/test_factory.cpp @@ -718,6 +718,7 @@ TEST(factory, AuthorityFactory_createCoordinateOperation_helmert_15_CF) { auto op = factory->createCoordinateOperation("6276", false); auto expected = "COORDINATEOPERATION[\"ITRF2008 to GDA94 (1)\",\n" + " VERSION[\"GA-Aus 2010\"],\n" " SOURCECRS[\n" " GEODCRS[\"ITRF2008\",\n" " DATUM[\"International Terrestrial Reference Frame " @@ -875,6 +876,7 @@ TEST( auto op = factory->createCoordinateOperation("1295", false); auto expected = "COORDINATEOPERATION[\"RGNC91-93 to NEA74 Noumea (4)\",\n" + " VERSION[\"ESRI-Ncl 0.05m\"],\n" " SOURCECRS[\n" " GEOGCRS[\"RGNC91-93\",\n" " DATUM[\"Reseau Geodesique de Nouvelle Caledonie 91-93\",\n" @@ -944,6 +946,7 @@ TEST(factory, AuthorityFactory_createCoordinateOperation_other_transformation) { auto op = factory->createCoordinateOperation("1884", false); auto expected = "COORDINATEOPERATION[\"S-JTSK (Ferro) to S-JTSK (1)\",\n" + " VERSION[\"EPSG-Cze\"],\n" " SOURCECRS[\n" " GEOGCRS[\"S-JTSK (Ferro)\",\n" " DATUM[\"System of the Unified Trigonometrical Cadastral " @@ -1472,7 +1475,7 @@ class FactoryWithTmpDatabase : public ::testing::Test { "'EPSG','4326','EPSG','1262',44.0,-143." "0,-90.0,-294.0,'EPSG','9001',NULL,NULL,NULL,NULL,NULL,NULL," "NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL," - "NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0);")) + "NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0);")) << last_error(); ASSERT_TRUE(execute( @@ -1481,7 +1484,8 @@ class FactoryWithTmpDatabase : public ::testing::Test { "'EPSG','9615'" ",'NTv2','EPSG','4326','EPSG','4326','EPSG','1262',1.0,'EPSG','" "8656','Latitude and longitude difference " - "file','nzgd2kgrid0005.gsb',NULL,NULL,NULL,NULL,NULL,NULL,0);")) + "file','nzgd2kgrid0005.gsb',NULL,NULL,NULL,NULL,NULL,NULL,NULL," + "0);")) << last_error(); ASSERT_TRUE(execute( @@ -1498,7 +1502,7 @@ class FactoryWithTmpDatabase : public ::testing::Test { "offset',-17.4,'EPSG','9110',NULL,NULL,NULL,NULL,NULL,NULL," "NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL," "NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL," - "NULL,NULL,NULL,NULL,NULL,NULL,0);")) + "NULL,NULL,NULL,NULL,NULL,NULL,NULL,0);")) << last_error(); ASSERT_TRUE(execute( @@ -1506,7 +1510,7 @@ class FactoryWithTmpDatabase : public ::testing::Test { "VALUES('EPSG','DUMMY_CONCATENATED','name',NULL,NULL," "'EPSG','4326','EPSG'" ",'4326','EPSG','1262',NULL,'EPSG','DUMMY_OTHER_TRANSFORMATION'" - ",'EPSG','DUMMY_OTHER_TRANSFORMATION',NULL,NULL,0);")) + ",'EPSG','DUMMY_OTHER_TRANSFORMATION',NULL,NULL,NULL,0);")) << last_error(); } @@ -1537,7 +1541,7 @@ class FactoryWithTmpDatabase : public ::testing::Test { "','EPSG'" ",'1262',1.0,0,0,0,'EPSG','9001',NULL,NULL,NULL,NULL,NULL,NULL," "NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL," - "NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0);")) + "NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0);")) << last_error(); } @@ -1845,7 +1849,7 @@ TEST_F(FactoryWithTmpDatabase, "'EPSG','9615'" ",'NTv2','EPSG','4326','OTHER','OTHER_4326','EPSG','1262',1.0,'EPSG','" "8656','Latitude and longitude difference " - "file','nzgd2kgrid0005.gsb',NULL,NULL,NULL,NULL,NULL,NULL,0);")) + "file','nzgd2kgrid0005.gsb',NULL,NULL,NULL,NULL,NULL,NULL,NULL,0);")) << last_error(); { auto res = factoryGeneral->createFromCoordinateReferenceSystemCodes( @@ -1877,7 +1881,7 @@ TEST_F(FactoryWithTmpDatabase, "'EPSG','9615'" ",'NTv2','EPSG','4326','EPSG','4326','EPSG','1262',10.0,'EPSG','" "8656','Latitude and longitude difference " - "file','nzgd2kgrid0005.gsb',NULL,NULL,NULL,NULL,NULL,NULL,0);")) + "file','nzgd2kgrid0005.gsb',NULL,NULL,NULL,NULL,NULL,NULL,NULL,0);")) << last_error(); ASSERT_TRUE( @@ -1886,7 +1890,8 @@ TEST_F(FactoryWithTmpDatabase, "TRANSFORMATION_1M_SMALL_EXTENT',NULL,NULL,'EPSG','9615'" ",'NTv2','EPSG','4326','EPSG','4326','EPSG','2060',1.0,'EPSG','" "8656','Latitude and longitude difference " - "file','nzgd2kgrid0005.gsb',NULL,NULL,NULL,NULL,NULL,NULL,0);")) + "file','nzgd2kgrid0005.gsb',NULL,NULL,NULL,NULL,NULL,NULL," + "NULL,0);")) << last_error(); ASSERT_TRUE(execute( @@ -1895,7 +1900,7 @@ TEST_F(FactoryWithTmpDatabase, "'EPSG','9615'" ",'NTv2','EPSG','4326','EPSG','4326','EPSG','1262',1.0,'EPSG','" "8656','Latitude and longitude difference " - "file','nzgd2kgrid0005.gsb',NULL,NULL,NULL,NULL,NULL,NULL,0);")) + "file','nzgd2kgrid0005.gsb',NULL,NULL,NULL,NULL,NULL,NULL,NULL,0);")) << last_error(); ASSERT_TRUE( @@ -1904,7 +1909,8 @@ TEST_F(FactoryWithTmpDatabase, "TRANSFORMATION_0.5M_DEPRECATED',NULL,NULL,'EPSG','9615'" ",'NTv2','EPSG','4326','EPSG','4326','EPSG','1262',1.0,'EPSG','" "8656','Latitude and longitude difference " - "file','nzgd2kgrid0005.gsb',NULL,NULL,NULL,NULL,NULL,NULL,1);")) + "file','nzgd2kgrid0005.gsb',NULL,NULL,NULL,NULL,NULL,NULL," + "NULL,1);")) << last_error(); auto factoryOTHER = @@ -2007,7 +2013,7 @@ TEST_F(FactoryWithTmpDatabase, AuthorityFactory_proj_based_transformation) { "NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL," "NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL," "NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL," - "NULL,NULL,NULL,NULL,NULL,NULL,0);")) + "NULL,NULL,NULL,NULL,NULL,NULL,NULL,0);")) << last_error(); auto factoryOTHER = @@ -2068,7 +2074,7 @@ TEST_F(FactoryWithTmpDatabase, AuthorityFactory_wkt_based_transformation) { "NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL," "NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL," "NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL," - "NULL,NULL,NULL,NULL,NULL,NULL,0);")) + "NULL,NULL,NULL,NULL,NULL,NULL,NULL,0);")) << last_error(); auto factoryOTHER = @@ -2103,7 +2109,7 @@ TEST_F(FactoryWithTmpDatabase, "NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL," "NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL," "NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL," - "NULL,NULL,NULL,NULL,NULL,NULL,0);")) + "NULL,NULL,NULL,NULL,NULL,NULL,NULL,0);")) << last_error(); auto factoryOTHER = @@ -2130,7 +2136,7 @@ TEST_F(FactoryWithTmpDatabase, "NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL," "NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL," "NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL," - "NULL,NULL,NULL,NULL,NULL,NULL,0);")) + "NULL,NULL,NULL,NULL,NULL,NULL,NULL,0);")) << last_error(); auto factoryOTHER = @@ -2620,7 +2626,7 @@ TEST_F(FactoryWithTmpDatabase, "NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL," "NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL," "NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL," - "NULL,NULL,NULL,NULL,NULL,NULL,0);")) + "NULL,NULL,NULL,NULL,NULL,NULL,NULL,0);")) << last_error(); ASSERT_TRUE( @@ -2632,7 +2638,7 @@ TEST_F(FactoryWithTmpDatabase, "NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL," "NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL," "NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL," - "NULL,NULL,NULL,NULL,NULL,NULL,0);")) + "NULL,NULL,NULL,NULL,NULL,NULL,NULL,0);")) << last_error(); auto dbContext = DatabaseContext::create(m_ctxt); -- cgit v1.2.3 From b4bbcc3f264602bb4b58a5c703cc220ed404d127 Mon Sep 17 00:00:00 2001 From: Chris Mayo Date: Mon, 25 Mar 2019 18:12:03 +0000 Subject: pj_strerrno: enable system error messages HAVE_STRERROR is defined in proj_config.h. --- test/unit/CMakeLists.txt | 2 ++ test/unit/proj_errno_string_test.cpp | 1 + 2 files changed, 3 insertions(+) (limited to 'test/unit') diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index 9b160be8..66a69c3f 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -69,6 +69,8 @@ endif() include_directories(${CMAKE_SOURCE_DIR}/include) include_directories(${SQLITE3_INCLUDE_DIR}) +# Add the directory containing proj_config.h +include_directories(${CMAKE_BINARY_DIR}/src) add_executable(proj_pj_transform_test main.cpp diff --git a/test/unit/proj_errno_string_test.cpp b/test/unit/proj_errno_string_test.cpp index dcdff5c4..a592b31f 100644 --- a/test/unit/proj_errno_string_test.cpp +++ b/test/unit/proj_errno_string_test.cpp @@ -29,6 +29,7 @@ #include #include "proj.h" +#include "proj_config.h" #include "gtest_include.h" -- cgit v1.2.3 From 399ebef6a66e57d389a7b7761e7373a4cebe86e5 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 25 Mar 2019 20:51:56 +0100 Subject: lookForGridInfo(): correctly return that a grid is present, if present on the file system, but not in the database --- test/unit/test_operation.cpp | 53 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) (limited to 'test/unit') diff --git a/test/unit/test_operation.cpp b/test/unit/test_operation.cpp index 9111b862..726fb565 100644 --- a/test/unit/test_operation.cpp +++ b/test/unit/test_operation.cpp @@ -5762,6 +5762,59 @@ TEST(operation, transformation_height_to_PROJ_string) { // --------------------------------------------------------------------------- +TEST(operation, transformation_Geographic3D_to_GravityRelatedHeight_gtx) { + auto wkt = + "COORDINATEOPERATION[\"ETRS89 to NAP height (1)\",\n" + " VERSION[\"RDNAP-Nld 2008\"],\n" + " SOURCECRS[\n" + " GEOGCRS[\"ETRS89\",\n" + " DATUM[\"European Terrestrial Reference System 1989\",\n" + " ELLIPSOID[\"GRS 1980\",6378137,298.257222101,\n" + " LENGTHUNIT[\"metre\",1]]],\n" + " PRIMEM[\"Greenwich\",0,\n" + " ANGLEUNIT[\"degree\",0.0174532925199433]],\n" + " CS[ellipsoidal,3],\n" + " AXIS[\"geodetic latitude (Lat)\",north,\n" + " ORDER[1],\n" + " ANGLEUNIT[\"degree\",0.0174532925199433]],\n" + " AXIS[\"geodetic longitude (Lon)\",east,\n" + " ORDER[2],\n" + " ANGLEUNIT[\"degree\",0.0174532925199433]],\n" + " AXIS[\"ellipsoidal height (h)\",up,\n" + " ORDER[3],\n" + " LENGTHUNIT[\"metre\",1]],\n" + " ID[\"EPSG\",4937]]],\n" + " TARGETCRS[\n" + " VERTCRS[\"NAP height\",\n" + " VDATUM[\"Normaal Amsterdams Peil\"],\n" + " CS[vertical,1],\n" + " AXIS[\"gravity-related height (H)\",up,\n" + " LENGTHUNIT[\"metre\",1]],\n" + " ID[\"EPSG\",5709]]],\n" + " METHOD[\"Geographic3D to GravityRelatedHeight (US .gtx)\",\n" + " ID[\"EPSG\",9665]],\n" + " PARAMETERFILE[\"Geoid (height correction) model " + "file\",\"naptrans2008.gtx\"],\n" + " OPERATIONACCURACY[0.01],\n" + " USAGE[\n" + " SCOPE[\"unknown\"],\n" + " AREA[\"Netherlands - onshore\"],\n" + " BBOX[50.75,3.2,53.7,7.22]],\n" + " ID[\"EPSG\",7001]]"; + ; + auto obj = WKTParser().createFromWKT(wkt); + auto transf = nn_dynamic_pointer_cast(obj); + ASSERT_TRUE(transf != nullptr); + + // Check that we correctly inverse files in the case of + // "Geographic3D to GravityRelatedHeight (US .gtx)" + EXPECT_EQ(transf->exportToPROJString(PROJStringFormatter::create().get()), + "+proj=pipeline +step +inv +proj=vgridshift " + "+grids=naptrans2008.gtx +multiplier=1"); +} + +// --------------------------------------------------------------------------- + TEST(operation, transformation_ntv2_to_PROJ_string) { auto transformation = Transformation::createNTv2( PropertyMap(), GeographicCRS::EPSG_4807, GeographicCRS::EPSG_4326, -- cgit v1.2.3 From 5893c7ddef817df0c42c7ee636e6e083b0c65aed Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Thu, 28 Mar 2019 17:33:26 +0100 Subject: createOperations(): improve BoundCRS<-->non-bound-CRS case Fixes #1388 Typically helps for projinfo -s "+proj=longlat +ellps=GRS80 +towgs84=1,2,3 +type=crs" -t EPSG:4258 by researching operations from the pivot WGS84 implied by the towgs84 clause to EPSG:4258. --- test/unit/test_operation.cpp | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'test/unit') diff --git a/test/unit/test_operation.cpp b/test/unit/test_operation.cpp index 0f719a6d..3f8fb37c 100644 --- a/test/unit/test_operation.cpp +++ b/test/unit/test_operation.cpp @@ -5485,6 +5485,38 @@ TEST(operation, boundCRS_of_geogCRS_to_projCRS) { // --------------------------------------------------------------------------- +TEST(operation, boundCRS_of_geogCRS_to_unrelated_geogCRS_context) { + auto src = BoundCRS::createFromTOWGS84( + GeographicCRS::EPSG_4807, std::vector{1, 2, 3, 4, 5, 6, 7}); + auto authFactory = + AuthorityFactory::create(DatabaseContext::create(), "EPSG"); + // ETRS89 + auto dst = authFactory->createCoordinateReferenceSystem("4258"); + auto ctxt = CoordinateOperationContext::create(authFactory, nullptr, 0.0); + auto list = + CoordinateOperationFactory::create()->createOperations(src, dst, ctxt); + ASSERT_EQ(list.size(), 1U); + // Check with it is a concatenated operation, since it doesn't particularly + // show up in the PROJ string + EXPECT_TRUE(dynamic_cast(list[0].get()) != + nullptr); + EXPECT_EQ(list[0]->nameStr(), "Transformation from NTF (Paris) to WGS84 + " + "Inverse of ETRS89 to WGS 84 (1)"); + EXPECT_EQ(list[0]->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=push +v_3 +step +proj=cart +ellps=clrk80ign " + "+step +proj=helmert +x=1 +y=2 +z=3 +rx=4 +ry=5 +rz=6 +s=7 " + "+convention=position_vector " + "+step +inv +proj=cart +ellps=GRS80 +step +proj=pop +v_3 " + "+step +proj=unitconvert +xy_in=rad +xy_out=deg " + "+step +proj=axisswap +order=2,1"); +} + +// --------------------------------------------------------------------------- + TEST(operation, geogCRS_to_boundCRS_of_geogCRS) { auto boundCRS = BoundCRS::createFromTOWGS84( GeographicCRS::EPSG_4807, std::vector{1, 2, 3, 4, 5, 6, 7}); -- cgit v1.2.3 From 6a7e24dce79f93b73f4919f267df2fdf3ee95713 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Thu, 28 Mar 2019 15:26:00 +0100 Subject: Add proj_normalize_for_visualization() Fixes #1301 This function takes the output PJ from proj_create_crs_to_crs(), and add (or undo) the needed axis swap operations so that the object returned by proj_normalize_for_visualization() has the usual GIS axis order. In this implementation, this does something only if the coordinate system of the source or target CRS, geographic or projected, has NORTH, EAST ordering. CompoundCRS wrapping those objects are also handled. --- test/unit/test_c_api.cpp | 27 ++++++++++ test/unit/test_operation.cpp | 120 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 147 insertions(+) (limited to 'test/unit') diff --git a/test/unit/test_c_api.cpp b/test/unit/test_c_api.cpp index 486ab0c7..12e98d7e 100644 --- a/test/unit/test_c_api.cpp +++ b/test/unit/test_c_api.cpp @@ -3220,4 +3220,31 @@ TEST_F(CApi, proj_get_crs_info_list_from_database) { proj_crs_info_list_destroy(list); } } + +// --------------------------------------------------------------------------- + +TEST_F(CApi, proj_normalize_for_visualization) { + + { + auto P = proj_create(m_ctxt, "+proj=utm +zone=31 +ellps=WGS84"); + ObjectKeeper keeper_P(P); + ASSERT_NE(P, nullptr); + auto Pnormalized = proj_normalize_for_visualization(m_ctxt, P); + ObjectKeeper keeper_Pnormalized(Pnormalized); + EXPECT_EQ(Pnormalized, nullptr); + } + + auto P = proj_create_crs_to_crs(m_ctxt, "EPSG:4326", "EPSG:32631", nullptr); + ObjectKeeper keeper_P(P); + ASSERT_NE(P, nullptr); + auto Pnormalized = proj_normalize_for_visualization(m_ctxt, P); + ObjectKeeper keeper_Pnormalized(Pnormalized); + ASSERT_NE(Pnormalized, nullptr); + auto projstr = proj_as_proj_string(m_ctxt, Pnormalized, PJ_PROJ_5, nullptr); + ASSERT_NE(projstr, nullptr); + EXPECT_EQ(std::string(projstr), + "+proj=pipeline +step +proj=unitconvert +xy_in=deg +xy_out=rad " + "+step +proj=utm +zone=31 +ellps=WGS84"); +} + } // namespace diff --git a/test/unit/test_operation.cpp b/test/unit/test_operation.cpp index 0f719a6d..a1774416 100644 --- a/test/unit/test_operation.cpp +++ b/test/unit/test_operation.cpp @@ -7648,3 +7648,123 @@ TEST(operation, validateParameters) { EXPECT_EQ(validation, expected); } } + +// --------------------------------------------------------------------------- + +TEST(operation, normalizeForVisualization) { + + auto authFactory = + AuthorityFactory::create(DatabaseContext::create(), "EPSG"); + + // Source(geographic) must be inverted + { + auto src = authFactory->createCoordinateReferenceSystem("4326"); + auto dst = authFactory->createCoordinateReferenceSystem("32631"); + auto op = + CoordinateOperationFactory::create()->createOperation(src, dst); + ASSERT_TRUE(op != nullptr); + auto opNormalized = op->normalizeForVisualization(); + EXPECT_FALSE(opNormalized->_isEquivalentTo(op.get())); + EXPECT_EQ(opNormalized->exportToPROJString( + PROJStringFormatter::create().get()), + "+proj=pipeline " + "+step +proj=unitconvert +xy_in=deg +xy_out=rad " + "+step +proj=utm +zone=31 +ellps=WGS84"); + } + + // Target(geographic) must be inverted + { + auto src = authFactory->createCoordinateReferenceSystem("32631"); + auto dst = authFactory->createCoordinateReferenceSystem("4326"); + auto op = + CoordinateOperationFactory::create()->createOperation(src, dst); + ASSERT_TRUE(op != nullptr); + auto opNormalized = op->normalizeForVisualization(); + EXPECT_FALSE(opNormalized->_isEquivalentTo(op.get())); + EXPECT_EQ(opNormalized->exportToPROJString( + PROJStringFormatter::create().get()), + "+proj=pipeline " + "+step +inv +proj=utm +zone=31 +ellps=WGS84 " + "+step +proj=unitconvert +xy_in=rad +xy_out=deg"); + } + + // Source(geographic) and target(projected) must be inverted + { + auto src = authFactory->createCoordinateReferenceSystem("4326"); + auto dst = authFactory->createCoordinateReferenceSystem("3040"); + auto op = + CoordinateOperationFactory::create()->createOperation(src, dst); + ASSERT_TRUE(op != nullptr); + auto opNormalized = op->normalizeForVisualization(); + EXPECT_FALSE(opNormalized->_isEquivalentTo(op.get())); + EXPECT_EQ(opNormalized->exportToPROJString( + PROJStringFormatter::create().get()), + "+proj=pipeline " + "+step +proj=unitconvert +xy_in=deg +xy_out=rad " + "+step +proj=utm +zone=28 +ellps=GRS80"); + } + + // No inversion + { + auto src = authFactory->createCoordinateReferenceSystem("32631"); + auto dst = authFactory->createCoordinateReferenceSystem("32632"); + auto op = + CoordinateOperationFactory::create()->createOperation(src, dst); + ASSERT_TRUE(op != nullptr); + auto opNormalized = op->normalizeForVisualization(); + EXPECT_TRUE(opNormalized->_isEquivalentTo(op.get())); + } + + // Source(compoundCRS) and target(geographic 3D) must be inverted + { + auto ctxt = + CoordinateOperationContext::create(authFactory, nullptr, 0.0); + ctxt->setUsePROJAlternativeGridNames(false); + auto src = CompoundCRS::create( + PropertyMap(), + std::vector{ + authFactory->createCoordinateReferenceSystem("4326"), + // EGM2008 height + authFactory->createCoordinateReferenceSystem("3855")}); + auto list = CoordinateOperationFactory::create()->createOperations( + src, + authFactory->createCoordinateReferenceSystem("4979"), // WGS 84 3D + ctxt); + ASSERT_EQ(list.size(), 2U); + auto op = list[1]; + auto opNormalized = op->normalizeForVisualization(); + EXPECT_FALSE(opNormalized->_isEquivalentTo(op.get())); + EXPECT_EQ(opNormalized->exportToPROJString( + PROJStringFormatter::create( + PROJStringFormatter::Convention::PROJ_5, + authFactory->databaseContext()) + .get()), + "+proj=pipeline " + "+step +proj=unitconvert +xy_in=deg +xy_out=rad " + "+step +proj=vgridshift +grids=egm08_25.gtx +multiplier=1 " + "+step +proj=unitconvert +xy_in=rad +xy_out=deg"); + } + + // Source(boundCRS) and target(geographic) must be inverted + { + auto src = BoundCRS::createFromTOWGS84( + GeographicCRS::EPSG_4269, std::vector{1, 2, 3, 4, 5, 6, 7}); + auto dst = authFactory->createCoordinateReferenceSystem("4326"); + auto op = + CoordinateOperationFactory::create()->createOperation(src, dst); + ASSERT_TRUE(op != nullptr); + auto opNormalized = op->normalizeForVisualization(); + EXPECT_FALSE(opNormalized->_isEquivalentTo(op.get())); + EXPECT_EQ(opNormalized->exportToPROJString( + PROJStringFormatter::create().get()), + "+proj=pipeline " + "+step +proj=unitconvert +xy_in=deg +xy_out=rad " + "+step +proj=push +v_3 " + "+step +proj=cart +ellps=GRS80 " + "+step +proj=helmert +x=1 +y=2 +z=3 +rx=4 +ry=5 +rz=6 +s=7 " + "+convention=position_vector " + "+step +inv +proj=cart +ellps=WGS84 " + "+step +proj=pop +v_3 " + "+step +proj=unitconvert +xy_in=rad +xy_out=deg"); + } +} -- cgit v1.2.3 From 47dd4dbc40cbba140f4ceb775ea5d5d628fba961 Mon Sep 17 00:00:00 2001 From: Kristian Evers Date: Thu, 28 Mar 2019 22:12:32 +0100 Subject: Adopt use of the noop conversion in ISO19111 code --- test/unit/test_datum.cpp | 4 ++-- test/unit/test_io.cpp | 12 ++++++------ test/unit/test_operation.cpp | 20 ++++++++++---------- 3 files changed, 18 insertions(+), 18 deletions(-) (limited to 'test/unit') diff --git a/test/unit/test_datum.cpp b/test/unit/test_datum.cpp index 23c14f67..fa53ff85 100644 --- a/test/unit/test_datum.cpp +++ b/test/unit/test_datum.cpp @@ -175,7 +175,7 @@ TEST(datum, prime_meridian_to_PROJString) { EXPECT_EQ(PrimeMeridian::GREENWICH->exportToPROJString( PROJStringFormatter::create().get()), - ""); + "+proj=noop"); EXPECT_EQ(PrimeMeridian::PARIS->exportToPROJString( PROJStringFormatter::create().get()), @@ -195,7 +195,7 @@ TEST(datum, prime_meridian_to_PROJString) { PropertyMap().set(IdentifiedObject::NAME_KEY, "Origin meridian"), Angle(0)) ->exportToPROJString(PROJStringFormatter::create().get()), - ""); + "+proj=noop"); EXPECT_TRUE(PrimeMeridian::GREENWICH->isEquivalentTo( PrimeMeridian::GREENWICH.get())); diff --git a/test/unit/test_io.cpp b/test/unit/test_io.cpp index 17b3c334..edf987ba 100644 --- a/test/unit/test_io.cpp +++ b/test/unit/test_io.cpp @@ -6541,7 +6541,7 @@ TEST(io, projstringformatter_helmert_3_param_noop) { fmt->addParam("x", 0); fmt->addParam("y", 0); fmt->addParam("z", 0); - EXPECT_EQ(fmt->toString(), ""); + EXPECT_EQ(fmt->toString(), "+proj=noop"); } // --------------------------------------------------------------------------- @@ -6557,7 +6557,7 @@ TEST(io, projstringformatter_helmert_7_param_noop) { fmt->addParam("rz", 0); fmt->addParam("s", 0); fmt->addParam("convention", "position_vector"); - EXPECT_EQ(fmt->toString(), ""); + EXPECT_EQ(fmt->toString(), "+proj=noop"); } // --------------------------------------------------------------------------- @@ -6587,7 +6587,7 @@ TEST(io, projstringformatter_merge_consecutive_helmert_3_param_noop) { fmt->addParam("x", -10); fmt->addParam("y", -20); fmt->addParam("z", -30); - EXPECT_EQ(fmt->toString(), ""); + EXPECT_EQ(fmt->toString(), "+proj=noop"); } // --------------------------------------------------------------------------- @@ -6599,7 +6599,7 @@ TEST(io, projstringformatter_cart_grs80_wgs84) { fmt->addStep("cart"); fmt->setCurrentStepInverted(true); fmt->addParam("ellps", "GRS80"); - EXPECT_EQ(fmt->toString(), ""); + EXPECT_EQ(fmt->toString(), "+proj=noop"); } // --------------------------------------------------------------------------- @@ -7334,7 +7334,7 @@ TEST(io, projparse_longlat_axis_neu) { auto op = CoordinateOperationFactory::create()->createOperation( GeographicCRS::EPSG_4326, NN_NO_CHECK(crs)); ASSERT_TRUE(op != nullptr); - EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), ""); + EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), "+proj=noop"); } // --------------------------------------------------------------------------- @@ -7437,7 +7437,7 @@ TEST(io, projparse_longlat_axisswap) { EXPECT_EQ( op->exportToPROJString(PROJStringFormatter::create().get()), (atoi(order1) == 2 && atoi(order2) == 1) - ? "" + ? "+proj=noop" : "+proj=pipeline +step +proj=axisswap +order=2,1 " "+step +proj=axisswap +order=" + std::string(order1) + "," + order2); diff --git a/test/unit/test_operation.cpp b/test/unit/test_operation.cpp index 0f719a6d..a11c815c 100644 --- a/test/unit/test_operation.cpp +++ b/test/unit/test_operation.cpp @@ -636,7 +636,7 @@ TEST(operation, transformation_createGeocentricTranslations_null) { EXPECT_EQ(transf->inverse()->exportToPROJString( PROJStringFormatter::create().get()), - ""); + "+proj=noop"); } // --------------------------------------------------------------------------- @@ -956,7 +956,7 @@ TEST(operation, transformation_successive_helmert_noop) { std::vector{}); EXPECT_EQ(concat->exportToPROJString(PROJStringFormatter::create().get()), - ""); + "+proj=noop"); } // --------------------------------------------------------------------------- @@ -4131,7 +4131,7 @@ TEST(operation, PROJ_based_empty) { SingleOperation::createPROJBased(PropertyMap(), "", nullptr, nullptr); EXPECT_EQ(conv->exportToPROJString(PROJStringFormatter::create().get()), - ""); + "+proj=noop"); EXPECT_EQ(conv->exportToWKT(WKTFormatter::create().get()), "CONVERSION[\"PROJ-based coordinate operation\",\n" @@ -4144,7 +4144,7 @@ TEST(operation, PROJ_based_empty) { EXPECT_EQ(conv->inverse()->exportToPROJString( PROJStringFormatter::create().get()), - ""); + "+proj=noop"); } // --------------------------------------------------------------------------- @@ -4328,7 +4328,7 @@ TEST(operation, geogCRS_to_geogCRS_context_filter_bbox) { ASSERT_EQ(list.size(), 1U); EXPECT_EQ( list[0]->exportToPROJString(PROJStringFormatter::create().get()), - ""); + "+proj=noop"); } } @@ -4344,7 +4344,7 @@ TEST(operation, geogCRS_to_geogCRS_context_incompatible_area) { ctxt); ASSERT_EQ(list.size(), 1U); EXPECT_EQ(list[0]->exportToPROJString(PROJStringFormatter::create().get()), - ""); + "+proj=noop"); } // --------------------------------------------------------------------------- @@ -4504,7 +4504,7 @@ TEST(operation, geogCRS_to_geogCRS_noop) { GeographicCRS::EPSG_4326, GeographicCRS::EPSG_4326); ASSERT_TRUE(op != nullptr); EXPECT_EQ(op->nameStr(), "Null geographic offset from WGS 84 to WGS 84"); - EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), ""); + EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), "+proj=noop"); EXPECT_EQ(op->inverse()->nameStr(), op->nameStr()); } @@ -4651,7 +4651,7 @@ TEST(operation, geogCRS_to_geogCRS_CH1903_to_CH1903plus_context) { EXPECT_EQ(list[0]->nameStr(), "CH1903 to ETRS89 (1) + Inverse of CH1903+ to ETRS89 (1)"); EXPECT_EQ(list[0]->exportToPROJString(PROJStringFormatter::create().get()), - ""); + "+proj=noop"); EXPECT_EQ(list[1]->nameStr(), "CH1903 to CH1903+ (1)"); EXPECT_EQ(list[1]->exportToPROJString(PROJStringFormatter::create().get()), @@ -4799,7 +4799,7 @@ TEST(operation, geocentricCRS_to_geocentricCRS_noop) { ASSERT_TRUE(op != nullptr); EXPECT_EQ(op->nameStr(), "Ballpark geocentric translation from WGS 84 to WGS 84"); - EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), ""); + EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), "+proj=noop"); EXPECT_EQ(op->inverse()->nameStr(), op->nameStr()); } @@ -6449,7 +6449,7 @@ TEST(operation, compoundCRS_to_geogCRS_3D_context) { PROJStringFormatter::Convention::PROJ_5, authFactory->databaseContext()) .get()), - ""); + "+proj=noop"); } } -- cgit v1.2.3 From 88f2661c9fd9fbf9d714a184243340cafb64d91d Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Fri, 29 Mar 2019 13:30:57 +0100 Subject: createOperations(): improve behaviour with input CRS from WKT that lacks intermediate IDs (fixes #1343) --- test/unit/test_operation.cpp | 171 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) (limited to 'test/unit') diff --git a/test/unit/test_operation.cpp b/test/unit/test_operation.cpp index 4e3ceb56..32acbf22 100644 --- a/test/unit/test_operation.cpp +++ b/test/unit/test_operation.cpp @@ -4746,6 +4746,52 @@ TEST(operation, geogCRS_to_geogCRS_3D) { // --------------------------------------------------------------------------- +TEST(operation, geogCRS_without_id_to_geogCRS_3D_context) { + auto authFactory = + AuthorityFactory::create(DatabaseContext::create(), "EPSG"); + auto ctxt = CoordinateOperationContext::create(authFactory, nullptr, 0.0); + auto src = + authFactory->createCoordinateReferenceSystem("4289"); // Amersfoort + auto dst = + authFactory->createCoordinateReferenceSystem("4937"); // ETRS89 3D + auto list = + CoordinateOperationFactory::create()->createOperations(src, dst, ctxt); + ASSERT_GE(list.size(), 1U); + auto wkt2 = "GEOGCRS[\"unnamed\",\n" + " DATUM[\"Amersfoort\",\n" + " ELLIPSOID[\"Bessel 1841\",6377397.155,299.1528128,\n" + " LENGTHUNIT[\"metre\",1]]],\n" + " PRIMEM[\"Greenwich\",0,\n" + " ANGLEUNIT[\"degree\",0.0174532925199433]],\n" + " CS[ellipsoidal,2],\n" + " AXIS[\"geodetic latitude (Lat)\",north,\n" + " ORDER[1],\n" + " ANGLEUNIT[\"degree\",0.0174532925199433]],\n" + " AXIS[\"geodetic longitude (Lon)\",east,\n" + " ORDER[2],\n" + " ANGLEUNIT[\"degree\",0.0174532925199433]]," + " USAGE[\n" + " SCOPE[\"unknown\"],\n" + " AREA[\"Netherlands - onshore\"],\n" + " BBOX[50.75,3.2,53.7,7.22]]]\n"; + + auto obj = WKTParser().createFromWKT(wkt2); + auto src_from_wkt2 = nn_dynamic_pointer_cast(obj); + ASSERT_TRUE(src_from_wkt2 != nullptr); + auto list2 = CoordinateOperationFactory::create()->createOperations( + NN_NO_CHECK(src_from_wkt2), dst, ctxt); + ASSERT_GE(list.size(), list2.size()); + for (size_t i = 0; i < list.size(); i++) { + const auto &op = list[i]; + const auto &op2 = list2[i]; + EXPECT_TRUE( + op->isEquivalentTo(op2.get(), IComparable::Criterion::EQUIVALENT)) + << op->nameStr() << " " << op2->nameStr(); + } +} + +// --------------------------------------------------------------------------- + TEST(operation, geocentricCRS_to_geogCRS_same_datum) { auto op = CoordinateOperationFactory::create()->createOperation( @@ -5172,6 +5218,50 @@ TEST(operation, projCRS_to_geogCRS) { // --------------------------------------------------------------------------- +TEST(operation, projCRS_no_id_to_geogCRS_context) { + auto authFactory = + AuthorityFactory::create(DatabaseContext::create(), "EPSG"); + auto ctxt = CoordinateOperationContext::create(authFactory, nullptr, 0.0); + auto src = authFactory->createCoordinateReferenceSystem( + "28992"); // Amersfoort / RD New + auto dst = + authFactory->createCoordinateReferenceSystem("4258"); // ETRS89 2D + auto list = + CoordinateOperationFactory::create()->createOperations(src, dst, ctxt); + ASSERT_GE(list.size(), 1U); + auto wkt2 = + "PROJCRS[\"unknown\",\n" + " BASEGEOGCRS[\"Amersfoort\",\n" + " DATUM[\"Amersfoort\",\n" + " ELLIPSOID[\"Bessel 1841\",6377397.155,299.1528128]]],\n" + " CONVERSION[\"unknown\",\n" + " METHOD[\"Oblique Stereographic\"],\n" + " PARAMETER[\"Latitude of natural origin\",52.1561605555556],\n" + " PARAMETER[\"Longitude of natural origin\",5.38763888888889],\n" + " PARAMETER[\"Scale factor at natural origin\",0.9999079],\n" + " PARAMETER[\"False easting\",155000],\n" + " PARAMETER[\"False northing\",463000]],\n" + " CS[Cartesian,2],\n" + " AXIS[\"(E)\",east],\n" + " AXIS[\"(N)\",north],\n" + " LENGTHUNIT[\"metre\",1],\n" + " ID[\"EPSG\",28992]]"; + auto obj = WKTParser().createFromWKT(wkt2); + auto src_from_wkt2 = nn_dynamic_pointer_cast(obj); + ASSERT_TRUE(src_from_wkt2 != nullptr); + auto list2 = CoordinateOperationFactory::create()->createOperations( + NN_NO_CHECK(src_from_wkt2), dst, ctxt); + ASSERT_GE(list.size(), list2.size() - 1); + for (size_t i = 0; i < list.size(); i++) { + const auto &op = list[i]; + const auto &op2 = list2[i]; + EXPECT_TRUE( + op->isEquivalentTo(op2.get(), IComparable::Criterion::EQUIVALENT)); + } +} + +// --------------------------------------------------------------------------- + TEST(operation, projCRS_to_projCRS) { auto op = CoordinateOperationFactory::create()->createOperation( @@ -6487,6 +6577,87 @@ TEST(operation, compoundCRS_to_geogCRS_3D_context) { // --------------------------------------------------------------------------- +TEST(operation, compoundCRS_from_WKT2_to_geogCRS_3D_context) { + auto authFactory = + AuthorityFactory::create(DatabaseContext::create(), "EPSG"); + auto ctxt = CoordinateOperationContext::create(authFactory, nullptr, 0.0); + auto src = authFactory->createCoordinateReferenceSystem( + "7415"); // Amersfoort / RD New + NAP height + auto dst = + authFactory->createCoordinateReferenceSystem("4937"); // ETRS89 3D + auto list = + CoordinateOperationFactory::create()->createOperations(src, dst, ctxt); + ASSERT_GE(list.size(), 1U); + auto wkt2 = src->exportToWKT( + WKTFormatter::create(WKTFormatter::Convention::WKT2_2018).get()); + auto obj = WKTParser().createFromWKT(wkt2); + auto src_from_wkt2 = nn_dynamic_pointer_cast(obj); + ASSERT_TRUE(src_from_wkt2 != nullptr); + auto list2 = CoordinateOperationFactory::create()->createOperations( + NN_NO_CHECK(src_from_wkt2), dst, ctxt); + ASSERT_GE(list.size(), list2.size()); + for (size_t i = 0; i < list.size(); i++) { + const auto &op = list[i]; + const auto &op2 = list2[i]; + EXPECT_TRUE( + op->isEquivalentTo(op2.get(), IComparable::Criterion::EQUIVALENT)); + } +} + +// --------------------------------------------------------------------------- + +TEST(operation, compoundCRS_from_WKT2_no_id_to_geogCRS_3D_context) { + auto authFactory = + AuthorityFactory::create(DatabaseContext::create(), "EPSG"); + auto ctxt = CoordinateOperationContext::create(authFactory, nullptr, 0.0); + ctxt->setSpatialCriterion( + CoordinateOperationContext::SpatialCriterion::PARTIAL_INTERSECTION); + auto src = authFactory->createCoordinateReferenceSystem( + "7415"); // Amersfoort / RD New + NAP height + auto dst = + authFactory->createCoordinateReferenceSystem("4937"); // ETRS89 3D + auto list = + CoordinateOperationFactory::create()->createOperations(src, dst, ctxt); + ASSERT_GE(list.size(), 1U); + auto wkt2 = + "COMPOUNDCRS[\"unknown\",\n" + " PROJCRS[\"unknown\",\n" + " BASEGEOGCRS[\"Amersfoort\",\n" + " DATUM[\"Amersfoort\",\n" + " ELLIPSOID[\"Bessel " + "1841\",6377397.155,299.1528128]]],\n" + " CONVERSION[\"unknown\",\n" + " METHOD[\"Oblique Stereographic\"],\n" + " PARAMETER[\"Latitude of natural origin\",52.1561605555556],\n" + " PARAMETER[\"Longitude of natural origin\",5.38763888888889],\n" + " PARAMETER[\"Scale factor at natural origin\",0.9999079],\n" + " PARAMETER[\"False easting\",155000],\n" + " PARAMETER[\"False northing\",463000]],\n" + " CS[Cartesian,2],\n" + " AXIS[\"(E)\",east],\n" + " AXIS[\"(N)\",north],\n" + " LENGTHUNIT[\"metre\",1]],\n" + " VERTCRS[\"NAP height\",\n" + " VDATUM[\"Normaal Amsterdams Peil\"],\n" + " CS[vertical,1],\n" + " AXIS[\"gravity-related height (H)\",up,\n" + " LENGTHUNIT[\"metre\",1]]]]"; + auto obj = WKTParser().createFromWKT(wkt2); + auto src_from_wkt2 = nn_dynamic_pointer_cast(obj); + ASSERT_TRUE(src_from_wkt2 != nullptr); + auto list2 = CoordinateOperationFactory::create()->createOperations( + NN_NO_CHECK(src_from_wkt2), dst, ctxt); + ASSERT_GE(list.size(), list2.size() - 1); + for (size_t i = 0; i < list.size(); i++) { + const auto &op = list[i]; + const auto &op2 = list2[i]; + EXPECT_TRUE( + op->isEquivalentTo(op2.get(), IComparable::Criterion::EQUIVALENT)); + } +} + +// --------------------------------------------------------------------------- + TEST(operation, boundCRS_to_compoundCRS) { auto objSrc = PROJStringParser().createFromPROJString( "+proj=longlat +ellps=GRS67 +nadgrids=@foo.gsb +type=crs"); -- cgit v1.2.3 From e41b9f143c783651ce8576f0ccc5ca612883c9e6 Mon Sep 17 00:00:00 2001 From: Mike Taves Date: Fri, 5 Apr 2019 00:18:16 +1300 Subject: CMake: cache C/C++ warn flags to compile PROJ targets Remove (most) needs to fiddle with CMAKE_C_FLAGS / CMAKE_CXX_FLAGS --- test/unit/CMakeLists.txt | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) (limited to 'test/unit') diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index 66a69c3f..40a3dd06 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -11,12 +11,6 @@ else() message(STATUS "Using internal GTest") -# FIXME: Deal with our old-school CMakeLists.txt behaving badly -set(_save_c_flags "${CMAKE_C_FLAGS}") -set(_save_cxx_flags "${CMAKE_CXX_FLAGS}") -string(REGEX REPLACE "\\-W[a-z\\-]+" "" CMAKE_C_FLAGS ${CMAKE_C_FLAGS}) -string(REGEX REPLACE "\\-W[a-z\\-]+" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) - # # Build Google Test # @@ -48,12 +42,6 @@ add_subdirectory( ${CMAKE_BINARY_DIR}/googletest-build EXCLUDE_FROM_ALL) -# FIXME: Deal with our old-school CMakeLists.txt behaving badly -set(CMAKE_C_FLAGS "${_save_c_flags}") -set(CMAKE_CXX_FLAGS "${_save_cxx_flags}") -unset(_save_c_flags) -unset(_save_cxx_flags) - # Provide the same target name as find_package(GTest) add_library(GTest::gtest ALIAS gtest) @@ -72,6 +60,9 @@ include_directories(${SQLITE3_INCLUDE_DIR}) # Add the directory containing proj_config.h include_directories(${CMAKE_BINARY_DIR}/src) +# Apply to targets in the current directory and below +add_compile_options(${PROJ_CXX_WARN_FLAGS}) + add_executable(proj_pj_transform_test main.cpp pj_transform_test.cpp) -- cgit v1.2.3 From 3aed84243a8188b54d19d7e9c26028796eb398b0 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Fri, 5 Apr 2019 12:54:56 +0200 Subject: _buildUnit(): avoid later division by zero Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=14055 Credit to OSS Fuzz --- test/unit/test_io.cpp | 3 ++- test/unit/test_operation.cpp | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'test/unit') diff --git a/test/unit/test_io.cpp b/test/unit/test_io.cpp index edf987ba..30e0b427 100644 --- a/test/unit/test_io.cpp +++ b/test/unit/test_io.cpp @@ -7334,7 +7334,8 @@ TEST(io, projparse_longlat_axis_neu) { auto op = CoordinateOperationFactory::create()->createOperation( GeographicCRS::EPSG_4326, NN_NO_CHECK(crs)); ASSERT_TRUE(op != nullptr); - EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), "+proj=noop"); + EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), + "+proj=noop"); } // --------------------------------------------------------------------------- diff --git a/test/unit/test_operation.cpp b/test/unit/test_operation.cpp index c4cafef6..08a3f6ad 100644 --- a/test/unit/test_operation.cpp +++ b/test/unit/test_operation.cpp @@ -4504,7 +4504,8 @@ TEST(operation, geogCRS_to_geogCRS_noop) { GeographicCRS::EPSG_4326, GeographicCRS::EPSG_4326); ASSERT_TRUE(op != nullptr); EXPECT_EQ(op->nameStr(), "Null geographic offset from WGS 84 to WGS 84"); - EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), "+proj=noop"); + EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), + "+proj=noop"); EXPECT_EQ(op->inverse()->nameStr(), op->nameStr()); } @@ -4845,7 +4846,8 @@ TEST(operation, geocentricCRS_to_geocentricCRS_noop) { ASSERT_TRUE(op != nullptr); EXPECT_EQ(op->nameStr(), "Ballpark geocentric translation from WGS 84 to WGS 84"); - EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), "+proj=noop"); + EXPECT_EQ(op->exportToPROJString(PROJStringFormatter::create().get()), + "+proj=noop"); EXPECT_EQ(op->inverse()->nameStr(), op->nameStr()); } -- cgit v1.2.3 From d9e2a15f2e17b6710ccffa3e271595e006ceadf2 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 16 Apr 2019 19:26:16 +0200 Subject: createOperations(): do not attempt using a unrelated datum intermediate when doing geog2D<-->geog3D conversions of same datum Seen when testing transformations between "CR 05" (EPSG:5365) and "CR-SIRGAS" (EPSG:8907) which require going through their corresponding 3D GeogCRS to find a Helmert transformation. --- test/unit/test_factory.cpp | 12 +++++++-- test/unit/test_operation.cpp | 61 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 2 deletions(-) (limited to 'test/unit') diff --git a/test/unit/test_factory.cpp b/test/unit/test_factory.cpp index 1ceef475..91024d62 100644 --- a/test/unit/test_factory.cpp +++ b/test/unit/test_factory.cpp @@ -1518,12 +1518,20 @@ class FactoryWithTmpDatabase : public ::testing::Test { const auto vals = std::vector{"SOURCE", "TARGET", "PIVOT"}; for (const auto &val : vals) { + ASSERT_TRUE( + execute("INSERT INTO geodetic_datum " + "VALUES('FOO','" + + val + "','" + val + + "','',NULL," + "'EPSG','7030','EPSG','8901','EPSG','1262',0);")) + << last_error(); ASSERT_TRUE(execute("INSERT INTO geodetic_crs " "VALUES('NS_" + val + "','" + val + "','" + val + "',NULL,NULL,'geographic 2D','EPSG','6422'," - "'EPSG','6326'," - "'EPSG','1262',NULL,0);")) + "'FOO','" + + val + "'," + "'EPSG','1262',NULL,0);")) << last_error(); } } diff --git a/test/unit/test_operation.cpp b/test/unit/test_operation.cpp index 08a3f6ad..b7b87d76 100644 --- a/test/unit/test_operation.cpp +++ b/test/unit/test_operation.cpp @@ -218,6 +218,11 @@ TEST(operation, SingleOperation) { EXPECT_TRUE(sop1->isEquivalentTo(sop1.get())); EXPECT_FALSE(sop1->isEquivalentTo(createUnrelatedObject().get())); + EXPECT_TRUE( + sop1->isEquivalentTo(sop1->CoordinateOperation::shallowClone().get())); + EXPECT_TRUE(sop1->inverse()->isEquivalentTo( + sop1->inverse()->CoordinateOperation::shallowClone().get())); + auto sop2 = Transformation::create( PropertyMap(), nn_static_pointer_cast(GeographicCRS::EPSG_4326), nn_static_pointer_cast(GeographicCRS::EPSG_4807), @@ -510,6 +515,8 @@ TEST(operation, concatenated_operation) { EXPECT_TRUE(concat->isEquivalentTo(concat.get())); EXPECT_FALSE(concat->isEquivalentTo(createUnrelatedObject().get())); + EXPECT_TRUE(concat->isEquivalentTo( + concat->CoordinateOperation::shallowClone().get())); EXPECT_FALSE( ConcatenatedOperation::create(PropertyMap(), std::vector{ @@ -4050,6 +4057,11 @@ TEST(operation, conversion_inverse) { EXPECT_TRUE(inv->isEquivalentTo(inv.get())); EXPECT_FALSE(inv->isEquivalentTo(createUnrelatedObject().get())); + + EXPECT_TRUE( + conv->isEquivalentTo(conv->CoordinateOperation::shallowClone().get())); + EXPECT_TRUE( + inv->isEquivalentTo(inv->CoordinateOperation::shallowClone().get())); } // --------------------------------------------------------------------------- @@ -4942,6 +4954,24 @@ TEST(operation, geogCRS_geocentricCRS_same_datum_to_context) { // --------------------------------------------------------------------------- +TEST(operation, + geog2D_to_geog3D_same_datum_but_with_potential_other_pivot_context) { + // Check that when going from geog2D to geog3D of same datum, we don't + // try to go through a WGS84 pivot... + auto authFactory = + AuthorityFactory::create(DatabaseContext::create(), "EPSG"); + auto ctxt = CoordinateOperationContext::create(authFactory, nullptr, 0.0); + auto list = CoordinateOperationFactory::create()->createOperations( + authFactory->createCoordinateReferenceSystem("5365"), // CR 05 2D + authFactory->createCoordinateReferenceSystem("5364"), // CR 05 3D + ctxt); + ASSERT_EQ(list.size(), 1U); + EXPECT_EQ(list[0]->exportToPROJString(PROJStringFormatter::create().get()), + "+proj=noop"); +} + +// --------------------------------------------------------------------------- + TEST(operation, geogCRS_to_geogCRS_different_datum_though_geocentric_transform_context) { auto authFactory = @@ -5402,6 +5432,37 @@ TEST(operation, projCRS_to_projCRS_south_pole_inverted_axis) { // --------------------------------------------------------------------------- +TEST(operation, projCRS_to_projCRS_through_geog3D) { + // Check that when going from projCRS to projCRS, using + // geog2D-->geog3D-->geog3D-->geog2D we do not have issues with + // inconsistent CRS chaining, due to how we 'hack' a bit some intermediate + // steps + auto authFactory = + AuthorityFactory::create(DatabaseContext::create(), "EPSG"); + auto ctxt = CoordinateOperationContext::create(authFactory, nullptr, 0.0); + auto list = CoordinateOperationFactory::create()->createOperations( + authFactory->createCoordinateReferenceSystem("5367"), // CR05 / CRTM05 + authFactory->createCoordinateReferenceSystem( + "8908"), // CR-SIRGAS / CRTM05 + ctxt); + ASSERT_EQ(list.size(), 1U); + EXPECT_EQ(list[0]->exportToPROJString(PROJStringFormatter::create().get()), + "+proj=pipeline +step +proj=axisswap +order=2,1 " + "+step +inv +proj=tmerc +lat_0=0 +lon_0=-84 +k=0.9999 " + "+x_0=500000 +y_0=0 +ellps=WGS84 " + "+step +proj=push +v_3 " + "+step +proj=cart +ellps=WGS84 " + "+step +proj=helmert +x=-0.16959 +y=0.35312 +z=0.51846 " + "+rx=-0.03385 +ry=0.16325 +rz=-0.03446 +s=0.03693 " + "+convention=position_vector " + "+step +inv +proj=cart +ellps=GRS80 " + "+step +proj=pop +v_3 " + "+step +proj=tmerc +lat_0=0 +lon_0=-84 +k=0.9999 +x_0=500000 " + "+y_0=0 +ellps=GRS80"); +} + +// --------------------------------------------------------------------------- + TEST(operation, boundCRS_of_geogCRS_to_geogCRS) { auto boundCRS = BoundCRS::createFromTOWGS84( GeographicCRS::EPSG_4807, std::vector{1, 2, 3, 4, 5, 6, 7}); -- cgit v1.2.3 From d8526d7870e4b91238c9a7b652ed03c21b77e884 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 22 Apr 2019 13:15:02 +0200 Subject: ESRI_WKT: preserve Gauss_Kruger in conversion name for round-tripping --- test/unit/test_io.cpp | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'test/unit') diff --git a/test/unit/test_io.cpp b/test/unit/test_io.cpp index 30e0b427..c4178f20 100644 --- a/test/unit/test_io.cpp +++ b/test/unit/test_io.cpp @@ -5180,6 +5180,43 @@ TEST(wkt_parse, wkt1_esri_ups_south) { // --------------------------------------------------------------------------- +TEST(wkt_parse, wkt1_esri_gauss_kruger) { + auto wkt = "PROJCS[\"ETRS_1989_UWPP_2000_PAS_8\",GEOGCS[\"GCS_ETRS_1989\"," + "DATUM[\"D_ETRS_1989\"," + "SPHEROID[\"GRS_1980\",6378137.0,298.257222101]]," + "PRIMEM[\"Greenwich\",0.0]," + "UNIT[\"Degree\",0.0174532925199433]]," + "PROJECTION[\"Gauss_Kruger\"]," + "PARAMETER[\"False_Easting\",8500000.0]," + "PARAMETER[\"False_Northing\",0.0]," + "PARAMETER[\"Central_Meridian\",24.0]," + "PARAMETER[\"Scale_Factor\",0.999923]," + "PARAMETER[\"Latitude_Of_Origin\",0.0]," + "UNIT[\"Meter\",1.0]]"; + + auto dbContext = DatabaseContext::create(); + auto obj = WKTParser().attachDatabaseContext(dbContext).createFromWKT(wkt); + auto crs = nn_dynamic_pointer_cast(obj); + ASSERT_TRUE(crs != nullptr); + + EXPECT_EQ( + crs->exportToWKT( + WKTFormatter::create(WKTFormatter::Convention::WKT1_ESRI, dbContext) + .get()), + wkt); + + auto crs2 = AuthorityFactory::create(dbContext, "ESRI") + ->createProjectedCRS("102177"); + + EXPECT_EQ( + crs2->exportToWKT( + WKTFormatter::create(WKTFormatter::Convention::WKT1_ESRI, dbContext) + .get()), + wkt); +} + +// --------------------------------------------------------------------------- + TEST(wkt_parse, invalid) { EXPECT_THROW(WKTParser().createFromWKT(""), ParsingException); EXPECT_THROW(WKTParser().createFromWKT("A"), ParsingException); -- cgit v1.2.3 From 292807eee9e1194175b64cb5c0a9f0b432352abc Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 22 Apr 2019 20:05:36 +0200 Subject: proj_create(): add support for compoundCRS and concatenatedOperation named from their components Support following syntaxes: - OGC URN combining references for compoundCRS: e.g. "urn:ogc:def:crs,crs:EPSG::2393,crs:EPSG::5717" - its GDAL shortcut: e.g. "EPSG:2393+5717" - OGC URN combining references for concatenated operations: e.g. "urn:ogc:def:coordinateOperation,coordinateOperation:EPSG::3895,coordinateOperation:EPSG::1618" --- test/unit/test_io.cpp | 58 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) (limited to 'test/unit') diff --git a/test/unit/test_io.cpp b/test/unit/test_io.cpp index 30e0b427..df2481e6 100644 --- a/test/unit/test_io.cpp +++ b/test/unit/test_io.cpp @@ -8775,6 +8775,39 @@ TEST(io, createFromUserInput) { EXPECT_THROW( createFromUserInput("urn:ogc:def:unhandled:EPSG::4326", dbContext), ParsingException); + EXPECT_THROW(createFromUserInput("urn:ogc:def:crs:non_existing_auth::4326", + dbContext), + NoSuchAuthorityCodeException); + EXPECT_THROW(createFromUserInput( + "urn:ogc:def:crs,crs:EPSG::2393,unhandled_type:EPSG::5717", + dbContext), + ParsingException); + EXPECT_THROW(createFromUserInput( + "urn:ogc:def:crs,crs:EPSG::2393,crs:EPSG::unexisting_code", + dbContext), + NoSuchAuthorityCodeException); + EXPECT_THROW( + createFromUserInput( + "urn:ogc:def:crs,crs:EPSG::2393::extra_element,crs:EPSG::EPSG", + dbContext), + ParsingException); + EXPECT_THROW(createFromUserInput("urn:ogc:def:coordinateOperation," + "coordinateOperation:EPSG::3895," + "unhandled_type:EPSG::1618", + dbContext), + ParsingException); + EXPECT_THROW( + createFromUserInput("urn:ogc:def:coordinateOperation," + "coordinateOperation:EPSG::3895," + "coordinateOperation:EPSG::unexisting_code", + dbContext), + NoSuchAuthorityCodeException); + EXPECT_THROW( + createFromUserInput("urn:ogc:def:coordinateOperation," + "coordinateOperation:EPSG::3895::extra_element," + "coordinateOperation:EPSG::1618", + dbContext), + ParsingException); EXPECT_NO_THROW(createFromUserInput("+proj=longlat", nullptr)); EXPECT_NO_THROW(createFromUserInput("EPSG:4326", dbContext)); @@ -8789,6 +8822,31 @@ TEST(io, createFromUserInput) { createFromUserInput("urn:ogc:def:meridian:EPSG::8901", dbContext)); EXPECT_NO_THROW( createFromUserInput("urn:ogc:def:ellipsoid:EPSG::7030", dbContext)); + { + auto obj = createFromUserInput("EPSG:2393+5717", dbContext); + auto crs = nn_dynamic_pointer_cast(obj); + ASSERT_TRUE(crs != nullptr); + EXPECT_EQ(crs->nameStr(), + "KKJ / Finland Uniform Coordinate System + N60 height"); + } + { + auto obj = createFromUserInput( + "urn:ogc:def:crs,crs:EPSG::2393,crs:EPSG::5717", dbContext); + auto crs = nn_dynamic_pointer_cast(obj); + ASSERT_TRUE(crs != nullptr); + EXPECT_EQ(crs->nameStr(), + "KKJ / Finland Uniform Coordinate System + N60 height"); + } + { + auto obj = createFromUserInput("urn:ogc:def:coordinateOperation," + "coordinateOperation:EPSG::3895," + "coordinateOperation:EPSG::1618", + dbContext); + auto concat = nn_dynamic_pointer_cast(obj); + ASSERT_TRUE(concat != nullptr); + EXPECT_EQ(concat->nameStr(), + "MGI (Ferro) to MGI (1) + MGI to WGS 84 (3)"); + } EXPECT_NO_THROW(createFromUserInput( "GEOGCRS[\"WGS 84\",\n" " DATUM[\"World Geodetic System 1984\",\n" -- cgit v1.2.3 From cca27b1fae234a90df42ff5341121759846dc39b Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 30 Apr 2019 14:31:16 +0200 Subject: Propagate ballpark transformation flag to inverse coordinate operations --- test/unit/test_operation.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'test/unit') diff --git a/test/unit/test_operation.cpp b/test/unit/test_operation.cpp index b7b87d76..e1ced807 100644 --- a/test/unit/test_operation.cpp +++ b/test/unit/test_operation.cpp @@ -5396,6 +5396,21 @@ TEST(operation, projCRS_to_projCRS_context_incompatible_areas) { // --------------------------------------------------------------------------- +TEST(operation, projCRS_to_projCRS_context_incompatible_areas_ballpark) { + auto authFactory = + AuthorityFactory::create(DatabaseContext::create(), "EPSG"); + auto ctxt = CoordinateOperationContext::create(authFactory, nullptr, 0.0); + auto list = CoordinateOperationFactory::create()->createOperations( + authFactory->createCoordinateReferenceSystem("26711"), // UTM 11 NAD27 + authFactory->createCoordinateReferenceSystem( + "3034"), // ETRS89 / LCC Europe + ctxt); + ASSERT_GE(list.size(), 1U); + EXPECT_TRUE(list[0]->hasBallparkTransformation()); +} + +// --------------------------------------------------------------------------- + TEST(operation, projCRS_to_projCRS_north_pole_inverted_axis) { auto authFactory = -- cgit v1.2.3 From b4a9e65cec051ca3cb16b8cccfa012d70ce10570 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 30 Apr 2019 14:56:32 +0200 Subject: createOperations(): in SourceTargetCRSExtentUse::INTERSECTION mode, early return if the intersection of the areas is empty --- test/unit/test_operation.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'test/unit') diff --git a/test/unit/test_operation.cpp b/test/unit/test_operation.cpp index e1ced807..730cd270 100644 --- a/test/unit/test_operation.cpp +++ b/test/unit/test_operation.cpp @@ -5411,6 +5411,24 @@ TEST(operation, projCRS_to_projCRS_context_incompatible_areas_ballpark) { // --------------------------------------------------------------------------- +TEST( + operation, + projCRS_to_projCRS_context_incompatible_areas_crs_extent_use_intersection) { + auto authFactory = + AuthorityFactory::create(DatabaseContext::create(), "EPSG"); + auto ctxt = CoordinateOperationContext::create(authFactory, nullptr, 0.0); + ctxt->setSourceAndTargetCRSExtentUse( + CoordinateOperationContext::SourceTargetCRSExtentUse::INTERSECTION); + auto list = CoordinateOperationFactory::create()->createOperations( + authFactory->createCoordinateReferenceSystem("26711"), // UTM 11 NAD27 + authFactory->createCoordinateReferenceSystem( + "3034"), // ETRS89 / LCC Europe + ctxt); + ASSERT_GE(list.size(), 0U); +} + +// --------------------------------------------------------------------------- + TEST(operation, projCRS_to_projCRS_north_pole_inverted_axis) { auto authFactory = -- cgit v1.2.3 From 09cbfb85c834d99e5a00f5989dc144613e0cfbf2 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 30 Apr 2019 17:25:38 +0200 Subject: WKT importer: accepts PROJ-based COORDINATEOPERATION --- test/unit/test_operation.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'test/unit') diff --git a/test/unit/test_operation.cpp b/test/unit/test_operation.cpp index 730cd270..a38e9df2 100644 --- a/test/unit/test_operation.cpp +++ b/test/unit/test_operation.cpp @@ -6477,6 +6477,18 @@ TEST(operation, compoundCRS_to_compoundCRS_context) { "+step +proj=hgridshift +grids=conus +step " "+proj=unitconvert +xy_in=rad +xy_out=deg +step +proj=axisswap " "+order=2,1"); + { + // Test that we can round-trip this through WKT and still get the same + // PROJ string. + auto wkt = list[0]->exportToWKT( + WKTFormatter::create(WKTFormatter::Convention::WKT2_2018).get()); + auto obj = WKTParser().createFromWKT(wkt); + auto co = nn_dynamic_pointer_cast(obj); + ASSERT_TRUE(co != nullptr); + EXPECT_EQ( + list[0]->exportToPROJString(PROJStringFormatter::create().get()), + co->exportToPROJString(PROJStringFormatter::create().get())); + } bool foundApprox = false; for (size_t i = 0; i < list.size(); i++) { -- cgit v1.2.3 From 5e98fed78205605ccb01ab4310d3cba292de73b4 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 6 May 2019 12:43:04 +0200 Subject: createOperations(): fix case of ETRS89 3D to proj string with nadgrids and geoidgrids Fixes https://lists.osgeo.org/pipermail/proj/2019-May/008519.html --- test/unit/test_operation.cpp | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'test/unit') diff --git a/test/unit/test_operation.cpp b/test/unit/test_operation.cpp index a38e9df2..f3d9eefe 100644 --- a/test/unit/test_operation.cpp +++ b/test/unit/test_operation.cpp @@ -5903,6 +5903,35 @@ TEST(operation, boundCRS_with_basecrs_with_extent_to_geogCRS) { // --------------------------------------------------------------------------- +TEST(operation, ETRS89_3D_to_proj_string_with_geoidgrids_nadgrids) { + auto authFactory = + AuthorityFactory::create(DatabaseContext::create(), "EPSG"); + // ETRS89 3D + auto src = authFactory->createCoordinateReferenceSystem("4937"); + auto objDst = PROJStringParser().createFromPROJString( + "+proj=sterea +lat_0=52.15616055555555 +lon_0=5.38763888888889 " + "+k=0.9999079 +x_0=155000 +y_0=463000 +ellps=bessel " + "+nadgrids=rdtrans2008.gsb +geoidgrids=naptrans2008.gtx +units=m " + "+type=crs"); + auto dst = nn_dynamic_pointer_cast(objDst); + ASSERT_TRUE(dst != nullptr); + auto ctxt = CoordinateOperationContext::create(authFactory, nullptr, 0.0); + auto list = CoordinateOperationFactory::create()->createOperations( + src, NN_NO_CHECK(dst), ctxt); + ASSERT_EQ(list.size(), 1U); + EXPECT_EQ(list[0]->exportToPROJString(PROJStringFormatter::create().get()), + "+proj=pipeline +step +proj=unitconvert +xy_in=deg +xy_out=rad " + "+step +proj=axisswap +order=2,1 " + "+step +inv +proj=vgridshift +grids=naptrans2008.gtx " + "+multiplier=1 " + "+step +inv +proj=hgridshift +grids=rdtrans2008.gsb " + "+step +proj=sterea +lat_0=52.1561605555556 " + "+lon_0=5.38763888888889 +k=0.9999079 +x_0=155000 " + "+y_0=463000 +ellps=bessel"); +} + +// --------------------------------------------------------------------------- + static VerticalCRSNNPtr createVerticalCRS() { PropertyMap propertiesVDatum; propertiesVDatum.set(Identifier::CODESPACE_KEY, "EPSG") -- cgit v1.2.3 From 61cf8c5b29c82ab7e46b207bd125eaad49c03021 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 6 May 2019 19:45:27 +0200 Subject: createOperations(): for 'Amersfoort / RD New + NAP height' (EPSG:7415) to ETRS89 (EPSG:4937), make sure that the vgridshift is applied first (ie on Amersfoort datum) before the hgridshift --- test/unit/test_operation.cpp | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) (limited to 'test/unit') diff --git a/test/unit/test_operation.cpp b/test/unit/test_operation.cpp index f3d9eefe..5ac1609d 100644 --- a/test/unit/test_operation.cpp +++ b/test/unit/test_operation.cpp @@ -5970,8 +5970,8 @@ static BoundCRSNNPtr createBoundVerticalCRS() { auto vertCRS = createVerticalCRS(); auto transformation = Transformation::createGravityRelatedHeightToGeographic3D( - PropertyMap(), vertCRS, GeographicCRS::EPSG_4979, "egm08_25.gtx", - std::vector()); + PropertyMap(), vertCRS, GeographicCRS::EPSG_4979, nullptr, + "egm08_25.gtx", std::vector()); return BoundCRS::create(vertCRS, GeographicCRS::EPSG_4979, transformation); } @@ -6756,6 +6756,22 @@ TEST(operation, compoundCRS_from_WKT2_no_id_to_geogCRS_3D_context) { auto list = CoordinateOperationFactory::create()->createOperations(src, dst, ctxt); ASSERT_GE(list.size(), 1U); + + { + // Important here is vgridshift before hgridshift + auto op_proj = + list[0]->exportToPROJString(PROJStringFormatter::create().get()); + EXPECT_EQ( + op_proj, + "+proj=pipeline +step +inv +proj=sterea +lat_0=52.1561605555556 " + "+lon_0=5.38763888888889 +k=0.9999079 +x_0=155000 +y_0=463000 " + "+ellps=bessel " + "+step +proj=vgridshift +grids=naptrans2008.gtx +multiplier=1 " + "+step +proj=hgridshift +grids=rdtrans2008.gsb " + "+step +proj=unitconvert +xy_in=rad +z_in=m +xy_out=deg +z_out=m " + "+step +proj=axisswap +order=2,1"); + } + auto wkt2 = "COMPOUNDCRS[\"unknown\",\n" " PROJCRS[\"unknown\",\n" @@ -6788,8 +6804,12 @@ TEST(operation, compoundCRS_from_WKT2_no_id_to_geogCRS_3D_context) { for (size_t i = 0; i < list.size(); i++) { const auto &op = list[i]; const auto &op2 = list2[i]; - EXPECT_TRUE( - op->isEquivalentTo(op2.get(), IComparable::Criterion::EQUIVALENT)); + auto op_proj = + op->exportToPROJString(PROJStringFormatter::create().get()); + auto op2_proj = + op2->exportToPROJString(PROJStringFormatter::create().get()); + EXPECT_EQ(op_proj, op2_proj) << "op=" << op->nameStr() + << " op2=" << op2->nameStr(); } } -- cgit v1.2.3 From 4d722565d63d504aab5fb2e403d1dd5c3b649d1a Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 8 May 2019 12:00:08 +0200 Subject: proj_normalize_for_visualization(): fix when there are coordinate operation alternatives --- test/unit/test_c_api.cpp | 65 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) (limited to 'test/unit') diff --git a/test/unit/test_c_api.cpp b/test/unit/test_c_api.cpp index 12e98d7e..bea3eaa1 100644 --- a/test/unit/test_c_api.cpp +++ b/test/unit/test_c_api.cpp @@ -3247,4 +3247,69 @@ TEST_F(CApi, proj_normalize_for_visualization) { "+step +proj=utm +zone=31 +ellps=WGS84"); } +// --------------------------------------------------------------------------- + +TEST_F(CApi, proj_normalize_for_visualization_with_alternatives) { + + auto P = proj_create_crs_to_crs(m_ctxt, "EPSG:4326", "EPSG:3003", nullptr); + ObjectKeeper keeper_P(P); + ASSERT_NE(P, nullptr); + auto Pnormalized = proj_normalize_for_visualization(m_ctxt, P); + ObjectKeeper keeper_Pnormalized(Pnormalized); + ASSERT_NE(Pnormalized, nullptr); + + { + PJ_COORD c; + // Approximately Roma + c.lpz.lam = 12.5; + c.lpz.phi = 42; + c.lpz.z = 0; + c = proj_trans(Pnormalized, PJ_FWD, c); + EXPECT_NEAR(c.xy.x, 1789912.46264783037, 1e-8); + EXPECT_NEAR(c.xy.y, 4655716.25402576849, 1e-8); + auto projstr = proj_pj_info(Pnormalized).definition; + ASSERT_NE(projstr, nullptr); + EXPECT_EQ(std::string(projstr), + "proj=pipeline step proj=unitconvert xy_in=deg xy_out=rad " + "step proj=push v_3 step proj=cart ellps=WGS84 " + "step inv proj=helmert x=-104.1 y=-49.1 z=-9.9 rx=0.971 " + "ry=-2.917 rz=0.714 s=-11.68 convention=position_vector " + "step inv proj=cart ellps=intl step proj=pop v_3 " + "step proj=tmerc lat_0=0 lon_0=9 k=0.9996 x_0=1500000 " + "y_0=0 ellps=intl"); + } + + { + PJ_COORD c; + // Approximately Roma + c.xyz.x = 1789912.46264783037; + c.xyz.y = 4655716.25402576849; + c.xyz.z = 0; + c = proj_trans(Pnormalized, PJ_INV, c); + EXPECT_NEAR(c.lp.lam, 12.5, 1e-8); + EXPECT_NEAR(c.lp.phi, 42, 1e-8); + } +} + +// --------------------------------------------------------------------------- + +TEST_F(CApi, proj_normalize_for_visualization_with_alternatives_reverse) { + + auto P = proj_create_crs_to_crs(m_ctxt, "EPSG:3003", "EPSG:4326", nullptr); + ObjectKeeper keeper_P(P); + ASSERT_NE(P, nullptr); + auto Pnormalized = proj_normalize_for_visualization(m_ctxt, P); + ObjectKeeper keeper_Pnormalized(Pnormalized); + ASSERT_NE(Pnormalized, nullptr); + + PJ_COORD c; + // Approximately Roma + c.xyz.x = 1789912.46264783037; + c.xyz.y = 4655716.25402576849; + c.xyz.z = 0; + c = proj_trans(Pnormalized, PJ_FWD, c); + EXPECT_NEAR(c.lp.lam, 12.5, 1e-8); + EXPECT_NEAR(c.lp.phi, 42, 1e-8); +} + } // namespace -- cgit v1.2.3 From 004e26293e258a9144e6e1d33049eb1753b82b89 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sun, 12 May 2019 09:03:48 +0200 Subject: Fix identification of GeodeticCRS expressed by PROJ string for EPSG authority --- test/unit/test_crs.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'test/unit') diff --git a/test/unit/test_crs.cpp b/test/unit/test_crs.cpp index d7303df9..fbbd4f64 100644 --- a/test/unit/test_crs.cpp +++ b/test/unit/test_crs.cpp @@ -1498,6 +1498,19 @@ TEST(crs, geodeticcrs_identify_db) { ->identify(factory); ASSERT_EQ(res.size(), 0U); } + { + // Test identification from PROJ string + auto obj = PROJStringParser().createFromPROJString( + "+proj=longlat +datum=WGS84 +type=crs"); + auto crs = nn_dynamic_pointer_cast(obj); + ASSERT_TRUE(crs != nullptr); + auto res = crs->identify(factory); + ASSERT_EQ(res.size(), 1U); + ASSERT_TRUE(!res.front().first->identifiers().empty()); + EXPECT_EQ(*res.front().first->identifiers()[0]->codeSpace(), "EPSG"); + EXPECT_EQ(res.front().first->identifiers()[0]->code(), "4326"); + EXPECT_EQ(res.front().second, 70); + } } // --------------------------------------------------------------------------- -- cgit v1.2.3 From 97d6060e596d1b044f84e7d140b26200ef56f65e Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Mon, 13 May 2019 09:33:38 -0500 Subject: identify(): take into account the authority passed in (fixes #1465) When identifying an object that has already a code with authority A but the authority of interest passed was B, then it was not checking that A != B, and did not try to search in the objects of B. --- test/unit/test_c_api.cpp | 32 ++++++++++++++++++++++++++++++++ test/unit/test_crs.cpp | 32 +++++++++++++++++++++++++++----- 2 files changed, 59 insertions(+), 5 deletions(-) (limited to 'test/unit') diff --git a/test/unit/test_c_api.cpp b/test/unit/test_c_api.cpp index bea3eaa1..b9ea0bd5 100644 --- a/test/unit/test_c_api.cpp +++ b/test/unit/test_c_api.cpp @@ -1650,6 +1650,38 @@ TEST_F(CApi, proj_identify) { ObjListKeeper keeper_res(res); EXPECT_EQ(res, nullptr); } + { + auto obj2 = proj_create( + m_ctxt, "+proj=longlat +datum=WGS84 +no_defs +type=crs"); + ObjectKeeper keeper2(obj2); + ASSERT_NE(obj2, nullptr); + int *confidence = nullptr; + auto res = proj_identify(m_ctxt, obj2, nullptr, nullptr, &confidence); + ObjListKeeper keeper_res(res); + EXPECT_EQ(proj_list_get_count(res), 4); + proj_int_list_destroy(confidence); + } + { + auto obj2 = proj_create_from_database(m_ctxt, "IGNF", "ETRS89UTM28", + PJ_CATEGORY_CRS, false, nullptr); + ObjectKeeper keeper2(obj2); + ASSERT_NE(obj2, nullptr); + int *confidence = nullptr; + auto res = proj_identify(m_ctxt, obj2, "EPSG", nullptr, &confidence); + ObjListKeeper keeper_res(res); + EXPECT_EQ(proj_list_get_count(res), 1); + auto gotCRS = proj_list_get(m_ctxt, res, 0); + ASSERT_NE(gotCRS, nullptr); + ObjectKeeper keeper_gotCRS(gotCRS); + auto auth = proj_get_id_auth_name(gotCRS, 0); + ASSERT_TRUE(auth != nullptr); + EXPECT_EQ(auth, std::string("EPSG")); + auto code = proj_get_id_code(gotCRS, 0); + ASSERT_TRUE(code != nullptr); + EXPECT_EQ(code, std::string("25828")); + EXPECT_EQ(confidence[0], 70); + proj_int_list_destroy(confidence); + } } // --------------------------------------------------------------------------- diff --git a/test/unit/test_crs.cpp b/test/unit/test_crs.cpp index fbbd4f64..0f0304b1 100644 --- a/test/unit/test_crs.cpp +++ b/test/unit/test_crs.cpp @@ -1984,13 +1984,35 @@ TEST(crs, projectedCRS_identify_no_db) { TEST(crs, projectedCRS_identify_db) { auto dbContext = DatabaseContext::create(); auto factoryEPSG = AuthorityFactory::create(dbContext, "EPSG"); + auto factoryIGNF = AuthorityFactory::create(dbContext, "IGNF"); + auto factoryAnonymous = AuthorityFactory::create(dbContext, std::string()); { // Identify by existing code - auto res = - factoryEPSG->createProjectedCRS("2172")->identify(factoryEPSG); - ASSERT_EQ(res.size(), 1U); - EXPECT_EQ(res.front().first->getEPSGCode(), 2172); - EXPECT_EQ(res.front().second, 100); + auto crs = factoryEPSG->createProjectedCRS("2172"); + { + auto res = crs->identify(factoryEPSG); + ASSERT_EQ(res.size(), 1U); + EXPECT_EQ(res.front().first->getEPSGCode(), 2172); + EXPECT_EQ(res.front().second, 100); + } + { + auto res = crs->identify(factoryAnonymous); + ASSERT_EQ(res.size(), 1U); + } + { + auto res = crs->identify(factoryIGNF); + ASSERT_EQ(res.size(), 0U); + } + } + { + // Identify by existing code + auto crs = factoryIGNF->createProjectedCRS("ETRS89UTM28"); + { + auto res = crs->identify(factoryEPSG); + ASSERT_EQ(res.size(), 1U); + EXPECT_EQ(res.front().first->getEPSGCode(), 25828); + EXPECT_EQ(res.front().second, 70); + } } { // Non-existing code -- cgit v1.2.3