A PROJ upgrade can silently change a transformation's output, and gie catches that by running a small regression test against the installed library. You create the test file, run it, and get a useful non-zero status when a result falls outside its allowed tolerance. The examples use gie 9.4.0 from Debian package proj-bin version 9.4.0-1build2. Allow about fifteen minutes if you already know the operation and expected coordinates.
gie is a regression-testing command, not a general coordinate converter. A test describes a PROJ operation, an input coordinate, and the result that should come back. It does not need elevated privileges, and the examples only read the PROJ installation and write files in the current directory.
Confirm which executable will run and record its version before comparing results from another machine or CI runner:
$ command -v gie
/usr/bin/gie
$ gie --version
gie: Rel. 9.4.0, March 1st, 2024
The manpage shipped with this installation is dated 1 March 2024 and documents PROJ 9.4. Version differences can affect operation selection, available grids, and numerical results. Keep the version beside any baseline that matters.
Checkpoint: if command -v gie finds nothing, install the distribution package that provides gie through your normal package-management process. Do not begin by using sudo on the test itself.
Create a file named utm.gie. The <gie> tags delimit the test region. Text outside those tags is ignored, so keeping the wrapper in place prevents a heading or comment from becoming accidental input.
<gie>
echo ** UTM projection test **
operation +proj=utm +zone=32 +ellps=GRS80
accept 12 55
expect 691875.63214 6098907.82501
</gie>
operation defines the projection. Each accept supplies an input coordinate, and the following expect supplies the coordinate that should be returned. Two values test 2D operation. Three or four values test 3D or 4D operation, including height or time as appropriate.
Run the file:
$ gie utm.gie
-------------------------------------------------------------------------------
Reading file 'utm.gie'
** UTM projection test **
-------------------------------------------------------------------------------
total: 1 tests succeeded, 0 tests skipped, 0 tests failed.
-------------------------------------------------------------------------------
A successful run returns status 0. The exact separator width can vary with the build; the important line reports one succeeded test and zero failures.
The default tolerance is 0.5 mm. That is strict enough to catch a changed operation or an incorrectly copied baseline, but it can be wrong for a test whose source data is only accurate to metres. Add a tolerance line before the coordinate pair when you have a defensible allowance:
<gie>
operation +proj=merc
tolerance 1 cm
accept 12 55
expect 1335833.89 7326837.72
</gie>
Units are parsed as part of the command. The manual points to proj -lu for the available unit names. Do not increase the tolerance merely to make a failing test green: record why the expected value has that uncertainty.
For repeated numerical stability checks, use roundtrip. It sends the accepted coordinate forward and back through the inverse operation. With no arguments it uses 100 iterations and the default tolerance; you can give a count, and then a tolerance:
operation +proj=merc
accept 12 55
roundtrip 10000 5 mm
Keep the operation and accept immediately associated with the round-trip test. A round trip is not a proof that an operation is correct: a paired forward and inverse implementation can agree while both disagree with an external reference.
Change the expected northing in utm.gie to an obviously wrong value and run it again:
$ sed 's/6098907.82501/6098900/' utm.gie > bad.gie
$ gie bad.gie
...
total: 0 tests succeeded, 0 tests skipped, 1 tests FAILED!
$ printf '%s\n' "$?"
1
The failure output shows the expected coordinate, the coordinate produced by PROJ, and the deviation against the current tolerance. The process status is 0 when all tests pass and non-zero when tests fail. In quiet mode, even errors are suppressed, so only the status remains:
$ gie --quiet utm.gie
$ printf '%s\n' "$?"
0
The manual describes a non-zero status as the number of failed tests. Treat any non-zero result as a failed check in a shell script. Capture it immediately, before running another command:
if gie --quiet tests.gie; then
printf '%s\n' 'PROJ tests passed'
else
status=$?
printf 'PROJ tests failed: %s failed test(s)\n' "$status" >&2
exit "$status"
fi
One operation can have many accept/expect pairs. Each accepted coordinate needs its own expected result. Keep comments and visual separators as plain text, because normal mode ignores lines that do not start with a command:
<gie>
operation +proj=utm +zone=32 +ellps=GRS80
# northern test point
accept 12 55
expect 691875.63214 6098907.82501
# another input, same operation
accept 12 56
expect 687071.4391 6210141.3267
</gie>
If a grid may not be installed on every runner, use require_grid to skip the affected cases when that grid is absent. Use ignore only when a specific PROJ error is genuinely an acceptable outcome. Skipping a test hides coverage, so make that choice visible in the file and in CI reporting.
PROJ 9.4 supports the stricter syntax introduced in 7.1. Wrap commands in <gie-strict> and </gie-strict>. In this mode comments must start with #, unknown commands are errors, and a continued command line must end with a space followed by a backslash:
<gie-strict>
# The backslash continues the operation.
operation proj=hgridshift +grids=example.gsb \
ellps=GRS80
tolerance 1 mm
accept 172.999892181021551 -45.001620431954613
expect 173 -45
</gie-strict>
Replace example.gsb with a real grid before running this example. A strict file catches misspelled commands that normal mode might ignore, but it also requires you to convert decorative separator lines into comments.
gie version where the baseline was created.accept has a matching expect, with the coordinate dimensionality intentional.--quiet is used.