Skip to content

Commit a0dfcf2

Browse files
authored
Merge pull request OSGeo#1390 from rouault/createoperation_boundcrs_more_aggresive
createOperations(): improve BoundCRS<-->non-bound-CRS case
2 parents 8d7a01b + 5893c7d commit a0dfcf2

File tree

2 files changed

+62
-1
lines changed

2 files changed

+62
-1
lines changed

src/iso19111/coordinateoperation.cpp

+30-1
Original file line numberDiff line numberDiff line change
@@ -11729,7 +11729,6 @@ CoordinateOperationFactory::Private::createOperations(
1172911729
return applyInverse(createOperations(targetCRS, sourceCRS, context));
1173011730
}
1173111731

11732-
// boundCRS to a geogCRS that is the same as the hubCRS
1173311732
auto boundSrc = dynamic_cast<const crs::BoundCRS *>(sourceCRS.get());
1173411733
auto geogDst = dynamic_cast<const crs::GeographicCRS *>(targetCRS.get());
1173511734
if (boundSrc && geogDst) {
@@ -11738,6 +11737,7 @@ CoordinateOperationFactory::Private::createOperations(
1173811737
dynamic_cast<const crs::GeographicCRS *>(hubSrc.get());
1173911738
auto geogCRSOfBaseOfBoundSrc =
1174011739
boundSrc->baseCRS()->extractGeographicCRS();
11740+
// Is it: boundCRS to a geogCRS that is the same as the hubCRS ?
1174111741
if (hubSrcGeog && geogCRSOfBaseOfBoundSrc &&
1174211742
(hubSrcGeog->_isEquivalentTo(
1174311743
geogDst, util::IComparable::Criterion::EQUIVALENT) ||
@@ -11855,6 +11855,35 @@ CoordinateOperationFactory::Private::createOperations(
1185511855
return res;
1185611856
}
1185711857

11858+
if (hubSrcGeog && geogCRSOfBaseOfBoundSrc) {
11859+
// This one should go to the above 'Is it: boundCRS to a geogCRS
11860+
// that is the same as the hubCRS ?' case
11861+
auto opsFirst = createOperations(sourceCRS, hubSrc, context);
11862+
auto opsLast = createOperations(hubSrc, targetCRS, context);
11863+
if (!opsFirst.empty() && !opsLast.empty()) {
11864+
for (const auto &opFirst : opsFirst) {
11865+
for (const auto &opLast : opsLast) {
11866+
// Exclude artificial transformations from the hub
11867+
// to the target CRS
11868+
if (!opLast->hasBallparkTransformation()) {
11869+
try {
11870+
res.emplace_back(
11871+
ConcatenatedOperation::
11872+
createComputeMetadata(
11873+
{opFirst, opLast},
11874+
!allowEmptyIntersection));
11875+
} catch (
11876+
const InvalidOperationEmptyIntersection &) {
11877+
}
11878+
}
11879+
}
11880+
}
11881+
if (!res.empty()) {
11882+
return res;
11883+
}
11884+
}
11885+
}
11886+
1185811887
return createOperations(boundSrc->baseCRS(), targetCRS, context);
1185911888
}
1186011889

test/unit/test_operation.cpp

+32
Original file line numberDiff line numberDiff line change
@@ -5485,6 +5485,38 @@ TEST(operation, boundCRS_of_geogCRS_to_projCRS) {
54855485

54865486
// ---------------------------------------------------------------------------
54875487

5488+
TEST(operation, boundCRS_of_geogCRS_to_unrelated_geogCRS_context) {
5489+
auto src = BoundCRS::createFromTOWGS84(
5490+
GeographicCRS::EPSG_4807, std::vector<double>{1, 2, 3, 4, 5, 6, 7});
5491+
auto authFactory =
5492+
AuthorityFactory::create(DatabaseContext::create(), "EPSG");
5493+
// ETRS89
5494+
auto dst = authFactory->createCoordinateReferenceSystem("4258");
5495+
auto ctxt = CoordinateOperationContext::create(authFactory, nullptr, 0.0);
5496+
auto list =
5497+
CoordinateOperationFactory::create()->createOperations(src, dst, ctxt);
5498+
ASSERT_EQ(list.size(), 1U);
5499+
// Check with it is a concatenated operation, since it doesn't particularly
5500+
// show up in the PROJ string
5501+
EXPECT_TRUE(dynamic_cast<ConcatenatedOperation *>(list[0].get()) !=
5502+
nullptr);
5503+
EXPECT_EQ(list[0]->nameStr(), "Transformation from NTF (Paris) to WGS84 + "
5504+
"Inverse of ETRS89 to WGS 84 (1)");
5505+
EXPECT_EQ(list[0]->exportToPROJString(PROJStringFormatter::create().get()),
5506+
"+proj=pipeline "
5507+
"+step +proj=axisswap +order=2,1 "
5508+
"+step +proj=unitconvert +xy_in=grad +xy_out=rad "
5509+
"+step +inv +proj=longlat +ellps=clrk80ign +pm=paris "
5510+
"+step +proj=push +v_3 +step +proj=cart +ellps=clrk80ign "
5511+
"+step +proj=helmert +x=1 +y=2 +z=3 +rx=4 +ry=5 +rz=6 +s=7 "
5512+
"+convention=position_vector "
5513+
"+step +inv +proj=cart +ellps=GRS80 +step +proj=pop +v_3 "
5514+
"+step +proj=unitconvert +xy_in=rad +xy_out=deg "
5515+
"+step +proj=axisswap +order=2,1");
5516+
}
5517+
5518+
// ---------------------------------------------------------------------------
5519+
54885520
TEST(operation, geogCRS_to_boundCRS_of_geogCRS) {
54895521
auto boundCRS = BoundCRS::createFromTOWGS84(
54905522
GeographicCRS::EPSG_4807, std::vector<double>{1, 2, 3, 4, 5, 6, 7});

0 commit comments

Comments
 (0)