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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
/*******************************************************************************
Simple example code demonstrating use of the proj.h API for 2D coordinate
transformations.
The main transformation setup object is PJ, well known from the two
former proj APIs (projects.h and proj_api.h)
The main data objects PJ_COORD and PJ_OBS are new, but encapsulate
the older LP, XY etc. objects in a framework for storing a 3D
observation taken at a 4D point in space-time, and including some
additional metadata (e.g. a serial number or an epsg code).
PJ_OBS and PJ_COORD use unions to enforce explicit statement of what
kind of coordinates are expected at a given spot in the code, where
the old API uses type punning, implicitly assuming that "you know what
you do". For backward compatibility, the new API is not really type
safe in the sense that you cannot use a cartesian coordinate where a
geographic is expected - but it makes it possible to explicitly state
in the code whet the programmer expected and intended.
The proj thread contexts have not seen widespread use, so one of the
intentions with this new API is to make them less visible on the API
surface.
A series of experiments have, however, shown that they, for (mostly)
historical reasons, are very hard to eliminate totally. But we have
reduced their API surface presence to a constructor and a destructor,
plus an extra argument to the PJ constructor, pj_create().
For single threaded programs, the calls to the context constructor
and destructor may be left out, and the default context selected
by passing a null-pointer to pj_create.
Note: This file is in-lined in the documentation. Any changes must be
reflected in docs/source/development/quickstart.rst
Thomas Knudsen, 2016-10-30/2017-07-06
*******************************************************************************/
#include <stdio.h>
#include <proj.h>
int main (void) {
PJ_CONTEXT *C;
PJ *P;
PJ *norm;
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_crs_to_crs (C,
"EPSG:4326",
"+proj=utm +zone=32 +datum=WGS84", /* or EPSG:32632 */
NULL);
if (0 == P) {
fprintf(stderr, "Failed to create transformation object.\n");
return 1;
}
/* This will ensure that the order of coordinates for the input CRS */
/* will be longitude, latitude, whereas EPSG:4326 mandates latitude, */
/* longitude */
norm = proj_normalize_for_visualization(C, P);
if (0 == norm) {
fprintf(stderr, "Failed to normalize transformation object.\n");
return 1;
}
proj_destroy(P);
P = norm;
/* a coordinate union representing Copenhagen: 55d N, 12d E */
/* Given that we have used proj_normalize_for_visualization(), the order of
/* coordinates is longitude, latitude, and values are expressed in degrees. */
a = proj_coord(12, 55, 0, 0);
/* transform to UTM zone 32, then back to geographical */
b = proj_trans(P, PJ_FWD, a);
printf("easting: %.3f, northing: %.3f\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;
}
|