21 #include <grass/gis.h>
22 #include <grass/gprojects.h>
23 #include <grass/glocale.h>
27 #ifdef PROJ_VERSION_NUM
28 #undef PROJ_VERSION_NUM
30 #define PROJ_VERSION_NUM ((PROJ_VERSION_MAJOR)*1000000+(PROJ_VERSION_MINOR)*10000+(PROJ_VERSION_PATCH)*100)
34 #define MULTIPLY_LOOP(x,y,c,m) \
36 for (i = 0; i < c; ++i) {\
42 #define DIVIDE_LOOP(x,y,c,m) \
44 for (i = 0; i < c; ++i) {\
50 static double METERS_in = 1.0, METERS_out = 1.0;
53 #if PROJ_VERSION_MAJOR >= 6
54 int get_pj_area(
double *xmin,
double *xmax,
double *ymin,
double *ymax)
56 struct Cell_head window;
65 if (window.proj != PROJECTION_LL) {
70 const char *projstr =
NULL;
73 struct Key_Value *in_proj_info, *in_unit_info;
74 struct pj_info iproj, oproj, tproj;
79 G_warning(_(
"Can't get projection info of current location"));
85 G_warning(_(
"Can't get projection units of current location"));
90 if (
pj_get_kv(&iproj, in_proj_info, in_unit_info) < 0) {
91 G_fatal_error(_(
"Can't get projection key values of current location"));
102 source_crs = proj_get_source_crs(
NULL, iproj.pj);
104 projstr = proj_as_proj_string(
NULL, source_crs, PJ_PROJ_5,
NULL);
108 proj_destroy(iproj.pj);
109 iproj.pj = source_crs;
116 G_asprintf(&tproj.def,
"+proj=pipeline +step +inv %s",
118 tproj.pj = proj_create(PJ_DEFAULT_CTX, tproj.def);
119 if (tproj.pj ==
NULL) {
120 G_warning(_(
"proj_create() failed for '%s'"), tproj.def);
123 proj_destroy(tproj.pj);
127 projstr = proj_as_proj_string(
NULL, tproj.pj, PJ_PROJ_5,
NULL);
128 if (projstr ==
NULL) {
129 G_warning(_(
"proj_create() failed for '%s'"), tproj.def);
132 proj_destroy(tproj.pj);
138 estep = (window.west + window.east) / 21.;
139 nstep = (window.north + window.south) / 21.;
140 for (i = 0; i < 20; i++) {
141 x[i] = window.west + estep * (i + 1);
144 x[i + 20] = window.west + estep * (i + 1);
145 y[i + 20] = window.south;
147 x[i + 40] = window.west;
148 y[i + 40] = window.south + nstep * (i + 1);
150 x[i + 60] = window.east;
151 y[i + 60] = window.south + nstep * (i + 1);
154 y[80] = window.north;
156 y[81] = window.south;
158 y[82] = window.north;
160 y[83] = window.south;
161 x[84] = (window.west + window.east) / 2.;
162 y[84] = (window.north + window.south) / 2.;
166 proj_destroy(tproj.pj);
168 *xmin = *xmax =
x[84];
169 *ymin = *ymax = y[84];
170 for (i = 0; i < 84; i++) {
181 G_debug(1,
"get_pj_area(): xmin %g, xmax %g, ymin %g, ymax %g",
182 *xmin, *xmax, *ymin, *ymax);
187 char *get_pj_type_string(PJ *pj)
189 char *pj_type =
NULL;
191 switch (proj_get_type(pj)) {
192 case PJ_TYPE_UNKNOWN:
195 case PJ_TYPE_ELLIPSOID:
198 case PJ_TYPE_PRIME_MERIDIAN:
201 case PJ_TYPE_GEODETIC_REFERENCE_FRAME:
202 G_asprintf(&pj_type,
"geodetic reference frame");
204 case PJ_TYPE_DYNAMIC_GEODETIC_REFERENCE_FRAME:
205 G_asprintf(&pj_type,
"dynamic geodetic reference frame");
207 case PJ_TYPE_VERTICAL_REFERENCE_FRAME:
208 G_asprintf(&pj_type,
"vertical reference frame");
210 case PJ_TYPE_DYNAMIC_VERTICAL_REFERENCE_FRAME:
211 G_asprintf(&pj_type,
"dynamic vertical reference frame");
213 case PJ_TYPE_DATUM_ENSEMBLE:
220 case PJ_TYPE_GEODETIC_CRS:
223 case PJ_TYPE_GEOCENTRIC_CRS:
228 case PJ_TYPE_GEOGRAPHIC_CRS:
231 case PJ_TYPE_GEOGRAPHIC_2D_CRS:
234 case PJ_TYPE_GEOGRAPHIC_3D_CRS:
237 case PJ_TYPE_VERTICAL_CRS:
240 case PJ_TYPE_PROJECTED_CRS:
243 case PJ_TYPE_COMPOUND_CRS:
246 case PJ_TYPE_TEMPORAL_CRS:
249 case PJ_TYPE_ENGINEERING_CRS:
252 case PJ_TYPE_BOUND_CRS:
255 case PJ_TYPE_OTHER_CRS:
258 case PJ_TYPE_CONVERSION:
261 case PJ_TYPE_TRANSFORMATION:
264 case PJ_TYPE_CONCATENATED_OPERATION:
265 G_asprintf(&pj_type,
"concatenated operation");
267 case PJ_TYPE_OTHER_COORDINATE_OPERATION:
268 G_asprintf(&pj_type,
"other coordinate operation");
316 const struct pj_info *info_out,
317 struct pj_info *info_trans)
319 if (info_in->pj ==
NULL)
322 if (info_in->def ==
NULL)
323 G_fatal_error(_(
"Input coordinate system definition is NULL"));
326 #if PROJ_VERSION_MAJOR >= 6
331 info_trans->pj =
NULL;
332 info_trans->meters = 1.;
333 info_trans->zone = 0;
334 sprintf(info_trans->proj,
"pipeline");
337 if (info_trans->def) {
341 info_trans->pj = proj_create(PJ_DEFAULT_CTX, info_trans->def);
342 if (info_trans->pj ==
NULL) {
343 G_warning(_(
"proj_create() failed for '%s'"), info_trans->def);
347 projstr = proj_as_proj_string(
NULL, info_trans->pj, PJ_PROJ_5,
NULL);
348 if (projstr ==
NULL) {
349 G_warning(_(
"proj_create() failed for '%s'"), info_trans->def);
359 info_trans->def =
G_store(projstr);
361 if (strstr(info_trans->def,
"axisswap")) {
362 G_warning(_(
"The transformation pipeline contains an '%s' step. "
363 "Remove this step if easting and northing are swapped in the output."),
367 G_debug(1,
"proj_create() pipeline: %s", info_trans->def);
372 ((
struct pj_info *)info_in)->meters = 1;
373 ((
struct pj_info *)info_out)->meters = 1;
378 else if (info_out->pj ==
NULL) {
379 const char *projstr =
NULL;
393 if (proj_get_type(info_in->pj) == PJ_TYPE_BOUND_CRS) {
396 G_debug(1,
"transform to ll equivalent: found bound crs");
397 source_crs = proj_get_source_crs(
NULL, info_in->pj);
399 projstr = proj_as_proj_string(
NULL, source_crs, PJ_PROJ_5,
NULL);
402 proj_destroy(source_crs);
407 G_debug(1,
"ll equivalent definition: %s", indef);
412 G_asprintf(&(info_trans->def),
"+proj=pipeline +step +inv %s",
414 info_trans->pj = proj_create(PJ_DEFAULT_CTX, info_trans->def);
415 if (info_trans->pj ==
NULL) {
416 G_warning(_(
"proj_create() failed for '%s'"), info_trans->def);
421 projstr = proj_as_proj_string(
NULL, info_trans->pj, PJ_PROJ_5,
NULL);
422 if (projstr ==
NULL) {
423 G_warning(_(
"proj_create() failed for '%s'"), info_trans->def);
431 else if (info_in->def && info_out->pj && info_out->def) {
433 char *indefcrs =
NULL, *outdefcrs =
NULL;
434 char *insrid =
NULL, *outsrid =
NULL;
435 int use_insrid = 0, use_outsrid = 0;
436 PJ *source_crs, *target_crs;
437 PJ_AREA *pj_area =
NULL;
438 double xmin, xmax, ymin, ymax;
443 G_debug(1,
"source proj string: %s", info_in->def);
444 G_debug(1,
"source type: %s", get_pj_type_string(info_in->pj));
445 indefcrs = info_in->def;
447 if (proj_get_type(info_in->pj) == PJ_TYPE_BOUND_CRS) {
448 source_crs = proj_get_source_crs(
NULL, info_in->pj);
452 projstr = proj_as_proj_string(
NULL, source_crs, PJ_PROJ_5,
NULL);
455 G_message(
"Input CRS definition converted from '%s' to '%s'",
456 info_in->def, indefcrs);
458 proj_destroy(source_crs);
463 G_debug(1,
"target proj string: %s", info_out->def);
464 G_debug(1,
"target type: %s", get_pj_type_string(info_out->pj));
465 outdefcrs = info_out->def;
467 if (proj_get_type(info_out->pj) == PJ_TYPE_BOUND_CRS) {
468 target_crs = proj_get_source_crs(
NULL, info_out->pj);
472 projstr = proj_as_proj_string(
NULL, target_crs, PJ_PROJ_5,
NULL);
475 G_message(
"Output CRS definition converted from '%s' to '%s'",
476 info_out->def, outdefcrs);
478 proj_destroy(target_crs);
485 if (strncmp(info_in->srid,
"epsg", 4) == 0)
488 insrid =
G_store(info_in->srid);
491 if (info_out->srid) {
492 if (strncmp(info_out->srid,
"epsg", 4) == 0)
495 outsrid =
G_store(info_out->srid);
505 G_debug(1,
"Input CRS definition: %s", indef);
514 G_debug(1,
"Output CRS definition: %s", outdef);
517 source_crs = proj_create(
NULL, indef);
518 target_crs = proj_create(
NULL, outdef);
521 if (get_pj_area(&xmin, &xmax, &ymin, &ymax)) {
522 pj_area = proj_area_create();
523 proj_area_set_bbox(pj_area, xmin, ymin, xmax, ymax);
526 if (source_crs && target_crs) {
527 PJ_OPERATION_FACTORY_CONTEXT *operation_ctx;
528 PJ_OBJ_LIST *op_list;
530 operation_ctx = proj_create_operation_factory_context(
NULL,
NULL);
536 op_list = proj_create_operations(
NULL,
543 op_count = proj_list_get_count(op_list);
547 G_warning(_(
"Found %d possible transformations"), op_count);
548 for (i = 0; i < op_count; i++) {
550 const char *area_of_use, *projstr;
552 PJ_PROJ_INFO pj_info;
555 op = proj_list_get(
NULL, op_list, i);
556 op_norm = proj_normalize_for_visualization(PJ_DEFAULT_CTX, op);
559 G_warning(_(
"proj_normalize_for_visualization() failed for operation %d"),
567 projstr = proj_as_proj_string(
NULL, op,
569 pj_info = proj_pj_info(op);
570 proj_get_area_of_use(
NULL, op, &w, &s, &e, &n, &area_of_use);
575 pj_info.description);
579 if (pj_info.accuracy > 0) {
584 #if PROJ_VERSION_NUM >= 6020000
585 str = proj_get_remarks(op);
590 str = proj_get_scope(op);
613 proj_list_destroy(op_list);
614 proj_operation_factory_context_destroy(operation_ctx);
617 proj_destroy(source_crs);
619 proj_destroy(target_crs);
622 G_debug(1,
"trying %s to %s", indef, outdef);
624 info_trans->pj = proj_create_crs_to_crs(PJ_DEFAULT_CTX,
629 if (info_trans->pj) {
630 const char *projstr =
NULL;
632 projstr = proj_as_proj_string(
NULL, info_trans->pj,
634 if (projstr ==
NULL) {
635 G_debug(1,
"proj_create_crs_to_crs() failed with PROJ%d for input \"%s\", output \"%s\"",
636 PROJ_VERSION_MAJOR, indef, outdef);
641 G_debug(1,
"trying %s to %s", indef, outdef);
644 proj_destroy(info_trans->pj);
645 info_trans->pj =
NULL;
646 info_trans->pj = proj_create_crs_to_crs(PJ_DEFAULT_CTX,
656 ((
struct pj_info *)info_in)->meters = 1;
659 ((
struct pj_info *)info_out)->meters = 1;
664 if (info_trans->pj) {
668 G_debug(1,
"proj_create_crs_to_crs() succeeded with PROJ%d",
671 projstr = proj_as_proj_string(
NULL, info_trans->pj,
674 info_trans->def =
G_store(projstr);
682 pj_norm = proj_normalize_for_visualization(PJ_DEFAULT_CTX, info_trans->pj);
685 G_warning(_(
"proj_normalize_for_visualization() failed for '%s'"),
689 projstr = proj_as_proj_string(
NULL, pj_norm,
691 if (projstr && *projstr) {
692 proj_destroy(info_trans->pj);
693 info_trans->pj = pj_norm;
694 info_trans->def =
G_store(projstr);
697 proj_destroy(pj_norm);
698 G_warning(_(
"No PROJ definition for normalized version of '%s'"),
708 G_debug(1,
"proj_create_crs_to_crs() pipeline: %s", info_trans->def);
711 proj_destroy(info_trans->pj);
712 info_trans->pj =
NULL;
716 if (info_trans->pj ==
NULL) {
717 G_debug(1,
"proj_create_crs_to_crs() failed with PROJ%d for input \"%s\", output \"%s\"",
718 PROJ_VERSION_MAJOR, indef, outdef);
720 G_warning(
"GPJ_init_transform(): falling back to proj_create()");
731 G_asprintf(&(info_trans->def),
"+proj=pipeline +step +inv %s +step %s",
736 info_trans->pj = proj_create(PJ_DEFAULT_CTX, info_trans->def);
737 G_debug(1,
"proj_create() pipeline: %s", info_trans->def);
741 proj_area_destroy(pj_area);
750 if (info_trans->pj ==
NULL) {
751 G_warning(_(
"proj_create() failed for '%s'"), info_trans->def);
756 info_trans->pj =
NULL;
757 info_trans->meters = 1.;
758 info_trans->zone = 0;
759 sprintf(info_trans->proj,
"pipeline");
762 if (info_trans->def) {
764 info_trans->pj = proj_create(PJ_DEFAULT_CTX, info_trans->def);
765 if (info_trans->pj ==
NULL) {
766 G_warning(_(
"proj_create() failed for '%s'"), info_trans->def);
773 else if (info_out->pj ==
NULL) {
774 G_asprintf(&(info_trans->def),
"+proj=pipeline +step +inv %s",
776 info_trans->pj = proj_create(PJ_DEFAULT_CTX, info_trans->def);
777 if (info_trans->pj ==
NULL) {
778 G_warning(_(
"proj_create() failed for '%s'"), info_trans->def);
783 else if (info_in->def && info_out->pj && info_out->def) {
785 char *insrid =
NULL, *outsrid =
NULL;
789 if (strncmp(info_in->srid,
"EPSG", 4) == 0)
792 insrid =
G_store(info_in->srid);
795 if (info_out->pj && info_out->srid) {
796 if (strncmp(info_out->srid,
"EPSG", 4) == 0)
799 outsrid =
G_store(info_out->srid);
802 info_trans->pj =
NULL;
804 if (insrid && outsrid) {
808 G_asprintf(&(info_trans->def),
"+proj=pipeline +step +inv +init=%s +step +init=%s",
812 info_trans->pj = proj_create_crs_to_crs(PJ_DEFAULT_CTX,
818 if (info_trans->pj) {
819 G_debug(1,
"proj_create_crs_to_crs() succeeded with PROJ5");
845 G_asprintf(&(info_trans->def),
"+proj=pipeline +step +inv %s +step %s",
848 info_trans->pj = proj_create(PJ_DEFAULT_CTX, info_trans->def);
857 if (info_trans->pj ==
NULL) {
858 G_warning(_(
"proj_create() failed for '%s'"), info_trans->def);
865 if (info_out->pj ==
NULL) {
867 G_warning(_(
"Unable to create latlong equivalent for '%s'"),
906 const struct pj_info *info_out,
907 const struct pj_info *info_trans,
int dir,
908 double *
x,
double *y,
double *z)
914 int in_is_ll, out_is_ll, in_deg2rad, out_rad2deg;
917 if (info_in->pj ==
NULL)
920 if (info_trans->pj ==
NULL)
923 in_deg2rad = out_rad2deg = 1;
926 METERS_in = info_in->meters;
927 in_is_ll = !strncmp(info_in->proj,
"ll", 2);
928 #if PROJ_VERSION_MAJOR >= 6
932 if (in_is_ll && proj_angular_input(info_trans->pj, dir) == 0) {
937 METERS_out = info_out->meters;
938 out_is_ll = !strncmp(info_out->proj,
"ll", 2);
939 #if PROJ_VERSION_MAJOR >= 6
943 if (out_is_ll && proj_angular_output(info_trans->pj, dir) == 0) {
955 METERS_out = info_in->meters;
956 out_is_ll = !strncmp(info_in->proj,
"ll", 2);
957 #if PROJ_VERSION_MAJOR >= 6
961 if (out_is_ll && proj_angular_output(info_trans->pj, dir) == 0) {
966 METERS_in = info_out->meters;
967 in_is_ll = !strncmp(info_out->proj,
"ll", 2);
968 #if PROJ_VERSION_MAJOR >= 6
972 if (in_is_ll && proj_angular_input(info_trans->pj, dir) == 0) {
987 c.lpzt.lam = (*x) / RAD_TO_DEG;
988 c.lpzt.phi = (*y) / RAD_TO_DEG;
1001 c.xyzt.x = *
x * METERS_in;
1002 c.xyzt.y = *y * METERS_in;
1010 c = proj_trans(info_trans->pj, dir, c);
1011 ok = proj_errno(info_trans->pj);
1014 G_warning(_(
"proj_trans() failed: %s"), proj_errno_string(ok));
1023 *
x = c.lp.lam * RAD_TO_DEG;
1024 *y = c.lp.phi * RAD_TO_DEG;
1035 *
x = c.xyzt.x / METERS_out;
1036 *y = c.xyzt.y / METERS_out;
1044 const struct pj_info *p_in, *p_out;
1046 if (info_out ==
NULL)
1049 if (dir == PJ_FWD) {
1058 METERS_in = p_in->meters;
1059 METERS_out = p_out->meters;
1064 if (strncmp(p_in->proj,
"ll", 2) == 0) {
1065 u = (*x) / RAD_TO_DEG;
1066 v = (*y) / RAD_TO_DEG;
1073 ok = pj_transform(p_in->pj, p_out->pj, 1, 0, &u, &v, &h);
1076 G_warning(_(
"pj_transform() failed: %s"), pj_strerrno(ok));
1080 if (strncmp(p_out->proj,
"ll", 2) == 0) {
1081 *
x = u * RAD_TO_DEG;
1082 *y = v * RAD_TO_DEG;
1085 *
x = u / METERS_out;
1086 *y = v / METERS_out;
1122 const struct pj_info *info_out,
1123 const struct pj_info *info_trans,
int dir,
1124 double *
x,
double *y,
double *z,
int n)
1132 int in_is_ll, out_is_ll, in_deg2rad, out_rad2deg;
1135 if (info_trans->pj ==
NULL)
1138 in_deg2rad = out_rad2deg = 1;
1139 if (dir == PJ_FWD) {
1141 METERS_in = info_in->meters;
1142 in_is_ll = !strncmp(info_in->proj,
"ll", 2);
1143 #if PROJ_VERSION_MAJOR >= 6
1147 if (in_is_ll && proj_angular_input(info_trans->pj, dir) == 0) {
1152 METERS_out = info_out->meters;
1153 out_is_ll = !strncmp(info_out->proj,
"ll", 2);
1154 #if PROJ_VERSION_MAJOR >= 6
1158 if (out_is_ll && proj_angular_output(info_trans->pj, dir) == 0) {
1170 METERS_out = info_in->meters;
1171 out_is_ll = !strncmp(info_in->proj,
"ll", 2);
1172 #if PROJ_VERSION_MAJOR >= 6
1176 if (out_is_ll && proj_angular_output(info_trans->pj, dir) == 0) {
1181 METERS_in = info_out->meters;
1182 in_is_ll = !strncmp(info_out->proj,
"ll", 2);
1183 #if PROJ_VERSION_MAJOR >= 6
1187 if (in_is_ll && proj_angular_input(info_trans->pj, dir) == 0) {
1199 z = G_malloc(
sizeof(
double) * n);
1201 for (i = 0; i < n; i++)
1216 for (i = 0; i < n; i++) {
1219 c.lpzt.lam = (*x) / RAD_TO_DEG;
1220 c.lpzt.phi = (*y) / RAD_TO_DEG;
1227 c = proj_trans(info_trans->pj, dir, c);
1228 if ((ok = proj_errno(info_trans->pj)) < 0)
1232 x[i] = c.lp.lam * RAD_TO_DEG;
1233 y[i] = c.lp.phi * RAD_TO_DEG;
1242 for (i = 0; i < n; i++) {
1245 c.lpzt.lam = (*x) / RAD_TO_DEG;
1246 c.lpzt.phi = (*y) / RAD_TO_DEG;
1253 c = proj_trans(info_trans->pj, dir, c);
1254 if ((ok = proj_errno(info_trans->pj)) < 0)
1258 x[i] = c.xy.x / METERS_out;
1259 y[i] = c.xy.y / METERS_out;
1266 for (i = 0; i < n; i++) {
1268 c.xyzt.x =
x[i] * METERS_in;
1269 c.xyzt.y = y[i] * METERS_in;
1271 c = proj_trans(info_trans->pj, dir, c);
1272 if ((ok = proj_errno(info_trans->pj)) < 0)
1276 x[i] = c.lp.lam * RAD_TO_DEG;
1277 y[i] = c.lp.phi * RAD_TO_DEG;
1286 for (i = 0; i < n; i++) {
1288 c.xyzt.x =
x[i] * METERS_in;
1289 c.xyzt.y = y[i] * METERS_in;
1291 c = proj_trans(info_trans->pj, dir, c);
1292 if ((ok = proj_errno(info_trans->pj)) < 0)
1295 x[i] = c.xy.x / METERS_out;
1296 y[i] = c.xy.y / METERS_out;
1304 G_warning(_(
"proj_trans() failed: %s"), proj_errno_string(ok));
1308 const struct pj_info *p_in, *p_out;
1310 if (dir == PJ_FWD) {
1319 METERS_in = p_in->meters;
1320 METERS_out = p_out->meters;
1323 z = G_malloc(
sizeof(
double) * n);
1325 for (i = 0; i < n; ++i)
1329 if (strncmp(p_in->proj,
"ll", 2) == 0) {
1330 if (strncmp(p_out->proj,
"ll", 2) == 0) {
1332 ok = pj_transform(info_in->pj, info_out->pj, n, 1,
x, y, z);
1337 ok = pj_transform(info_in->pj, info_out->pj, n, 1,
x, y, z);
1342 if (strncmp(p_out->proj,
"ll", 2) == 0) {
1344 ok = pj_transform(info_in->pj, info_out->pj, n, 1,
x, y, z);
1349 ok = pj_transform(info_in->pj, info_out->pj, n, 1,
x, y, z);
1357 G_warning(_(
"pj_transform() failed: %s"), pj_strerrno(ok));
1385 const struct pj_info *info_in,
const struct pj_info *info_out)
1389 struct pj_info info_trans;
1396 METERS_in = info_in->meters;
1397 METERS_out = info_out->meters;
1399 if (strncmp(info_in->proj,
"ll", 2) == 0) {
1401 c.lpzt.lam = (*x) / RAD_TO_DEG;
1402 c.lpzt.phi = (*y) / RAD_TO_DEG;
1405 c = proj_trans(info_trans.pj, PJ_FWD, c);
1406 ok = proj_errno(info_trans.pj);
1408 if (strncmp(info_out->proj,
"ll", 2) == 0) {
1410 *
x = c.lp.lam * RAD_TO_DEG;
1411 *y = c.lp.phi * RAD_TO_DEG;
1415 *
x = c.xy.x / METERS_out;
1416 *y = c.xy.y / METERS_out;
1421 c.xyzt.x = *
x * METERS_in;
1422 c.xyzt.y = *y * METERS_in;
1425 c = proj_trans(info_trans.pj, PJ_FWD, c);
1426 ok = proj_errno(info_trans.pj);
1428 if (strncmp(info_out->proj,
"ll", 2) == 0) {
1430 *
x = c.lp.lam * RAD_TO_DEG;
1431 *y = c.lp.phi * RAD_TO_DEG;
1435 *
x = c.xy.x / METERS_out;
1436 *y = c.xy.y / METERS_out;
1439 proj_destroy(info_trans.pj);
1442 G_warning(_(
"proj_trans() failed: %d"), ok);
1448 METERS_in = info_in->meters;
1449 METERS_out = info_out->meters;
1451 if (strncmp(info_in->proj,
"ll", 2) == 0) {
1452 if (strncmp(info_out->proj,
"ll", 2) == 0) {
1453 u = (*x) / RAD_TO_DEG;
1454 v = (*y) / RAD_TO_DEG;
1455 ok = pj_transform(info_in->pj, info_out->pj, 1, 0, &u, &v, &h);
1456 *
x = u * RAD_TO_DEG;
1457 *y = v * RAD_TO_DEG;
1460 u = (*x) / RAD_TO_DEG;
1461 v = (*y) / RAD_TO_DEG;
1462 ok = pj_transform(info_in->pj, info_out->pj, 1, 0, &u, &v, &h);
1463 *
x = u / METERS_out;
1464 *y = v / METERS_out;
1468 if (strncmp(info_out->proj,
"ll", 2) == 0) {
1471 ok = pj_transform(info_in->pj, info_out->pj, 1, 0, &u, &v, &h);
1472 *
x = u * RAD_TO_DEG;
1473 *y = v * RAD_TO_DEG;
1478 ok = pj_transform(info_in->pj, info_out->pj, 1, 0, &u, &v, &h);
1479 *
x = u / METERS_out;
1480 *y = v / METERS_out;
1484 G_warning(_(
"pj_transform() failed: %s"), pj_strerrno(ok));
1514 const struct pj_info *info_in,
const struct pj_info *info_out)
1520 struct pj_info info_trans;
1527 METERS_in = info_in->meters;
1528 METERS_out = info_out->meters;
1531 h = G_malloc(
sizeof *h *
count);
1533 for (i = 0; i <
count; ++i)
1538 if (strncmp(info_in->proj,
"ll", 2) == 0) {
1540 if (strncmp(info_out->proj,
"ll", 2) == 0) {
1541 for (i = 0; i <
count; i++) {
1543 c.lpzt.lam =
x[i] / RAD_TO_DEG;
1544 c.lpzt.phi = y[i] / RAD_TO_DEG;
1546 c = proj_trans(info_trans.pj, PJ_FWD, c);
1547 if ((ok = proj_errno(info_trans.pj)) < 0)
1550 x[i] = c.lp.lam * RAD_TO_DEG;
1551 y[i] = c.lp.phi * RAD_TO_DEG;
1555 for (i = 0; i <
count; i++) {
1557 c.lpzt.lam =
x[i] / RAD_TO_DEG;
1558 c.lpzt.phi = y[i] / RAD_TO_DEG;
1560 c = proj_trans(info_trans.pj, PJ_FWD, c);
1561 if ((ok = proj_errno(info_trans.pj)) < 0)
1564 x[i] = c.xy.x / METERS_out;
1565 y[i] = c.xy.y / METERS_out;
1571 if (strncmp(info_out->proj,
"ll", 2) == 0) {
1572 for (i = 0; i <
count; i++) {
1574 c.xyzt.x =
x[i] * METERS_in;
1575 c.xyzt.y = y[i] * METERS_in;
1577 c = proj_trans(info_trans.pj, PJ_FWD, c);
1578 if ((ok = proj_errno(info_trans.pj)) < 0)
1581 x[i] = c.lp.lam * RAD_TO_DEG;
1582 y[i] = c.lp.phi * RAD_TO_DEG;
1586 for (i = 0; i <
count; i++) {
1588 c.xyzt.x =
x[i] * METERS_in;
1589 c.xyzt.y = y[i] * METERS_in;
1591 c = proj_trans(info_trans.pj, PJ_FWD, c);
1592 if ((ok = proj_errno(info_trans.pj)) < 0)
1595 x[i] = c.xy.x / METERS_out;
1596 y[i] = c.xy.y / METERS_out;
1602 proj_destroy(info_trans.pj);
1605 G_warning(_(
"proj_trans() failed: %d"), ok);
1608 METERS_in = info_in->meters;
1609 METERS_out = info_out->meters;
1612 h = G_malloc(
sizeof *h *
count);
1614 for (i = 0; i <
count; ++i)
1618 if (strncmp(info_in->proj,
"ll", 2) == 0) {
1619 if (strncmp(info_out->proj,
"ll", 2) == 0) {
1621 ok = pj_transform(info_in->pj, info_out->pj,
count, 1,
x, y, h);
1626 ok = pj_transform(info_in->pj, info_out->pj,
count, 1,
x, y, h);
1631 if (strncmp(info_out->proj,
"ll", 2) == 0) {
1633 ok = pj_transform(info_in->pj, info_out->pj,
count, 1,
x, y, h);
1638 ok = pj_transform(info_in->pj, info_out->pj,
count, 1,
x, y, h);
1646 G_warning(_(
"pj_transform() failed: %s"), pj_strerrno(ok));