快速启动¶
这是对projapi的简短介绍。在下一节中,我们将创建一个简单的程序,将大地坐标转换为UTM,然后再转换回来。这个程序一次解释几行。完整的程序可以在本节末尾看到。
有关项目的详细信息,请参阅API的以下部分 API reference 具体情况。
在可以使用Proj API之前,必须包含 proj.h
头文件。这里 stdio.h
也包括在内,以便我们可以将一些文本打印到屏幕上:
#include <stdio.h>
#include <proj.h>
让我们声明几个变量,稍后将在程序中使用。下面将讨论每个变量。看到了吗 reference for more info on data types .
PJ_CONTEXT *C;
PJ *P;
PJ *norm;
PJ_COORD a, b;
为了在多线程程序中使用 PJ_CONTEXT
线程-使用上下文。在这个特定的例子中,它不是必需的,但是为了完整起见,我们在这里演示了它的用法。
C = proj_context_create();
接下来,我们创建 PJ
变换对象 P
使用函数 proj_create_crs_to_crs()
。
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;
}
在这里,我们建立了从地理坐标到UTM区域32N的转换。
proj_create_crs_to_crs()
以以下内容为论据:
线程上下文
C
上面创建的,描述源坐标参考系(CRS)的字符串,
描述目标CRS的字符串和
使用区域的可选描述。
建议为程序使用的每个线程创建一个线程上下文。这确保了所有 PJ
在相同上下文中创建的对象将共享资源,如错误号和加载的栅格。
如果你确定 P
将仅由单个程序线程使用,您可以传递 NULL
用于线程上下文。这会将默认线程上下文分配给 P
。
源和目标CR的字符串可以是以下任意一个:
投影字符串,例如
+proj=longlat +datum=WGS84 +type=crs
,由他们的代码标识的CR,例如
EPSG:4326
或urn:ogc:def:crs:EPSG::4326
,或熟知文本(WKT)字符串,例如:
GEOGCRS["WGS 84",
DATUM["World Geodetic System 1984",
ELLIPSOID["WGS 84",6378137,298.257223563,
LENGTHUNIT["metre",1]]],
PRIMEM["Greenwich",0,
ANGLEUNIT["degree",0.0174532925199433]],
CS[ellipsoidal,2],
AXIS["geodetic latitude (Lat)",north,
ORDER[1],
ANGLEUNIT["degree",0.0174532925199433]],
AXIS["geodetic longitude (Lon)",east,
ORDER[2],
ANGLEUNIT["degree",0.0174532925199433]],
USAGE[
SCOPE["unknown"],
AREA["World"],
BBOX[-90,-180,90,180]],
ID["EPSG",4326]]
警告
不建议使用Proj字符串来描述CRS。Proj字符串的主要缺点之一是它们无法描述大地基准面,除了在 +datum
参数。
proj_create_crs_to_crs()
将返回一个指向 PJ
对象,或者在出错的情况下为空指针。可以使用以下命令检索错误的详细信息 proj_context_errno()
。看见 错误处理 了解更多详细信息。
现在我们在中有了标准化的转换对象 P
,我们可以将其与 proj_trans()
将坐标从源CRS转换到目标CRS,但首先我们将讨论坐标的解释。
默认情况下,一个 PJ
转换对象接受以源CRS的单位和轴顺序表示的坐标,并返回以目标CRS的单位和轴顺序表示的转换后的坐标。
对于大多数地理CRS,单位将以度为单位。在极少数情况下,例如EPSG:4807/NTF(巴黎),这可能是梯度。对于EPSG当局定义的地理CRS,坐标的顺序是纬度第一,经度第二。当使用投影字符串时,顺序是相反的;经度第一,纬度第二。
对于投影的CRS,单位可能有所不同(米、美英尺等)。对于EPSG授权机构定义的投影CR,对于东/北方向,顺序可能是先向东、后向北或相反。使用投影字符串时,顺序将是先向东,然后向北,除非 +axis
参数会对其进行修改。
如果您希望使用统一的轴顺序,而不考虑源和目标CRS要求的轴顺序,则可以使用 proj_normalize_for_visualization()
功能。
proj_normalize_for_visualization()
获取线程上下文和现有的 PJ
对象,并从它生成一个新的 PJ
它接受作为输入,并使用传统的地理信息系统顺序返回作为输出坐标。也就是说,经度后跟纬度,对于地理CRS,可以选择后跟海拔和时间,对于大多数投影的CRS,可以选择东经和北纬。
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;
接下来,我们创建一个 PJ_COORD
坐标对象,使用函数 proj_coord()
。
下例创建了北纬55°12°E(哥本哈根)的坐标。
因为我们已经将转换对象标准化为 proj_normalize_for_visualization()
,坐标的顺序是经度后跟纬度,单位是度。
a = proj_coord(12, 55, 0, 0);
现在,我们可以使用函数将坐标转换为UTM区域32 proj_trans()
。
b = proj_trans(P, PJ_FWD, a);
printf("easting: %.3f, northing: %.3f\n", b.enu.e, b.enu.n);
proj_trans()
以以下内容为论据:
一个
PJ
变换对象,一个
PJ_DIRECTION
方向,以及这个
PJ_COORD
要变换的坐标。
方向参数可以是以下参数之一:
PJ_FWD
--从源CRS到目标CRS的前向转换。PJ_IDENT
--“Identity”,原样返回源坐标。PJ_INV
--目标CRS到源CRS的逆转换。
它返回新转换的 PJ_COORD
协调。
我们可以反向执行转换(从UTM区域32返回到地理区域),如下所示:
b = proj_trans(P, PJ_INV, b);
printf("longitude: %g, latitude: %g\n", b.lp.lam, b.lp.phi);
在结束程序之前,我们需要释放分配给对象的内存:
proj_destroy(P);
proj_context_destroy(C); /* may be omitted in the single threaded case */
示例代码的完整可编译版本如下所示:
1#include <stdio.h>
2#include <proj.h>
3
4int main (void) {
5 PJ_CONTEXT *C;
6 PJ *P;
7 PJ *norm;
8 PJ_COORD a, b;
9
10 /* or you may set C=PJ_DEFAULT_CTX if you are sure you will */
11 /* use PJ objects from only one thread */
12 C = proj_context_create();
13
14 P = proj_create_crs_to_crs (C,
15 "EPSG:4326",
16 "+proj=utm +zone=32 +datum=WGS84", /* or EPSG:32632 */
17 NULL);
18
19 if (0 == P) {
20 fprintf(stderr, "Failed to create transformation object.\n");
21 return 1;
22 }
23
24 /* This will ensure that the order of coordinates for the input CRS */
25 /* will be longitude, latitude, whereas EPSG:4326 mandates latitude, */
26 /* longitude */
27 norm = proj_normalize_for_visualization(C, P);
28 if (0 == norm) {
29 fprintf(stderr, "Failed to normalize transformation object.\n");
30 return 1;
31 }
32 proj_destroy(P);
33 P = norm;
34
35 /* a coordinate union representing Copenhagen: 55d N, 12d E */
36 /* Given that we have used proj_normalize_for_visualization(), the order of
37 /* coordinates is longitude, latitude, and values are expressed in degrees. */
38 a = proj_coord(12, 55, 0, 0);
39
40 /* transform to UTM zone 32, then back to geographical */
41 b = proj_trans(P, PJ_FWD, a);
42 printf("easting: %.3f, northing: %.3f\n", b.enu.e, b.enu.n);
43
44 b = proj_trans(P, PJ_INV, b);
45 printf("longitude: %g, latitude: %g\n", b.lp.lam, b.lp.phi);
46
47 /* Clean up */
48 proj_destroy(P);
49 proj_context_destroy(C); /* may be omitted in the single threaded case */
50 return 0;
51}