Quick start¶
This is a short introduction to the PROJ API. In the following section we create a simple program that transforms a geodetic coordinate to UTM and back again. The program is explained a few lines at a time. The complete program can be seen at the end of the section.
See the following sections for more in-depth descriptions of different parts of the PROJ API or consult the API reference for specifics.
Before the PROJ API can be used it is necessary to include the proj.h
header
file. Here stdio.h
is also included so we can print some text to the screen:
#include <stdio.h>
#include <proj.h>
Let’s declare a few variables that’ll be used later in the program. Each variable will be discussed below. See the reference for more info on data types.
PJ_CONTEXT *C;
PJ *P;
PJ_COORD a, b;
For use in multi-threaded programs the PJ_CONTEXT
threading-context is used.
In this particular example it is not needed, but for the sake of completeness
it created here. The section on threads discusses
this in detail.
/* use PJ objects from only one thread */
Next we create the PJ
transformation object P
with the function
proj_create
. proj_create
takes the threading context C
created above,
and a proj-string that defines the desired transformation. Here we transform
from geodetic coordinate to UTM zone 32N.
It is recommended to create one threading-context per thread used by the program.
This ensures that all PJ
objects created in the same context will be sharing
resources such as error-numbers and loaded grids.
In case the creation of the PJ
object fails an error message is displayed and
the program returns. See Error handling for further
details.
P = proj_create (C, "+proj=utm +zone=32 +ellps=GRS80");
if (0==P)
PROJ uses it’s own data structures for handling coordinates. Here we use a
PJ_COORD
which is easily assigned with the function proj_coord
. Note
that the input values are converted to radians with proj_torad
. This is
necessary since PROJ is using radians internally. See Transformations
for further details.
/* note: PROJ.4 works in radians, hence the proj_torad() calls */
The coordinate defined above is transformed with proj_trans_coord
. For this
a PJ
object, a transformation direction (either forward or inverse) and the
coordinate is needed. The transformed coordinate is returned in b
.
Here the forward (PJ_FWD
) transformation from geodetic to UTM is made.
/* transform to UTM zone 32, then back to geographical */
b = proj_trans (P, PJ_FWD, a);
The inverse transformation (UTM to geodetic) is done similar to above,
this time using PJ_INV
as the direction.
printf ("easting: %g, northing: %g\n", b.enu.e, b.enu.n);
b = proj_trans (P, PJ_INV, b);
Before ending the program the allocated memory needs to be released again:
/* Clean up */
proj_destroy (P);
A complete compilable version of the above can be seen here:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | #include <stdio.h>
#include <proj.h>
int main (void) {
PJ_CONTEXT *C;
PJ *P;
PJ_COORD a, b;
/* or you may set C=PJ_DEFAULT_CTX if you are sure you will */
/* use PJ objects from only one thread */
C = proj_context_create();
P = proj_create (C, "+proj=utm +zone=32 +ellps=GRS80");
if (0==P)
return puts ("Oops"), 0;
/* a coordinate union representing Copenhagen: 55d N, 12d E */
/* note: PROJ.4 works in radians, hence the proj_torad() calls */
a = proj_coord (proj_torad(12), proj_torad(55), 0, 0);
/* transform to UTM zone 32, then back to geographical */
b = proj_trans (P, PJ_FWD, a);
printf ("easting: %g, northing: %g\n", b.enu.e, b.enu.n);
b = proj_trans (P, PJ_INV, b);
printf ("longitude: %g, latitude: %g\n", b.lp.lam, b.lp.phi);
/* Clean up */
proj_destroy (P);
proj_context_destroy (C); /* may be omitted in the single threaded case */
return 0;
}
|