aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/sql/customizations.sql32
-rw-r--r--data/sql/proj_db_table_defs.sql1
-rw-r--r--data/sql/unit_of_measure.sql190
-rw-r--r--docs/source/development/reference/functions.rst3
-rw-r--r--include/proj/io.hpp30
-rwxr-xr-xscripts/build_db.py2
-rw-r--r--src/iso19111/c_api.cpp127
-rw-r--r--src/iso19111/factory.cpp58
-rw-r--r--src/proj.h42
-rw-r--r--test/unit/test_c_api.cpp42
-rw-r--r--test/unit/test_factory.cpp84
11 files changed, 497 insertions, 114 deletions
diff --git a/data/sql/customizations.sql b/data/sql/customizations.sql
index 82328f3c..fd67b8a1 100644
--- a/data/sql/customizations.sql
+++ b/data/sql/customizations.sql
@@ -135,3 +135,35 @@ INSERT INTO "alias_name" VALUES('geodetic_datum','EPSG','6312','hermannskogel','
INSERT INTO "alias_name" VALUES('geodetic_datum','EPSG','6299','ire65','PROJ');
INSERT INTO "alias_name" VALUES('geodetic_datum','EPSG','6272','nzgd49','PROJ');
INSERT INTO "alias_name" VALUES('geodetic_datum','EPSG','6277','OSGB36','PROJ');
+
+---- PROJ unit short names -----
+
+-- Linear units
+UPDATE unit_of_measure SET proj_short_name = 'mm' WHERE auth_name = 'EPSG' AND code = '1025';
+UPDATE unit_of_measure SET proj_short_name = 'cm' WHERE auth_name = 'EPSG' AND code = '1033';
+UPDATE unit_of_measure SET proj_short_name = 'm' WHERE auth_name = 'EPSG' AND code = '9001';
+UPDATE unit_of_measure SET proj_short_name = 'ft' WHERE auth_name = 'EPSG' AND code = '9002';
+UPDATE unit_of_measure SET proj_short_name = 'us-ft' WHERE auth_name = 'EPSG' AND code = '9003';
+UPDATE unit_of_measure SET proj_short_name = 'fath' WHERE auth_name = 'EPSG' AND code = '9014';
+UPDATE unit_of_measure SET proj_short_name = 'kmi' WHERE auth_name = 'EPSG' AND code = '9030';
+UPDATE unit_of_measure SET proj_short_name = 'us-ch' WHERE auth_name = 'EPSG' AND code = '9033';
+UPDATE unit_of_measure SET proj_short_name = 'us-mi' WHERE auth_name = 'EPSG' AND code = '9035';
+UPDATE unit_of_measure SET proj_short_name = 'km' WHERE auth_name = 'EPSG' AND code = '9036';
+UPDATE unit_of_measure SET proj_short_name = 'ind-ft' WHERE auth_name = 'EPSG' AND code = '9081';
+UPDATE unit_of_measure SET proj_short_name = 'ind-yd' WHERE auth_name = 'EPSG' AND code = '9085';
+UPDATE unit_of_measure SET proj_short_name = 'mi' WHERE auth_name = 'EPSG' AND code = '9093';
+UPDATE unit_of_measure SET proj_short_name = 'yd' WHERE auth_name = 'EPSG' AND code = '9096';
+UPDATE unit_of_measure SET proj_short_name = 'ch' WHERE auth_name = 'EPSG' AND code = '9097';
+UPDATE unit_of_measure SET proj_short_name = 'link' WHERE auth_name = 'EPSG' AND code = '9098';
+
+-- Angular units
+UPDATE unit_of_measure SET proj_short_name = 'rad' WHERE auth_name = 'EPSG' AND code = '9101';
+UPDATE unit_of_measure SET proj_short_name = 'deg' WHERE auth_name = 'EPSG' AND code = '9102';
+UPDATE unit_of_measure SET proj_short_name = 'grad' WHERE auth_name = 'EPSG' AND code = '9105';
+
+-- PROJ specific units
+INSERT INTO "unit_of_measure" VALUES('PROJ','DM','decimeter','length',0.01,'dm',0);
+INSERT INTO "unit_of_measure" VALUES('PROJ','IN','inch','length',0.0254,'in',0);
+INSERT INTO "unit_of_measure" VALUES('PROJ','US_IN','US survey inch','length',0.025400050800101,'us-in',0);
+INSERT INTO "unit_of_measure" VALUES('PROJ','US_YD','US survey yard','length',0.914401828803658,'us-yd',0);
+INSERT INTO "unit_of_measure" VALUES('PROJ','IND_CH','Indian chain','length',20.11669506,'ind-ch',0);
diff --git a/data/sql/proj_db_table_defs.sql b/data/sql/proj_db_table_defs.sql
index 166929af..df20de31 100644
--- a/data/sql/proj_db_table_defs.sql
+++ b/data/sql/proj_db_table_defs.sql
@@ -14,6 +14,7 @@ CREATE TABLE unit_of_measure(
name TEXT NOT NULL CHECK (length(name) >= 2),
type TEXT NOT NULL CHECK (type IN ('length', 'angle', 'scale', 'time')),
conv_factor FLOAT,
+ proj_short_name TEXT, -- PROJ string name, like 'm', 'ft'. Might be NULL
deprecated BOOLEAN NOT NULL CHECK (deprecated IN (0, 1)),
CONSTRAINT pk_unit_of_measure PRIMARY KEY (auth_name, code)
);
diff --git a/data/sql/unit_of_measure.sql b/data/sql/unit_of_measure.sql
index a3011c94..d361c159 100644
--- a/data/sql/unit_of_measure.sql
+++ b/data/sql/unit_of_measure.sql
@@ -1,97 +1,97 @@
--- This file has been generated by scripts/build_db.py. DO NOT EDIT !
-INSERT INTO "unit_of_measure" VALUES('EPSG','1024','bin','scale',1.0,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','1025','millimetre','length',0.001,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','1026','metre per second','length',1.0,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','1027','millimetres per year','length',3.16887651727314875889e-11,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','1028','parts per billion','scale',1.0e-09,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','1029','year','time',31556925.445,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','1030','parts per billion per year','scale',3.16887651727314834646e-17,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','1031','milliarc-second','angle',4.84813681109535528357e-09,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','1032','milliarc-seconds per year','angle',1.53631468932075975278e-16,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','1033','centimetre','length',0.01,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','1034','centimetres per year','length',3.1688765172731483714e-10,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','1035','radian per second','angle',1.0,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','1036','unity per second','scale',1.0,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','1040','second','time',1.0,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','1041','parts per million per year','scale',3.1688765172731486173e-14,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','1042','metres per year','length',3.16887651727314861947e-08,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','1043','arc-seconds per year','angle',1.53631468932075975646e-13,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9001','metre','length',1.0,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9002','foot','length',0.3048,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9003','US survey foot','length',3.04800609601219241184e-01,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9005','Clarke''s foot','length',0.3047972654,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9014','fathom','length',1.8288,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9030','nautical mile','length',1852.0,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9031','German legal metre','length',1.0000135965,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9033','US survey chain','length',2.01168402336804703618e+01,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9034','US survey link','length',2.0116840233680469141e-01,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9035','US survey mile','length',1.60934721869443751532e+03,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9036','kilometre','length',1000.0,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9037','Clarke''s yard','length',0.9143917962,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9038','Clarke''s chain','length',20.1166195164,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9039','Clarke''s link','length',0.201166195164,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9040','British yard (Sears 1922)','length',9.14398414616028665236e-01,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9041','British foot (Sears 1922)','length',3.04799471538676203241e-01,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9042','British chain (Sears 1922)','length',2.01167651215526319683e+01,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9043','British link (Sears 1922)','length',2.01167651215526294139e-01,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9050','British yard (Benoit 1895 A)','length',0.9143992,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9051','British foot (Benoit 1895 A)','length',3.04799733333333322526e-01,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9052','British chain (Benoit 1895 A)','length',20.1167824,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9053','British link (Benoit 1895 A)','length',0.201167824,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9060','British yard (Benoit 1895 B)','length',9.14399204289812361778e-01,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9061','British foot (Benoit 1895 B)','length',3.04799734763270768755e-01,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9062','British chain (Benoit 1895 B)','length',2.01167824943758724023e+01,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9063','British link (Benoit 1895 B)','length',2.01167824943758705158e-01,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9070','British foot (1865)','length',3.04800833333333354158e-01,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9080','Indian foot','length',3.04799510248146943158e-01,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9081','Indian foot (1937)','length',0.30479841,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9082','Indian foot (1962)','length',0.3047996,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9083','Indian foot (1975)','length',0.3047995,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9084','Indian yard','length',9.14398530744440773965e-01,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9085','Indian yard (1937)','length',0.91439523,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9086','Indian yard (1962)','length',0.9143988,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9087','Indian yard (1975)','length',0.9143985,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9093','Statute mile','length',1609.344,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9094','Gold Coast foot','length',3.04799710181508809458e-01,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9095','British foot (1936)','length',0.3048007491,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9096','yard','length',0.9144,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9097','chain','length',20.1168,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9098','link','length',0.201168,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9099','British yard (Sears 1922 truncated)','length',0.914398,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9101','radian','angle',1.0,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9102','degree','angle',1.74532925199432781271e-02,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9103','arc-minute','angle',2.90888208665721309346e-04,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9104','arc-second','angle',4.84813681109535476055e-06,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9105','grad','angle',1.57079632679489496205e-02,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9106','gon','angle',1.57079632679489496205e-02,1);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9107','degree minute second','angle',NULL,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9108','degree minute second hemisphere','angle',NULL,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9109','microradian','angle',1.0e-06,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9110','sexagesimal DMS','angle',NULL,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9111','sexagesimal DM','angle',NULL,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9112','centesimal minute','angle',1.57079632679489491868e-04,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9113','centesimal second','angle',1.57079632679489496951e-06,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9114','mil_6400','angle',9.81747704246809351283e-04,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9115','degree minute','angle',NULL,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9116','degree hemisphere','angle',NULL,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9117','hemisphere degree','angle',NULL,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9118','degree minute hemisphere','angle',NULL,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9119','hemisphere degree minute','angle',NULL,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9120','hemisphere degree minute second','angle',NULL,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9121','sexagesimal DMS.s','angle',NULL,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9122','degree (supplier to define representation)','angle',1.74532925199432781271e-02,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9201','unity','scale',1.0,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9202','parts per million','scale',1.0e-06,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9203','coefficient','scale',1.0,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9204','Bin width 330 US survey feet','length',1.00584201168402344707e+02,1);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9205','Bin width 165 US survey feet','length',5.02921005842011723538e+01,1);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9206','Bin width 82.5 US survey feet','length',2.51460502921005861769e+01,1);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9207','Bin width 37.5 metres','length',37.5,1);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9208','Bin width 25 metres','length',25.0,1);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9209','Bin width 12.5 metres','length',12.5,1);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9210','Bin width 6.25 metres','length',6.25,1);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9211','Bin width 3.125 metres','length',3.125,1);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9300','British foot (Sears 1922 truncated)','length',3.04799333333333366535e-01,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9301','British chain (Sears 1922 truncated)','length',20.116756,0);
-INSERT INTO "unit_of_measure" VALUES('EPSG','9302','British link (Sears 1922 truncated)','length',0.20116756,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','1024','bin','scale',1.0,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','1025','millimetre','length',0.001,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','1026','metre per second','length',1.0,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','1027','millimetres per year','length',3.16887651727314875889e-11,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','1028','parts per billion','scale',1.0e-09,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','1029','year','time',31556925.445,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','1030','parts per billion per year','scale',3.16887651727314834646e-17,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','1031','milliarc-second','angle',4.84813681109535528357e-09,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','1032','milliarc-seconds per year','angle',1.53631468932075975278e-16,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','1033','centimetre','length',0.01,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','1034','centimetres per year','length',3.1688765172731483714e-10,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','1035','radian per second','angle',1.0,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','1036','unity per second','scale',1.0,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','1040','second','time',1.0,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','1041','parts per million per year','scale',3.1688765172731486173e-14,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','1042','metres per year','length',3.16887651727314861947e-08,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','1043','arc-seconds per year','angle',1.53631468932075975646e-13,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9001','metre','length',1.0,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9002','foot','length',0.3048,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9003','US survey foot','length',3.04800609601219241184e-01,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9005','Clarke''s foot','length',0.3047972654,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9014','fathom','length',1.8288,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9030','nautical mile','length',1852.0,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9031','German legal metre','length',1.0000135965,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9033','US survey chain','length',2.01168402336804703618e+01,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9034','US survey link','length',2.0116840233680469141e-01,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9035','US survey mile','length',1.60934721869443751532e+03,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9036','kilometre','length',1000.0,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9037','Clarke''s yard','length',0.9143917962,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9038','Clarke''s chain','length',20.1166195164,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9039','Clarke''s link','length',0.201166195164,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9040','British yard (Sears 1922)','length',9.14398414616028665236e-01,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9041','British foot (Sears 1922)','length',3.04799471538676203241e-01,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9042','British chain (Sears 1922)','length',2.01167651215526319683e+01,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9043','British link (Sears 1922)','length',2.01167651215526294139e-01,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9050','British yard (Benoit 1895 A)','length',0.9143992,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9051','British foot (Benoit 1895 A)','length',3.04799733333333322526e-01,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9052','British chain (Benoit 1895 A)','length',20.1167824,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9053','British link (Benoit 1895 A)','length',0.201167824,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9060','British yard (Benoit 1895 B)','length',9.14399204289812361778e-01,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9061','British foot (Benoit 1895 B)','length',3.04799734763270768755e-01,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9062','British chain (Benoit 1895 B)','length',2.01167824943758724023e+01,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9063','British link (Benoit 1895 B)','length',2.01167824943758705158e-01,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9070','British foot (1865)','length',3.04800833333333354158e-01,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9080','Indian foot','length',3.04799510248146943158e-01,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9081','Indian foot (1937)','length',0.30479841,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9082','Indian foot (1962)','length',0.3047996,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9083','Indian foot (1975)','length',0.3047995,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9084','Indian yard','length',9.14398530744440773965e-01,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9085','Indian yard (1937)','length',0.91439523,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9086','Indian yard (1962)','length',0.9143988,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9087','Indian yard (1975)','length',0.9143985,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9093','Statute mile','length',1609.344,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9094','Gold Coast foot','length',3.04799710181508809458e-01,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9095','British foot (1936)','length',0.3048007491,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9096','yard','length',0.9144,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9097','chain','length',20.1168,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9098','link','length',0.201168,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9099','British yard (Sears 1922 truncated)','length',0.914398,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9101','radian','angle',1.0,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9102','degree','angle',1.74532925199432781271e-02,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9103','arc-minute','angle',2.90888208665721309346e-04,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9104','arc-second','angle',4.84813681109535476055e-06,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9105','grad','angle',1.57079632679489496205e-02,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9106','gon','angle',1.57079632679489496205e-02,NULL,1);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9107','degree minute second','angle',NULL,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9108','degree minute second hemisphere','angle',NULL,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9109','microradian','angle',1.0e-06,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9110','sexagesimal DMS','angle',NULL,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9111','sexagesimal DM','angle',NULL,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9112','centesimal minute','angle',1.57079632679489491868e-04,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9113','centesimal second','angle',1.57079632679489496951e-06,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9114','mil_6400','angle',9.81747704246809351283e-04,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9115','degree minute','angle',NULL,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9116','degree hemisphere','angle',NULL,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9117','hemisphere degree','angle',NULL,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9118','degree minute hemisphere','angle',NULL,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9119','hemisphere degree minute','angle',NULL,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9120','hemisphere degree minute second','angle',NULL,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9121','sexagesimal DMS.s','angle',NULL,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9122','degree (supplier to define representation)','angle',1.74532925199432781271e-02,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9201','unity','scale',1.0,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9202','parts per million','scale',1.0e-06,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9203','coefficient','scale',1.0,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9204','Bin width 330 US survey feet','length',1.00584201168402344707e+02,NULL,1);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9205','Bin width 165 US survey feet','length',5.02921005842011723538e+01,NULL,1);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9206','Bin width 82.5 US survey feet','length',2.51460502921005861769e+01,NULL,1);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9207','Bin width 37.5 metres','length',37.5,NULL,1);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9208','Bin width 25 metres','length',25.0,NULL,1);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9209','Bin width 12.5 metres','length',12.5,NULL,1);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9210','Bin width 6.25 metres','length',6.25,NULL,1);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9211','Bin width 3.125 metres','length',3.125,NULL,1);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9300','British foot (Sears 1922 truncated)','length',3.04799333333333366535e-01,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9301','British chain (Sears 1922 truncated)','length',20.116756,NULL,0);
+INSERT INTO "unit_of_measure" VALUES('EPSG','9302','British link (Sears 1922 truncated)','length',0.20116756,NULL,0);
diff --git a/docs/source/development/reference/functions.rst b/docs/source/development/reference/functions.rst
index 983e8a50..2d68ff68 100644
--- a/docs/source/development/reference/functions.rst
+++ b/docs/source/development/reference/functions.rst
@@ -521,6 +521,9 @@ Lists
entry of the returned array is a NULL-entry. The array is statically
allocated and does not need to be freed after use.
+ Note: starting with PROJ 7.1, this function is deprecated by
+ :cpp:func:`proj_get_units_from_database`
+
:returns: :c:type:`PJ_UNITS*`
.. c:function:: const PJ_PRIME_MERIDIANS* proj_list_prime_meridians(void)
diff --git a/include/proj/io.hpp b/include/proj/io.hpp
index 3dcf7928..f07f78b8 100644
--- a/include/proj/io.hpp
+++ b/include/proj/io.hpp
@@ -1013,6 +1013,8 @@ class PROJ_GCC_DLL AuthorityFactory {
PROJ_DLL std::string getDescriptionText(const std::string &code) const;
+ // non-standard
+
/** CRS information */
struct CRSInfo {
/** Authority name */
@@ -1049,7 +1051,33 @@ class PROJ_GCC_DLL AuthorityFactory {
PROJ_DLL std::list<CRSInfo> getCRSInfoList() const;
- // non-standard
+ /** Unit information */
+ struct UnitInfo {
+ /** Authority name */
+ std::string authName;
+ /** Code */
+ std::string code;
+ /** Name */
+ std::string name;
+ /** Category: one of "linear", "linear_per_time", "angular",
+ * "angular_per_time", "scale", "scale_per_time" or "time" */
+ std::string category;
+ /** Conversion factor to the SI unit.
+ * It might be 0 in some cases to indicate no known conversion factor.
+ */
+ double convFactor;
+ /** PROJ short name (may be empty) */
+ std::string projShortName;
+ /** Whether the object is deprecated */
+ bool deprecated;
+
+ //! @cond Doxygen_Suppress
+ UnitInfo();
+ //! @endcond
+ };
+
+ PROJ_DLL std::list<UnitInfo> getUnitList() const;
+
PROJ_DLL static AuthorityFactoryNNPtr
create(const DatabaseContextNNPtr &context,
const std::string &authorityName);
diff --git a/scripts/build_db.py b/scripts/build_db.py
index 6eed3867..5897a2d8 100755
--- a/scripts/build_db.py
+++ b/scripts/build_db.py
@@ -68,7 +68,7 @@ def ingest_epsg():
def fill_unit_of_measure(proj_db_cursor):
proj_db_cursor.execute(
- "INSERT INTO unit_of_measure SELECT ?, uom_code, unit_of_meas_name, unit_of_meas_type, factor_b / factor_c, deprecated FROM epsg.epsg_unitofmeasure", (EPSG_AUTHORITY,))
+ "INSERT INTO unit_of_measure SELECT ?, uom_code, unit_of_meas_name, unit_of_meas_type, factor_b / factor_c, NULL, deprecated FROM epsg.epsg_unitofmeasure", (EPSG_AUTHORITY,))
def fill_ellipsoid(proj_db_cursor):
diff --git a/src/iso19111/c_api.cpp b/src/iso19111/c_api.cpp
index d5f299c2..13152662 100644
--- a/src/iso19111/c_api.cpp
+++ b/src/iso19111/c_api.cpp
@@ -662,7 +662,8 @@ PJ *proj_create_from_database(PJ_CONTEXT *ctx, const char *auth_name,
// ---------------------------------------------------------------------------
//! @cond Doxygen_Suppress
-static const char *get_unit_category(UnitOfMeasure::Type type) {
+static const char *get_unit_category(const std::string &unit_name,
+ UnitOfMeasure::Type type) {
const char *ret = nullptr;
switch (type) {
case UnitOfMeasure::Type::UNKNOWN:
@@ -672,19 +673,26 @@ static const char *get_unit_category(UnitOfMeasure::Type type) {
ret = "none";
break;
case UnitOfMeasure::Type::ANGULAR:
- ret = "angular";
+ ret = unit_name.find(" per ") != std::string::npos ? "angular_per_time"
+ : "angular";
break;
case UnitOfMeasure::Type::LINEAR:
- ret = "linear";
+ ret = unit_name.find(" per ") != std::string::npos ? "linear_per_time"
+ : "linear";
break;
case UnitOfMeasure::Type::SCALE:
- ret = "scale";
+ ret = unit_name.find(" per year") != std::string::npos ||
+ unit_name.find(" per second") != std::string::npos
+ ? "scale_per_time"
+ : "scale";
break;
case UnitOfMeasure::Type::TIME:
ret = "time";
break;
case UnitOfMeasure::Type::PARAMETRIC:
- ret = "parametric";
+ ret = unit_name.find(" per ") != std::string::npos
+ ? "parametric_per_time"
+ : "parametric";
break;
}
return ret;
@@ -704,8 +712,9 @@ static const char *get_unit_category(UnitOfMeasure::Type type) {
* @param out_conv_factor Pointer to a value to store the conversion
* factor of the prime meridian longitude unit to radian. or NULL
* @param out_category Pointer to a string value to store the parameter name. or
- * NULL. This value might be "unknown", "none", "linear", "angular", "scale",
- * "time" or "parametric";
+ * NULL. This value might be "unknown", "none", "linear", "linear_per_time",
+ * "angular", "angular_per_time", "scale", "scale_per_time", "time",
+ * "parametric" or "parametric_per_time"
* @return TRUE in case of success
*/
int proj_uom_get_info_from_database(PJ_CONTEXT *ctx, const char *auth_name,
@@ -726,7 +735,7 @@ int proj_uom_get_info_from_database(PJ_CONTEXT *ctx, const char *auth_name,
*out_conv_factor = obj->conversionToSI();
}
if (out_category) {
- *out_category = get_unit_category(obj->type());
+ *out_category = get_unit_category(obj->name(), obj->type());
}
ctx->cpp_context->autoCloseDbIfNeeded();
return true;
@@ -2585,6 +2594,100 @@ void proj_crs_info_list_destroy(PROJ_CRS_INFO **list) {
// ---------------------------------------------------------------------------
+/** \brief Enumerate units from the database, taking into account various
+ * criteria.
+ *
+ * The returned object is an array of PROJ_UNIT_INFO* pointers, whose last
+ * entry is NULL. This array should be freed with proj_unit_list_destroy()
+ *
+ * @param ctx PROJ context, or NULL for default context
+ * @param auth_name Authority name, used to restrict the search.
+ * Or NULL for all authorities.
+ * @param category Filter by category, if this parameter is not NULL. Category
+ * is one of "linear", "linear_per_time", "angular", "angular_per_time",
+ * "scale", "scale_per_time" or "time"
+ * @param allow_deprecated whether we should return deprecated objects as well.
+ * @param out_result_count Output parameter pointing to an integer to receive
+ * the size of the result list. Might be NULL
+ * @return an array of PROJ_UNIT_INFO* pointers to be freed with
+ * proj_unit_list_destroy(), or NULL in case of error.
+ *
+ * @since 7.1
+ */
+PROJ_UNIT_INFO **proj_get_units_from_database(PJ_CONTEXT *ctx,
+ const char *auth_name,
+ const char *category,
+ int allow_deprecated,
+ int *out_result_count) {
+ SANITIZE_CTX(ctx);
+ PROJ_UNIT_INFO **ret = nullptr;
+ int i = 0;
+ try {
+ auto factory = AuthorityFactory::create(getDBcontext(ctx),
+ auth_name ? auth_name : "");
+ auto list = factory->getUnitList();
+ ret = new PROJ_UNIT_INFO *[list.size() + 1];
+ for (const auto &info : list) {
+ if (category && info.category != category) {
+ continue;
+ }
+ if (!allow_deprecated && info.deprecated) {
+ continue;
+ }
+ ret[i] = new PROJ_UNIT_INFO;
+ ret[i]->auth_name = pj_strdup(info.authName.c_str());
+ ret[i]->code = pj_strdup(info.code.c_str());
+ ret[i]->name = pj_strdup(info.name.c_str());
+ ret[i]->category = pj_strdup(info.category.c_str());
+ ret[i]->conv_factor = info.convFactor;
+ ret[i]->proj_short_name =
+ info.projShortName.empty()
+ ? nullptr
+ : pj_strdup(info.projShortName.c_str());
+ ret[i]->deprecated = info.deprecated;
+ i++;
+ }
+ ret[i] = nullptr;
+ if (out_result_count)
+ *out_result_count = i;
+ ctx->cpp_context->autoCloseDbIfNeeded();
+ return ret;
+ } catch (const std::exception &e) {
+ proj_log_error(ctx, __FUNCTION__, e.what());
+ if (ret) {
+ ret[i + 1] = nullptr;
+ proj_unit_list_destroy(ret);
+ }
+ if (out_result_count)
+ *out_result_count = 0;
+ }
+ ctx->cpp_context->autoCloseDbIfNeeded();
+ return nullptr;
+}
+
+// ---------------------------------------------------------------------------
+
+/** \brief Destroy the result returned by
+ * proj_get_units_from_database().
+ *
+ * @since 7.1
+ */
+void proj_unit_list_destroy(PROJ_UNIT_INFO **list) {
+ if (list) {
+ for (int i = 0; list[i] != nullptr; i++) {
+ pj_dalloc(list[i]->auth_name);
+ pj_dalloc(list[i]->code);
+ pj_dalloc(list[i]->name);
+ pj_dalloc(list[i]->category);
+ pj_dalloc(list[i]->proj_short_name);
+ delete list[i];
+ }
+ delete[] list;
+ }
+}
+
+// ---------------------------------------------------------------------------
+
/** \brief Return the Conversion of a DerivedCRS (such as a ProjectedCRS),
* or the Transformation from the baseCRS to the hubCRS of a BoundCRS
*
@@ -6749,8 +6852,9 @@ int proj_coordoperation_get_param_index(PJ_CONTEXT *ctx,
* unit code. or NULL
* @param out_unit_category Pointer to a string value to store the parameter
* name. or
- * NULL. This value might be "unknown", "none", "linear", "angular", "scale",
- * "time" or "parametric";
+ * NULL. This value might be "unknown", "none", "linear", "linear_per_time",
+ * "angular", "angular_per_time", "scale", "scale_per_time", "time",
+ * "parametric" or "parametric_per_time"
* @return TRUE in case of success.
*/
@@ -6852,7 +6956,8 @@ int proj_coordoperation_get_param(
*out_unit_code = unit.code().c_str();
}
if (out_unit_category) {
- *out_unit_category = get_unit_category(unit.type());
+ *out_unit_category =
+ get_unit_category(unit.name(), unit.type());
}
}
}
diff --git a/src/iso19111/factory.cpp b/src/iso19111/factory.cpp
index 1c836367..6a707e0d 100644
--- a/src/iso19111/factory.cpp
+++ b/src/iso19111/factory.cpp
@@ -5214,6 +5214,64 @@ std::list<AuthorityFactory::CRSInfo> AuthorityFactory::getCRSInfoList() const {
// ---------------------------------------------------------------------------
+//! @cond Doxygen_Suppress
+AuthorityFactory::UnitInfo::UnitInfo()
+ : authName{}, code{}, name{}, category{}, convFactor{}, projShortName{},
+ deprecated{} {}
+//! @endcond
+
+// ---------------------------------------------------------------------------
+
+/** \brief Return the list of units.
+ * @throw FactoryException
+ *
+ * @since 7.1
+ */
+std::list<AuthorityFactory::UnitInfo> AuthorityFactory::getUnitList() const {
+ std::string sql = "SELECT auth_name, code, name, type, conv_factor, "
+ "proj_short_name, deprecated FROM unit_of_measure";
+ ListOfParams params;
+ if (d->hasAuthorityRestriction()) {
+ sql += " WHERE auth_name = ?";
+ params.emplace_back(d->authority());
+ }
+ sql += " ORDER BY auth_name, code";
+
+ auto sqlRes = d->run(sql, params);
+ std::list<AuthorityFactory::UnitInfo> res;
+ for (const auto &row : sqlRes) {
+ AuthorityFactory::UnitInfo info;
+ info.authName = row[0];
+ info.code = row[1];
+ info.name = row[2];
+ const std::string &raw_category(row[3]);
+ if (raw_category == "length") {
+ info.category = info.name.find(" per ") != std::string::npos
+ ? "linear_per_time"
+ : "linear";
+ } else if (raw_category == "angle") {
+ info.category = info.name.find(" per ") != std::string::npos
+ ? "angular_per_time"
+ : "angular";
+ } else if (raw_category == "scale") {
+ info.category =
+ info.name.find(" per year") != std::string::npos ||
+ info.name.find(" per second") != std::string::npos
+ ? "scale_per_time"
+ : "scale";
+ } else {
+ info.category = raw_category;
+ }
+ info.convFactor = row[4].empty() ? 0 : c_locale_stod(row[4]);
+ info.projShortName = row[5];
+ info.deprecated = row[6] == "1";
+ res.emplace_back(info);
+ }
+ return res;
+}
+
+// ---------------------------------------------------------------------------
+
/** \brief Gets the official name from a possibly alias name.
*
* @param aliasedName Alias name.
diff --git a/src/proj.h b/src/proj.h
index 90a11739..8f48217f 100644
--- a/src/proj.h
+++ b/src/proj.h
@@ -912,6 +912,39 @@ typedef struct
int allow_deprecated;
} PROJ_CRS_LIST_PARAMETERS;
+/** \brief Structure given description of a unit.
+ *
+ * This structure may grow over time, and should not be directly allocated by
+ * client code.
+ * @since 7.1
+ */
+typedef struct
+{
+ /** Authority name. */
+ char* auth_name;
+
+ /** Object code. */
+ char* code;
+
+ /** Object name. For example "metre", "US survey foot", etc. */
+ char* name;
+
+ /** Category of the unit: one of "linear", "linear_per_time", "angular",
+ * "angular_per_time", "scale", "scale_per_time" or "time" */
+ char* category;
+
+ /** Conversion factor to apply to transform from that unit to the
+ * corresponding SI unit (metre for "linear", radian for "angular", etc.).
+ * It might be 0 in some cases to indicate no known conversion factor. */
+ double conv_factor;
+
+ /** PROJ short name, like "m", "ft", "us-ft", etc... Might be NULL */
+ char* proj_short_name;
+
+ /** Whether the object is deprecated */
+ int deprecated;
+} PROJ_UNIT_INFO;
+
/**@}*/
@@ -1077,6 +1110,15 @@ PROJ_CRS_INFO PROJ_DLL **proj_get_crs_info_list_from_database(
void PROJ_DLL proj_crs_info_list_destroy(PROJ_CRS_INFO** list);
+PROJ_UNIT_INFO PROJ_DLL **proj_get_units_from_database(
+ PJ_CONTEXT *ctx,
+ const char *auth_name,
+ const char *category,
+ int allow_deprecated,
+ int *out_result_count);
+
+void PROJ_DLL proj_unit_list_destroy(PROJ_UNIT_INFO** list);
+
/* ------------------------------------------------------------------------- */
diff --git a/test/unit/test_c_api.cpp b/test/unit/test_c_api.cpp
index 0f1b906e..bcd14c0f 100644
--- a/test/unit/test_c_api.cpp
+++ b/test/unit/test_c_api.cpp
@@ -3401,6 +3401,48 @@ TEST_F(CApi, proj_get_crs_info_list_from_database) {
// ---------------------------------------------------------------------------
+TEST_F(CApi, proj_get_units_from_database) {
+ { proj_unit_list_destroy(nullptr); }
+
+ {
+ auto list = proj_get_units_from_database(nullptr, nullptr, nullptr,
+ true, nullptr);
+ ASSERT_NE(list, nullptr);
+ ASSERT_NE(list[0], nullptr);
+ ASSERT_NE(list[0]->auth_name, nullptr);
+ ASSERT_NE(list[0]->code, nullptr);
+ ASSERT_NE(list[0]->name, nullptr);
+ proj_unit_list_destroy(list);
+ }
+
+ {
+ int result_count = 0;
+ auto list = proj_get_units_from_database(nullptr, "EPSG", "linear",
+ false, &result_count);
+ ASSERT_NE(list, nullptr);
+ EXPECT_GT(result_count, 1);
+ EXPECT_EQ(list[result_count], nullptr);
+ bool found9001 = false;
+ for (int i = 0; i < result_count; i++) {
+ EXPECT_EQ(std::string(list[i]->auth_name), "EPSG");
+ if (std::string(list[i]->code) == "9001") {
+ EXPECT_EQ(std::string(list[i]->name), "metre");
+ EXPECT_EQ(std::string(list[i]->category), "linear");
+ EXPECT_EQ(list[i]->conv_factor, 1.0);
+ ASSERT_NE(list[i]->proj_short_name, nullptr);
+ EXPECT_EQ(std::string(list[i]->proj_short_name), "m");
+ EXPECT_EQ(list[i]->deprecated, 0);
+ found9001 = true;
+ }
+ EXPECT_EQ(list[i]->deprecated, 0);
+ }
+ EXPECT_TRUE(found9001);
+ proj_unit_list_destroy(list);
+ }
+}
+
+// ---------------------------------------------------------------------------
+
TEST_F(CApi, proj_normalize_for_visualization) {
{
diff --git a/test/unit/test_factory.cpp b/test/unit/test_factory.cpp
index c7ae458e..aee2f572 100644
--- a/test/unit/test_factory.cpp
+++ b/test/unit/test_factory.cpp
@@ -1401,16 +1401,18 @@ class FactoryWithTmpDatabase : public ::testing::Test {
void populateWithFakeEPSG() {
ASSERT_TRUE(execute("INSERT INTO unit_of_measure "
- "VALUES('EPSG','9001','metre','length',1.0,0);"))
+ "VALUES('EPSG','9001','metre','length',1.0,NULL,"
+ "0);"))
<< last_error();
ASSERT_TRUE(execute("INSERT INTO unit_of_measure "
"VALUES('EPSG','9102','degree','angle',1."
- "74532925199432781271e-02,0);"))
+ "74532925199432781271e-02,NULL,0);"))
<< last_error();
ASSERT_TRUE(execute(
"INSERT INTO unit_of_measure VALUES('EPSG','9122','degree "
"(supplier to "
- "define representation)','angle',1.74532925199432781271e-02,0);"))
+ "define representation)','angle',1.74532925199432781271e-02,NULL,"
+ "0);"))
<< last_error();
ASSERT_TRUE(
execute("INSERT INTO area "
@@ -1470,7 +1472,8 @@ class FactoryWithTmpDatabase : public ::testing::Test {
<< last_error();
ASSERT_TRUE(execute("INSERT INTO unit_of_measure "
- "VALUES('EPSG','9201','unity','scale',1.0,0);"))
+ "VALUES('EPSG','9201','unity','scale',1.0,"
+ "NULL,0);"))
<< last_error();
ASSERT_TRUE(execute(
@@ -1547,7 +1550,7 @@ class FactoryWithTmpDatabase : public ::testing::Test {
ASSERT_TRUE(execute(
"INSERT INTO unit_of_measure VALUES('EPSG','9110','sexagesimal "
- "DMS','angle',NULL,0);"))
+ "DMS','angle',NULL,NULL,0);"))
<< last_error();
ASSERT_TRUE(execute(
@@ -2933,7 +2936,7 @@ TEST(factory, getCRSInfoList) {
auto list = factory->getCRSInfoList();
EXPECT_GT(list.size(), 1U);
bool foundEPSG = false;
- bool foundIGNF = true;
+ bool foundIGNF = false;
bool found4326 = false;
for (const auto &info : list) {
foundEPSG |= info.authName == "EPSG";
@@ -3023,4 +3026,73 @@ TEST(factory, getCRSInfoList) {
EXPECT_TRUE(found6871);
}
}
+
+// ---------------------------------------------------------------------------
+
+TEST(factory, getUnitList) {
+ auto ctxt = DatabaseContext::create();
+ {
+ auto factory = AuthorityFactory::create(ctxt, std::string());
+ auto list = factory->getUnitList();
+ EXPECT_GT(list.size(), 1U);
+ bool foundEPSG = false;
+ bool foundPROJ = false;
+ bool found1027 = false;
+ bool found1028 = false;
+ bool found1032 = false;
+ bool found1036 = false;
+ bool found9001 = false;
+ bool found9101 = false;
+ for (const auto &info : list) {
+ foundEPSG |= info.authName == "EPSG";
+ foundPROJ |= info.authName == "PROJ";
+ if (info.authName == "EPSG" && info.code == "1027") {
+ EXPECT_EQ(info.name, "millimetres per year");
+ EXPECT_EQ(info.category, "linear_per_time");
+ found1027 = true;
+ } else if (info.authName == "EPSG" && info.code == "1028") {
+ EXPECT_EQ(info.name, "parts per billion");
+ EXPECT_EQ(info.category, "scale");
+ found1028 = true;
+ } else if (info.authName == "EPSG" && info.code == "1032") {
+ EXPECT_EQ(info.name, "milliarc-seconds per year");
+ EXPECT_EQ(info.category, "angular_per_time");
+ found1032 = true;
+ } else if (info.authName == "EPSG" && info.code == "1036") {
+ EXPECT_EQ(info.name, "unity per second");
+ EXPECT_EQ(info.category, "scale_per_time");
+ found1036 = true;
+ } else if (info.authName == "EPSG" && info.code == "9001") {
+ EXPECT_EQ(info.name, "metre");
+ EXPECT_EQ(info.category, "linear");
+ EXPECT_EQ(info.convFactor, 1.0);
+ EXPECT_EQ(info.projShortName, "m");
+ EXPECT_FALSE(info.deprecated);
+ found9001 = true;
+ } else if (info.authName == "EPSG" && info.code == "9101") {
+ EXPECT_EQ(info.name, "radian");
+ EXPECT_EQ(info.category, "angular");
+ EXPECT_FALSE(info.deprecated);
+ found9101 = true;
+ }
+ }
+ EXPECT_TRUE(foundEPSG);
+ EXPECT_TRUE(foundPROJ);
+ EXPECT_TRUE(found1027);
+ EXPECT_TRUE(found1028);
+ EXPECT_TRUE(found1032);
+ EXPECT_TRUE(found1036);
+ EXPECT_TRUE(found9001);
+ EXPECT_TRUE(found9101);
+ }
+ {
+ auto factory = AuthorityFactory::create(ctxt, "EPSG");
+ auto list = factory->getUnitList();
+ EXPECT_GT(list.size(), 1U);
+ for (const auto &info : list) {
+ EXPECT_EQ(info.authName, "EPSG");
+ }
+ }
+}
+
} // namespace