Skip to content

Commit

Permalink
Take into account new EPSG methods 'Cartesian Grid Offsets by TIN Int…
Browse files Browse the repository at this point in the history
…erpolation (JSON)' and 'Vertical Offset by TIN Interpolation (JSON)'

and remove custom transformations for Finland TIN base transformations
that were previously under the PROJ authority
  • Loading branch information
rouault committed Dec 16, 2024
1 parent 387f442 commit 944979c
Show file tree
Hide file tree
Showing 11 changed files with 170 additions and 58 deletions.
2 changes: 1 addition & 1 deletion data/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ set(ALL_SQL_IN "${CMAKE_CURRENT_BINARY_DIR}/all.sql.in")
set(PROJ_DB "${CMAKE_CURRENT_BINARY_DIR}/proj.db")
include(sql_filelist.cmake)

set(PROJ_DB_SQL_EXPECTED_MD5 "179a5d10e801cb758db7aaa925b97a8f")
set(PROJ_DB_SQL_EXPECTED_MD5 "c2184d9fca631e88f21e4c0d8899d391")

add_custom_command(
OUTPUT ${PROJ_DB}
Expand Down
6 changes: 6 additions & 0 deletions data/sql/consistency_checks_triggers.sql
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,12 @@ FOR EACH ROW BEGIN
SELECT RAISE(ABORT, 'insert on grid_transformation violates constraint: target_crs(auth_name, code) not found')
WHERE NOT EXISTS (SELECT 1 FROM crs_view WHERE crs_view.auth_name = NEW.target_crs_auth_name AND crs_view.code = NEW.target_crs_code);

SELECT RAISE(ABORT, 'insert on grid_transformation violates constraint: interpolation_crs(auth_name, code) not found')
WHERE NEW.interpolation_crs_code IS NOT NULL AND NOT EXISTS (SELECT 1 FROM crs_view WHERE crs_view.auth_name = NEW.interpolation_crs_auth_name AND crs_view.code = NEW.interpolation_crs_code);

SELECT RAISE(ABORT, 'insert on grid_transformation violates constraint: interpolation_crs must be a GeodeticCRS on non-TIN shift based files')
WHERE NEW.method_name NOT LIKE '%JSON%' AND NEW.interpolation_crs_code IS NOT NULL AND NOT EXISTS (SELECT 1 FROM geodetic_crs WHERE geodetic_crs.auth_name = NEW.interpolation_crs_auth_name AND geodetic_crs.code = NEW.interpolation_crs_code);

SELECT RAISE(ABORT, 'insert on grid_transformation violates constraint: source_crs must not be deprecated when grid_transformation is not deprecated')
WHERE EXISTS(SELECT 1 FROM crs_view crs WHERE crs.auth_name = NEW.source_crs_auth_name AND crs.code = NEW.source_crs_code AND crs.deprecated != 0) AND NEW.deprecated = 0 AND NOT (NEW.auth_name = 'ESRI');
SELECT RAISE(ABORT, 'insert on grid_transformation violates constraint: target_crs must not be deprecated when grid_transformation is not deprecated')
Expand Down
6 changes: 6 additions & 0 deletions data/sql/grid_transformation.sql
Original file line number Diff line number Diff line change
Expand Up @@ -1762,6 +1762,12 @@ INSERT INTO "grid_transformation" VALUES('EPSG','10697','EUREF-FIN to N2000 heig
INSERT INTO "usage" VALUES('EPSG','22014','grid_transformation','EPSG','10697','EPSG','3333','EPSG','1133');
INSERT INTO "grid_transformation" VALUES('EPSG','10698','EUREF-FIN to EUREF-FIN + N2000 height (2)','Replaces EUREF-FIN to EUREF-FIN + N2000 height (1) (code 10696). Reversible alternative to EUREF-FIN to N2000 height (2) (code 10697). File also available in 3 ASCII formats.','EPSG','1124','Geog3D to Geog2D+GravityRelatedHeight (gtg)','EPSG','10689','EPSG','10692',0.014,'EPSG','8666','Geoid (height correction) model file','fi_nls_fin2023n2000.tif',NULL,NULL,NULL,NULL,'EPSG','10690','NLS-Fin 2023',0);
INSERT INTO "usage" VALUES('EPSG','22015','grid_transformation','EPSG','10698','EPSG','3333','EPSG','1270');
INSERT INTO "grid_transformation" VALUES('EPSG','10703','KKJ / Finland Uniform Coordinate System to EUREF-FIN / TM35FIN(E,N) (1)','This YKJ to ETRS-TM35FIN TINshift transformation is the recommended method for KKJ to EUREF-FIN transformations, to be used in preference to transformation KKJ to ETRS89 (2) (code 10098).','EPSG','1138','Cartesian Grid Offsets by TIN Interpolation (JSON)','EPSG','2393','EPSG','3067',0.03,'EPSG','1064','TIN offset file','fi_nls_ykj_etrs35fin.json',NULL,NULL,NULL,NULL,NULL,NULL,'NLS-FIN TINshift',0);
INSERT INTO "usage" VALUES('EPSG','22055','grid_transformation','EPSG','10703','EPSG','3333','EPSG','1273');
INSERT INTO "grid_transformation" VALUES('EPSG','10704','N43 height to N60 height (1)','Accuracy has not been determined.','EPSG','1137','Vertical Offset by TIN Interpolation (JSON)','EPSG','8675','EPSG','5717',999.0,'EPSG','1064','TIN offset file','fi_nls_n43_n60.json',NULL,NULL,NULL,NULL,'EPSG','2393','NLS-Fin TINshift',0);
INSERT INTO "usage" VALUES('EPSG','22018','grid_transformation','EPSG','10704','EPSG','4522','EPSG','1059');
INSERT INTO "grid_transformation" VALUES('EPSG','10705','N60 height to N2000 height (1)','Recommended method for N60<>N2000 trasformations, as more accurate than concatenating geoid models.','EPSG','1137','Vertical Offset by TIN Interpolation (JSON)','EPSG','5717','EPSG','3900',0.005,'EPSG','1064','TIN offset file','fi_nls_n60_n2000.json',NULL,NULL,NULL,NULL,'EPSG','2393','NLS-Fin TINshift',0);
INSERT INTO "usage" VALUES('EPSG','22201','grid_transformation','EPSG','10705','EPSG','3333','EPSG','1059');
INSERT INTO "grid_transformation" VALUES('EPSG','15486','CH1903 to CH1903+ (1)','For improved accuracy (0.01m) use CHENyx06 interpolation programme FINELTRA. File CHENyx06 replaced by CHENyx06a; there is a small area at the border of the data where some more real data has been introduced. swisstopo consider the change insignificant.','EPSG','9615','NTv2','EPSG','4149','EPSG','4150',0.2,'EPSG','8656','Latitude and longitude difference file','CHENyx06a.gsb',NULL,NULL,NULL,NULL,NULL,NULL,'BfL-Che',0);
INSERT INTO "usage" VALUES('EPSG','11497','grid_transformation','EPSG','15486','EPSG','1286','EPSG','1085');
INSERT INTO "grid_transformation" VALUES('EPSG','15488','RRAF 1991 to IGN 1988 MG height (1)','May be used for transformations from WGS 84 to IGN 1988 MG. Accuracy at each 0.025 deg x 0.025 degree grid node is given within the geoid model file.','EPSG','9664','Geographic3D to GravityRelatedHeight (IGN1997)','EPSG','4973','EPSG','5617',0.2,'EPSG','8666','Geoid (height correction) model file','ggg00_mg.txt',NULL,NULL,NULL,NULL,NULL,NULL,'IGN Glp MG',1);
Expand Down
33 changes: 4 additions & 29 deletions data/sql/other_transformation_custom.sql
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,9 @@ INSERT INTO "usage" VALUES('PROJ','NGO48_TO_ETRS89NO_USAGE','other_transformatio

-- Finland triangulated files

INSERT INTO other_transformation VALUES(
'PROJ','YKJ_TO_ETRS35FIN','KKJ / Finland Uniform Coordinate System to ETRS35FIN',
'Transformation based on a triangulated irregular network',
'PROJ','PROJString','+proj=pipeline +step +proj=axisswap +order=2,1 +step +proj=tinshift +file=fi_nls_ykj_etrs35fin.json',
'EPSG','2393','EPSG','3067',0.1,
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,NULL,NULL,NULL,NULL,NULL,NULL,0);
INSERT INTO "usage" VALUES('PROJ','YKJ_TO_ETRS35FIN_USAGE','other_transformation','PROJ','YKJ_TO_ETRS35FIN','EPSG','3333','EPSG','1024');

INSERT INTO "concatenated_operation" VALUES('PROJ','KKJ_TO_ETRS89','KKJ to ETRS89 (using PROJ:YKJ_TO_ETRS35FIN)','Transformation based on a triangulated irregular network','EPSG','4123','EPSG','4258',NULL,NULL,0);
INSERT INTO "concatenated_operation" VALUES('PROJ','KKJ_TO_ETRS89','KKJ to ETRS89 (using EPSG:10703)','Transformation based on a triangulated irregular network','EPSG','4123','EPSG','4258',NULL,NULL,0);
INSERT INTO "concatenated_operation_step" VALUES('PROJ','KKJ_TO_ETRS89',1,'EPSG','18193');
INSERT INTO "concatenated_operation_step" VALUES('PROJ','KKJ_TO_ETRS89',2,'PROJ','YKJ_TO_ETRS35FIN');
INSERT INTO "concatenated_operation_step" VALUES('PROJ','KKJ_TO_ETRS89',2,'EPSG','10703');
INSERT INTO "concatenated_operation_step" VALUES('PROJ','KKJ_TO_ETRS89',3,'EPSG','16065');
INSERT INTO "usage" VALUES(
'PROJ',
Expand All @@ -40,9 +32,9 @@ INSERT INTO "usage" VALUES(
'EPSG','1024' -- unknown
);

INSERT INTO "concatenated_operation" VALUES('PROJ','KKJ_TO_EUREF_FIN','KKJ to EUREF-FIN (using PROJ:YKJ_TO_ETRS35FIN)','Transformation based on a triangulated irregular network','EPSG','4123','EPSG','10690',NULL,NULL,0);
INSERT INTO "concatenated_operation" VALUES('PROJ','KKJ_TO_EUREF_FIN','KKJ to EUREF-FIN (using EPSG:10703)','Transformation based on a triangulated irregular network','EPSG','4123','EPSG','10690',NULL,NULL,0);
INSERT INTO "concatenated_operation_step" VALUES('PROJ','KKJ_TO_EUREF_FIN',1,'EPSG','18193');
INSERT INTO "concatenated_operation_step" VALUES('PROJ','KKJ_TO_EUREF_FIN',2,'PROJ','YKJ_TO_ETRS35FIN');
INSERT INTO "concatenated_operation_step" VALUES('PROJ','KKJ_TO_EUREF_FIN',2,'EPSG','10703');
INSERT INTO "concatenated_operation_step" VALUES('PROJ','KKJ_TO_EUREF_FIN',3,'EPSG','16065');
INSERT INTO "usage" VALUES(
'PROJ',
Expand All @@ -53,20 +45,3 @@ INSERT INTO "usage" VALUES(
'EPSG','3333', -- extent
'EPSG','1024' -- unknown
);

INSERT INTO other_transformation VALUES(
'PROJ','N43_TO_N60','N43 height to N60 height',
'Transformation based on a triangulated irregular network',
'PROJ','PROJString','+proj=pipeline +step +proj=tmerc +lat_0=0 +lon_0=27 +k=1 +x_0=3500000 +y_0=0 +ellps=intl +step +proj=tinshift +file=fi_nls_n43_n60.json +step +inv +proj=tmerc +lat_0=0 +lon_0=27 +k=1 +x_0=3500000 +y_0=0 +ellps=intl',
'EPSG','8675','EPSG','5717',0.01,
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,NULL,NULL,NULL,'EPSG','4123',NULL,0);
INSERT INTO "usage" VALUES('PROJ','N43_TO_N60_USAGE','other_transformation','PROJ','N43_TO_N60','EPSG','4522','EPSG','1024');


INSERT INTO other_transformation VALUES(
'PROJ','N60_TO_N2000','N60 height to N2000 height',
'Transformation based on a triangulated irregular network',
'PROJ','PROJString','+proj=pipeline +step +proj=tmerc +lat_0=0 +lon_0=27 +k=1 +x_0=3500000 +y_0=0 +ellps=intl +step +proj=tinshift +file=fi_nls_n60_n2000.json +step +inv +proj=tmerc +lat_0=0 +lon_0=27 +k=1 +x_0=3500000 +y_0=0 +ellps=intl',
'EPSG','5717','EPSG','3900',0.01,
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,NULL,NULL,NULL,'EPSG','4123',NULL,0);
INSERT INTO "usage" VALUES('PROJ','N60_TO_N2000_USAGE','other_transformation','PROJ','N60_TO_N2000','EPSG','3333','EPSG','1024');
4 changes: 2 additions & 2 deletions data/sql/proj_db_table_defs.sql
Original file line number Diff line number Diff line change
Expand Up @@ -833,11 +833,11 @@ CREATE TABLE grid_transformation(

deprecated BOOLEAN NOT NULL CHECK (deprecated IN (0, 1)),

CONSTRAINT pk_grid_transformation PRIMARY KEY (auth_name, code),
CONSTRAINT pk_grid_transformation PRIMARY KEY (auth_name, code)
--CONSTRAINT fk_grid_transformation_coordinate_operation FOREIGN KEY (auth_name, code) REFERENCES coordinate_operation(auth_name, code) ON DELETE CASCADE,
--CONSTRAINT fk_grid_transformation_source_crs FOREIGN KEY (source_crs_auth_name, source_crs_code) REFERENCES crs(auth_name, code) ON DELETE CASCADE,
--CONSTRAINT fk_grid_transformation_target_crs FOREIGN KEY (target_crs_auth_name, target_crs_code) REFERENCES crs(auth_name, code) ON DELETE CASCADE,
CONSTRAINT fk_grid_transformation_interpolation_crs FOREIGN KEY (interpolation_crs_auth_name, interpolation_crs_code) REFERENCES geodetic_crs(auth_name, code) ON DELETE CASCADE
-- CONSTRAINT fk_grid_transformation_interpolation_crs FOREIGN KEY (interpolation_crs_auth_name, interpolation_crs_code) REFERENCES crs_view(auth_name, code) ON DELETE CASCADE
) WITHOUT ROWID;

-- Table that describe packages/archives that contain several grids
Expand Down
8 changes: 5 additions & 3 deletions scripts/build_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -692,7 +692,7 @@ def fill_helmert_transformation(proj_db_cursor):
'?,?,?, ?, ?,?,?, ?,?, ?,?, ?, ?,?,?,?,?, ?,?,?,?,?, ?,?,?, ?,?,?,?,?, ?,?,?,?,?, ?,?,?, ?,?,?, ?,?,?,?,?, ?,?)', arg)

def fill_grid_transformation(proj_db_cursor):
proj_db_cursor.execute("SELECT coord_op_code, coord_op_name, coord_op_method_code, coord_op_method_name, source_crs_code, target_crs_code, coord_op_accuracy, coord_tfm_version, epsg_coordoperation.deprecated, epsg_coordoperation.remarks FROM epsg.epsg_coordoperation LEFT JOIN epsg.epsg_coordoperationmethod USING (coord_op_method_code) WHERE coord_op_type IN ('transformation', 'point motion operation') AND coord_op_method_code NOT IN (1131, 1136) AND (coord_op_method_name LIKE 'Geographic3D to%' OR coord_op_method_name LIKE 'Geog3D to%' OR coord_op_method_name LIKE 'Point motion by grid%' OR coord_op_method_name LIKE 'Vertical % by %grid%' OR coord_op_method_name IN ('NADCON', 'NADCON5 (2D)', 'NADCON5 (3D)', 'NTv1', 'NTv2', 'VERTCON', 'Geocentric translation by Grid Interpolation (IGN)', 'Geographic3D Offset by velocity grid (NTv2_Vel)', 'New Zealand Deformation Model'))")
proj_db_cursor.execute("SELECT coord_op_code, coord_op_name, coord_op_method_code, coord_op_method_name, source_crs_code, target_crs_code, coord_op_accuracy, coord_tfm_version, epsg_coordoperation.deprecated, epsg_coordoperation.remarks FROM epsg.epsg_coordoperation LEFT JOIN epsg.epsg_coordoperationmethod USING (coord_op_method_code) WHERE coord_op_type IN ('transformation', 'point motion operation') AND coord_op_method_code NOT IN (1131, 1136) AND (coord_op_method_name LIKE 'Geographic3D to%' OR coord_op_method_name LIKE 'Geog3D to%' OR coord_op_method_name LIKE 'Point motion by grid%' OR coord_op_method_name LIKE 'Vertical % by %grid%' OR coord_op_method_name IN ('NADCON', 'NADCON5 (2D)', 'NADCON5 (3D)', 'NTv1', 'NTv2', 'VERTCON', 'Geocentric translation by Grid Interpolation (IGN)', 'Geographic3D Offset by velocity grid (NTv2_Vel)', 'New Zealand Deformation Model', 'Cartesian Grid Offsets by TIN Interpolation (JSON)', 'Vertical Offset by TIN Interpolation (JSON)'))")
for (code, name, method_code, method_name, source_crs_code, target_crs_code, coord_op_accuracy, coord_tfm_version, deprecated, remarks) in proj_db_cursor.fetchall():
expected_order = 1
max_n_params = 3 if method_name == 'Geocentric translation by Grid Interpolation (IGN)' else 2
Expand Down Expand Up @@ -731,7 +731,7 @@ def fill_grid_transformation(proj_db_cursor):
expected_order += 1
n_params = expected_order - 1

assert param_code[0] in (1048, 1050, 1063, 8656, 8657, 8666, 8732, 8727), (code, param_code[0])
assert param_code[0] in (1048, 1050, 1063, 1064, 8656, 8657, 8666, 8732, 8727), (code, param_code[0])

grid2_param_auth_name = None
grid2_param_code = None
Expand Down Expand Up @@ -783,9 +783,11 @@ def fill_grid_transformation(proj_db_cursor):
# 1124: Geog3D to Geog2D+GravityRelatedHeight (gtg)
# 1126: Vertical change by geoid grid difference (NRCan)
# 1135: Geog3D to Geog2D+GravityRelatedHeight (NGS bin)
# 1137: Vertical Offset by TIN Interpolation (JSON)
# 1138: Cartesian Grid Offsets by TIN Interpolation (JSON)
# WARNING: update Transformation::isGeographic3DToGravityRelatedHeight()
# in src/iso19111/operation/singleoperation.cpp if adding new methods
elif method_code in (1071, 1080, 1081, 1083, 1084, 1085, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1100, 1101, 1103, 1105, 1110, 1112, 1113, 1114, 1115, 1118, 1122, 1124, 1126, 1128, 1129, 1135) and n_params == 2:
elif method_code in (1071, 1080, 1081, 1083, 1084, 1085, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1097, 1098, 1100, 1101, 1103, 1105, 1110, 1112, 1113, 1114, 1115, 1118, 1122, 1124, 1126, 1128, 1129, 1135, 1137, 1138) and n_params == 2:
assert param_code[1] == 1048, (code, method_code, param_code[1])
interpolation_crs_auth_name = EPSG_AUTHORITY
interpolation_crs_code = str(int(param_value[1])) # needed to avoid codes like XXXX.0
Expand Down
6 changes: 3 additions & 3 deletions src/iso19111/factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6281,7 +6281,7 @@ operation::CoordinateOperationNNPtr AuthorityFactory::createCoordinateOperation(
.set(common::IdentifiedObject::NAME_KEY, method_name);

std::vector<metadata::PositionalAccuracyNNPtr> accuracies;
if (!accuracy.empty()) {
if (!accuracy.empty() && accuracy != "999.0") {
accuracies.emplace_back(
metadata::PositionalAccuracy::create(accuracy));
}
Expand Down Expand Up @@ -6393,7 +6393,7 @@ operation::CoordinateOperationNNPtr AuthorityFactory::createCoordinateOperation(
.set(common::IdentifiedObject::NAME_KEY, method_name);

std::vector<metadata::PositionalAccuracyNNPtr> accuracies;
if (!accuracy.empty()) {
if (!accuracy.empty() && accuracy != "999.0") {
accuracies.emplace_back(
metadata::PositionalAccuracy::create(accuracy));
}
Expand Down Expand Up @@ -6531,7 +6531,7 @@ operation::CoordinateOperationNNPtr AuthorityFactory::createCoordinateOperation(
}

std::vector<metadata::PositionalAccuracyNNPtr> accuracies;
if (!accuracy.empty()) {
if (!accuracy.empty() && accuracy != "999.0") {
accuracies.emplace_back(
metadata::PositionalAccuracy::create(accuracy));
}
Expand Down
Loading

0 comments on commit 944979c

Please sign in to comment.