22 #include "mosaic_util.h"
23 #include "create_xgrid.h"
29 #define AREA_RATIO_THRESH (1.e-6)
30 #define MASK_THRESH (0.5)
31 #define EPSLN8 (1.e-8)
32 #define EPSLN30 (1.0e-30)
33 #define EPSLN10 (1.0e-10)
34 #define R2D (180/M_PI)
35 #define TPI (2.0*M_PI)
46 int get_maxxgrid(
void)
51 int get_maxxgrid_(
void)
53 return get_maxxgrid();
61 void get_grid_area_(
const int *
nlon,
const int *
nlat,
const double *lon,
const double *lat,
double *
area)
66 void get_grid_area(
const int *
nlon,
const int *
nlat,
const double *lon,
const double *lat,
double *
area)
68 int nx, ny, nxp, i, j, n_in;
69 double x_in[20], y_in[20];
75 for(j=0; j<ny; j++)
for(i=0; i < nx; i++) {
76 x_in[0] = lon[j*nxp+i];
77 x_in[1] = lon[j*nxp+i+1];
78 x_in[2] = lon[(j+1)*nxp+i+1];
79 x_in[3] = lon[(j+1)*nxp+i];
80 y_in[0] = lat[j*nxp+i];
81 y_in[1] = lat[j*nxp+i+1];
82 y_in[2] = lat[(j+1)*nxp+i+1];
83 y_in[3] = lat[(j+1)*nxp+i];
84 n_in = fix_lon(x_in, y_in, 4, M_PI);
85 area[j*nx+i] = poly_area(x_in, y_in, n_in);
95 void get_grid_area_ug_(
const int *npts,
const double *lon,
const double *lat,
double *
area)
97 get_grid_area_ug(npts, lon, lat,
area);
100 void get_grid_area_ug(
const int *npts,
const double *lon,
const double *lat,
double *
area)
103 double x_in[20], y_in[20];
108 for(l=0; l<nl; l++) {
110 x_in[1] = lon[l*nv+1];
111 x_in[2] = lon[l*nv+2];
112 x_in[3] = lon[l*nv+3];
114 y_in[1] = lat[l*nv+1];
115 y_in[2] = lat[l*nv+2];
116 y_in[3] = lat[l*nv+3];
117 n_in = fix_lon(x_in, y_in, nv, M_PI);
118 area[l] = poly_area(x_in, y_in, n_in);
124 void get_grid_great_circle_area_(
const int *
nlon,
const int *
nlat,
const double *lon,
const double *lat,
double *
area)
130 void get_grid_great_circle_area(
const int *
nlon,
const int *
nlat,
const double *lon,
const double *lat,
double *
area)
132 int nx, ny, nxp, nyp, i, j;
134 struct Node *grid=NULL;
135 double *x=NULL, *y=NULL, *z=NULL;
143 x = (
double *)malloc(nxp*nyp*
sizeof(
double));
144 y = (
double *)malloc(nxp*nyp*
sizeof(
double));
145 z = (
double *)malloc(nxp*nyp*
sizeof(
double));
149 for(j=0; j<ny; j++)
for(i=0; i < nx; i++) {
157 addEnd(grid, x[n0], y[n0], z[n0], 0, 0, 0, -1);
158 addEnd(grid, x[n1], y[n1], z[n1], 0, 0, 0, -1);
159 addEnd(grid, x[n2], y[n2], z[n2], 0, 0, 0, -1);
160 addEnd(grid, x[n3], y[n3], z[n3], 0, 0, 0, -1);
161 area[j*nx+i] = gridArea(grid);
170 void get_grid_great_circle_area_ug_(
const int *npts,
const double *lon,
const double *lat,
double *
area)
172 get_grid_great_circle_area_ug(npts, lon, lat,
area);
176 void get_grid_great_circle_area_ug(
const int *npts,
const double *lon,
const double *lat,
double *
area)
180 struct Node *grid=NULL;
181 double *x=NULL, *y=NULL, *z=NULL;
186 x = (
double *)malloc(nl*nv*
sizeof(
double));
187 y = (
double *)malloc(nl*nv*
sizeof(
double));
188 z = (
double *)malloc(nl*nv*
sizeof(
double));
192 for(l=0; l<nv; l++) {
200 addEnd(grid, x[n0], y[n0], z[n0], 0, 0, 0, -1);
201 addEnd(grid, x[n1], y[n1], z[n1], 0, 0, 0, -1);
202 addEnd(grid, x[n2], y[n2], z[n2], 0, 0, 0, -1);
203 addEnd(grid, x[n3], y[n3], z[n3], 0, 0, 0, -1);
204 area[l] = gridArea(grid);
213 void get_grid_area_dimensionless(
const int *
nlon,
const int *
nlat,
const double *lon,
const double *lat,
double *
area)
215 int nx, ny, nxp, i, j, n_in;
216 double x_in[20], y_in[20];
222 for(j=0; j<ny; j++)
for(i=0; i < nx; i++) {
223 x_in[0] = lon[j*nxp+i];
224 x_in[1] = lon[j*nxp+i+1];
225 x_in[2] = lon[(j+1)*nxp+i+1];
226 x_in[3] = lon[(j+1)*nxp+i];
227 y_in[0] = lat[j*nxp+i];
228 y_in[1] = lat[j*nxp+i+1];
229 y_in[2] = lat[(j+1)*nxp+i+1];
230 y_in[3] = lat[(j+1)*nxp+i];
231 n_in = fix_lon(x_in, y_in, 4, M_PI);
232 area[j*nx+i] = poly_area_dimensionless(x_in, y_in, n_in);
239 void get_grid_area_no_adjust(
const int *
nlon,
const int *
nlat,
const double *lon,
const double *lat,
double *
area)
241 int nx, ny, nxp, i, j, n_in;
242 double x_in[20], y_in[20];
248 for(j=0; j<ny; j++)
for(i=0; i < nx; i++) {
249 x_in[0] = lon[j*nxp+i];
250 x_in[1] = lon[j*nxp+i+1];
251 x_in[2] = lon[(j+1)*nxp+i+1];
252 x_in[3] = lon[(j+1)*nxp+i];
253 y_in[0] = lat[j*nxp+i];
254 y_in[1] = lat[j*nxp+i+1];
255 y_in[2] = lat[(j+1)*nxp+i+1];
256 y_in[3] = lat[(j+1)*nxp+i];
258 area[j*nx+i] = poly_area_no_adjust(x_in, y_in, n_in);
269 int create_xgrid_1dx2d_order1_(
const int *nlon_in,
const int *nlat_in,
const int *nlon_out,
const int *nlat_out,
270 const double *lon_in,
const double *lat_in,
const double *lon_out,
const double *lat_out,
271 const double *mask_in,
int *i_in,
int *j_in,
int *i_out,
int *j_out,
double *xgrid_area)
275 nxgrid = create_xgrid_1dx2d_order1(nlon_in, nlat_in, nlon_out, nlat_out, lon_in, lat_in, lon_out, lat_out, mask_in,
276 i_in, j_in, i_out, j_out, xgrid_area);
281 int create_xgrid_1dx2d_order1(
const int *nlon_in,
const int *nlat_in,
const int *nlon_out,
const int *nlat_out,
const double *lon_in,
282 const double *lat_in,
const double *lon_out,
const double *lat_out,
283 const double *mask_in,
int *i_in,
int *j_in,
int *i_out,
284 int *j_out,
double *xgrid_area)
287 int nx1, ny1, nx2, ny2, nx1p, nx2p;
288 int i1, j1, i2, j2, nxgrid;
289 double ll_lon, ll_lat, ur_lon, ur_lat, x_in[MV], y_in[MV], x_out[MV], y_out[MV];
290 double *area_in, *area_out, min_area;
302 area_in = (
double *)malloc(nx1*ny1*
sizeof(
double));
303 area_out = (
double *)malloc(nx2*ny2*
sizeof(
double));
304 tmpx = (
double *)malloc((nx1+1)*(ny1+1)*
sizeof(
double));
305 tmpy = (
double *)malloc((nx1+1)*(ny1+1)*
sizeof(
double));
306 for(j1=0; j1<=ny1; j1++)
for(i1=0; i1<=nx1; i1++) {
307 tmpx[j1*nx1p+i1] = lon_in[i1];
308 tmpy[j1*nx1p+i1] = lat_in[j1];
312 get_grid_area(nlon_in, nlat_in, tmpx, tmpy, area_in);
314 get_grid_area_no_adjust(nlon_in, nlat_in, tmpx, tmpy, area_in);
316 get_grid_area(nlon_out, nlat_out, lon_out, lat_out, area_out);
320 for(j1=0; j1<ny1; j1++)
for(i1=0; i1<nx1; i1++)
if( mask_in[j1*nx1+i1] > MASK_THRESH ) {
322 ll_lon = lon_in[i1]; ll_lat = lat_in[j1];
323 ur_lon = lon_in[i1+1]; ur_lat = lat_in[j1+1];
324 for(j2=0; j2<ny2; j2++)
for(i2=0; i2<nx2; i2++) {
328 y_in[0] = lat_out[j2*nx2p+i2];
329 y_in[1] = lat_out[j2*nx2p+i2+1];
330 y_in[2] = lat_out[(j2+1)*nx2p+i2+1];
331 y_in[3] = lat_out[(j2+1)*nx2p+i2];
332 if ( (y_in[0]<=ll_lat) && (y_in[1]<=ll_lat)
333 && (y_in[2]<=ll_lat) && (y_in[3]<=ll_lat) )
continue;
334 if ( (y_in[0]>=ur_lat) && (y_in[1]>=ur_lat)
335 && (y_in[2]>=ur_lat) && (y_in[3]>=ur_lat) )
continue;
337 x_in[0] = lon_out[j2*nx2p+i2];
338 x_in[1] = lon_out[j2*nx2p+i2+1];
339 x_in[2] = lon_out[(j2+1)*nx2p+i2+1];
340 x_in[3] = lon_out[(j2+1)*nx2p+i2];
341 n_in = fix_lon(x_in, y_in, 4, (ll_lon+ur_lon)/2);
343 if ( (n_out = clip ( x_in, y_in, n_in, ll_lon, ll_lat, ur_lon, ur_lat, x_out, y_out )) > 0 ) {
344 Xarea = poly_area (x_out, y_out, n_out ) * mask_in[j1*nx1+i1];
345 min_area = min(area_in[j1*nx1+i1], area_out[j2*nx2+i2]);
346 if( Xarea/min_area > AREA_RATIO_THRESH ) {
347 xgrid_area[nxgrid] = Xarea;
353 if(nxgrid > MAXXGRID) error_handler(
"nxgrid is greater than MAXXGRID, increase MAXXGRID");
373 int create_xgrid_1dx2d_order1_ug_(
const int *nlon_in,
const int *nlat_in,
const int *npts_out,
374 const double *lon_in,
const double *lat_in,
const double *lon_out,
const double *lat_out,
375 const double *mask_in,
int *i_in,
int *j_in,
int *l_out,
double *xgrid_area)
379 nxgrid = create_xgrid_1dx2d_order1_ug(nlon_in, nlat_in, npts_out, lon_in, lat_in, lon_out, lat_out, mask_in,
380 i_in, j_in, l_out, xgrid_area);
385 int create_xgrid_1dx2d_order1_ug(
const int *nlon_in,
const int *nlat_in,
const int *npts_out,
const double *lon_in,
386 const double *lat_in,
const double *lon_out,
const double *lat_out,
387 const double *mask_in,
int *i_in,
int *j_in,
int *l_out,
double *xgrid_area)
390 int nx1, ny1, nx1p, nv, npts2;
391 int i1, j1, l2, nxgrid;
392 double ll_lon, ll_lat, ur_lon, ur_lat, x_in[MV], y_in[MV], x_out[MV], y_out[MV];
393 double *area_in, *area_out, min_area;
404 area_in = (
double *)malloc(nx1*ny1*
sizeof(
double));
405 area_out = (
double *)malloc(npts2*
sizeof(
double));
406 tmpx = (
double *)malloc((nx1+1)*(ny1+1)*
sizeof(
double));
407 tmpy = (
double *)malloc((nx1+1)*(ny1+1)*
sizeof(
double));
408 for(j1=0; j1<=ny1; j1++)
for(i1=0; i1<=nx1; i1++) {
409 tmpx[j1*nx1p+i1] = lon_in[i1];
410 tmpy[j1*nx1p+i1] = lat_in[j1];
414 get_grid_area(nlon_in, nlat_in, tmpx, tmpy, area_in);
416 get_grid_area_no_adjust(nlon_in, nlat_in, tmpx, tmpy, area_in);
418 get_grid_area_ug(npts_out, lon_out, lat_out, area_out);
422 for(j1=0; j1<ny1; j1++)
for(i1=0; i1<nx1; i1++)
if( mask_in[j1*nx1+i1] > MASK_THRESH ) {
424 ll_lon = lon_in[i1]; ll_lat = lat_in[j1];
425 ur_lon = lon_in[i1+1]; ur_lat = lat_in[j1+1];
426 for(l2=0; l2<npts2; l2++) {
430 y_in[0] = lat_out[l2*nv];
431 y_in[1] = lat_out[l2*nv+1];
432 y_in[2] = lat_out[l2*nv+2];
433 y_in[3] = lat_out[l2*nv+3];
434 if ( (y_in[0]<=ll_lat) && (y_in[1]<=ll_lat)
435 && (y_in[2]<=ll_lat) && (y_in[3]<=ll_lat) )
continue;
436 if ( (y_in[0]>=ur_lat) && (y_in[1]>=ur_lat)
437 && (y_in[2]>=ur_lat) && (y_in[3]>=ur_lat) )
continue;
439 x_in[0] = lon_out[l2*nv];
440 x_in[1] = lon_out[l2*nv+1];
441 x_in[2] = lon_out[l2*nv+2];
442 x_in[3] = lon_out[l2*nv+3];
443 n_in = fix_lon(x_in, y_in, 4, (ll_lon+ur_lon)/2);
445 if ( (n_out = clip ( x_in, y_in, n_in, ll_lon, ll_lat, ur_lon, ur_lat, x_out, y_out )) > 0 ) {
446 Xarea = poly_area (x_out, y_out, n_out ) * mask_in[j1*nx1+i1];
447 min_area = min(area_in[j1*nx1+i1], area_out[l2]);
448 if( Xarea/min_area > AREA_RATIO_THRESH ) {
449 xgrid_area[nxgrid] = Xarea;
454 if(nxgrid > MAXXGRID) error_handler(
"nxgrid is greater than MAXXGRID, increase MAXXGRID");
473 int create_xgrid_1dx2d_order2_(
const int *nlon_in,
const int *nlat_in,
const int *nlon_out,
const int *nlat_out,
474 const double *lon_in,
const double *lat_in,
const double *lon_out,
const double *lat_out,
475 const double *mask_in,
int *i_in,
int *j_in,
int *i_out,
int *j_out,
476 double *xgrid_area,
double *xgrid_clon,
double *xgrid_clat)
479 nxgrid = create_xgrid_1dx2d_order2(nlon_in, nlat_in, nlon_out, nlat_out, lon_in, lat_in, lon_out, lat_out, mask_in, i_in,
480 j_in, i_out, j_out, xgrid_area, xgrid_clon, xgrid_clat);
484 int create_xgrid_1dx2d_order2(
const int *nlon_in,
const int *nlat_in,
const int *nlon_out,
const int *nlat_out,
485 const double *lon_in,
const double *lat_in,
const double *lon_out,
const double *lat_out,
486 const double *mask_in,
int *i_in,
int *j_in,
int *i_out,
int *j_out,
487 double *xgrid_area,
double *xgrid_clon,
double *xgrid_clat)
490 int nx1, ny1, nx2, ny2, nx1p, nx2p;
491 int i1, j1, i2, j2, nxgrid;
492 double ll_lon, ll_lat, ur_lon, ur_lat, x_in[MV], y_in[MV], x_out[MV], y_out[MV];
493 double *area_in, *area_out, min_area;
505 area_in = (
double *)malloc(nx1*ny1*
sizeof(
double));
506 area_out = (
double *)malloc(nx2*ny2*
sizeof(
double));
507 tmpx = (
double *)malloc((nx1+1)*(ny1+1)*
sizeof(
double));
508 tmpy = (
double *)malloc((nx1+1)*(ny1+1)*
sizeof(
double));
509 for(j1=0; j1<=ny1; j1++)
for(i1=0; i1<=nx1; i1++) {
510 tmpx[j1*nx1p+i1] = lon_in[i1];
511 tmpy[j1*nx1p+i1] = lat_in[j1];
513 get_grid_area(nlon_in, nlat_in, tmpx, tmpy, area_in);
514 get_grid_area(nlon_out, nlat_out, lon_out, lat_out, area_out);
518 for(j1=0; j1<ny1; j1++)
for(i1=0; i1<nx1; i1++)
if( mask_in[j1*nx1+i1] > MASK_THRESH ) {
520 ll_lon = lon_in[i1]; ll_lat = lat_in[j1];
521 ur_lon = lon_in[i1+1]; ur_lat = lat_in[j1+1];
522 for(j2=0; j2<ny2; j2++)
for(i2=0; i2<nx2; i2++) {
524 double xarea, lon_in_avg;
526 y_in[0] = lat_out[j2*nx2p+i2];
527 y_in[1] = lat_out[j2*nx2p+i2+1];
528 y_in[2] = lat_out[(j2+1)*nx2p+i2+1];
529 y_in[3] = lat_out[(j2+1)*nx2p+i2];
530 if ( (y_in[0]<=ll_lat) && (y_in[1]<=ll_lat)
531 && (y_in[2]<=ll_lat) && (y_in[3]<=ll_lat) )
continue;
532 if ( (y_in[0]>=ur_lat) && (y_in[1]>=ur_lat)
533 && (y_in[2]>=ur_lat) && (y_in[3]>=ur_lat) )
continue;
535 x_in[0] = lon_out[j2*nx2p+i2];
536 x_in[1] = lon_out[j2*nx2p+i2+1];
537 x_in[2] = lon_out[(j2+1)*nx2p+i2+1];
538 x_in[3] = lon_out[(j2+1)*nx2p+i2];
539 n_in = fix_lon(x_in, y_in, 4, (ll_lon+ur_lon)/2);
540 lon_in_avg = avgval_double(n_in, x_in);
542 if ( (n_out = clip ( x_in, y_in, n_in, ll_lon, ll_lat, ur_lon, ur_lat, x_out, y_out )) > 0 ) {
543 xarea = poly_area (x_out, y_out, n_out ) * mask_in[j1*nx1+i1];
544 min_area = min(area_in[j1*nx1+i1], area_out[j2*nx2+i2]);
545 if(xarea/min_area > AREA_RATIO_THRESH ) {
546 xgrid_area[nxgrid] = xarea;
547 xgrid_clon[nxgrid] = poly_ctrlon(x_out, y_out, n_out, lon_in_avg);
548 xgrid_clat[nxgrid] = poly_ctrlat (x_out, y_out, n_out );
554 if(nxgrid > MAXXGRID) error_handler(
"nxgrid is greater than MAXXGRID, increase MAXXGRID");
573 int create_xgrid_2dx1d_order1_(
const int *nlon_in,
const int *nlat_in,
const int *nlon_out,
const int *nlat_out,
574 const double *lon_in,
const double *lat_in,
const double *lon_out,
const double *lat_out,
575 const double *mask_in,
int *i_in,
int *j_in,
int *i_out,
576 int *j_out,
double *xgrid_area)
580 nxgrid = create_xgrid_2dx1d_order1(nlon_in, nlat_in, nlon_out, nlat_out, lon_in, lat_in, lon_out, lat_out, mask_in,
581 i_in, j_in, i_out, j_out, xgrid_area);
585 int create_xgrid_2dx1d_order1(
const int *nlon_in,
const int *nlat_in,
const int *nlon_out,
const int *nlat_out,
const double *lon_in,
586 const double *lat_in,
const double *lon_out,
const double *lat_out,
587 const double *mask_in,
int *i_in,
int *j_in,
int *i_out,
588 int *j_out,
double *xgrid_area)
591 int nx1, ny1, nx2, ny2, nx1p, nx2p;
592 int i1, j1, i2, j2, nxgrid;
593 double ll_lon, ll_lat, ur_lon, ur_lat, x_in[MV], y_in[MV], x_out[MV], y_out[MV];
594 double *area_in, *area_out, min_area;
608 area_in = (
double *)malloc(nx1*ny1*
sizeof(
double));
609 area_out = (
double *)malloc(nx2*ny2*
sizeof(
double));
610 tmpx = (
double *)malloc((nx2+1)*(ny2+1)*
sizeof(
double));
611 tmpy = (
double *)malloc((nx2+1)*(ny2+1)*
sizeof(
double));
612 for(j2=0; j2<=ny2; j2++)
for(i2=0; i2<=nx2; i2++) {
613 tmpx[j2*nx2p+i2] = lon_out[i2];
614 tmpy[j2*nx2p+i2] = lat_out[j2];
616 get_grid_area(nlon_in, nlat_in, lon_in, lat_in, area_in);
617 get_grid_area(nlon_out, nlat_out, tmpx, tmpy, area_out);
622 for(j2=0; j2<ny2; j2++)
for(i2=0; i2<nx2; i2++) {
624 ll_lon = lon_out[i2]; ll_lat = lat_out[j2];
625 ur_lon = lon_out[i2+1]; ur_lat = lat_out[j2+1];
626 for(j1=0; j1<ny1; j1++)
for(i1=0; i1<nx1; i1++)
if( mask_in[j1*nx1+i1] > MASK_THRESH ) {
628 y_in[0] = lat_in[j1*nx1p+i1];
629 y_in[1] = lat_in[j1*nx1p+i1+1];
630 y_in[2] = lat_in[(j1+1)*nx1p+i1+1];
631 y_in[3] = lat_in[(j1+1)*nx1p+i1];
632 if ( (y_in[0]<=ll_lat) && (y_in[1]<=ll_lat)
633 && (y_in[2]<=ll_lat) && (y_in[3]<=ll_lat) )
continue;
634 if ( (y_in[0]>=ur_lat) && (y_in[1]>=ur_lat)
635 && (y_in[2]>=ur_lat) && (y_in[3]>=ur_lat) )
continue;
637 x_in[0] = lon_in[j1*nx1p+i1];
638 x_in[1] = lon_in[j1*nx1p+i1+1];
639 x_in[2] = lon_in[(j1+1)*nx1p+i1+1];
640 x_in[3] = lon_in[(j1+1)*nx1p+i1];
642 n_in = fix_lon(x_in, y_in, 4, (ll_lon+ur_lon)/2);
644 if ( (n_out = clip ( x_in, y_in, n_in, ll_lon, ll_lat, ur_lon, ur_lat, x_out, y_out )) > 0 ) {
645 Xarea = poly_area ( x_out, y_out, n_out ) * mask_in[j1*nx1+i1];
646 min_area = min(area_in[j1*nx1+i1], area_out[j2*nx2+i2]);
647 if( Xarea/min_area > AREA_RATIO_THRESH ) {
648 xgrid_area[nxgrid] = Xarea;
654 if(nxgrid > MAXXGRID) error_handler(
"nxgrid is greater than MAXXGRID, increase MAXXGRID");
675 int create_xgrid_2dx1d_order2_(
const int *nlon_in,
const int *nlat_in,
const int *nlon_out,
const int *nlat_out,
676 const double *lon_in,
const double *lat_in,
const double *lon_out,
const double *lat_out,
677 const double *mask_in,
int *i_in,
int *j_in,
int *i_out,
int *j_out,
678 double *xgrid_area,
double *xgrid_clon,
double *xgrid_clat)
681 nxgrid = create_xgrid_2dx1d_order2(nlon_in, nlat_in, nlon_out, nlat_out, lon_in, lat_in, lon_out, lat_out, mask_in, i_in,
682 j_in, i_out, j_out, xgrid_area, xgrid_clon, xgrid_clat);
687 int create_xgrid_2dx1d_order2(
const int *nlon_in,
const int *nlat_in,
const int *nlon_out,
const int *nlat_out,
688 const double *lon_in,
const double *lat_in,
const double *lon_out,
const double *lat_out,
689 const double *mask_in,
int *i_in,
int *j_in,
int *i_out,
int *j_out,
690 double *xgrid_area,
double *xgrid_clon,
double *xgrid_clat)
693 int nx1, ny1, nx2, ny2, nx1p, nx2p;
694 int i1, j1, i2, j2, nxgrid;
695 double ll_lon, ll_lat, ur_lon, ur_lat, x_in[MV], y_in[MV], x_out[MV], y_out[MV];
697 double *area_in, *area_out, min_area;
712 area_in = (
double *)malloc(nx1*ny1*
sizeof(
double));
713 area_out = (
double *)malloc(nx2*ny2*
sizeof(
double));
714 tmpx = (
double *)malloc((nx2+1)*(ny2+1)*
sizeof(
double));
715 tmpy = (
double *)malloc((nx2+1)*(ny2+1)*
sizeof(
double));
716 for(j2=0; j2<=ny2; j2++)
for(i2=0; i2<=nx2; i2++) {
717 tmpx[j2*nx2p+i2] = lon_out[i2];
718 tmpy[j2*nx2p+i2] = lat_out[j2];
720 get_grid_area(nlon_in, nlat_in, lon_in, lat_in, area_in);
721 get_grid_area(nlon_out, nlat_out, tmpx, tmpy, area_out);
726 for(j2=0; j2<ny2; j2++)
for(i2=0; i2<nx2; i2++) {
728 ll_lon = lon_out[i2]; ll_lat = lat_out[j2];
729 ur_lon = lon_out[i2+1]; ur_lat = lat_out[j2+1];
730 for(j1=0; j1<ny1; j1++)
for(i1=0; i1<nx1; i1++)
if( mask_in[j1*nx1+i1] > MASK_THRESH ) {
732 y_in[0] = lat_in[j1*nx1p+i1];
733 y_in[1] = lat_in[j1*nx1p+i1+1];
734 y_in[2] = lat_in[(j1+1)*nx1p+i1+1];
735 y_in[3] = lat_in[(j1+1)*nx1p+i1];
736 if ( (y_in[0]<=ll_lat) && (y_in[1]<=ll_lat)
737 && (y_in[2]<=ll_lat) && (y_in[3]<=ll_lat) )
continue;
738 if ( (y_in[0]>=ur_lat) && (y_in[1]>=ur_lat)
739 && (y_in[2]>=ur_lat) && (y_in[3]>=ur_lat) )
continue;
741 x_in[0] = lon_in[j1*nx1p+i1];
742 x_in[1] = lon_in[j1*nx1p+i1+1];
743 x_in[2] = lon_in[(j1+1)*nx1p+i1+1];
744 x_in[3] = lon_in[(j1+1)*nx1p+i1];
746 n_in = fix_lon(x_in, y_in, 4, (ll_lon+ur_lon)/2);
747 lon_in_avg = avgval_double(n_in, x_in);
749 if ( (n_out = clip ( x_in, y_in, n_in, ll_lon, ll_lat, ur_lon, ur_lat, x_out, y_out )) > 0 ) {
750 xarea = poly_area (x_out, y_out, n_out ) * mask_in[j1*nx1+i1];
751 min_area = min(area_in[j1*nx1+i1], area_out[j2*nx2+i2]);
752 if(xarea/min_area > AREA_RATIO_THRESH ) {
753 xgrid_area[nxgrid] = xarea;
754 xgrid_clon[nxgrid] = poly_ctrlon(x_out, y_out, n_out, lon_in_avg);
755 xgrid_clat[nxgrid] = poly_ctrlat (x_out, y_out, n_out );
761 if(nxgrid > MAXXGRID) error_handler(
"nxgrid is greater than MAXXGRID, increase MAXXGRID");
781 int create_xgrid_2dx2d_order1_(
const int *nlon_in,
const int *nlat_in,
const int *nlon_out,
const int *nlat_out,
782 const double *lon_in,
const double *lat_in,
const double *lon_out,
const double *lat_out,
783 const double *mask_in,
int *i_in,
int *j_in,
int *i_out,
784 int *j_out,
double *xgrid_area)
788 nxgrid = create_xgrid_2dx2d_order1(nlon_in, nlat_in, nlon_out, nlat_out, lon_in, lat_in, lon_out, lat_out, mask_in,
789 i_in, j_in, i_out, j_out, xgrid_area);
793 int create_xgrid_2dx2d_order1(
const int *nlon_in,
const int *nlat_in,
const int *nlon_out,
const int *nlat_out,
794 const double *lon_in,
const double *lat_in,
const double *lon_out,
const double *lat_out,
795 const double *mask_in,
int *i_in,
int *j_in,
int *i_out,
796 int *j_out,
double *xgrid_area)
800 int nx1, nx2, ny1, ny2, nx1p, nx2p, nxgrid;
801 double *area_in, *area_out;
803 int *istart2=NULL, *iend2=NULL;
804 int npts_left, nblks_left, pos, m, npts_my, ij;
805 double *lon_out_min_list,*lon_out_max_list,*lon_out_avg,*lat_out_min_list,*lat_out_max_list;
806 double *lon_out_list, *lat_out_list;
807 int *pnxgrid=NULL, *pstart;
808 int *pi_in=NULL, *pj_in=NULL, *pi_out=NULL, *pj_out=NULL;
809 double *pxgrid_area=NULL;
811 int nthreads, nxgrid_block_max;
820 area_in = (
double *)malloc(nx1*ny1*
sizeof(
double));
821 area_out = (
double *)malloc(nx2*ny2*
sizeof(
double));
822 get_grid_area(nlon_in, nlat_in, lon_in, lat_in, area_in);
823 get_grid_area(nlon_out, nlat_out, lon_out, lat_out, area_out);
828 nthreads = omp_get_num_threads();
833 istart2 = (
int *)malloc(nblocks*
sizeof(
int));
834 iend2 = (
int *)malloc(nblocks*
sizeof(
int));
836 pstart = (
int *)malloc(nblocks*
sizeof(
int));
837 pnxgrid = (
int *)malloc(nblocks*
sizeof(
int));
839 nxgrid_block_max = MAXXGRID/nblocks;
841 for(m=0; m<nblocks; m++) {
843 pstart[m] = m*nxgrid_block_max;
851 pxgrid_area = xgrid_area;
854 pi_in = (
int *)malloc(MAXXGRID*
sizeof(
int));
855 pj_in = (
int *)malloc(MAXXGRID*
sizeof(
int));
856 pi_out = (
int *)malloc(MAXXGRID*
sizeof(
int));
857 pj_out = (
int *)malloc(MAXXGRID*
sizeof(
int));
858 pxgrid_area = (
double *)malloc(MAXXGRID*
sizeof(
double));
862 nblks_left = nblocks;
864 for(m=0; m<nblocks; m++) {
866 npts_my = npts_left/nblks_left;
867 iend2[m] = istart2[m] + npts_my - 1;
869 npts_left -= npts_my;
873 lon_out_min_list = (
double *)malloc(nx2*ny2*
sizeof(
double));
874 lon_out_max_list = (
double *)malloc(nx2*ny2*
sizeof(
double));
875 lat_out_min_list = (
double *)malloc(nx2*ny2*
sizeof(
double));
876 lat_out_max_list = (
double *)malloc(nx2*ny2*
sizeof(
double));
877 lon_out_avg = (
double *)malloc(nx2*ny2*
sizeof(
double));
878 n2_list = (
int *)malloc(nx2*ny2*
sizeof(
int));
879 lon_out_list = (
double *)malloc(MAX_V*nx2*ny2*
sizeof(
double));
880 lat_out_list = (
double *)malloc(MAX_V*nx2*ny2*
sizeof(
double));
882 #pragma omp parallel for default(none) shared(nx2,ny2,nx2p,lon_out,lat_out,lat_out_min_list, \
883 lat_out_max_list,lon_out_min_list,lon_out_max_list, \
884 lon_out_avg,n2_list,lon_out_list,lat_out_list)
886 for(ij=0; ij<nx2*ny2; ij++){
887 int i2, j2, n, n0, n1, n2, n3, n2_in, l;
888 double x2_in[MV], y2_in[MV];
892 n0 = j2*nx2p+i2; n1 = j2*nx2p+i2+1;
893 n2 = (j2+1)*nx2p+i2+1; n3 = (j2+1)*nx2p+i2;
894 x2_in[0] = lon_out[n0]; y2_in[0] = lat_out[n0];
895 x2_in[1] = lon_out[n1]; y2_in[1] = lat_out[n1];
896 x2_in[2] = lon_out[n2]; y2_in[2] = lat_out[n2];
897 x2_in[3] = lon_out[n3]; y2_in[3] = lat_out[n3];
899 lat_out_min_list[n] = minval_double(4, y2_in);
900 lat_out_max_list[n] = maxval_double(4, y2_in);
901 n2_in = fix_lon(x2_in, y2_in, 4, M_PI);
902 if(n2_in > MAX_V) error_handler(
"create_xgrid.c: n2_in is greater than MAX_V");
903 lon_out_min_list[n] = minval_double(n2_in, x2_in);
904 lon_out_max_list[n] = maxval_double(n2_in, x2_in);
905 lon_out_avg[n] = avgval_double(n2_in, x2_in);
907 for(l=0; l<n2_in; l++) {
908 lon_out_list[n*MAX_V+l] = x2_in[l];
909 lat_out_list[n*MAX_V+l] = y2_in[l];
916 #pragma omp parallel for default(none) shared(nblocks,nx1,ny1,nx1p,mask_in,lon_in,lat_in, \
917 istart2,iend2,nx2,lat_out_min_list,lat_out_max_list, \
918 n2_list,lon_out_list,lat_out_list,lon_out_min_list, \
919 lon_out_max_list,lon_out_avg,area_in,area_out, \
920 pxgrid_area,pnxgrid,pi_in,pj_in,pi_out,pj_out,pstart,nthreads)
922 for(m=0; m<nblocks; m++) {
924 for(j1=0; j1<ny1; j1++)
for(i1=0; i1<nx1; i1++)
if( mask_in[j1*nx1+i1] > MASK_THRESH ) {
925 int n0, n1, n2, n3, l,n1_in;
926 double lat_in_min,lat_in_max,lon_in_min,lon_in_max,lon_in_avg;
927 double x1_in[MV], y1_in[MV], x_out[MV], y_out[MV];
929 n0 = j1*nx1p+i1; n1 = j1*nx1p+i1+1;
930 n2 = (j1+1)*nx1p+i1+1; n3 = (j1+1)*nx1p+i1;
931 x1_in[0] = lon_in[n0]; y1_in[0] = lat_in[n0];
932 x1_in[1] = lon_in[n1]; y1_in[1] = lat_in[n1];
933 x1_in[2] = lon_in[n2]; y1_in[2] = lat_in[n2];
934 x1_in[3] = lon_in[n3]; y1_in[3] = lat_in[n3];
935 lat_in_min = minval_double(4, y1_in);
936 lat_in_max = maxval_double(4, y1_in);
937 n1_in = fix_lon(x1_in, y1_in, 4, M_PI);
938 lon_in_min = minval_double(n1_in, x1_in);
939 lon_in_max = maxval_double(n1_in, x1_in);
940 lon_in_avg = avgval_double(n1_in, x1_in);
941 for(ij=istart2[m]; ij<=iend2[m]; ij++) {
942 int n_out, i2, j2, n2_in;
943 double xarea, dx, lon_out_min, lon_out_max;
944 double x2_in[MAX_V], y2_in[MAX_V];
949 if(lat_out_min_list[ij] >= lat_in_max || lat_out_max_list[ij] <= lat_in_min )
continue;
952 for(l=0; l<n2_in; l++) {
953 x2_in[l] = lon_out_list[ij*MAX_V+l];
954 y2_in[l] = lat_out_list[ij*MAX_V+l];
956 lon_out_min = lon_out_min_list[ij];
957 lon_out_max = lon_out_max_list[ij];
958 dx = lon_out_avg[ij] - lon_in_avg;
962 for (l=0; l<n2_in; l++) x2_in[l] += TPI;
964 else if (dx > M_PI) {
967 for (l=0; l<n2_in; l++) x2_in[l] -= TPI;
973 if(lon_out_min >= lon_in_max || lon_out_max <= lon_in_min )
continue;
974 if ( (n_out = clip_2dx2d( x1_in, y1_in, n1_in, x2_in, y2_in, n2_in, x_out, y_out )) > 0) {
977 xarea = poly_area (x_out, y_out, n_out ) * mask_in[j1*nx1+i1];
978 min_area = min(area_in[j1*nx1+i1], area_out[j2*nx2+i2]);
979 if( xarea/min_area > AREA_RATIO_THRESH ) {
981 if(pnxgrid[m]>= MAXXGRID/nthreads)
982 error_handler(
"nxgrid is greater than MAXXGRID/nthreads, increase MAXXGRID, decrease nthreads, or increase number of MPI ranks");
983 nn = pstart[m] + pnxgrid[m]-1;
985 pxgrid_area[nn] = xarea;
1000 nxgrid = pnxgrid[0];
1010 for(m=0; m<nblocks; m++) {
1011 for(i=0; i<pnxgrid[m]; i++) {
1013 i_in[nxgrid] = pi_in[nn];
1014 j_in[nxgrid] = pj_in[nn];
1015 i_out[nxgrid] = pi_out[nn];
1016 j_out[nxgrid] = pj_out[nn];
1017 xgrid_area[nxgrid] = pxgrid_area[nn];
1030 free(lon_out_min_list);
1031 free(lon_out_max_list);
1032 free(lat_out_min_list);
1033 free(lat_out_max_list);
1050 int create_xgrid_2dx2d_order2_(
const int *nlon_in,
const int *nlat_in,
const int *nlon_out,
const int *nlat_out,
1051 const double *lon_in,
const double *lat_in,
const double *lon_out,
const double *lat_out,
1052 const double *mask_in,
int *i_in,
int *j_in,
int *i_out,
int *j_out,
1053 double *xgrid_area,
double *xgrid_clon,
double *xgrid_clat)
1056 nxgrid = create_xgrid_2dx2d_order2(nlon_in, nlat_in, nlon_out, nlat_out, lon_in, lat_in, lon_out, lat_out, mask_in, i_in,
1057 j_in, i_out, j_out, xgrid_area, xgrid_clon, xgrid_clat);
1061 int create_xgrid_2dx2d_order2(
const int *nlon_in,
const int *nlat_in,
const int *nlon_out,
const int *nlat_out,
1062 const double *lon_in,
const double *lat_in,
const double *lon_out,
const double *lat_out,
1063 const double *mask_in,
int *i_in,
int *j_in,
int *i_out,
int *j_out,
1064 double *xgrid_area,
double *xgrid_clon,
double *xgrid_clat)
1068 int nx1, nx2, ny1, ny2, nx1p, nx2p, nxgrid;
1069 double *area_in, *area_out;
1071 int *istart2=NULL, *iend2=NULL;
1072 int npts_left, nblks_left, pos, m, npts_my, ij;
1073 double *lon_out_min_list,*lon_out_max_list,*lon_out_avg,*lat_out_min_list,*lat_out_max_list;
1074 double *lon_out_list, *lat_out_list;
1075 int *pnxgrid=NULL, *pstart;
1076 int *pi_in=NULL, *pj_in=NULL, *pi_out=NULL, *pj_out=NULL;
1077 double *pxgrid_area=NULL, *pxgrid_clon=NULL, *pxgrid_clat=NULL;
1079 int nthreads, nxgrid_block_max;
1088 area_in = (
double *)malloc(nx1*ny1*
sizeof(
double));
1089 area_out = (
double *)malloc(nx2*ny2*
sizeof(
double));
1090 get_grid_area(nlon_in, nlat_in, lon_in, lat_in, area_in);
1091 get_grid_area(nlon_out, nlat_out, lon_out, lat_out, area_out);
1094 #if defined(_OPENMP)
1095 #pragma omp parallel
1096 nthreads = omp_get_num_threads();
1101 istart2 = (
int *)malloc(nblocks*
sizeof(
int));
1102 iend2 = (
int *)malloc(nblocks*
sizeof(
int));
1104 pstart = (
int *)malloc(nblocks*
sizeof(
int));
1105 pnxgrid = (
int *)malloc(nblocks*
sizeof(
int));
1107 nxgrid_block_max = MAXXGRID/nblocks;
1109 for(m=0; m<nblocks; m++) {
1111 pstart[m] = m*nxgrid_block_max;
1119 pxgrid_area = xgrid_area;
1120 pxgrid_clon = xgrid_clon;
1121 pxgrid_clat = xgrid_clat;
1124 pi_in = (
int *)malloc(MAXXGRID*
sizeof(
int));
1125 pj_in = (
int *)malloc(MAXXGRID*
sizeof(
int));
1126 pi_out = (
int *)malloc(MAXXGRID*
sizeof(
int));
1127 pj_out = (
int *)malloc(MAXXGRID*
sizeof(
int));
1128 pxgrid_area = (
double *)malloc(MAXXGRID*
sizeof(
double));
1129 pxgrid_clon = (
double *)malloc(MAXXGRID*
sizeof(
double));
1130 pxgrid_clat = (
double *)malloc(MAXXGRID*
sizeof(
double));
1133 npts_left = nx2*ny2;
1134 nblks_left = nblocks;
1136 for(m=0; m<nblocks; m++) {
1138 npts_my = npts_left/nblks_left;
1139 iend2[m] = istart2[m] + npts_my - 1;
1141 npts_left -= npts_my;
1145 lon_out_min_list = (
double *)malloc(nx2*ny2*
sizeof(
double));
1146 lon_out_max_list = (
double *)malloc(nx2*ny2*
sizeof(
double));
1147 lat_out_min_list = (
double *)malloc(nx2*ny2*
sizeof(
double));
1148 lat_out_max_list = (
double *)malloc(nx2*ny2*
sizeof(
double));
1149 lon_out_avg = (
double *)malloc(nx2*ny2*
sizeof(
double));
1150 n2_list = (
int *)malloc(nx2*ny2*
sizeof(
int));
1151 lon_out_list = (
double *)malloc(MAX_V*nx2*ny2*
sizeof(
double));
1152 lat_out_list = (
double *)malloc(MAX_V*nx2*ny2*
sizeof(
double));
1153 #if defined(_OPENMP)
1154 #pragma omp parallel for default(none) shared(nx2,ny2,nx2p,lon_out,lat_out,lat_out_min_list, \
1155 lat_out_max_list,lon_out_min_list,lon_out_max_list, \
1156 lon_out_avg,n2_list,lon_out_list,lat_out_list)
1158 for(ij=0; ij<nx2*ny2; ij++){
1159 int i2, j2, n, n0, n1, n2, n3, n2_in, l;
1160 double x2_in[MV], y2_in[MV];
1164 n0 = j2*nx2p+i2; n1 = j2*nx2p+i2+1;
1165 n2 = (j2+1)*nx2p+i2+1; n3 = (j2+1)*nx2p+i2;
1166 x2_in[0] = lon_out[n0]; y2_in[0] = lat_out[n0];
1167 x2_in[1] = lon_out[n1]; y2_in[1] = lat_out[n1];
1168 x2_in[2] = lon_out[n2]; y2_in[2] = lat_out[n2];
1169 x2_in[3] = lon_out[n3]; y2_in[3] = lat_out[n3];
1171 lat_out_min_list[n] = minval_double(4, y2_in);
1172 lat_out_max_list[n] = maxval_double(4, y2_in);
1173 n2_in = fix_lon(x2_in, y2_in, 4, M_PI);
1174 if(n2_in > MAX_V) error_handler(
"create_xgrid.c: n2_in is greater than MAX_V");
1175 lon_out_min_list[n] = minval_double(n2_in, x2_in);
1176 lon_out_max_list[n] = maxval_double(n2_in, x2_in);
1177 lon_out_avg[n] = avgval_double(n2_in, x2_in);
1179 for(l=0; l<n2_in; l++) {
1180 lon_out_list[n*MAX_V+l] = x2_in[l];
1181 lat_out_list[n*MAX_V+l] = y2_in[l];
1187 #if defined(_OPENMP)
1188 #pragma omp parallel for default(none) shared(nblocks,nx1,ny1,nx1p,mask_in,lon_in,lat_in, \
1189 istart2,iend2,nx2,lat_out_min_list,lat_out_max_list, \
1190 n2_list,lon_out_list,lat_out_list,lon_out_min_list, \
1191 lon_out_max_list,lon_out_avg,area_in,area_out, \
1192 pxgrid_area,pnxgrid,pxgrid_clon,pxgrid_clat,pi_in, \
1193 pj_in,pi_out,pj_out,pstart,nthreads)
1195 for(m=0; m<nblocks; m++) {
1197 for(j1=0; j1<ny1; j1++)
for(i1=0; i1<nx1; i1++)
if( mask_in[j1*nx1+i1] > MASK_THRESH ) {
1198 int n0, n1, n2, n3, l,n1_in;
1199 double lat_in_min,lat_in_max,lon_in_min,lon_in_max,lon_in_avg;
1200 double x1_in[MV], y1_in[MV], x_out[MV], y_out[MV];
1202 n0 = j1*nx1p+i1; n1 = j1*nx1p+i1+1;
1203 n2 = (j1+1)*nx1p+i1+1; n3 = (j1+1)*nx1p+i1;
1204 x1_in[0] = lon_in[n0]; y1_in[0] = lat_in[n0];
1205 x1_in[1] = lon_in[n1]; y1_in[1] = lat_in[n1];
1206 x1_in[2] = lon_in[n2]; y1_in[2] = lat_in[n2];
1207 x1_in[3] = lon_in[n3]; y1_in[3] = lat_in[n3];
1208 lat_in_min = minval_double(4, y1_in);
1209 lat_in_max = maxval_double(4, y1_in);
1210 n1_in = fix_lon(x1_in, y1_in, 4, M_PI);
1211 lon_in_min = minval_double(n1_in, x1_in);
1212 lon_in_max = maxval_double(n1_in, x1_in);
1213 lon_in_avg = avgval_double(n1_in, x1_in);
1214 for(ij=istart2[m]; ij<=iend2[m]; ij++) {
1215 int n_out, i2, j2, n2_in;
1216 double xarea, dx, lon_out_min, lon_out_max;
1217 double x2_in[MAX_V], y2_in[MAX_V];
1222 if(lat_out_min_list[ij] >= lat_in_max || lat_out_max_list[ij] <= lat_in_min )
continue;
1224 n2_in = n2_list[ij];
1225 for(l=0; l<n2_in; l++) {
1226 x2_in[l] = lon_out_list[ij*MAX_V+l];
1227 y2_in[l] = lat_out_list[ij*MAX_V+l];
1229 lon_out_min = lon_out_min_list[ij];
1230 lon_out_max = lon_out_max_list[ij];
1231 dx = lon_out_avg[ij] - lon_in_avg;
1235 for (l=0; l<n2_in; l++) x2_in[l] += TPI;
1237 else if (dx > M_PI) {
1240 for (l=0; l<n2_in; l++) x2_in[l] -= TPI;
1246 if(lon_out_min >= lon_in_max || lon_out_max <= lon_in_min )
continue;
1247 if ( (n_out = clip_2dx2d( x1_in, y1_in, n1_in, x2_in, y2_in, n2_in, x_out, y_out )) > 0) {
1250 xarea = poly_area (x_out, y_out, n_out ) * mask_in[j1*nx1+i1];
1251 min_area = min(area_in[j1*nx1+i1], area_out[j2*nx2+i2]);
1252 if( xarea/min_area > AREA_RATIO_THRESH ) {
1254 if(pnxgrid[m]>= MAXXGRID/nthreads)
1255 error_handler(
"nxgrid is greater than MAXXGRID/nthreads, increase MAXXGRID, decrease nthreads, or increase number of MPI ranks");
1256 nn = pstart[m] + pnxgrid[m]-1;
1257 pxgrid_area[nn] = xarea;
1258 pxgrid_clon[nn] = poly_ctrlon(x_out, y_out, n_out, lon_in_avg);
1259 pxgrid_clat[nn] = poly_ctrlat (x_out, y_out, n_out );
1272 nxgrid = pnxgrid[0];
1284 for(m=0; m<nblocks; m++) {
1285 for(i=0; i<pnxgrid[m]; i++) {
1287 i_in[nxgrid] = pi_in[nn];
1288 j_in[nxgrid] = pj_in[nn];
1289 i_out[nxgrid] = pi_out[nn];
1290 j_out[nxgrid] = pj_out[nn];
1291 xgrid_area[nxgrid] = pxgrid_area[nn];
1292 xgrid_clon[nxgrid] = pxgrid_clon[nn];
1293 xgrid_clat[nxgrid] = pxgrid_clat[nn];
1308 free(lon_out_min_list);
1309 free(lon_out_max_list);
1310 free(lat_out_min_list);
1311 free(lat_out_max_list);
1326 int clip(
const double lon_in[],
const double lat_in[],
int n_in,
double ll_lon,
double ll_lat,
1327 double ur_lon,
double ur_lat,
double lon_out[],
double lat_out[])
1329 double x_tmp[MV], y_tmp[MV], x_last, y_last;
1330 int i_in, i_out, n_out, inside_last, inside;
1333 x_last = lon_in[n_in-1];
1334 y_last = lat_in[n_in-1];
1335 inside_last = (x_last >= ll_lon);
1336 for (i_in=0,i_out=0;i_in<n_in;i_in++) {
1339 if ((inside=(lon_in[i_in] >= ll_lon))!=inside_last) {
1340 x_tmp[i_out] = ll_lon;
1341 y_tmp[i_out++] = y_last + (ll_lon - x_last) * (lat_in[i_in] - y_last) / (lon_in[i_in] - x_last);
1346 x_tmp[i_out] = lon_in[i_in];
1347 y_tmp[i_out++] = lat_in[i_in];
1349 x_last = lon_in[i_in];
1350 y_last = lat_in[i_in];
1351 inside_last = inside;
1353 if (!(n_out=i_out))
return(0);
1356 x_last = x_tmp[n_out-1];
1357 y_last = y_tmp[n_out-1];
1358 inside_last = (x_last <= ur_lon);
1359 for (i_in=0,i_out=0;i_in<n_out;i_in++) {
1362 if ((inside=(x_tmp[i_in] <= ur_lon))!=inside_last) {
1363 lon_out[i_out] = ur_lon;
1364 lat_out[i_out++] = y_last + (ur_lon - x_last) * (y_tmp[i_in] - y_last)
1365 / (x_tmp[i_in] - x_last);
1370 lon_out[i_out] = x_tmp[i_in];
1371 lat_out[i_out++] = y_tmp[i_in];
1374 x_last = x_tmp[i_in];
1375 y_last = y_tmp[i_in];
1376 inside_last = inside;
1378 if (!(n_out=i_out))
return(0);
1381 x_last = lon_out[n_out-1];
1382 y_last = lat_out[n_out-1];
1383 inside_last = (y_last >= ll_lat);
1384 for (i_in=0,i_out=0;i_in<n_out;i_in++) {
1387 if ((inside=(lat_out[i_in] >= ll_lat))!=inside_last) {
1388 y_tmp[i_out] = ll_lat;
1389 x_tmp[i_out++] = x_last + (ll_lat - y_last) * (lon_out[i_in] - x_last) / (lat_out[i_in] - y_last);
1394 x_tmp[i_out] = lon_out[i_in];
1395 y_tmp[i_out++] = lat_out[i_in];
1397 x_last = lon_out[i_in];
1398 y_last = lat_out[i_in];
1399 inside_last = inside;
1401 if (!(n_out=i_out))
return(0);
1404 x_last = x_tmp[n_out-1];
1405 y_last = y_tmp[n_out-1];
1406 inside_last = (y_last <= ur_lat);
1407 for (i_in=0,i_out=0;i_in<n_out;i_in++) {
1410 if ((inside=(y_tmp[i_in] <= ur_lat))!=inside_last) {
1411 lat_out[i_out] = ur_lat;
1412 lon_out[i_out++] = x_last + (ur_lat - y_last) * (x_tmp[i_in] - x_last) / (y_tmp[i_in] - y_last);
1417 lon_out[i_out] = x_tmp[i_in];
1418 lat_out[i_out++] = y_tmp[i_in];
1420 x_last = x_tmp[i_in];
1421 y_last = y_tmp[i_in];
1422 inside_last = inside;
1433 int clip_2dx2d(
const double lon1_in[],
const double lat1_in[],
int n1_in,
1434 const double lon2_in[],
const double lat2_in[],
int n2_in,
1435 double lon_out[],
double lat_out[])
1437 double lon_tmp[MV], lat_tmp[MV];
1438 double x1_0, y1_0, x1_1, y1_1, x2_0, y2_0, x2_1, y2_1;
1439 double dx1, dy1, dx2, dy2, determ, ds1, ds2;
1440 int i_out, n_out, inside_last, inside, i1, i2;
1445 for(i1=0; i1<n1_in; i1++) {
1446 lon_tmp[i1] = lon1_in[i1];
1447 lat_tmp[i1] = lat1_in[i1];
1449 x2_0 = lon2_in[n2_in-1];
1450 y2_0 = lat2_in[n2_in-1];
1451 for(i2=0; i2<n2_in; i2++) {
1454 x1_0 = lon_tmp[n_out-1];
1455 y1_0 = lat_tmp[n_out-1];
1456 inside_last = inside_edge( x2_0, y2_0, x2_1, y2_1, x1_0, y1_0);
1457 for(i1=0, i_out=0; i1<n_out; i1++) {
1460 if((inside = inside_edge(x2_0, y2_0, x2_1, y2_1, x1_1, y1_1)) != inside_last ) {
1468 ds1 = y1_0*x1_1 - y1_1*x1_0;
1469 ds2 = y2_0*x2_1 - y2_1*x2_0;
1470 determ = dy2*dx1 - dy1*dx2;
1471 if(fabs(determ) < EPSLN30) {
1472 error_handler(
"the line between <x1_0,y1_0> and <x1_1,y1_1> should not parallel to "
1473 "the line between <x2_0,y2_0> and <x2_1,y2_1>");
1475 lon_out[i_out] = (dx2*ds1 - dx1*ds2)/determ;
1476 lat_out[i_out++] = (dy2*ds1 - dy1*ds2)/determ;
1481 lon_out[i_out] = x1_1;
1482 lat_out[i_out++] = y1_1;
1486 inside_last = inside;
1488 if(!(n_out=i_out))
return 0;
1489 for(i1=0; i1<n_out; i1++) {
1490 lon_tmp[i1] = lon_out[i1];
1491 lat_tmp[i1] = lat_out[i1];
1502 int create_xgrid_great_circle_(
const int *nlon_in,
const int *nlat_in,
const int *nlon_out,
const int *nlat_out,
1503 const double *lon_in,
const double *lat_in,
const double *lon_out,
const double *lat_out,
1504 const double *mask_in,
int *i_in,
int *j_in,
int *i_out,
int *j_out,
1505 double *xgrid_area,
double *xgrid_clon,
double *xgrid_clat)
1508 nxgrid = create_xgrid_great_circle(nlon_in, nlat_in, nlon_out, nlat_out, lon_in, lat_in, lon_out, lat_out,
1509 mask_in, i_in, j_in, i_out, j_out, xgrid_area, xgrid_clon, xgrid_clat);
1514 int create_xgrid_great_circle(
const int *nlon_in,
const int *nlat_in,
const int *nlon_out,
const int *nlat_out,
1515 const double *lon_in,
const double *lat_in,
const double *lon_out,
const double *lat_out,
1516 const double *mask_in,
int *i_in,
int *j_in,
int *i_out,
int *j_out,
1517 double *xgrid_area,
double *xgrid_clon,
double *xgrid_clat)
1520 int nx1, nx2, ny1, ny2, nx1p, nx2p, ny1p, ny2p, nxgrid, n1_in, n2_in;
1521 int n0, n1, n2, n3, i1, j1, i2, j2;
1522 double x1_in[MV], y1_in[MV], z1_in[MV];
1523 double x2_in[MV], y2_in[MV], z2_in[MV];
1524 double x_out[MV], y_out[MV], z_out[MV];
1525 double *x1=NULL, *y1=NULL, *z1=NULL;
1526 double *x2=NULL, *y2=NULL, *z2=NULL;
1528 double *area1, *area2, min_area;
1541 x1 = (
double *)malloc(nx1p*ny1p*
sizeof(
double));
1542 y1 = (
double *)malloc(nx1p*ny1p*
sizeof(
double));
1543 z1 = (
double *)malloc(nx1p*ny1p*
sizeof(
double));
1544 x2 = (
double *)malloc(nx2p*ny2p*
sizeof(
double));
1545 y2 = (
double *)malloc(nx2p*ny2p*
sizeof(
double));
1546 z2 = (
double *)malloc(nx2p*ny2p*
sizeof(
double));
1548 latlon2xyz(nx1p*ny1p, lon_in, lat_in, x1, y1, z1);
1549 latlon2xyz(nx2p*ny2p, lon_out, lat_out, x2, y2, z2);
1551 area1 = (
double *)malloc(nx1*ny1*
sizeof(
double));
1552 area2 = (
double *)malloc(nx2*ny2*
sizeof(
double));
1553 get_grid_great_circle_area(nlon_in, nlat_in, lon_in, lat_in, area1);
1554 get_grid_great_circle_area(nlon_out, nlat_out, lon_out, lat_out, area2);
1558 for(j1=0; j1<ny1; j1++)
for(i1=0; i1<nx1; i1++)
if( mask_in[j1*nx1+i1] > MASK_THRESH ) {
1560 n0 = j1*nx1p+i1; n1 = (j1+1)*nx1p+i1;
1561 n2 = (j1+1)*nx1p+i1+1; n3 = j1*nx1p+i1+1;
1562 x1_in[0] = x1[n0]; y1_in[0] = y1[n0]; z1_in[0] = z1[n0];
1563 x1_in[1] = x1[n1]; y1_in[1] = y1[n1]; z1_in[1] = z1[n1];
1564 x1_in[2] = x1[n2]; y1_in[2] = y1[n2]; z1_in[2] = z1[n2];
1565 x1_in[3] = x1[n3]; y1_in[3] = y1[n3]; z1_in[3] = z1[n3];
1567 for(j2=0; j2<ny2; j2++)
for(i2=0; i2<nx2; i2++) {
1571 n0 = j2*nx2p+i2; n1 = (j2+1)*nx2p+i2;
1572 n2 = (j2+1)*nx2p+i2+1; n3 = j2*nx2p+i2+1;
1573 x2_in[0] = x2[n0]; y2_in[0] = y2[n0]; z2_in[0] = z2[n0];
1574 x2_in[1] = x2[n1]; y2_in[1] = y2[n1]; z2_in[1] = z2[n1];
1575 x2_in[2] = x2[n2]; y2_in[2] = y2[n2]; z2_in[2] = z2[n2];
1576 x2_in[3] = x2[n3]; y2_in[3] = y2[n3]; z2_in[3] = z2[n3];
1578 if ( (n_out = clip_2dx2d_great_circle( x1_in, y1_in, z1_in, n1_in, x2_in, y2_in, z2_in, n2_in,
1579 x_out, y_out, z_out)) > 0) {
1580 xarea = great_circle_area ( n_out, x_out, y_out, z_out ) * mask_in[j1*nx1+i1];
1581 min_area = min(area1[j1*nx1+i1], area2[j2*nx2+i2]);
1582 if( xarea/min_area > AREA_RATIO_THRESH ) {
1583 #ifdef debug_test_create_xgrid
1584 printf(
"(i2,j2)=(%d,%d), (i1,j1)=(%d,%d), xarea=%g\n", i2, j2, i1, j1, xarea);
1586 xgrid_area[nxgrid] = xarea;
1587 xgrid_clon[nxgrid] = 0;
1588 xgrid_clat[nxgrid] = 0;
1594 if(nxgrid > MAXXGRID) error_handler(
"nxgrid is greater than MAXXGRID, increase MAXXGRID");
1615 int create_xgrid_great_circle_ug_(
const int *nlon_in,
const int *nlat_in,
const int *npts_out,
1616 const double *lon_in,
const double *lat_in,
const double *lon_out,
const double *lat_out,
1617 const double *mask_in,
int *i_in,
int *j_in,
int *l_out,
1618 double *xgrid_area,
double *xgrid_clon,
double *xgrid_clat)
1621 nxgrid = create_xgrid_great_circle_ug(nlon_in, nlat_in, npts_out, lon_in, lat_in, lon_out, lat_out,
1622 mask_in, i_in, j_in, l_out, xgrid_area, xgrid_clon, xgrid_clat);
1627 int create_xgrid_great_circle_ug(
const int *nlon_in,
const int *nlat_in,
const int *npts_out,
1628 const double *lon_in,
const double *lat_in,
const double *lon_out,
const double *lat_out,
1629 const double *mask_in,
int *i_in,
int *j_in,
int *l_out,
1630 double *xgrid_area,
double *xgrid_clon,
double *xgrid_clat)
1633 int nx1, ny1, npts2, nx1p, ny1p, nxgrid, n1_in, n2_in, nv;
1634 int n0, n1, n2, n3, i1, j1, l2;
1635 double x1_in[MV], y1_in[MV], z1_in[MV];
1636 double x2_in[MV], y2_in[MV], z2_in[MV];
1637 double x_out[MV], y_out[MV], z_out[MV];
1638 double *x1=NULL, *y1=NULL, *z1=NULL;
1639 double *x2=NULL, *y2=NULL, *z2=NULL;
1641 double *area1, *area2, min_area;
1652 x1 = (
double *)malloc(nx1p*ny1p*
sizeof(
double));
1653 y1 = (
double *)malloc(nx1p*ny1p*
sizeof(
double));
1654 z1 = (
double *)malloc(nx1p*ny1p*
sizeof(
double));
1655 x2 = (
double *)malloc(npts2*nv*
sizeof(
double));
1656 y2 = (
double *)malloc(npts2*nv*
sizeof(
double));
1657 z2 = (
double *)malloc(npts2*nv*
sizeof(
double));
1659 latlon2xyz(nx1p*ny1p, lon_in, lat_in, x1, y1, z1);
1660 latlon2xyz(npts2*nv, lon_out, lat_out, x2, y2, z2);
1662 area1 = (
double *)malloc(nx1*ny1*
sizeof(
double));
1663 area2 = (
double *)malloc(npts2*
sizeof(
double));
1664 get_grid_great_circle_area(nlon_in, nlat_in, lon_in, lat_in, area1);
1665 get_grid_great_circle_area_ug(npts_out, lon_out, lat_out, area2);
1669 for(j1=0; j1<ny1; j1++)
for(i1=0; i1<nx1; i1++)
if( mask_in[j1*nx1+i1] > MASK_THRESH ) {
1671 n0 = j1*nx1p+i1; n1 = (j1+1)*nx1p+i1;
1672 n2 = (j1+1)*nx1p+i1+1; n3 = j1*nx1p+i1+1;
1673 x1_in[0] = x1[n0]; y1_in[0] = y1[n0]; z1_in[0] = z1[n0];
1674 x1_in[1] = x1[n1]; y1_in[1] = y1[n1]; z1_in[1] = z1[n1];
1675 x1_in[2] = x1[n2]; y1_in[2] = y1[n2]; z1_in[2] = z1[n2];
1676 x1_in[3] = x1[n3]; y1_in[3] = y1[n3]; z1_in[3] = z1[n3];
1678 for(l2=0; l2<npts2; l2++) {
1682 n0 = l2*nv; n1 = l2*nv+1;
1683 n2 = l2*nv+2; n3 = l2*nv+3;
1684 x2_in[0] = x2[n0]; y2_in[0] = y2[n0]; z2_in[0] = z2[n0];
1685 x2_in[1] = x2[n1]; y2_in[1] = y2[n1]; z2_in[1] = z2[n1];
1686 x2_in[2] = x2[n2]; y2_in[2] = y2[n2]; z2_in[2] = z2[n2];
1687 x2_in[3] = x2[n3]; y2_in[3] = y2[n3]; z2_in[3] = z2[n3];
1689 if ( (n_out = clip_2dx2d_great_circle( x1_in, y1_in, z1_in, n1_in, x2_in, y2_in, z2_in, n2_in,
1690 x_out, y_out, z_out)) > 0) {
1691 xarea = great_circle_area ( n_out, x_out, y_out, z_out ) * mask_in[j1*nx1+i1];
1692 min_area = min(area1[j1*nx1+i1], area2[l2]);
1693 if( xarea/min_area > AREA_RATIO_THRESH ) {
1694 #ifdef debug_test_create_xgrid
1695 printf(
"(l2)=(%d,%d), (i1,j1)=(%d,%d), xarea=%g\n", l2, i1, j1, xarea);
1697 xgrid_area[nxgrid] = xarea;
1698 xgrid_clon[nxgrid] = 0;
1699 xgrid_clat[nxgrid] = 0;
1704 if(nxgrid > MAXXGRID) error_handler(
"nxgrid is greater than MAXXGRID, increase MAXXGRID");
1737 int clip_2dx2d_great_circle(
const double x1_in[],
const double y1_in[],
const double z1_in[],
int n1_in,
1738 const double x2_in[],
const double y2_in[],
const double z2_in [],
int n2_in,
1739 double x_out[],
double y_out[],
double z_out[])
1741 struct Node *grid1List=NULL;
1742 struct Node *grid2List=NULL;
1743 struct Node *intersectList=NULL;
1744 struct Node *polyList=NULL;
1745 struct Node *curList=NULL;
1746 struct Node *firstIntersect=NULL, *curIntersect=NULL;
1747 struct Node *temp1=NULL, *temp2=NULL, *temp=NULL;
1749 int i1, i2, i1p, i2p, i2p2, npts1, npts2;
1750 int nintersect, n_out;
1751 int maxiter1, maxiter2, iter1, iter2;
1752 int found1, found2, curListNum;
1753 int has_inbound, inbound;
1754 double pt1[MV][3], pt2[MV][3];
1755 double *p1_0=NULL, *p1_1=NULL;
1756 double *p2_0=NULL, *p2_1=NULL, *p2_2=NULL;
1757 double intersect[3];
1759 double min_x1, max_x1, min_y1, max_y1, min_z1, max_z1;
1760 double min_x2, max_x2, min_y2, max_y2, min_z2, max_z2;
1764 min_x1 = minval_double(n1_in, x1_in);
1765 max_x2 = maxval_double(n2_in, x2_in);
1766 if(min_x1 >= max_x2+RANGE_CHECK_CRITERIA)
return 0;
1767 max_x1 = maxval_double(n1_in, x1_in);
1768 min_x2 = minval_double(n2_in, x2_in);
1769 if(min_x2 >= max_x1+RANGE_CHECK_CRITERIA)
return 0;
1771 min_y1 = minval_double(n1_in, y1_in);
1772 max_y2 = maxval_double(n2_in, y2_in);
1773 if(min_y1 >= max_y2+RANGE_CHECK_CRITERIA)
return 0;
1774 max_y1 = maxval_double(n1_in, y1_in);
1775 min_y2 = minval_double(n2_in, y2_in);
1776 if(min_y2 >= max_y1+RANGE_CHECK_CRITERIA)
return 0;
1778 min_z1 = minval_double(n1_in, z1_in);
1779 max_z2 = maxval_double(n2_in, z2_in);
1780 if(min_z1 >= max_z2+RANGE_CHECK_CRITERIA)
return 0;
1781 max_z1 = maxval_double(n1_in, z1_in);
1782 min_z2 = minval_double(n2_in, z2_in);
1783 if(min_z2 >= max_z1+RANGE_CHECK_CRITERIA)
return 0;
1787 grid1List = getNext();
1788 grid2List = getNext();
1789 intersectList = getNext();
1790 polyList = getNext();
1793 for(i1=0; i1<n1_in; i1++) addEnd(grid1List, x1_in[i1], y1_in[i1], z1_in[i1], 0, 0, 0, -1);
1794 for(i2=0; i2<n2_in; i2++) addEnd(grid2List, x2_in[i2], y2_in[i2], z2_in[i2], 0, 0, 0, -1);
1795 npts1 = length(grid1List);
1796 npts2 = length(grid2List);
1800 #ifdef debug_test_create_xgrid
1801 printf(
"\nNOTE from clip_2dx2d_great_circle: begin to set inside value grid1List\n");
1807 if(insidePolygon(temp, grid2List))
1811 temp = getNextNode(temp);
1814 #ifdef debug_test_create_xgrid
1815 printf(
"\nNOTE from clip_2dx2d_great_circle: begin to set inside value of grid2List\n");
1821 if(insidePolygon(temp, grid1List))
1825 temp = getNextNode(temp);
1831 if( gridArea(grid1List) <= 0 )
1832 error_handler(
"create_xgrid.c(clip_2dx2d_great_circle): grid box 1 is not convex");
1833 if( gridArea(grid2List) <= 0 )
1834 error_handler(
"create_xgrid.c(clip_2dx2d_great_circle): grid box 2 is not convex");
1836 #ifdef debug_test_create_xgrid
1837 printNode(grid1List,
"grid1List");
1838 printNode(grid2List,
"grid2List");
1846 for(i1=0; i1<npts1; i1++) {
1847 getCoordinates(temp, pt1[i1]);
1851 for(i2=0; i2<npts2; i2++) {
1852 getCoordinates(temp, pt2[i2]);
1856 firstIntersect=getNext();
1857 curIntersect = getNext();
1859 #ifdef debug_test_create_xgrid
1860 printf(
"\n\n************************ Start line_intersect_2D_3D ******************************\n");
1864 for(i1=0; i1<npts1; i1++) {
1868 for(i2=0; i2<npts2; i2++) {
1870 i2p2 = (i2+2)%npts2;
1874 #ifdef debug_test_create_xgrid
1875 printf(
"\n******************************************************************************\n");
1876 printf(
" i1 = %d, i2 = %d \n", i1, i2);
1877 printf(
"********************************************************************************\n");
1879 if( line_intersect_2D_3D(p1_0, p1_1, p2_0, p2_1, p2_2, intersect, &u1, &u2, &inbound) ) {
1885 if(addIntersect(intersectList, intersect[0], intersect[1], intersect[2], 1, u1, u2, inbound, i1, i1p, i2, i2p)) {
1889 insertIntersect(grid1List, intersect[0], intersect[1], intersect[2], 0.0, u2, inbound, p1_1[0], p1_1[1], p1_1[2]);
1892 insertIntersect(grid1List, intersect[0], intersect[1], intersect[2], u1, u2, inbound, p1_0[0], p1_0[1], p1_0[2]);
1895 p1_1[0] = intersect[0];
1896 p1_1[1] = intersect[1];
1897 p1_1[2] = intersect[2];
1900 p1_0[0] = intersect[0];
1901 p1_0[1] = intersect[1];
1902 p1_0[2] = intersect[2];
1906 insertIntersect(grid2List, intersect[0], intersect[1], intersect[2], 0.0, u1, 0, p2_1[0], p2_1[1], p2_1[2]);
1908 insertIntersect(grid2List, intersect[0], intersect[1], intersect[2], u2, u1, 0, p2_0[0], p2_0[1], p2_0[2]);
1911 p2_1[0] = intersect[0];
1912 p2_1[1] = intersect[1];
1913 p2_1[2] = intersect[2];
1916 p2_0[0] = intersect[0];
1917 p2_0[1] = intersect[1];
1918 p2_0[2] = intersect[2];
1932 temp = intersectList;
1933 nintersect = length(intersectList);
1934 if(nintersect > 1) {
1935 getFirstInbound(intersectList, firstIntersect);
1936 if(firstIntersect->initialized) {
1942 if( !has_inbound && nintersect > 1) {
1943 setInbound(intersectList, grid1List);
1944 getFirstInbound(intersectList, firstIntersect);
1945 if(firstIntersect->initialized) has_inbound = 1;
1952 maxiter1 = nintersect;
1953 #ifdef debug_test_create_xgrid
1954 printf(
"\nNOTE from clip_2dx2d_great_circle: number of intersect is %d\n", nintersect);
1955 printf(
"\n size of grid2List is %d, size of grid1List is %d\n", length(grid2List), length(grid1List));
1956 printNode(intersectList,
"beginning intersection list");
1957 printNode(grid2List,
"beginning clip list");
1958 printNode(grid1List,
"beginning subj list");
1959 printf(
"\n************************ End line_intersect_2D_3D **********************************\n\n");
1961 temp1 = getNode(grid1List, *firstIntersect);
1962 if( temp1 == NULL) {
1963 double lon[10], lat[10];
1965 xyz2latlon(n1_in, x1_in, y1_in, z1_in, lon, lat);
1966 for(i=0; i< n1_in; i++) printf(
"lon1 = %g, lat1 = %g\n", lon[i]*R2D, lat[i]*R2D);
1968 xyz2latlon(n2_in, x2_in, y2_in, z2_in, lon, lat);
1969 for(i=0; i< n2_in; i++) printf(
"lon2 = %g, lat2 = %g\n", lon[i]*R2D, lat[i]*R2D);
1972 error_handler(
"firstIntersect is not in the grid1List");
1974 addNode(polyList, *firstIntersect);
1976 #ifdef debug_test_create_xgrid
1977 printNode(polyList,
"polyList at stage 1");
1981 curList = grid1List;
1987 copyNode(curIntersect, *firstIntersect);
1991 while( iter1 < maxiter1 ) {
1992 #ifdef debug_test_create_xgrid
1993 printf(
"\n----------- At iteration = %d\n\n", iter1+1 );
1994 printNode(curIntersect,
"curIntersect at the begining of iter1");
1997 temp1 = getNode(curList, *curIntersect);
1998 temp2 = temp1->Next;
1999 if( temp2 == NULL ) temp2 = curList;
2001 maxiter2 = length(curList);
2005 while( iter2 < maxiter2 ) {
2006 int temp2IsIntersect;
2008 temp2IsIntersect = 0;
2009 if( isIntersect( *temp2 ) ) {
2013 if( sameNode( *temp2, *firstIntersect) ) {
2018 temp3 = temp2->Next;
2019 if( temp3 == NULL) temp3 = curList;
2020 if( temp3 == NULL) error_handler(
"creat_xgrid.c: temp3 can not be NULL");
2025 temp2IsIntersect = 1;
2026 if( isIntersect(*temp3) || (temp3->isInside == 1) ) found2 = 0;
2029 copyNode(curIntersect, *temp2);
2033 addNode(polyList, *temp2);
2034 #ifdef debug_test_create_xgrid
2035 printNode(polyList,
"polyList at stage 2");
2037 if(temp2IsIntersect) {
2041 temp2 = temp2->Next;
2042 if( temp2 == NULL ) temp2 = curList;
2047 if( !found2 ) error_handler(
" not found the next intersection ");
2050 if( sameNode( *curIntersect, *firstIntersect) ) {
2056 addNode(polyList, *curIntersect);
2057 #ifdef debug_test_create_xgrid
2058 printNode(polyList,
"polyList at stage 3");
2064 if( curListNum == 0) {
2065 curList = grid2List;
2069 curList = grid1List;
2074 if(!found1) error_handler(
"not return back to the first intersection");
2077 if( nintersect > 0) error_handler(
"After clipping, nintersect should be 0");
2081 while (temp1 != NULL) {
2082 getCoordinate(*temp1, x_out+n_out, y_out+n_out, z_out+n_out);
2083 temp1 = temp1->Next;
2088 if( n_out < 3) n_out = 0;
2089 #ifdef debug_test_create_xgrid
2090 printNode(polyList,
"polyList after clipping");
2099 #ifdef debug_test_create_xgrid
2100 printf(
"\nNOTE from clip_2dx2d_great_circle: check if grid1 is inside grid2\n");
2105 if(temp->intersect != 1) {
2106 #ifdef debug_test_create_xgrid
2107 printf(
"grid1->isInside = %d\n", temp->isInside);
2109 if( temp->isInside == 1) n1in2++;
2111 temp = getNextNode(temp);
2118 getCoordinate(*temp, &x_out[n], &y_out[n], &z_out[n]);
2120 temp = getNextNode(temp);
2123 if(n_out>0)
return n_out;
2129 #ifdef debug_test_create_xgrid
2130 printf(
"\nNOTE from clip_2dx2d_great_circle: check if grid2 is inside grid1\n");
2136 if(temp->intersect != 1) {
2137 #ifdef debug_test_create_xgrid
2138 printf(
"grid2->isInside = %d\n", temp->isInside);
2140 if( temp->isInside == 1) n2in1++;
2142 temp = getNextNode(temp);
2150 getCoordinate(*temp, &x_out[n], &y_out[n], &z_out[n]);
2152 temp = getNextNode(temp);
2171 int line_intersect_2D_3D(
double *a1,
double *a2,
double *q1,
double *q2,
double *q3,
2172 double *intersect,
double *u_a,
double *u_q,
int *inbound){
2181 double p1[3], v1[3], v2[3];
2182 double c1[3], c2[3], c3[3];
2183 double coincident,
sense, norm;
2185 int is_inter1, is_inter2;
2190 if(samePoint(a1[0], a1[1], a1[2], q1[0], q1[1], q1[2])) {
2193 intersect[0] = a1[0];
2194 intersect[1] = a1[1];
2195 intersect[2] = a1[2];
2196 #ifdef debug_test_create_xgrid
2197 printf(
"\nNOTE from line_intersect_2D_3D: u_a = %19.15f, u_q=%19.15f, inbound=%d\n", *u_a, *u_q, *inbound);
2201 else if (samePoint(a1[0], a1[1], a1[2], q2[0], q2[1], q2[2])) {
2204 intersect[0] = a1[0];
2205 intersect[1] = a1[1];
2206 intersect[2] = a1[2];
2207 #ifdef debug_test_create_xgrid
2208 printf(
"\nNOTE from line_intersect_2D_3D: u_a = %19.15f, u_q=%19.15f, inbound=%d\n", *u_a, *u_q, *inbound);
2212 else if(samePoint(a2[0], a2[1], a2[2], q1[0], q1[1], q1[2])) {
2213 #ifdef debug_test_create_xgrid
2214 printf(
"\nNOTE from line_intersect_2D_3D: u_a = %19.15f, u_q=%19.15f, inbound=%d\n", *u_a, *u_q, *inbound);
2218 intersect[0] = a2[0];
2219 intersect[1] = a2[1];
2220 intersect[2] = a2[2];
2223 else if (samePoint(a2[0], a2[1], a2[2], q2[0], q2[1], q2[2])) {
2224 #ifdef debug_test_create_xgrid
2225 printf(
"\nNOTE from line_intersect_2D_3D: u_a = %19.15f, u_q=%19.15f, inbound=%d\n", *u_a, *u_q, *inbound);
2229 intersect[0] = a2[0];
2230 intersect[1] = a2[1];
2231 intersect[2] = a2[2];
2248 is_inter1 = intersect_tri_with_line(plane, a1, a2, plane_p, u_a);
2253 if(fabs(*u_a) < EPSLN8) *u_a = 0;
2254 if(fabs(*u_a-1) < EPSLN8) *u_a = 1;
2257 #ifdef debug_test_create_xgrid
2258 printf(
"\nNOTE from line_intersect_2D_3D: u_a = %19.15f\n", *u_a);
2262 if( (*u_a < 0) || (*u_a > 1) )
return 0;
2276 is_inter2 = intersect_tri_with_line(plane, q1, q2, plane_p, u_q);
2281 if(fabs(*u_q) < EPSLN8) *u_q = 0;
2282 if(fabs(*u_q-1) < EPSLN8) *u_q = 1;
2283 #ifdef debug_test_create_xgrid
2284 printf(
"\nNOTE from line_intersect_2D_3D: u_q = %19.15f\n", *u_q);
2288 if( (*u_q < 0) || (*u_q > 1) )
return 0;
2293 vect_cross(a1, a2, c1);
2294 vect_cross(q1, q2, c2);
2295 vect_cross(c1, c2, c3);
2296 coincident = metric(c3);
2298 if(fabs(coincident) < EPSLN30)
return 0;
2301 intersect[0]=a1[0] + u*(a2[0]-a1[0]);
2302 intersect[1]=a1[1] + u*(a2[1]-a1[1]);
2303 intersect[2]=a1[2] + u*(a2[2]-a1[2]);
2305 norm = metric( intersect );
2306 for(i = 0; i < 3; i ++) intersect[i] /= norm;
2309 if(*u_q != 0 && *u_q != 1){
2311 p1[0] = a2[0]-a1[0];
2312 p1[1] = a2[1]-a1[1];
2313 p1[2] = a2[2]-a1[2];
2314 v1[0] = q2[0]-q1[0];
2315 v1[1] = q2[1]-q1[1];
2316 v1[2] = q2[2]-q1[2];
2317 v2[0] = q3[0]-q2[0];
2318 v2[1] = q3[1]-q2[1];
2319 v2[2] = q3[2]-q2[2];
2321 vect_cross(v1, v2, c1);
2322 vect_cross(v1, p1, c2);
2324 sense = dot(c1, c2);
2326 if(
sense > 0) *inbound = 2;
2328 #ifdef debug_test_create_xgrid
2329 printf(
"\nNOTE from line_intersect_2D_3D: inbound=%d\n", *inbound);
2341 double poly_ctrlat(
const double x[],
const double y[],
int n)
2343 double ctrlat = 0.0;
2348 double dx = (x[ip]-x[i]);
2349 double dy, avg_y, hdy;
2355 avg_y = (lat1+lat2)*0.5;
2356 if (dx==0.0)
continue;
2357 if(dx > M_PI) dx = dx - 2.0*M_PI;
2358 if(dx < -M_PI) dx = dx + 2.0*M_PI;
2360 if ( fabs(hdy)< SMALL_VALUE )
2361 ctrlat -= dx*(2*cos(avg_y) + lat2*sin(avg_y) - cos(lat1) );
2363 ctrlat -= dx*( (sin(hdy)/hdy)*(2*cos(avg_y) + lat2*sin(avg_y)) - cos(lat1) );
2365 return (ctrlat*RADIUS*RADIUS);
2372 double poly_ctrlon(
const double x[],
const double y[],
int n,
double clon)
2374 double ctrlon = 0.0;
2379 double phi1, phi2, dphi, lat1, lat2, dphi1, dphi2;
2380 double f1, f2, fac, fint;
2387 if (dphi==0.0)
continue;
2389 f1 = 0.5*(cos(lat1)*sin(lat1)+lat1);
2390 f2 = 0.5*(cos(lat2)*sin(lat2)+lat2);
2394 if(dphi > M_PI) dphi = dphi - 2.0*M_PI;
2395 if(dphi < -M_PI) dphi = dphi + 2.0*M_PI;
2396 dphi1 = phi1 - clon;
2397 if( dphi1 > M_PI) dphi1 -= 2.0*M_PI;
2398 if( dphi1 <-M_PI) dphi1 += 2.0*M_PI;
2400 if( dphi2 > M_PI) dphi2 -= 2.0*M_PI;
2401 if( dphi2 <-M_PI) dphi2 += 2.0*M_PI;
2403 if(fabs(dphi2 -dphi1) < M_PI) {
2404 ctrlon -= dphi * (dphi1*f1+dphi2*f2)/2.0;
2411 fint = f1 + (f2-f1)*(fac-dphi1)/fabs(dphi);
2412 ctrlon -= 0.5*dphi1*(dphi1-fac)*f1 - 0.5*dphi2*(dphi2+fac)*f2
2413 + 0.5*fac*(dphi1+dphi2)*fint;
2417 return (ctrlon*RADIUS*RADIUS);
2424 double box_ctrlat(
double ll_lon,
double ll_lat,
double ur_lon,
double ur_lat)
2426 double dphi = ur_lon-ll_lon;
2429 if(dphi > M_PI) dphi = dphi - 2.0*M_PI;
2430 if(dphi < -M_PI) dphi = dphi + 2.0*M_PI;
2431 ctrlat = dphi*(cos(ur_lat) + ur_lat*sin(ur_lat)-(cos(ll_lat) + ll_lat*sin(ll_lat)));
2432 return (ctrlat*RADIUS*RADIUS);
2439 double box_ctrlon(
double ll_lon,
double ll_lat,
double ur_lon,
double ur_lat,
double clon)
2441 double phi1, phi2, dphi, lat1, lat2, dphi1, dphi2;
2442 double f1, f2, fac, fint;
2443 double ctrlon = 0.0;
2445 for( i =0; i<2; i++) {
2449 lat1 = lat2 = ll_lat;
2454 lat1 = lat2 = ur_lat;
2457 f1 = 0.5*(cos(lat1)*sin(lat1)+lat1);
2458 f2 = 0.5*(cos(lat2)*sin(lat2)+lat2);
2460 if(dphi > M_PI) dphi = dphi - 2.0*M_PI;
2461 if(dphi < -M_PI) dphi = dphi + 2.0*M_PI;
2463 dphi1 = phi1 - clon;
2464 if( dphi1 > M_PI) dphi1 -= 2.0*M_PI;
2465 if( dphi1 <-M_PI) dphi1 += 2.0*M_PI;
2467 if( dphi2 > M_PI) dphi2 -= 2.0*M_PI;
2468 if( dphi2 <-M_PI) dphi2 += 2.0*M_PI;
2470 if(fabs(dphi2 -dphi1) < M_PI) {
2471 ctrlon -= dphi * (dphi1*f1+dphi2*f2)/2.0;
2478 fint = f1 + (f2-f1)*(fac-dphi1)/fabs(dphi);
2479 ctrlon -= 0.5*dphi1*(dphi1-fac)*f1 - 0.5*dphi2*(dphi2+fac)*f2
2480 + 0.5*fac*(dphi1+dphi2)*fint;
2483 return (ctrlon*RADIUS*RADIUS);
2491 double grid_box_radius(
const double *x,
const double *y,
const double *z,
int n)
2497 for(i=0; i<n-1; i++) {
2498 for(j=i+1; j<n; j++) {
2499 radius = max(radius, pow(x[i]-x[j],2.)+pow(y[i]-y[j],2.)+pow(z[i]-z[j],2.));
2503 radius = sqrt(radius);
2515 double dist_between_boxes(
const double *x1,
const double *y1,
const double *z1,
int n1,
2516 const double *x2,
const double *y2,
const double *z2,
int n2)
2522 for(i=0; i<n1; i++) {
2523 for(j=0; j<n2; j++) {
2524 dist = max(dist, pow(x1[i]-x2[j],2.)+pow(y1[i]-y2[j],2.)+pow(z1[i]-z2[j],2.));
2542 int inside_edge(
double x0,
double y0,
double x1,
double y1,
double x,
double y)
2544 const double SMALL = 1.e-12;
2547 product = ( x-x0 )*(y1-y0) + (x0-x1)*(y-y0);
2548 return (product<=SMALL) ? 1:0;
2555 #ifdef test_create_xgrid
2557 #include "create_xgrid.h"
2560 #define D2R (M_PI/180)
2561 #define R2D (180/M_PI)
2562 #define MAXPOINT 1000
2564 int main(
int argc,
char* argv[])
2567 double lon1_in[MAXPOINT], lat1_in[MAXPOINT];
2568 double lon2_in[MAXPOINT], lat2_in[MAXPOINT];
2569 double x1_in[MAXPOINT], y1_in[MAXPOINT], z1_in[MAXPOINT];
2570 double x2_in[MAXPOINT], y2_in[MAXPOINT], z2_in[MAXPOINT];
2571 double lon_out[20], lat_out[20];
2572 double x_out[20], y_out[20], z_out[20];
2573 int n1_in, n2_in, n_out, i, j;
2574 int nlon1=0, nlat1=0, nlon2=0, nlat2=0;
2579 for(n=11; n<=ntest; n++) {
2591 n1_in = 4; n2_in = 4;
2593 lon1_in[0] = 20; lat1_in[0] = 10;
2594 lon1_in[1] = 20; lat1_in[1] = 12;
2595 lon1_in[2] = 22; lat1_in[2] = 12;
2596 lon1_in[3] = 22; lat1_in[3] = 10;
2597 lon2_in[0] = 21; lat2_in[0] = 11;
2598 lon2_in[1] = 21; lat2_in[1] = 14;
2599 lon2_in[2] = 24; lat2_in[2] = 14;
2600 lon2_in[3] = 24; lat2_in[3] = 11;
2612 lon1_in[0] = 20; lat1_in[0] = 10;
2613 lon1_in[1] = 20; lat1_in[1] = 12;
2614 lon1_in[2] = 22; lat1_in[2] = 12;
2615 lon1_in[3] = 22; lat1_in[3] = 10;
2617 for(i=0; i<n2_in; i++) {
2618 lon2_in[i] = lon1_in[i];
2619 lat2_in[i] = lat1_in[i];
2632 n1_in = 4; n2_in = 4;
2634 lon1_in[0] = 251.7; lat1_in[0] = 88.98;
2635 lon1_in[1] = 148.3; lat1_in[1] = 88.98;
2636 lon1_in[2] = 57.81; lat1_in[2] = 88.72;
2637 lon1_in[3] = 342.2; lat1_in[3] = 88.72;
2639 lon2_in[0] = 150; lat2_in[0] = 88;
2640 lon2_in[1] = 150; lat2_in[1] = 90;
2641 lon2_in[2] = 152.5; lat2_in[2] = 90;
2642 lon2_in[3] = 152.5; lat2_in[3] = 88;
2660 n1_in = 4; n2_in = 4;
2663 lon1_in[0] = -160; lat1_in[0] = 88.5354;
2664 lon1_in[1] = 152.011; lat1_in[1] = 87.8123;
2665 lon1_in[2] = 102.985; lat1_in[2] = 88.4008;
2666 lon1_in[3] = 20; lat1_in[3] = 89.8047;
2668 lon2_in[0] = 145; lat2_in[0] = 88;
2669 lon2_in[1] = 145; lat2_in[1] = 90;
2670 lon2_in[2] = 150; lat2_in[2] = 90;
2671 lon2_in[3] = 150; lat2_in[3] = 88;
2683 n1_in = 4; n2_in = 4;
2686 lon1_in[0] = -202.6; lat1_in[0] = 87.95;
2687 lon1_in[1] = -280.; lat1_in[1] = 89.56;
2688 lon1_in[2] = -100.0; lat1_in[2] = 90;
2689 lon1_in[3] = -190.; lat1_in[3] = 88;
2691 lon2_in[0] = 145; lat2_in[0] = 88;
2692 lon2_in[1] = 145; lat2_in[1] = 90;
2693 lon2_in[2] = 150; lat2_in[2] = 90;
2694 lon2_in[3] = 150; lat2_in[3] = 88;
2708 n1_in = 4; n2_in = 4;
2711 lon1_in[0] = -160; lat1_in[0] = 88.5354;
2712 lon1_in[1] = 152.011; lat1_in[1] = 87.8123;
2713 lon1_in[2] = 102.985; lat1_in[2] = 88.4008;
2714 lon1_in[3] = 20; lat1_in[3] = 89.8047;
2716 lon2_in[0] = -202.6; lat2_in[0] = 87.95;
2717 lon2_in[1] = -280.; lat2_in[1] = 89.56;
2718 lon2_in[2] = -100.0; lat2_in[2] = 90;
2719 lon2_in[3] = -190.; lat2_in[3] = 88;
2731 n1_in = 4; n2_in = 4;
2733 lon1_in[0] = 20; lat1_in[0] = 10;
2734 lon1_in[1] = 20; lat1_in[1] = 12;
2735 lon1_in[2] = 22; lat1_in[2] = 12;
2736 lon1_in[3] = 22; lat1_in[3] = 10;
2737 lon2_in[0] = 18; lat2_in[0] = 8;
2738 lon2_in[1] = 18; lat2_in[1] = 14;
2739 lon2_in[2] = 24; lat2_in[2] = 14;
2740 lon2_in[3] = 24; lat2_in[3] = 8;
2753 n1_in = 4; n2_in = 4;
2756 lon1_in[0] = 350.0; lat1_in[0] = -45;
2757 lon1_in[1] = 350.0; lat1_in[1] = -43.43;
2758 lon1_in[2] = 352.1; lat1_in[2] = -43.41;
2759 lon1_in[3] = 352.1; lat1_in[3] = -44.98;
2760 lon2_in[0] = 350.0; lat2_in[0] = -46;
2761 lon2_in[1] = 350.0; lat2_in[1] = -44;
2762 lon2_in[2] = 352.5; lat2_in[2] = -44;
2763 lon2_in[3] = 352.5; lat2_in[3] = -46;
2776 n1_in = 4; n2_in = 4;
2778 lon1_in[0] = 305.0; lat1_in[0] = -35.26;
2779 lon1_in[1] = 305.0; lat1_in[1] = -33.80;
2780 lon1_in[2] = 306.6; lat1_in[2] = -34.51;
2781 lon1_in[3] = 306.6; lat1_in[3] = -35.99;
2782 lon2_in[0] = 125; lat2_in[0] = 32;
2783 lon2_in[1] = 125; lat2_in[1] = 34;
2784 lon2_in[2] = 127.5; lat2_in[2] = 34;
2785 lon2_in[3] = 127.5; lat2_in[3] = 32;
2798 n1_in = 4; n2_in = 4;
2800 lon1_in[0] = 125.0; lat1_in[0] = 1.46935;
2801 lon1_in[1] = 126.573; lat1_in[1] = 1.5091;
2802 lon1_in[2] = 126.573; lat1_in[2] = 0;
2803 lon1_in[3] = 125.0; lat1_in[3] = 0;
2804 lon2_in[0] = 125; lat2_in[0] = 0;
2805 lon2_in[1] = 125; lat2_in[1] = 2;
2806 lon2_in[2] = 127.5; lat2_in[2] = 2;
2807 lon2_in[3] = 127.5; lat2_in[3] = 0;
2824 n1_in = (nlon1+1)*(nlat1+1);
2825 n2_in = (nlon2+1)*(nlat2+1);
2827 lon1_in[0] = 350.0; lat1_in[0] = 90.00;
2828 lon1_in[1] = 170.0; lat1_in[1] = 87.92;
2829 lon1_in[2] = 260.0; lat1_in[2] = 87.92;
2830 lon1_in[3] = 215.0; lat1_in[3] = 87.06;
2842 lon2_in[0] = 167.5; lat2_in[0] = 88;
2843 lon2_in[1] = 170; lat2_in[1] = 88;
2844 lon2_in[2] = 167.5; lat2_in[2] = 90;
2845 lon2_in[3] = 170; lat2_in[3] = 90;
2891 n1_in = (nlon1+1)*(nlat1+1);
2892 n2_in = (nlon2+1)*(nlat2+1);
2894 lon1_in[0] = 111.3; lat1_in[0] = 1.591;
2895 lon1_in[1] = 109.7; lat1_in[1] = 2.926;
2896 lon1_in[2] = 108.2; lat1_in[2] = 4.256;
2897 lon1_in[3] = 110.0; lat1_in[3] = 0.000;
2898 lon1_in[4] = 108.4; lat1_in[4] = 1.335;
2899 lon1_in[5] = 106.8; lat1_in[5] = 2.668;
2900 lon1_in[6] = 108.7; lat1_in[6] = -1.591;
2901 lon1_in[7] = 107.1; lat1_in[7] = -0.256;
2902 lon1_in[8] = 105.5; lat1_in[8] = 1.078;
2904 lon2_in[0] = 107.5; lat2_in[0] = 0;
2905 lon2_in[1] = 110; lat2_in[1] = 0;
2906 lon2_in[2] = 107.5; lat2_in[2] = 2;
2907 lon2_in[3] = 110; lat2_in[3] = 2;
2924 n1_in = (nlon1+1)*(nlat1+1);
2925 n2_in = (nlon2+1)*(nlat2+1);
2928 for(j=0; j<=nlat1; j++)
for(i=0; i<=nlon1; i++){
2929 lon1_in[j*(nlon1+1)+i] = 20.0 + (i-1)*2.0;
2930 lat1_in[j*(nlon1+1)+i] = 10.0 + (j-1)*2.0;
2932 for(j=0; j<=nlat2; j++)
for(i=0; i<=nlon2; i++){
2933 lon2_in[j*(nlon2+1)+i] = 19.0 + (i-1)*2.0;
2934 lat2_in[j*(nlon2+1)+i] = 9.0 + (j-1)*2.0;
2945 n1_in = (nlon1+1)*(nlat1+1);
2946 n2_in = (nlon2+1)*(nlat2+1);
2975 lon1_in[0] = 120.369397984526174; lat1_in[0] = 16.751543427495864;
2976 lon1_in[1] = 119.999999999999986; lat1_in[1] = 16.751871929590038;
2977 lon1_in[2] = 120.369397846883501; lat1_in[2] = 16.397797979598028;
2978 lon1_in[3] = 119.999999999999986; lat1_in[3] = 16.398120477217255;
2979 lon2_in[0] = 120.369415056522087; lat2_in[0] = 16.752176828509153;
2980 lon2_in[1] = 119.999999999999986; lat2_in[1] = 16.752505523196167;
2981 lon2_in[2] = 120.369415056522087; lat2_in[2] = 16.397797949548146;
2982 lon2_in[3] = 119.999999999999986; lat2_in[3] = 16.398120477217255;
2988 error_handler(
"test_create_xgrid: incorrect case number");
2993 for(i=0; i<n1_in; i++) {
2994 lon1_in[i] *= D2R; lat1_in[i] *=D2R;
2996 for(i=0; i<n2_in; i++) {
2997 lon2_in[i] *= D2R; lat2_in[i] *=D2R;
3001 printf(
"\n*********************************************************\n");
3002 printf(
"\n Case %d \n", n);
3003 printf(
"\n*********************************************************\n");
3008 int *i1, *j1, *i2, *j2;
3009 double *xarea, *xclon, *xclat, *mask1;
3011 mask1 = (
double *)malloc(nlon1*nlat1*
sizeof(
double));
3012 i1 = (
int *)malloc(MAXXGRID*
sizeof(
int));
3013 j1 = (
int *)malloc(MAXXGRID*
sizeof(
int));
3014 i2 = (
int *)malloc(MAXXGRID*
sizeof(
int));
3015 j2 = (
int *)malloc(MAXXGRID*
sizeof(
int));
3016 xarea = (
double *)malloc(MAXXGRID*
sizeof(
double));
3017 xclon = (
double *)malloc(MAXXGRID*
sizeof(
double));
3018 xclat = (
double *)malloc(MAXXGRID*
sizeof(
double));
3020 for(i=0; i<nlon1*nlat1; i++) mask1[i] = 1.0;
3022 nxgrid = create_xgrid_great_circle(&nlon1, &nlat1, &nlon2, &nlat2, lon1_in, lat1_in,
3023 lon2_in, lat2_in, mask1, i1, j1, i2, j2,
3024 xarea, xclon, xclat);
3025 printf(
"\n*********************************************************\n");
3026 printf(
"\n First input grid box longitude, latitude \n \n");
3027 for(i=0; i<n1_in; i++) printf(
" %g, %g \n", lon1_in[i]*R2D, lat1_in[i]*R2D);
3029 printf(
"\n Second input grid box longitude, latitude \n \n");
3030 for(i=0; i<n2_in; i++) printf(
" %g, %g \n", lon2_in[i]*R2D, lat2_in[i]*R2D);
3032 printf(
"\n Number of exchange grid is %d\n", nxgrid);
3033 for(i=0; i<nxgrid; i++) {
3034 printf(
"(i1,j1)=(%d,%d), (i2,j2)=(%d, %d), xgrid_area=%g, xgrid_clon=%g, xgrid_clat=%g\n",
3035 i1[i], j1[i], i2[i], j2[i], xarea[i], xclon[i], xclat[i]);
3040 double *x1, *y1, *z1, *area1;
3045 for(i=0; i<nxgrid; i++) {
3046 area_sum+= xarea[i];
3049 area1 = (
double *)malloc((nlon1)*(nlat1)*
sizeof(
double));
3050 get_grid_great_circle_area_(&nlon1, &nlat1, lon1_in, lat1_in, area1);
3052 printf(
"xgrid area sum is %g, grid 1 area is %g\n", area_sum, area1[0]);
3066 latlon2xyz(n1_in, lon1_in, lat1_in, x1_in, y1_in, z1_in);
3067 latlon2xyz(n2_in, lon2_in, lat2_in, x2_in, y2_in, z2_in);
3069 n_out = clip_2dx2d_great_circle(x1_in, y1_in, z1_in, 4, x2_in, y2_in, z2_in, n2_in,
3070 x_out, y_out, z_out);
3071 xyz2latlon(n_out, x_out, y_out, z_out, lon_out, lat_out);
3073 printf(
"\n*********************************************************\n");
3074 printf(
"\n First input grid box longitude, latitude \n \n");
3075 for(i=0; i<n1_in; i++) printf(
" %g, %g \n", lon1_in[i]*R2D, lat1_in[i]*R2D);
3077 printf(
"\n Second input grid box longitude, latitude \n \n");
3078 for(i=0; i<n2_in; i++) printf(
" %g, %g \n", lon2_in[i]*R2D, lat2_in[i]*R2D);
3080 printf(
"\n output clip grid box longitude, latitude for case 1 \n \n");
3081 for(i=0; i<n_out; i++) printf(
" %g, %g \n", lon_out[i]*R2D, lat_out[i]*R2D);
pure elemental type(point) function latlon2xyz(lat, lon)
Return the (x,y,z) position of a given (lat,lon) point.
real(r8_kind), dimension(:,:), allocatable area
area of each grid box
integer nlat
No description.
integer nlon
No description.
integer sense
No description.