Home / Alt manpages / proj(1)

  • proj(1)
  • User command
  • linux

Project Coordinates Safely with PROJ's proj Command

Feed proj a coordinate pair in the wrong order and it stays quiet, handing back numbers that look plausible and are wrong. This guide gets you converting longitude and latitude to projected x and y, reversing the conversion, and checking the result before it goes anywhere near a script or a data pipeline. The examples use the proj-bin package version 9.4.0 installed on Ubuntu, with the command-line interface documented by the local PROJ 9.4 manpage. Allow about 10 minutes if PROJ is already installed.

Before you start

You need a shell, the proj command, and coordinates whose reference system you actually understand, not just recognise. Check the installation and version first:

command -v proj
proj --version
dpkg-query -W -f='${Package} ${Version}\n' proj-bin

On this system the relevant output is Rel. 9.4.0, March 1st, 2024 and proj-bin 9.4.0-1build2. Your distribution may package a different release, so keep the local manpage nearby when behaviour differs.

Checkpoint

Continue only when proj resolves to the intended installation. No example in this guide needs elevated privileges.

1. Choose the conversion and coordinate order

proj performs a forward conversion from geographic longitude and latitude to cartesian projected coordinates. The ordinary ASCII input format is two whitespace-separated values in the first two fields. Extra fields get copied straight through to the output, as long as both input and output are ASCII.

For a forward conversion, write longitude first and latitude second. This point is longitude 0 degrees, latitude 51 degrees, passed to UTM zone 30 on the WGS84 ellipsoid:

printf '%s\n' '0 51' | proj +proj=utm +zone=30 +ellps=WGS84

The output is:

710488.86    5654109.18

First value: easting. Second: northing. The default forward format prints two decimal places, and those numbers are in metres because the ellipsoid and projection parameters here use metre-based units.

The +proj and other +opt arguments describe the cartographic operation. You can also hand the local manpage a projected CRS identifier instead, which is often easier to audit when you already know the EPSG code:

printf '%s\n' '0 51' | proj EPSG:32630 -f '%.3f'

That produces 710488.857 5654109.179: the same result, just three decimal places instead of two. EPSG:32630 is WGS84 / UTM zone 30N. Do not swap a known source or target CRS for a convenient-looking code. The projection will run and print numbers happily either way; only one set of numbers is right for your data.

2. Make precision and input visible

Use -f with a printf-style format when a stable number of decimal places matters:

printf '%s\n' '0 51' | proj +proj=utm +zone=30 +ellps=WGS84 -f '%.3f'

For a quick audit, -E copies the input coordinates before the converted values, and -d 2 rounds the output to two decimal places:

printf '%s\n' '0 51' | proj +proj=utm +zone=30 +ellps=WGS84 -E -d 2
0 51    710488.86    5654109.18

That is worth doing on anything piped through a stream, because each output row keeps an obvious link back to its input. -d has been around since version 5.2.0. None of this formatting touches the internal coordinate calculation, only what you see.

Checkpoint

Compare one known point by hand or against a trusted GIS tool. Confirm that input order, hemisphere, zone, ellipsoid and output units all match your data specification.

3. Reverse a projected coordinate

Use -I for the inverse operation, feeding it the projected x and y values under the same projection definition:

printf '%s\n' '710488.857 5654109.179' | proj -I +proj=utm +zone=30 +ellps=WGS84 -f '%.6f'

The result is:

-0.000000    51.000000

Inverse output is longitude then latitude. Normally the manpage formats that as degrees, minutes and seconds; -f is what asks for decimal degrees instead. There is also a separate invproj command, an alias-style interface to the same inverse mode:

printf '%s\n' '710488.857 5654109.179' | invproj +proj=utm +zone=30 +ellps=WGS84 -f '%.6f'

No invproj on your platform? Use proj -I instead. Either way, keep the projection parameters identical between the two directions. A different zone or ellipsoid can still spit out a plausible-looking longitude and latitude, which is exactly what makes the error easy to miss.

4. Handle latitude-first input deliberately

Some files store latitude before longitude. -r reverses the expected input order, so use it only when the file format actually says the first field is latitude:

printf '%s\n' '51 0' | proj +proj=utm +zone=30 +ellps=WGS84 -r -f '%.3f'

That should match the earlier forward conversion, formatting aside. -s is a different switch: it reverses the output order instead of the input. The two are easy to mix up: -r changes how input is read, -s changes how output is written. Prefer explicit field names in a pipeline, and test both a northern and a southern point when the source format is not under your control.

5. Inspect a result without changing data

For a detailed diagnostic, -V prints an annotated listing and implies -v. It is a genuinely useful check on the projection parameters, ellipsoid, input interpretation and scale information:

printf '%s\n' '-120 35.8' | proj EPSG:6421 -V

The local manpage's own example identifies EPSG:6421 as NAD83(2011) / California zone 4 and shows the selected Lambert Conformal Conic parameters, ellipsoid details, projected coordinates and distortion measures. Treat this as a diagnostic record, not a stable machine-readable format. For a short inventory of available projection names, use:

proj -l=merc

That lists the Mercator projection identifier and its defining parameters. -lp, -lP, -le and -lu list projection identifiers, expanded projection descriptions, ellipsoids and distance units respectively.

Common traps and recovery

  • Wrong order. Longitude and latitude are expected by default. Use -r only for a latitude-first source, and -s only when the output consumer needs reversed fields.
  • Wrong reference system. proj only does geographic and projected conversion within one datum. Reach for cs2cs when you need a transformation between different coordinate reference systems, including datum translation.
  • Unexpected text. Lines starting with # are control lines by default and can pass through without processing. Use -t if your input uses a different control-line character.
  • Silent-looking bad data. Use -E, -V, a known test point and explicit formatting before you process a large file. Redirect output to a new file until the sample checks out, so the original stays recoverable.
  • Failed conversion. The default error marker is an asterisk followed by a tab, which is easy to miss in a wall of numbers. Use -e 'ERROR' when a downstream script needs a recognisable string, and check the exit status too.

Done means

  • You identified the installed PROJ version and confirmed which proj binary you are using.
  • You converted a known longitude and latitude with an explicit projection and ellipsoid.
  • You reversed the result with the same parameters and got the original point back.
  • You checked coordinate order, units, precision and output before touching a larger file.
  • You know when to reach for cs2cs instead of proj for datum or CRS-to-CRS work.