26 #define MULTIPLY_LOOP(x, y, c, m) \
28 for (i = 0; i < c; ++i) { \
34 #define DIVIDE_LOOP(x, y, c, m) \
36 for (i = 0; i < c; ++i) { \
42 static double METERS_in = 1.0, METERS_out = 1.0;
45 #if PROJ_VERSION_MAJOR >= 6
46 int get_pj_area(
const struct pj_info *iproj,
double *xmin,
double *xmax,
47 double *ymin,
double *ymax)
64 const char *projstr =
NULL;
72 if (proj_get_type(iproj->
pj) == PJ_TYPE_BOUND_CRS) {
75 source_crs = proj_get_source_crs(
NULL, iproj->
pj);
78 proj_as_proj_string(
NULL, source_crs, PJ_PROJ_5,
NULL);
82 proj_destroy(source_crs);
86 projstr = proj_as_proj_string(
NULL, iproj->
pj, PJ_PROJ_5,
NULL);
98 G_asprintf(&tproj.
def,
"+proj=pipeline +step +inv %s +over", indef);
99 G_debug(1,
"get_pj_area() tproj.def: %s", tproj.
def);
100 tproj.
pj = proj_create(PJ_DEFAULT_CTX, tproj.
def);
106 proj_destroy(tproj.
pj);
110 projstr = proj_as_proj_string(
NULL, tproj.
pj, PJ_PROJ_5,
NULL);
111 if (projstr ==
NULL) {
115 proj_destroy(tproj.
pj);
120 G_debug(1,
"proj_create() projstr '%s'", projstr);
126 estep = (window.
east - window.
west) / 21.;
128 for (i = 0; i < 20; i++) {
129 x[i] = window.
west + estep * (i + 1);
132 x[i + 20] = window.
west + estep * (i + 1);
133 y[i + 20] = window.
south;
135 x[i + 40] = window.
west;
136 y[i + 40] = window.
south + nstep * (i + 1);
138 x[i + 60] = window.
east;
139 y[i + 60] = window.
south + nstep * (i + 1);
142 y[80] = window.
north;
144 y[81] = window.
south;
146 y[82] = window.
north;
148 y[83] = window.
south;
149 x[84] = (window.
west + window.
east) / 2.;
154 proj_destroy(tproj.
pj);
157 *xmin = *xmax =
x[84];
158 *ymin = *ymax = y[84];
159 for (i = 0; i < 84; i++) {
174 if (*xmin < -180 && *xmax < 180 && *xmin + 360 > *xmax) {
178 else if (*xmax > 180 && *xmin > -180 && *xmax - 360 < *xmin) {
185 G_debug(1,
"input window east: %.8f", window.
east);
186 G_debug(1,
"input window west: %.8f", window.
west);
188 G_debug(1,
"transformed xmin: %.8f", *xmin);
189 G_debug(1,
"transformed xmax: %.8f", *xmax);
190 G_debug(1,
"transformed ymin: %.8f", *ymin);
191 G_debug(1,
"transformed ymax: %.8f", *ymax);
197 if (fabs(*xmin) > 180) {
198 G_warning(
_(
"Invalid west longitude %g"), *xmin);
201 if (fabs(*xmax) > 180) {
202 G_warning(
_(
"Invalid east longitude %g"), *xmax);
205 if (fabs(*ymin) > 90) {
206 G_warning(
_(
"Invalid south latitude %g"), *ymin);
209 if (fabs(*ymax) > 90) {
210 G_warning(
_(
"Invalid north latitude %g"), *ymax);
214 G_warning(
_(
"South %g is larger than north %g"), *ymin, *ymax);
218 G_debug(1,
"get_pj_area(): xmin %g, xmax %g, ymin %g, ymax %g", *xmin,
219 *xmax, *ymin, *ymax);
224 char *get_pj_type_string(PJ *
pj)
226 char *pj_type =
NULL;
228 switch (proj_get_type(
pj)) {
229 case PJ_TYPE_UNKNOWN:
232 case PJ_TYPE_ELLIPSOID:
235 case PJ_TYPE_PRIME_MERIDIAN:
238 case PJ_TYPE_GEODETIC_REFERENCE_FRAME:
239 G_asprintf(&pj_type,
"geodetic reference frame");
241 case PJ_TYPE_DYNAMIC_GEODETIC_REFERENCE_FRAME:
242 G_asprintf(&pj_type,
"dynamic geodetic reference frame");
244 case PJ_TYPE_VERTICAL_REFERENCE_FRAME:
245 G_asprintf(&pj_type,
"vertical reference frame");
247 case PJ_TYPE_DYNAMIC_VERTICAL_REFERENCE_FRAME:
248 G_asprintf(&pj_type,
"dynamic vertical reference frame");
250 case PJ_TYPE_DATUM_ENSEMBLE:
258 case PJ_TYPE_GEODETIC_CRS:
261 case PJ_TYPE_GEOCENTRIC_CRS:
267 case PJ_TYPE_GEOGRAPHIC_CRS:
270 case PJ_TYPE_GEOGRAPHIC_2D_CRS:
273 case PJ_TYPE_GEOGRAPHIC_3D_CRS:
276 case PJ_TYPE_VERTICAL_CRS:
279 case PJ_TYPE_PROJECTED_CRS:
282 case PJ_TYPE_COMPOUND_CRS:
285 case PJ_TYPE_TEMPORAL_CRS:
288 case PJ_TYPE_ENGINEERING_CRS:
291 case PJ_TYPE_BOUND_CRS:
294 case PJ_TYPE_OTHER_CRS:
297 case PJ_TYPE_CONVERSION:
300 case PJ_TYPE_TRANSFORMATION:
303 case PJ_TYPE_CONCATENATED_OPERATION:
304 G_asprintf(&pj_type,
"concatenated operation");
306 case PJ_TYPE_OTHER_COORDINATE_OPERATION:
307 G_asprintf(&pj_type,
"other coordinate operation");
317 PJ *get_pj_object(
const struct pj_info *in_gpj,
char **in_defstr)
326 in_pj = proj_create(PJ_DEFAULT_CTX, in_gpj->
srid);
335 ((
struct pj_info *)in_gpj)->meters = 1;
338 if (!in_pj && in_gpj->
wkt) {
339 G_debug(1,
"Trying WKT '%s' ...", in_gpj->
wkt);
340 in_pj = proj_create(PJ_DEFAULT_CTX, in_gpj->
wkt);
349 ((
struct pj_info *)in_gpj)->meters = 1;
352 if (!in_pj && in_gpj->
pj) {
353 in_pj = proj_clone(PJ_DEFAULT_CTX, in_gpj->
pj);
355 if (*in_defstr && !**in_defstr)
376 if (proj_get_type(in_pj) == PJ_TYPE_BOUND_CRS) {
380 source_crs = proj_get_source_crs(
NULL, in_pj);
384 if (*in_defstr && !**in_defstr)
435 const struct pj_info *info_out,
445 #if PROJ_VERSION_MAJOR >= 6
452 info_trans->
zone = 0;
453 sprintf(info_trans->
proj,
"pipeline");
456 if (info_trans->
def) {
461 if (!info_in->
pj || !info_in->
proj[0] || !info_out->
pj ||
462 !info_out->
proj[0]) {
464 "A custom pipeline requires input and output projection info"));
470 info_trans->
pj = proj_create(PJ_DEFAULT_CTX, info_trans->
def);
471 if (info_trans->
pj ==
NULL) {
472 G_warning(
_(
"proj_create() failed for '%s'"), info_trans->
def);
476 projstr = proj_as_proj_string(
NULL, info_trans->
pj, PJ_PROJ_5,
NULL);
477 if (projstr ==
NULL) {
478 G_warning(
_(
"proj_create() failed for '%s'"), info_trans->
def);
490 if (strstr(info_trans->
def,
"axisswap")) {
492 _(
"The transformation pipeline contains an '%s' step. "
493 "Remove this step if easting and northing are swapped in "
498 G_debug(1,
"proj_create() pipeline: %s", info_trans->
def);
503 ((
struct pj_info *)info_in)->meters = 1;
504 ((
struct pj_info *)info_out)->meters = 1;
509 else if (info_out->
pj ==
NULL) {
510 const char *projstr =
NULL;
515 G_debug(1,
"ll equivalent definition: %s", indef);
520 G_asprintf(&(info_trans->
def),
"+proj=pipeline +step +inv %s", indef);
521 info_trans->
pj = proj_create(PJ_DEFAULT_CTX, info_trans->
def);
522 if (info_trans->
pj ==
NULL) {
523 G_warning(
_(
"proj_create() failed for '%s'"), info_trans->
def);
528 projstr = proj_as_proj_string(
NULL, info_trans->
pj, PJ_PROJ_5,
NULL);
529 if (projstr ==
NULL) {
530 G_warning(
_(
"proj_create() failed for '%s'"), info_trans->
def);
538 else if (info_in->
def && info_out->
pj && info_out->
def) {
540 char *insrid =
NULL, *outsrid =
NULL;
542 PJ_OBJ_LIST *op_list;
543 PJ_OPERATION_FACTORY_CONTEXT *operation_ctx;
544 PJ_AREA *pj_area =
NULL;
545 double xmin, xmax, ymin, ymax;
546 int op_count = 0, op_count_area = 0;
552 if (get_pj_area(info_in, &xmin, &xmax, &ymin, &ymax)) {
553 pj_area = proj_area_create();
554 proj_area_set_bbox(pj_area, xmin, ymin, xmax, ymax);
557 G_warning(
_(
"Unable to determine area of interest for '%s'"),
563 G_debug(1,
"source proj string: %s", info_in->
def);
564 G_debug(1,
"source type: %s", get_pj_type_string(info_in->
pj));
568 if (strncmp(info_in->
srid,
"epsg", 4) == 0) {
571 ((
struct pj_info *)info_in)->srid = insrid;
576 in_pj = get_pj_object(info_in, &indef);
577 if (in_pj ==
NULL || indef ==
NULL) {
578 G_warning(
_(
"Input CRS not available for '%s'"), info_in->
def);
582 G_debug(1,
"Input CRS definition: %s", indef);
584 G_debug(1,
"target proj string: %s", info_out->
def);
585 G_debug(1,
"target type: %s", get_pj_type_string(info_out->
pj));
588 if (info_out->
srid) {
589 if (strncmp(info_out->
srid,
"epsg", 4) == 0) {
592 ((
struct pj_info *)info_out)->srid = outsrid;
597 out_pj = get_pj_object(info_out, &outdef);
598 if (out_pj ==
NULL || outdef ==
NULL) {
599 G_warning(
_(
"Output CRS not available for '%s'"), info_out->
def);
603 G_debug(1,
"Output CRS definition: %s", outdef);
608 proj_create_operation_factory_context(PJ_DEFAULT_CTX,
NULL);
615 op_list = proj_create_operations(PJ_DEFAULT_CTX, in_pj, out_pj,
617 proj_operation_factory_context_destroy(operation_ctx);
621 op_count = proj_list_get_count(op_list);
627 for (i = 0; i < op_count; i++) {
628 const char *area_of_use, *projstr;
633 op = proj_list_get(PJ_DEFAULT_CTX, op_list, i);
634 op_norm = proj_normalize_for_visualization(PJ_DEFAULT_CTX, op);
637 G_warning(
_(
"proj_normalize_for_visualization() failed for "
647 proj_get_area_of_use(
NULL, op, &w, &s, &e, &n, &area_of_use);
663 #if PROJ_VERSION_NUM >= 6020000
664 const char *str = proj_get_remarks(op);
670 str = proj_get_scope(op);
677 projstr = proj_as_proj_string(
NULL, op, PJ_PROJ_5,
NULL);
691 "with the %s option"),
697 proj_list_destroy(op_list);
721 proj_create_operation_factory_context(PJ_DEFAULT_CTX,
NULL);
722 proj_operation_factory_context_set_area_of_interest(
723 PJ_DEFAULT_CTX, operation_ctx, xmin, ymin, xmax, ymax);
724 proj_operation_factory_context_set_spatial_criterion(
725 PJ_DEFAULT_CTX, operation_ctx,
726 PROJ_SPATIAL_CRITERION_PARTIAL_INTERSECTION);
728 proj_operation_factory_context_set_grid_availability_use(
729 PJ_DEFAULT_CTX, operation_ctx,
731 proj_context_is_network_enabled(PJ_DEFAULT_CTX)
732 ? PROJ_GRID_AVAILABILITY_KNOWN_AVAILABLE
735 PROJ_GRID_AVAILABILITY_DISCARD_OPERATION_IF_MISSING_GRID);
745 op_list = proj_create_operations(PJ_DEFAULT_CTX, in_pj, out_pj,
747 proj_operation_factory_context_destroy(operation_ctx);
750 op_count_area = proj_list_get_count(op_list);
751 if (op_count_area == 0) {
755 else if (op_count_area == 1) {
756 info_trans->
pj = proj_list_get(PJ_DEFAULT_CTX, op_list, 0);
762 info_trans->
pj = proj_list_get(PJ_DEFAULT_CTX, op_list, 0);
765 proj_list_destroy(op_list);
791 proj_destroy(out_pj);
793 if (info_trans->
pj) {
797 G_debug(1,
"proj_create_crs_to_crs() succeeded with PROJ%d",
801 proj_as_proj_string(
NULL, info_trans->
pj, PJ_PROJ_5,
NULL);
811 pj_norm = proj_normalize_for_visualization(PJ_DEFAULT_CTX,
816 _(
"proj_normalize_for_visualization() failed for '%s'"),
821 proj_as_proj_string(
NULL, pj_norm, PJ_PROJ_5,
NULL);
822 if (projstr && *projstr) {
823 proj_destroy(info_trans->
pj);
824 info_trans->
pj = pj_norm;
828 proj_destroy(pj_norm);
829 G_warning(
_(
"No PROJ definition for normalized version "
839 proj_destroy(info_trans->
pj);
845 proj_area_destroy(pj_area);
854 if (info_trans->
pj ==
NULL) {
855 G_warning(
_(
"proj_create() failed for '%s'"), info_trans->
def);
862 info_trans->
zone = 0;
863 sprintf(info_trans->
proj,
"pipeline");
866 if (info_trans->
def) {
868 info_trans->
pj = proj_create(PJ_DEFAULT_CTX, info_trans->
def);
869 if (info_trans->
pj ==
NULL) {
870 G_warning(
_(
"proj_create() failed for '%s'"), info_trans->
def);
877 else if (info_out->
pj ==
NULL) {
878 G_asprintf(&(info_trans->
def),
"+proj=pipeline +step +inv %s",
880 info_trans->
pj = proj_create(PJ_DEFAULT_CTX, info_trans->
def);
881 if (info_trans->
pj ==
NULL) {
882 G_warning(
_(
"proj_create() failed for '%s'"), info_trans->
def);
887 else if (info_in->
def && info_out->
pj && info_out->
def) {
889 char *insrid =
NULL, *outsrid =
NULL;
893 if (strncmp(info_in->
srid,
"EPSG", 4) == 0)
899 if (info_out->
pj && info_out->
srid) {
900 if (strncmp(info_out->
srid,
"EPSG", 4) == 0)
908 if (insrid && outsrid) {
913 "+proj=pipeline +step +inv +init=%s +step +init=%s",
918 proj_create_crs_to_crs(PJ_DEFAULT_CTX, indef, outdef,
NULL);
921 if (info_trans->
pj) {
922 G_debug(1,
"proj_create_crs_to_crs() succeeded with PROJ5");
949 "+proj=pipeline +step +inv %s +step %s", indef, outdef);
951 info_trans->
pj = proj_create(PJ_DEFAULT_CTX, info_trans->
def);
960 if (info_trans->
pj ==
NULL) {
961 G_warning(
_(
"proj_create() failed for '%s'"), info_trans->
def);
968 if (info_out->
pj ==
NULL) {
970 G_warning(
_(
"Unable to create latlong equivalent for '%s'"),
1009 const struct pj_info *info_trans,
int dir,
double *
x,
1010 double *y,
double *z)
1016 int in_is_ll, out_is_ll, in_deg2rad, out_rad2deg;
1022 if (info_trans->
pj ==
NULL)
1025 in_deg2rad = out_rad2deg = 1;
1026 if (dir == PJ_FWD) {
1028 METERS_in = info_in->
meters;
1029 in_is_ll = !strncmp(info_in->
proj,
"ll", 2);
1030 #if PROJ_VERSION_MAJOR >= 6
1034 if (in_is_ll && proj_angular_input(info_trans->
pj, dir) == 0) {
1039 METERS_out = info_out->
meters;
1040 out_is_ll = !strncmp(info_out->
proj,
"ll", 2);
1041 #if PROJ_VERSION_MAJOR >= 6
1045 if (out_is_ll && proj_angular_output(info_trans->
pj, dir) == 0) {
1057 METERS_out = info_in->
meters;
1058 out_is_ll = !strncmp(info_in->
proj,
"ll", 2);
1059 #if PROJ_VERSION_MAJOR >= 6
1063 if (out_is_ll && proj_angular_output(info_trans->
pj, dir) == 0) {
1068 METERS_in = info_out->
meters;
1069 in_is_ll = !strncmp(info_out->
proj,
"ll", 2);
1070 #if PROJ_VERSION_MAJOR >= 6
1074 if (in_is_ll && proj_angular_input(info_trans->
pj, dir) == 0) {
1103 c.xyzt.x = *
x * METERS_in;
1104 c.xyzt.y = *y * METERS_in;
1111 G_debug(1,
"c.xyzt.x: %g", c.xyzt.x);
1112 G_debug(1,
"c.xyzt.y: %g", c.xyzt.y);
1113 G_debug(1,
"c.xyzt.z: %g", c.xyzt.z);
1116 c = proj_trans(info_trans->
pj, dir, c);
1117 ok = proj_errno(info_trans->
pj);
1120 G_warning(
_(
"proj_trans() failed: %s"), proj_errno_string(ok));
1141 *
x = c.xyzt.x / METERS_out;
1142 *y = c.xyzt.y / METERS_out;
1150 const struct pj_info *p_in, *p_out;
1152 if (info_out ==
NULL)
1155 if (dir == PJ_FWD) {
1164 METERS_in = p_in->
meters;
1165 METERS_out = p_out->
meters;
1170 if (strncmp(p_in->
proj,
"ll", 2) == 0) {
1179 ok = pj_transform(p_in->
pj, p_out->
pj, 1, 0, &u, &v, &h);
1182 G_warning(
_(
"pj_transform() failed: %s"), pj_strerrno(ok));
1186 if (strncmp(p_out->
proj,
"ll", 2) == 0) {
1191 *
x = u / METERS_out;
1192 *y = v / METERS_out;
1228 const struct pj_info *info_out,
1229 const struct pj_info *info_trans,
int dir,
double *
x,
1230 double *y,
double *z,
int n)
1238 int in_is_ll, out_is_ll, in_deg2rad, out_rad2deg;
1241 if (info_trans->
pj ==
NULL)
1244 in_deg2rad = out_rad2deg = 1;
1245 if (dir == PJ_FWD) {
1247 METERS_in = info_in->
meters;
1248 in_is_ll = !strncmp(info_in->
proj,
"ll", 2);
1249 #if PROJ_VERSION_MAJOR >= 6
1253 if (in_is_ll && proj_angular_input(info_trans->
pj, dir) == 0) {
1258 METERS_out = info_out->
meters;
1259 out_is_ll = !strncmp(info_out->
proj,
"ll", 2);
1260 #if PROJ_VERSION_MAJOR >= 6
1264 if (out_is_ll && proj_angular_output(info_trans->
pj, dir) == 0) {
1276 METERS_out = info_in->
meters;
1277 out_is_ll = !strncmp(info_in->
proj,
"ll", 2);
1278 #if PROJ_VERSION_MAJOR >= 6
1282 if (out_is_ll && proj_angular_output(info_trans->
pj, dir) == 0) {
1287 METERS_in = info_out->
meters;
1288 in_is_ll = !strncmp(info_out->
proj,
"ll", 2);
1289 #if PROJ_VERSION_MAJOR >= 6
1293 if (in_is_ll && proj_angular_input(info_trans->
pj, dir) == 0) {
1307 for (i = 0; i < n; i++)
1322 for (i = 0; i < n; i++) {
1333 c = proj_trans(info_trans->
pj, dir, c);
1334 if ((ok = proj_errno(info_trans->
pj)) < 0)
1348 for (i = 0; i < n; i++) {
1359 c = proj_trans(info_trans->
pj, dir, c);
1360 if ((ok = proj_errno(info_trans->
pj)) < 0)
1364 x[i] = c.xy.x / METERS_out;
1365 y[i] = c.xy.y / METERS_out;
1372 for (i = 0; i < n; i++) {
1374 c.xyzt.x =
x[i] * METERS_in;
1375 c.xyzt.y = y[i] * METERS_in;
1377 c = proj_trans(info_trans->
pj, dir, c);
1378 if ((ok = proj_errno(info_trans->
pj)) < 0)
1392 for (i = 0; i < n; i++) {
1394 c.xyzt.x =
x[i] * METERS_in;
1395 c.xyzt.y = y[i] * METERS_in;
1397 c = proj_trans(info_trans->
pj, dir, c);
1398 if ((ok = proj_errno(info_trans->
pj)) < 0)
1401 x[i] = c.xy.x / METERS_out;
1402 y[i] = c.xy.y / METERS_out;
1410 G_warning(
_(
"proj_trans() failed: %s"), proj_errno_string(ok));
1414 const struct pj_info *p_in, *p_out;
1416 if (dir == PJ_FWD) {
1425 METERS_in = p_in->
meters;
1426 METERS_out = p_out->
meters;
1431 for (i = 0; i < n; ++i)
1435 if (strncmp(p_in->
proj,
"ll", 2) == 0) {
1436 if (strncmp(p_out->
proj,
"ll", 2) == 0) {
1438 ok = pj_transform(info_in->
pj, info_out->
pj, n, 1,
x, y, z);
1443 ok = pj_transform(info_in->
pj, info_out->
pj, n, 1,
x, y, z);
1448 if (strncmp(p_out->
proj,
"ll", 2) == 0) {
1450 ok = pj_transform(info_in->
pj, info_out->
pj, n, 1,
x, y, z);
1455 ok = pj_transform(info_in->
pj, info_out->
pj, n, 1,
x, y, z);
1463 G_warning(
_(
"pj_transform() failed: %s"), pj_strerrno(ok));
1491 const struct pj_info *info_out)
1503 METERS_in = info_in->
meters;
1504 METERS_out = info_out->
meters;
1506 if (strncmp(info_in->
proj,
"ll", 2) == 0) {
1512 c = proj_trans(info_trans.
pj, PJ_FWD, c);
1513 ok = proj_errno(info_trans.
pj);
1515 if (strncmp(info_out->
proj,
"ll", 2) == 0) {
1522 *
x = c.xy.x / METERS_out;
1523 *y = c.xy.y / METERS_out;
1528 c.xyzt.x = *
x * METERS_in;
1529 c.xyzt.y = *y * METERS_in;
1532 c = proj_trans(info_trans.
pj, PJ_FWD, c);
1533 ok = proj_errno(info_trans.
pj);
1535 if (strncmp(info_out->
proj,
"ll", 2) == 0) {
1542 *
x = c.xy.x / METERS_out;
1543 *y = c.xy.y / METERS_out;
1546 proj_destroy(info_trans.
pj);
1555 METERS_in = info_in->
meters;
1556 METERS_out = info_out->
meters;
1558 if (strncmp(info_in->
proj,
"ll", 2) == 0) {
1559 if (strncmp(info_out->
proj,
"ll", 2) == 0) {
1562 ok = pj_transform(info_in->
pj, info_out->
pj, 1, 0, &u, &v, &h);
1569 ok = pj_transform(info_in->
pj, info_out->
pj, 1, 0, &u, &v, &h);
1570 *
x = u / METERS_out;
1571 *y = v / METERS_out;
1575 if (strncmp(info_out->
proj,
"ll", 2) == 0) {
1578 ok = pj_transform(info_in->
pj, info_out->
pj, 1, 0, &u, &v, &h);
1585 ok = pj_transform(info_in->
pj, info_out->
pj, 1, 0, &u, &v, &h);
1586 *
x = u / METERS_out;
1587 *y = v / METERS_out;
1591 G_warning(
_(
"pj_transform() failed: %s"), pj_strerrno(ok));
1621 const struct pj_info *info_in,
1622 const struct pj_info *info_out)
1636 METERS_in = info_in->
meters;
1637 METERS_out = info_out->
meters;
1642 for (i = 0; i <
count; ++i)
1647 if (strncmp(info_in->
proj,
"ll", 2) == 0) {
1649 if (strncmp(info_out->
proj,
"ll", 2) == 0) {
1650 for (i = 0; i <
count; i++) {
1655 c = proj_trans(info_trans.
pj, PJ_FWD, c);
1656 if ((ok = proj_errno(info_trans.
pj)) < 0)
1664 for (i = 0; i <
count; i++) {
1669 c = proj_trans(info_trans.
pj, PJ_FWD, c);
1670 if ((ok = proj_errno(info_trans.
pj)) < 0)
1673 x[i] = c.xy.x / METERS_out;
1674 y[i] = c.xy.y / METERS_out;
1680 if (strncmp(info_out->
proj,
"ll", 2) == 0) {
1681 for (i = 0; i <
count; i++) {
1683 c.xyzt.x =
x[i] * METERS_in;
1684 c.xyzt.y = y[i] * METERS_in;
1686 c = proj_trans(info_trans.
pj, PJ_FWD, c);
1687 if ((ok = proj_errno(info_trans.
pj)) < 0)
1695 for (i = 0; i <
count; i++) {
1697 c.xyzt.x =
x[i] * METERS_in;
1698 c.xyzt.y = y[i] * METERS_in;
1700 c = proj_trans(info_trans.
pj, PJ_FWD, c);
1701 if ((ok = proj_errno(info_trans.
pj)) < 0)
1704 x[i] = c.xy.x / METERS_out;
1705 y[i] = c.xy.y / METERS_out;
1711 proj_destroy(info_trans.
pj);
1717 METERS_in = info_in->
meters;
1718 METERS_out = info_out->
meters;
1723 for (i = 0; i <
count; ++i)
1727 if (strncmp(info_in->
proj,
"ll", 2) == 0) {
1728 if (strncmp(info_out->
proj,
"ll", 2) == 0) {
1730 ok = pj_transform(info_in->
pj, info_out->
pj,
count, 1,
x, y, h);
1735 ok = pj_transform(info_in->
pj, info_out->
pj,
count, 1,
x, y, h);
1740 if (strncmp(info_out->
proj,
"ll", 2) == 0) {
1742 ok = pj_transform(info_in->
pj, info_out->
pj,
count, 1,
x, y, h);
1747 ok = pj_transform(info_in->
pj, info_out->
pj,
count, 1,
x, y, h);
1755 G_warning(
_(
"pj_transform() failed: %s"), pj_strerrno(ok));
void G_free(void *)
Free allocated memory.
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
void G_warning(const char *,...) __attribute__((format(printf
char * G_store_upper(const char *)
Copy string to allocated memory and convert copied string to upper case.
void G_get_set_window(struct Cell_head *)
Get the current working window (region)
char * G_store_lower(const char *)
Copy string to allocated memory and convert copied string to lower case.
void void void G_important_message(const char *,...) __attribute__((format(printf
int G_asprintf(char **, const char *,...) __attribute__((format(printf
int G_debug(int, const char *,...) __attribute__((format(printf
char * G_store(const char *)
Copy string to allocated memory.
int GPJ_get_equivalent_latlong(struct pj_info *, struct pj_info *)
int GPJ_transform(const struct pj_info *info_in, const struct pj_info *info_out, const struct pj_info *info_trans, int dir, double *x, double *y, double *z)
Re-project a point between two co-ordinate systems using a transformation object prepared with GPJ_pr...
int pj_do_proj(double *x, double *y, const struct pj_info *info_in, const struct pj_info *info_out)
Re-project a point between two co-ordinate systems.
int pj_do_transform(int count, double *x, double *y, double *h, const struct pj_info *info_in, const struct pj_info *info_out)
Re-project an array of points between two co-ordinate systems with optional ellipsoidal height conver...
int GPJ_transform_array(const struct pj_info *info_in, const struct pj_info *info_out, const struct pj_info *info_trans, int dir, double *x, double *y, double *z, int n)
Re-project an array of points between two co-ordinate systems using a transformation object prepared ...
#define MULTIPLY_LOOP(x, y, c, m)
int GPJ_init_transform(const struct pj_info *info_in, const struct pj_info *info_out, struct pj_info *info_trans)
Create a PROJ transformation object to transform coordinates from an input SRS to an output SRS.
#define DIVIDE_LOOP(x, y, c, m)
#define PROJECTION_LL
Projection code - Latitude-Longitude.
2D/3D raster map header (used also for region)
double north
Extent coordinates (north)
double east
Extent coordinates (east)
double south
Extent coordinates (south)
double west
Extent coordinates (west)