Skip to content

Commit df810ea

Browse files
authored
Merge pull request #4773 from rouault/etrs89_again
createOperations(): tune geod_crs_of_datum_ensemble <--> geod_crs_of_another_datum
2 parents 4fcabe3 + 00d0f25 commit df810ea

12 files changed

Lines changed: 518 additions & 535 deletions

data/sql/alias_name.sql

Lines changed: 0 additions & 269 deletions
Large diffs are not rendered by default.

data/sql/final_consistency_checks.sql

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,8 @@ FOR EACH ROW BEGIN
6666
AND g1.source_crs_code = g2.source_crs_code
6767
AND g1.target_crs_auth_name = g2.target_crs_auth_name
6868
AND g1.target_crs_code = g2.target_crs_code
69-
WHERE g1.auth_name = 'PROJ'
70-
AND g1.code NOT LIKE '%_RESTRICTED_TO_VERTCRS%'
71-
AND g1.code != 'ED50_TO_ETRS89_CATALONIA'
72-
AND g2.auth_name = 'EPSG'
73-
AND g2.deprecated = 0 AND
74-
((g1.interpolation_crs_auth_name IS NULL AND g2.interpolation_crs_auth_name IS NULL) OR
69+
WHERE g1.auth_name = 'PROJ' AND g1.code NOT LIKE '%_RESTRICTED_TO_VERTCRS%' AND g2.auth_name = 'EPSG' AND g2.deprecated = 0 AND (
70+
(g1.interpolation_crs_auth_name IS NULL AND g2.interpolation_crs_auth_name IS NULL) OR
7571
(g1.interpolation_crs_auth_name IS NOT NULL AND g2.interpolation_crs_auth_name IS NOT NULL AND
7672
g1.interpolation_crs_auth_name = g2.interpolation_crs_auth_name AND
7773
g1.interpolation_crs_code = g2.interpolation_crs_code)))

data/sql/grid_transformation_custom.sql

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,6 @@
66
INSERT INTO "grid_transformation" VALUES('PROJ','BD72_TO_BEREF2002','BD72 to ETRS89-BEL [BEREF2002] (3)','Copy of BD72 to ETRS89-BEL [BEREF2011] (3) EPSG:8369','EPSG','9615','NTv2','EPSG','4313','EPSG','11063',0.01,'EPSG','8656','Latitude and longitude difference file','bd72lb72_etrs89lb08.gsb',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'IGN-Bel 0.01m',0);
77
INSERT INTO "usage" VALUES('PROJ','BD72_TO_BEREF2002_USAGE','grid_transformation','PROJ','BD72_TO_BEREF2002','EPSG','1347','EPSG','1150');
88

9-
-- Catalonia
10-
11-
-- FIXME: remove this record when EPSG has fixed that issue
12-
INSERT INTO "grid_transformation" VALUES('PROJ','ED50_TO_ETRS89_CATALONIA','ED50 to ETRS89 (14)','Copy of ED50 to ETRS89-ESP [REGENTE] (14) EPSG:5661','EPSG','9615','NTv2','EPSG','4230','EPSG','4258',0.05,'EPSG','8656','Latitude and longitude difference file','100800401.gsb',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,'ICC-Esp Cat',0);
13-
INSERT INTO "usage" VALUES('PROJ','ED50_TO_ETRS89_CATALONIA_USAGE','grid_transformation','PROJ','ED50_TO_ETRS89_CATALONIA','EPSG','3732','EPSG','1079');
14-
159
-- Denmark
1610

1711
INSERT INTO "grid_transformation" VALUES(

data/sql/proj.db.sql.expected.md5

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
398415c72838764acfc012b2182c5db9
1+
49ee5cee7798112c25b15bc17eafe6f2

include/proj/internal/io_internal.hpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,17 @@ NS_PROJ_START
4545

4646
namespace io {
4747

48+
// CRS subtypes
49+
#define CRS_SUBTYPE_GEOG_2D "geographic 2D"
50+
#define CRS_SUBTYPE_GEOG_3D "geographic 3D"
51+
#define CRS_SUBTYPE_GEOCENTRIC "geocentric"
52+
#define CRS_SUBTYPE_OTHER "other"
53+
#define CRS_SUBTYPE_PROJECTED "projected"
54+
#define CRS_SUBTYPE_DERIVED_PROJECTED "derived projected"
55+
#define CRS_SUBTYPE_ENGINEERING "engineering"
56+
#define CRS_SUBTYPE_VERTICAL "vertical"
57+
#define CRS_SUBTYPE_COMPOUND "compound"
58+
4859
// ---------------------------------------------------------------------------
4960

5061
class WKTConstants {

include/proj/io.hpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1339,14 +1339,6 @@ class PROJ_GCC_DLL AuthorityFactory {
13391339
const metadata::ExtentPtr &intersectingExtent2,
13401340
bool skipIntermediateExtentIntersection = false) const;
13411341

1342-
PROJ_INTERNAL std::vector<operation::CoordinateOperationNNPtr>
1343-
getOperationsFromAlias(const std::string &crs1Name,
1344-
const std::string &crs2Name,
1345-
bool usePROJAlternativeGridNames,
1346-
bool discardIfMissingGrid,
1347-
bool considerKnownGridsAsAvailable,
1348-
bool discardSuperseded) const;
1349-
13501342
typedef std::pair<common::IdentifiedObjectNNPtr, std::string>
13511343
PairObjectName;
13521344
PROJ_INTERNAL std::list<PairObjectName>

scripts/build_db.py

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1169,26 +1169,6 @@ def fill_alias(proj_db_cursor):
11691169
if not match:
11701170
print('Cannot find CRS %s in geodetic_crs, projected_crs, vertical_crs or compound_crs' % (code))
11711171

1172-
proj_db_cursor.execute("SELECT DISTINCT object_code, alias, coord_op_name FROM epsg.epsg_alias, epsg.epsg_coordoperation ON coord_op_code = object_code WHERE object_table_name = 'epsg_coordoperation' AND epsg_coordoperation.deprecated = 0")
1173-
for row in proj_db_cursor.fetchall():
1174-
code, alt_name, new_name = row
1175-
# We could potentially ingest all records, but the only use of them for
1176-
# now is to workaround effects of the creation of national ETRS89-XXX
1177-
# datums. See https://github.com/OSGeo/PROJ/pull/4736 for more details
1178-
if "ETRS89" not in alt_name:
1179-
# print('Ignoring alias %s for coordinate operation %s %s' % (alt_name, code, new_name))
1180-
continue
1181-
1182-
proj_db_cursor.execute('SELECT table_name FROM coordinate_operation_view WHERE code = ?', (code,))
1183-
row = proj_db_cursor.fetchone()
1184-
if row is not None:
1185-
table_name = row[0]
1186-
if table_name != "conversion":
1187-
proj_db_cursor.execute("INSERT INTO alias_name VALUES (?,'EPSG',?,?,'EPSG')", (table_name, code, alt_name))
1188-
continue
1189-
1190-
print('Cannot find coordinate operation %s for alias %s' % (code, alt_name))
1191-
11921172

11931173
def find_table(proj_db_cursor, code):
11941174
for table_name in ('helmert_transformation', 'grid_transformation', 'concatenated_operation', 'geodetic_crs', 'projected_crs', 'vertical_crs', 'compound_crs'):

src/iso19111/factory.cpp

Lines changed: 33 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -106,17 +106,6 @@ namespace io {
106106

107107
//! @cond Doxygen_Suppress
108108

109-
// CRS subtypes
110-
#define GEOG_2D "geographic 2D"
111-
#define GEOG_3D "geographic 3D"
112-
#define GEOCENTRIC "geocentric"
113-
#define OTHER "other"
114-
#define PROJECTED "projected"
115-
#define DERIVED_PROJECTED "derived projected"
116-
#define ENGINEERING "engineering"
117-
#define VERTICAL "vertical"
118-
#define COMPOUND "compound"
119-
120109
#define GEOG_2D_SINGLE_QUOTED "'geographic 2D'"
121110
#define GEOG_3D_SINGLE_QUOTED "'geographic 3D'"
122111
#define GEOCENTRIC_SINGLE_QUOTED "'geocentric'"
@@ -2520,12 +2509,12 @@ std::vector<std::string> DatabaseContext::Private::getInsertStatementsFor(
25202509
identifyOrInsert(self, coordinateSystem, "GEODETIC_CRS", authName, code,
25212510
csAuthName, csCode, sqlStatements);
25222511

2523-
const char *type = GEOG_2D;
2512+
const char *type = CRS_SUBTYPE_GEOG_2D;
25242513
if (coordinateSystem->axisList().size() == 3) {
25252514
if (dynamic_cast<const crs::GeographicCRS *>(crs.get())) {
2526-
type = GEOG_3D;
2515+
type = CRS_SUBTYPE_GEOG_3D;
25272516
} else {
2528-
type = GEOCENTRIC;
2517+
type = CRS_SUBTYPE_GEOCENTRIC;
25292518
}
25302519
}
25312520

@@ -5538,23 +5527,24 @@ AuthorityFactory::createGeodeticCRS(const std::string &code,
55385527

55395528
auto ellipsoidalCS =
55405529
util::nn_dynamic_pointer_cast<cs::EllipsoidalCS>(cs);
5541-
if ((type == GEOG_2D || type == GEOG_3D) && ellipsoidalCS) {
5530+
if ((type == CRS_SUBTYPE_GEOG_2D || type == CRS_SUBTYPE_GEOG_3D) &&
5531+
ellipsoidalCS) {
55425532
auto crsRet = crs::GeographicCRS::create(
55435533
props, datum, datumEnsemble, NN_NO_CHECK(ellipsoidalCS));
55445534
d->context()->d->cache(cacheKey, crsRet);
55455535
return crsRet;
55465536
}
55475537

55485538
auto geocentricCS = util::nn_dynamic_pointer_cast<cs::CartesianCS>(cs);
5549-
if (type == GEOCENTRIC && geocentricCS) {
5539+
if (type == CRS_SUBTYPE_GEOCENTRIC && geocentricCS) {
55505540
auto crsRet = crs::GeodeticCRS::create(props, datum, datumEnsemble,
55515541
NN_NO_CHECK(geocentricCS));
55525542
d->context()->d->cache(cacheKey, crsRet);
55535543
return crsRet;
55545544
}
55555545

55565546
auto sphericalCS = util::nn_dynamic_pointer_cast<cs::SphericalCS>(cs);
5557-
if (type == OTHER && sphericalCS) {
5547+
if (type == CRS_SUBTYPE_OTHER && sphericalCS) {
55585548
auto crsRet = crs::GeodeticCRS::create(props, datum, datumEnsemble,
55595549
NN_NO_CHECK(sphericalCS));
55605550
d->context()->d->cache(cacheKey, crsRet);
@@ -6214,23 +6204,23 @@ AuthorityFactory::createCoordinateReferenceSystem(const std::string &code,
62146204
code);
62156205
}
62166206
const auto &type = res.front()[0];
6217-
if (type == GEOG_2D || type == GEOG_3D || type == GEOCENTRIC ||
6218-
type == OTHER) {
6207+
if (type == CRS_SUBTYPE_GEOG_2D || type == CRS_SUBTYPE_GEOG_3D ||
6208+
type == CRS_SUBTYPE_GEOCENTRIC || type == CRS_SUBTYPE_OTHER) {
62196209
return createGeodeticCRS(code);
62206210
}
6221-
if (type == VERTICAL) {
6211+
if (type == CRS_SUBTYPE_VERTICAL) {
62226212
return createVerticalCRS(code);
62236213
}
6224-
if (type == PROJECTED) {
6214+
if (type == CRS_SUBTYPE_PROJECTED) {
62256215
return createProjectedCRS(code);
62266216
}
6227-
if (type == DERIVED_PROJECTED) {
6217+
if (type == CRS_SUBTYPE_DERIVED_PROJECTED) {
62286218
return createDerivedProjectedCRS(code);
62296219
}
6230-
if (type == ENGINEERING) {
6220+
if (type == CRS_SUBTYPE_ENGINEERING) {
62316221
return createEngineeringCRS(code);
62326222
}
6233-
if (allowCompound && type == COMPOUND) {
6223+
if (allowCompound && type == CRS_SUBTYPE_COMPOUND) {
62346224
return createCompoundCRS(code);
62356225
}
62366226
throw FactoryException("unhandled CRS type: " + type);
@@ -9060,23 +9050,23 @@ std::list<AuthorityFactory::CRSInfo> AuthorityFactory::getCRSInfoList() const {
90609050
info.code = row[1];
90619051
info.name = row[2];
90629052
const auto &type = row[3];
9063-
if (type == GEOG_2D) {
9053+
if (type == CRS_SUBTYPE_GEOG_2D) {
90649054
info.type = AuthorityFactory::ObjectType::GEOGRAPHIC_2D_CRS;
9065-
} else if (type == GEOG_3D) {
9055+
} else if (type == CRS_SUBTYPE_GEOG_3D) {
90669056
info.type = AuthorityFactory::ObjectType::GEOGRAPHIC_3D_CRS;
9067-
} else if (type == GEOCENTRIC) {
9057+
} else if (type == CRS_SUBTYPE_GEOCENTRIC) {
90689058
info.type = AuthorityFactory::ObjectType::GEOCENTRIC_CRS;
9069-
} else if (type == OTHER) {
9059+
} else if (type == CRS_SUBTYPE_OTHER) {
90709060
info.type = AuthorityFactory::ObjectType::GEODETIC_CRS;
9071-
} else if (type == PROJECTED) {
9061+
} else if (type == CRS_SUBTYPE_PROJECTED) {
90729062
info.type = AuthorityFactory::ObjectType::PROJECTED_CRS;
9073-
} else if (type == VERTICAL) {
9063+
} else if (type == CRS_SUBTYPE_VERTICAL) {
90749064
info.type = AuthorityFactory::ObjectType::VERTICAL_CRS;
9075-
} else if (type == COMPOUND) {
9065+
} else if (type == CRS_SUBTYPE_COMPOUND) {
90769066
info.type = AuthorityFactory::ObjectType::COMPOUND_CRS;
9077-
} else if (type == ENGINEERING) {
9067+
} else if (type == CRS_SUBTYPE_ENGINEERING) {
90789068
info.type = AuthorityFactory::ObjectType::ENGINEERING_CRS;
9079-
} else if (type == DERIVED_PROJECTED) {
9069+
} else if (type == CRS_SUBTYPE_DERIVED_PROJECTED) {
90809070
info.type = AuthorityFactory::ObjectType::DERIVED_PROJECTED_CRS;
90819071
}
90829072
info.deprecated = row[4] == "1";
@@ -9450,17 +9440,22 @@ AuthorityFactory::createObjectsFromNameEx(
94509440
res.emplace_back(TableType("geodetic_crs", std::string()));
94519441
break;
94529442
case ObjectType::GEOCENTRIC_CRS:
9453-
res.emplace_back(TableType("geodetic_crs", GEOCENTRIC));
9443+
res.emplace_back(
9444+
TableType("geodetic_crs", CRS_SUBTYPE_GEOCENTRIC));
94549445
break;
94559446
case ObjectType::GEOGRAPHIC_CRS:
9456-
res.emplace_back(TableType("geodetic_crs", GEOG_2D));
9457-
res.emplace_back(TableType("geodetic_crs", GEOG_3D));
9447+
res.emplace_back(
9448+
TableType("geodetic_crs", CRS_SUBTYPE_GEOG_2D));
9449+
res.emplace_back(
9450+
TableType("geodetic_crs", CRS_SUBTYPE_GEOG_3D));
94589451
break;
94599452
case ObjectType::GEOGRAPHIC_2D_CRS:
9460-
res.emplace_back(TableType("geodetic_crs", GEOG_2D));
9453+
res.emplace_back(
9454+
TableType("geodetic_crs", CRS_SUBTYPE_GEOG_2D));
94619455
break;
94629456
case ObjectType::GEOGRAPHIC_3D_CRS:
9463-
res.emplace_back(TableType("geodetic_crs", GEOG_3D));
9457+
res.emplace_back(
9458+
TableType("geodetic_crs", CRS_SUBTYPE_GEOG_3D));
94649459
break;
94659460
case ObjectType::PROJECTED_CRS:
94669461
res.emplace_back(TableType("projected_crs", std::string()));
@@ -10596,62 +10591,6 @@ AuthorityFactory::getPointMotionOperationsFor(
1059610591
return res;
1059710592
}
1059810593

10599-
// ---------------------------------------------------------------------------
10600-
10601-
std::vector<operation::CoordinateOperationNNPtr>
10602-
AuthorityFactory::getOperationsFromAlias(const std::string &crs1Name,
10603-
const std::string &crs2Name,
10604-
bool usePROJAlternativeGridNames,
10605-
bool discardIfMissingGrid,
10606-
bool considerKnownGridsAsAvailable,
10607-
bool discardSuperseded) const {
10608-
std::string sql("SELECT alias.auth_name, alias.code FROM alias_name alias "
10609-
"JOIN coordinate_operation_view cov "
10610-
"ON alias.table_name = cov.table_name "
10611-
"AND alias.auth_name = cov.auth_name "
10612-
"AND alias.code = cov.code "
10613-
"WHERE alias.table_name IN ('grid_transformation', "
10614-
"'helmert_transformation', 'other_transformation', "
10615-
"'concatenated_operation') "
10616-
"AND (alt_name LIKE ? OR alt_name LIKE ?) "
10617-
"AND NOT (alt_name LIKE ? OR alt_name LIKE ? OR alt_name "
10618-
"LIKE ? OR alt_name LIKE ?) "
10619-
"AND cov.deprecated = 0");
10620-
if (discardSuperseded) {
10621-
sql += " AND NOT EXISTS (SELECT 1 FROM supersession ss WHERE "
10622-
"ss.superseded_table_name = cov.table_name AND "
10623-
"ss.superseded_auth_name = cov.auth_name AND "
10624-
"ss.superseded_code = cov.code AND "
10625-
"ss.superseded_table_name = ss.replacement_table_name AND "
10626-
"ss.same_source_target_crs = 1)";
10627-
}
10628-
ListOfParams params{
10629-
std::string(crs1Name).append(" to ").append(crs2Name).append("%"),
10630-
std::string(crs2Name).append(" to ").append(crs1Name).append("%"),
10631-
// If looking for "MGI to ETRS89", don't match "ETRS89 to ETRS89-XXX"
10632-
std::string(crs1Name).append(" to ").append(crs1Name).append("-%"),
10633-
std::string(crs2Name).append(" to ").append(crs2Name).append("-%"),
10634-
// If looking for "MGI to ETRS89", don't match "MGI to ETRS89-XXX" (not
10635-
// an actual example, but just in case)
10636-
std::string(crs1Name).append(" to ").append(crs2Name).append("-%"),
10637-
std::string(crs2Name).append(" to ").append(crs1Name).append("-%"),
10638-
};
10639-
10640-
std::vector<operation::CoordinateOperationNNPtr> res;
10641-
auto sqlRes = d->run(sql, params);
10642-
for (const auto &row : sqlRes) {
10643-
const auto &auth_name = row[0];
10644-
const auto &code = row[1];
10645-
auto op = d->createFactory(auth_name)->createCoordinateOperation(
10646-
code, usePROJAlternativeGridNames);
10647-
if (!discardIfMissingGrid ||
10648-
!d->rejectOpDueToMissingGrid(op, considerKnownGridsAsAvailable)) {
10649-
res.emplace_back(op);
10650-
}
10651-
}
10652-
return res;
10653-
}
10654-
1065510594
//! @endcond
1065610595

1065710596
// ---------------------------------------------------------------------------

0 commit comments

Comments
 (0)