diff options
| -rw-r--r-- | docs/source/apps/cct.rst | 27 | ||||
| -rw-r--r-- | src/apps/cct.cpp | 47 | ||||
| -rwxr-xr-x | test/cli/testcct | 93 | ||||
| -rw-r--r-- | test/cli/testcct_out.dist | 2 |
4 files changed, 162 insertions, 7 deletions
diff --git a/docs/source/apps/cct.rst b/docs/source/apps/cct.rst index 8f138d92..b8504b8d 100644 --- a/docs/source/apps/cct.rst +++ b/docs/source/apps/cct.rst @@ -17,9 +17,9 @@ Synopsis or - **cct** [**-cIostvz** [args]] {operation_reference} file ... + **cct** [**-cIostvz** [args]] {object_definition} file ... -Where {operation_reference} is one of the possibilities accepted +Where {object_definition} is one of the possibilities accepted by :c:func:`proj_create`, provided it expresses a coordinate operation - a proj-string, @@ -39,6 +39,15 @@ by :c:func:`proj_create`, provided it expresses a coordinate operation operations in :program:`cct`. +or + + **cct** [**-cIostvz** [args]] {object_reference} file ... + +where {object_reference} is a filename preceded by the '@' character. The +file referenced by the {object_reference} must contain a valid +{object_definition}. + + .. versionadded:: 8.0.0 @@ -185,6 +194,20 @@ Should give results comparable to the classic :program:`proj` command $ echo 12 56 100 2018.0 auxiliary data | cct +proj=merc 1335833.8895 7522963.2411 100.0000 2018.0000 auxiliary data +7. Coordinate operation referenced through its code + +.. code-block:: console + + $ echo 3541657.3778 948984.2343 5201383.5231 2020.5 | cct EPSG:8366 + 3541657.9112 948983.7503 5201383.2482 2020.5000 + +8. Coordinate operation referenced through its name + +.. code-block:: console + + $ echo 3541657.3778 948984.2343 5201383.5231 2020.5 | cct "ITRF2014 to ETRF2014 (1)" + 3541657.9112 948983.7503 5201383.2482 2020.5000 + Background ********** diff --git a/src/apps/cct.cpp b/src/apps/cct.cpp index 4de3cf8e..c482efc2 100644 --- a/src/apps/cct.cpp +++ b/src/apps/cct.cpp @@ -77,6 +77,8 @@ Thomas Knudsen, thokn@sdfe.dk, 2016-05-25/2017-10-26 #include <stdlib.h> #include <string.h> #include <stdarg.h> + +#include <fstream> // std::ifstream #include <iostream> #include "proj.h" @@ -293,20 +295,55 @@ int main(int argc, char **argv) { /* Setup transformation */ if (o-> pargc == 0 && o->fargc > 0) { - /* Assume we got a auth:code combination */ std::string input(o->fargv[0]); + + if (!input.empty() && input[0] == '@') { + std::ifstream fs; + auto filename = input.substr(1); + fs.open(filename, std::fstream::in | std::fstream::binary); + if (!fs.is_open()) { + std::cerr << "cannot open " << filename << std::endl; + std::exit(1); + } + input.clear(); + while (!fs.eof()) { + char buffer[256]; + fs.read(buffer, sizeof(buffer)); + input.append(buffer, static_cast<size_t>(fs.gcount())); + if (input.size() > 100 * 1000) { + fs.close(); + std::cerr << "too big file " << filename << std::endl; + std::exit(1); + } + } + fs.close(); + } + + /* Assume we got a auth:code combination */ auto n = input.find(":"); if (n > 0) { std::string auth = input.substr(0,n); std::string code = input.substr(n+1, input.length()); - P = proj_create_from_database( - nullptr, auth.c_str(), code.c_str(), PJ_CATEGORY_COORDINATE_OPERATION, 0, nullptr - ); + // Check that the authority matches one of the known ones + auto authorityList = proj_get_authorities_from_database(nullptr); + if( authorityList ) + { + for( auto iter = authorityList; *iter; iter++ ) + { + if( *iter == auth ) { + P = proj_create_from_database( + nullptr, auth.c_str(), code.c_str(), + PJ_CATEGORY_COORDINATE_OPERATION, 0, nullptr); + break; + } + } + proj_string_list_destroy(authorityList); + } } if( P == nullptr ) { /* if we didn't get a auth:code combo we try to see if the input matches */ /* anything else */ - P = proj_create(nullptr, o->fargv[0]); + P = proj_create(nullptr, input.c_str()); } /* If instantiating operation without +-options optargpm thinks the input is */ diff --git a/test/cli/testcct b/test/cli/testcct index bbe698bd..db7c70a9 100755 --- a/test/cli/testcct +++ b/test/cli/testcct @@ -44,6 +44,99 @@ echo "3541658.0000 948985.0000 5201384.0000 2020.5" >> b $EXE EPSG:8366 a b >>${OUT} /bin/rm a b +cat > in.wkt <<EOF +COORDINATEOPERATION["ITRF2014 to ETRF2014 (1)", + VERSION["EUREF-Eur"], + SOURCECRS[ + GEODCRS["ITRF2014", + DYNAMIC[ + FRAMEEPOCH[2010]], + DATUM["International Terrestrial Reference Frame 2014", + ELLIPSOID["GRS 1980",6378137,298.257222101, + LENGTHUNIT["metre",1]]], + PRIMEM["Greenwich",0, + ANGLEUNIT["degree",0.0174532925199433]], + CS[Cartesian,3], + AXIS["(X)",geocentricX, + ORDER[1], + LENGTHUNIT["metre",1]], + AXIS["(Y)",geocentricY, + ORDER[2], + LENGTHUNIT["metre",1]], + AXIS["(Z)",geocentricZ, + ORDER[3], + LENGTHUNIT["metre",1]], + ID["EPSG",7789]]], + TARGETCRS[ + GEODCRS["ETRF2014", + DATUM["European Terrestrial Reference Frame 2014", + ELLIPSOID["GRS 1980",6378137,298.257222101, + LENGTHUNIT["metre",1]]], + PRIMEM["Greenwich",0, + ANGLEUNIT["degree",0.0174532925199433]], + CS[Cartesian,3], + AXIS["(X)",geocentricX, + ORDER[1], + LENGTHUNIT["metre",1]], + AXIS["(Y)",geocentricY, + ORDER[2], + LENGTHUNIT["metre",1]], + AXIS["(Z)",geocentricZ, + ORDER[3], + LENGTHUNIT["metre",1]], + ID["EPSG",8401]]], + METHOD["Time-dependent Position Vector tfm (geocentric)", + ID["EPSG",1053]], + PARAMETER["X-axis translation",0, + LENGTHUNIT["millimetre",0.001], + ID["EPSG",8605]], + PARAMETER["Y-axis translation",0, + LENGTHUNIT["millimetre",0.001], + ID["EPSG",8606]], + PARAMETER["Z-axis translation",0, + LENGTHUNIT["millimetre",0.001], + ID["EPSG",8607]], + PARAMETER["X-axis rotation",0, + ANGLEUNIT["milliarc-second",4.84813681109536E-09], + ID["EPSG",8608]], + PARAMETER["Y-axis rotation",0, + ANGLEUNIT["milliarc-second",4.84813681109536E-09], + ID["EPSG",8609]], + PARAMETER["Z-axis rotation",0, + ANGLEUNIT["milliarc-second",4.84813681109536E-09], + ID["EPSG",8610]], + PARAMETER["Scale difference",0, + SCALEUNIT["parts per billion",1E-09], + ID["EPSG",8611]], + PARAMETER["Rate of change of X-axis translation",0, + LENGTHUNIT["millimetres per year",3.16887651727315E-11], + ID["EPSG",1040]], + PARAMETER["Rate of change of Y-axis translation",0, + LENGTHUNIT["millimetres per year",3.16887651727315E-11], + ID["EPSG",1041]], + PARAMETER["Rate of change of Z-axis translation",0, + LENGTHUNIT["millimetres per year",3.16887651727315E-11], + ID["EPSG",1042]], + PARAMETER["Rate of change of X-axis rotation",0.085, + ANGLEUNIT["milliarc-seconds per year",1.53631468932076E-16], + ID["EPSG",1043]], + PARAMETER["Rate of change of Y-axis rotation",0.531, + ANGLEUNIT["milliarc-seconds per year",1.53631468932076E-16], + ID["EPSG",1044]], + PARAMETER["Rate of change of Z-axis rotation",-0.77, + ANGLEUNIT["milliarc-seconds per year",1.53631468932076E-16], + ID["EPSG",1045]], + PARAMETER["Rate of change of Scale difference",0, + SCALEUNIT["parts per billion per year",3.16887651727315E-17], + ID["EPSG",1046]], + PARAMETER["Parameter reference epoch",1989, + TIMEUNIT["year",31556925.445], + ID["EPSG",1047]]] +EOF +echo "Test cct with WKT in a file" >> ${OUT} +echo "3541657.3778 948984.2343 5201383.5231 2020.5" | $EXE @in.wkt >>${OUT} +rm in.wkt + # do 'diff' with distribution results echo "diff ${OUT} with testcct_out.dist" diff -u ${OUT} ${TEST_CLI_DIR}/testcct_out.dist diff --git a/test/cli/testcct_out.dist b/test/cli/testcct_out.dist index 7788f0bb..353deb17 100644 --- a/test/cli/testcct_out.dist +++ b/test/cli/testcct_out.dist @@ -8,3 +8,5 @@ Test cct with object name initialization Test cct with object code initialization and file input 3541657.9112 948983.7503 5201383.2482 2020.5000 3541658.5334 948984.5160 5201383.7251 2020.5000 +Test cct with WKT in a file + 3541657.9112 948983.7503 5201383.2482 2020.5000 |
