GRASS Programmer's Manual
6.4.2(2012)
|
00001 00019 #include <stdlib.h> 00020 #include <stdio.h> 00021 00022 #include <grass/gstypes.h> 00023 #include <grass/glocale.h> 00024 00025 #include "gsget.h" 00026 #include "rowcol.h" 00027 00028 #define FIRST_SURF_ID 110658 00029 00030 static geosurf *Surf_top; 00031 static int Invertmask; 00032 00033 /***********************************************************************/ 00034 void gs_err(const char *msg) 00035 { 00036 G_warning("%s", msg); 00037 00038 return; 00039 } 00040 00047 void gs_init(void) 00048 { 00049 Surf_top = NULL; 00050 00051 return; 00052 } 00053 00062 geosurf *gs_get_surf(int id) 00063 { 00064 geosurf *gs; 00065 00066 G_debug(5, "gs_get_surf():"); 00067 00068 for (gs = Surf_top; gs; gs = gs->next) { 00069 if (gs->gsurf_id == id) { 00070 G_debug(5, " id=%d", id); 00071 return (gs); 00072 } 00073 } 00074 00075 return (NULL); 00076 } 00077 00086 geosurf *gs_get_prev_surface(int id) 00087 { 00088 geosurf *ps; 00089 00090 G_debug(5, "gs_get_prev_surface"); 00091 00092 for (ps = Surf_top; ps; ps = ps->next) { 00093 if (ps->gsurf_id == id - 1) { 00094 return (ps); 00095 } 00096 } 00097 00098 return (NULL); 00099 } 00100 00108 int gs_getall_surfaces(geosurf ** gsurfs) 00109 { 00110 geosurf *gs; 00111 int i; 00112 00113 for (i = 0, gs = Surf_top; gs; gs = gs->next, i++) { 00114 gsurfs[i] = gs; 00115 } 00116 00117 G_debug(5, "gs_num_surfaces(): num=%d", i); 00118 00119 return (i); 00120 } 00121 00127 int gs_num_surfaces(void) 00128 { 00129 geosurf *gs; 00130 int i; 00131 00132 for (i = 0, gs = Surf_top; gs; gs = gs->next, i++) ; 00133 00134 G_debug(5, "gs_num_surfaces(): num=%d", i); 00135 00136 return (i); 00137 } 00138 00139 00149 int gs_att_is_set(geosurf * surf, IFLAG att) 00150 { 00151 geosurf *gs; 00152 00153 if (surf) { 00154 return (NOTSET_ATT != surf->att[att].att_src); 00155 } 00156 00157 /* if surf == NULL, look at all surfs */ 00158 for (gs = Surf_top; gs; gs = gs->next) { 00159 if (NOTSET_ATT != gs->att[att].att_src) { 00160 return (1); 00161 } 00162 } 00163 00164 return (0); 00165 } 00166 00172 geosurf *gs_get_last_surface(void) 00173 { 00174 geosurf *ls; 00175 00176 if (!Surf_top) { 00177 return (NULL); 00178 } 00179 00180 for (ls = Surf_top; ls->next; ls = ls->next) ; 00181 00182 G_debug(5, "gs_get_last_surface(): last surface id=%d", ls->gsurf_id); 00183 00184 return (ls); 00185 } 00186 00187 00193 geosurf *gs_get_new_surface(void) 00194 { 00195 geosurf *ns, *ls; 00196 00197 ns = (geosurf *) G_malloc(sizeof(geosurf)); /* G_fatal_error */ 00198 if (!ns) { 00199 return (NULL); 00200 } 00201 00202 if ((ls = gs_get_last_surface())) { 00203 ls->next = ns; 00204 ns->gsurf_id = ls->gsurf_id + 1; 00205 } 00206 else { 00207 Surf_top = ns; 00208 ns->gsurf_id = FIRST_SURF_ID; 00209 } 00210 00211 ns->next = NULL; 00212 00213 G_debug(5, "gs_get_new_surface(): id=%d", ns->gsurf_id); 00214 00215 return (ns); 00216 } 00217 00232 int gs_init_surf(geosurf * gs, double ox, double oy, int rows, int cols, 00233 double xres, double yres) 00234 { 00235 geosurf *ps; 00236 int i; 00237 00238 if (!gs) { 00239 return (-1); 00240 } 00241 00242 G_debug(5, "gs_init_surf() id=%d", gs->gsurf_id); 00243 00244 /* default attributes */ 00245 for (i = 0; i < MAX_ATTS; i++) { 00246 gs->att[i].att_src = NOTSET_ATT; 00247 gs->att[i].att_type = ATTY_INT; 00248 gs->att[i].hdata = -1; 00249 gs->att[i].user_func = NULL; 00250 gs->att[i].constant = 0.; 00251 gs->att[i].lookup = NULL; 00252 gs->att[i].min_nz = gs->att[i].max_nz = gs->att[i].range_nz = 0; 00253 gs->att[i].default_null = 0.; 00254 } 00255 00256 /* default values */ 00257 gs->ox = ox; 00258 gs->oy = oy; 00259 gs->rows = rows; 00260 gs->cols = cols; 00261 gs->xres = xres; 00262 gs->yres = yres; 00263 gs->x_mod = 2; 00264 gs->y_mod = 2; 00265 gs->x_modw = rows / 30; 00266 gs->y_modw = rows / 30; 00267 gs->xmin = ox; 00268 gs->xmax = ox + (cols - 1) * xres; 00269 gs->xrange = gs->xmax - gs->xmin; 00270 gs->ymin = oy; 00271 gs->ymax = oy + (rows - 1) * yres; 00272 gs->yrange = gs->ymax - gs->ymin; 00273 gs->zmin = gs->zmin_nz = gs->zminmasked = 0; 00274 gs->zmax = gs->zmax_nz = 0; 00275 gs->zrange = gs->zrange_nz = 0; 00276 gs->wire_color = 0x00888888; 00277 gs->x_trans = gs->y_trans = gs->z_trans = 0.0; 00278 gs->nz_topo = gs->nz_color = 0; 00279 gs->norm_needupdate = 1; 00280 gs->mask_needupdate = 1; 00281 gs->curmask = NULL; 00282 gs->norms = NULL; 00283 00284 gs->draw_mode = DM_GOURAUD; 00285 00286 /* default z_exag value */ 00287 if (gs->gsurf_id == FIRST_SURF_ID) { 00288 gs->z_exag = 1.0; 00289 } 00290 else { 00291 ps = gs_get_prev_surface(gs->gsurf_id); 00292 gs->z_exag = ps->z_exag; 00293 } 00294 00295 return (0); 00296 } 00297 00306 int gs_init_normbuff(geosurf * gs) 00307 { 00308 long size; 00309 00310 if (!gs) { 00311 return (0); 00312 } 00313 00314 if (gs->norms) { 00315 G_free(gs->norms); 00316 } 00317 00318 size = gs->rows * gs->cols * sizeof(unsigned long); 00319 00320 gs->norms = (unsigned long *)G_malloc(size); /* G_fatal_error */ 00321 if (!gs->norms) { 00322 return (-1); 00323 } 00324 00325 gs->norm_needupdate = 1; 00326 00327 return (1); 00328 } 00329 00337 void print_frto(float (*ft)[4]) 00338 { 00339 fprintf(stderr, "FROM: %f, %f, %f\n", ft[FROM][X], ft[FROM][Y], 00340 ft[FROM][Z]); 00341 fprintf(stderr, "TO: %f, %f, %f\n", ft[TO][X], ft[TO][Y], ft[TO][Z]); 00342 00343 return; 00344 } 00345 00353 void print_realto(float *rt) 00354 { 00355 fprintf(stderr, "REAL TO: %f, %f, %f\n", rt[X], rt[Y], rt[Z]); 00356 00357 return; 00358 } 00359 00367 void print_256lookup(int *buff) 00368 { 00369 int i; 00370 00371 for (i = 0; i < 256; i++) { 00372 if (!(i % 8)) { 00373 fprintf(stderr, "\n"); 00374 } 00375 00376 fprintf(stderr, "%x ", buff[i]); 00377 } 00378 00379 fprintf(stderr, "\n"); 00380 00381 return; 00382 } 00383 00391 void print_surf_fields(geosurf * s) 00392 { 00393 fprintf(stderr, "ID: %d\n", s->gsurf_id); 00394 fprintf(stderr, "rows: %d cols: %d\n", s->rows, s->cols); 00395 fprintf(stderr, "draw_mode: %x\n", s->draw_mode); 00396 fprintf(stderr, "wire_color: %lx\n", s->wire_color); 00397 fprintf(stderr, "ox: %lf oy: %lf\n", s->ox, s->oy); 00398 fprintf(stderr, "xres: %lf yres: %lf\n", s->xres, s->yres); 00399 fprintf(stderr, "z_exag: %f \n", s->z_exag); 00400 fprintf(stderr, "x_trans: %f y_trans: %f z_trans: %f\n", 00401 s->x_trans, s->y_trans, s->z_trans); 00402 fprintf(stderr, "xmin: %f ymin: %f zmin: %f\n", 00403 s->xmin, s->ymin, s->zmin); 00404 fprintf(stderr, "xmax: %f ymax: %f zmax: %f\n", 00405 s->xmax, s->ymax, s->zmax); 00406 fprintf(stderr, "x_mod: %d y_mod: %d x_modw: %d y_modw: %d\n", 00407 s->x_mod, s->y_mod, s->x_modw, s->y_modw); 00408 00409 return; 00410 } 00411 00419 void print_view_fields(geoview * gv) 00420 { 00421 fprintf(stderr, "coord_sys: %d\n", gv->coord_sys); 00422 fprintf(stderr, "view_proj: %d\n", gv->view_proj); 00423 fprintf(stderr, "infocus: %d\n", gv->infocus); 00424 print_frto(gv->from_to); 00425 fprintf(stderr, "twist: %d fov: %d\n", gv->twist, gv->fov); 00426 fprintf(stderr, "incl: %d look: %d\n", gv->incl, gv->look); 00427 fprintf(stderr, "real_to: %f %f %f\n", 00428 gv->real_to[X], gv->real_to[Y], gv->real_to[Z]); 00429 fprintf(stderr, "vert_exag: %f scale: %f \n", gv->vert_exag, gv->scale); 00430 00431 return; 00432 } 00433 00441 void gs_set_defaults(geosurf * gs, float *defs, float *null_defs) 00442 { 00443 int i; 00444 00445 G_debug(5, "gs_set_defaults(): id=%d", gs->gsurf_id); 00446 00447 for (i = 0; i < MAX_ATTS; i++) { 00448 gs->att[i].constant = defs[i]; 00449 gs->att[i].default_null = null_defs[i]; 00450 gs->att[i].lookup = NULL; 00451 gs->att[i].hdata = -1; 00452 gs->att[i].att_src = NOTSET_ATT; 00453 } 00454 00455 return; 00456 } 00457 00463 void gs_delete_surf(int id) 00464 { 00465 geosurf *fs; 00466 00467 G_debug(5, "gs_delete_surf"); 00468 00469 fs = gs_get_surf(id); 00470 00471 if (fs) { 00472 gs_free_surf(fs); 00473 } 00474 00475 return; 00476 } 00477 00487 int gs_free_surf(geosurf * fs) 00488 { 00489 geosurf *gs; 00490 int found = 0; 00491 00492 G_debug(5, "gs_free_surf"); 00493 00494 if (Surf_top) { 00495 if (fs == Surf_top) { 00496 if (Surf_top->next) { 00497 /* can't free top if last */ 00498 found = 1; 00499 Surf_top = fs->next; 00500 } 00501 else { 00502 gs_free_unshared_buffs(fs); 00503 00504 if (fs->curmask) { 00505 G_free(fs->curmask); 00506 } 00507 00508 if (fs->norms) { 00509 G_free(fs->norms); 00510 } 00511 00512 G_free(fs); 00513 Surf_top = NULL; 00514 } 00515 } 00516 else { 00517 for (gs = Surf_top; gs && !found; gs = gs->next) { 00518 if (gs->next) { 00519 if (gs->next == fs) { 00520 found = 1; 00521 gs->next = fs->next; 00522 } 00523 } 00524 } 00525 } 00526 00527 if (found) { 00528 gs_free_unshared_buffs(fs); 00529 00530 if (fs->curmask) { 00531 G_free(fs->curmask); 00532 } 00533 00534 if (fs->norms) { 00535 G_free(fs->norms); 00536 } 00537 00538 G_free(fs); 00539 fs = NULL; 00540 } 00541 00542 return (found); 00543 } 00544 00545 return (-1); 00546 } 00547 00557 void gs_free_unshared_buffs(geosurf * fs) 00558 { 00559 geosurf *gs; 00560 int i, j, same; 00561 int old_datah; 00562 00563 G_debug(5, "gs_free_unshared_buffs"); 00564 00565 /* for each attribute 00566 if !same, free buff 00567 */ 00568 for (i = 0; i < MAX_ATTS; i++) { 00569 same = 0; 00570 00571 if (0 < (old_datah = fs->att[i].hdata)) { 00572 /* for ea att of all other surfs */ 00573 for (gs = Surf_top; gs; gs = gs->next) { 00574 for (j = 0; j < MAX_ATTS; j++) { 00575 if (old_datah == gs->att[j].hdata) { 00576 same = 1; 00577 } 00578 } 00579 } 00580 00581 if (!same) { 00582 gsds_free_datah(old_datah); 00583 } 00584 } 00585 } 00586 00587 return; 00588 } 00589 00597 int gs_num_datah_reused(int dh) 00598 { 00599 geosurf *gs; 00600 int ref, j; 00601 00602 G_debug(5, "gs_num_datah_reused"); 00603 00604 /* for each attribute 00605 if same, ++reference 00606 */ 00607 /* for ea att of all surfs */ 00608 ref = 0; 00609 00610 for (gs = Surf_top; gs; gs = gs->next) { 00611 for (j = 0; j < MAX_ATTS; j++) { 00612 if (dh == gs->att[j].hdata) { 00613 ref++; 00614 } 00615 } 00616 } 00617 00618 return (ref); 00619 } 00620 00630 int gs_get_att_type(geosurf * gs, int desc) 00631 { 00632 G_debug(5, "gs_get_att_type"); 00633 00634 if (!LEGAL_ATT(desc)) { 00635 return (-1); 00636 } 00637 00638 if (gs) { 00639 if (gs->att[desc].att_src != NOTSET_ATT) { 00640 return (gs->att[desc].att_type); 00641 } 00642 } 00643 00644 return (-1); 00645 } 00646 00656 int gs_get_att_src(geosurf * gs, int desc) 00657 { 00658 if (gs) 00659 G_debug(5, "gs_get_att_src(): id=%d, desc=%d", gs->gsurf_id, desc); 00660 if (!LEGAL_ATT(desc)) { 00661 return (-1); 00662 } 00663 00664 if (gs) { 00665 return (gs->att[desc].att_src); 00666 } 00667 00668 return (-1); 00669 } 00670 00681 typbuff *gs_get_att_typbuff(geosurf * gs, int desc, int to_write) 00682 { 00683 typbuff *tb; 00684 geosurf *gsref; 00685 00686 if (gs) { 00687 G_debug(5, "gs_get_att_typbuff(): id=%d desc=%d to_write=%d", 00688 gs->gsurf_id, desc, to_write); 00689 if ((tb = gsds_get_typbuff(gs->att[desc].hdata, to_write))) { 00690 tb->tfunc = NULL; 00691 00692 if (desc == ATT_TOPO) { 00693 gsref = gsdiff_get_SDref(); 00694 00695 if (gsref && gsref != gs) { 00696 tb->tfunc = gsdiff_do_SD; 00697 } 00698 } 00699 00700 return (tb); 00701 } 00702 } 00703 00704 return (NULL); 00705 } 00706 00717 int gs_malloc_att_buff(geosurf * gs, int desc, int type) 00718 { 00719 int hdata, dims[2], ndims; 00720 00721 G_debug(5, "gs_malloc_att_buff"); 00722 00723 if (gs) { 00724 if (0 < (hdata = gs->att[desc].hdata)) { 00725 dims[0] = gs->rows; 00726 dims[1] = gs->cols; 00727 ndims = 2; 00728 gs_set_att_type(gs, desc, type); 00729 00730 return (gsds_alloc_typbuff(hdata, dims, ndims, type)); 00731 } 00732 } 00733 00734 return (-1); 00735 } 00736 00746 int gs_malloc_lookup(geosurf * gs, int desc) 00747 { 00748 int size; 00749 00750 G_debug(5, "gs_malloc_lookup"); 00751 00752 if (gs) { 00753 if (gs->att[desc].lookup) { 00754 G_free(gs->att[desc].lookup); 00755 gs->att[desc].lookup = NULL; 00756 } 00757 00758 switch (gs->att[desc].att_type) { 00759 case (ATTY_SHORT): 00760 size = 32768 * sizeof(int); 00761 00762 /* positive integers only, because use as array index */ 00763 gs->att[desc].lookup = (int *)G_malloc(size); /* G_fatal_error */ 00764 if (!gs->att[desc].lookup) { 00765 return (-1); 00766 } 00767 00768 break; 00769 case (ATTY_CHAR): 00770 size = 256 * sizeof(int); 00771 00772 /* unsigned char */ 00773 gs->att[desc].lookup = (int *)G_malloc(size); 00774 if (!gs->att[desc].lookup) { 00775 return (-1); 00776 } 00777 00778 break; 00779 default: 00780 G_warning("bad type: gs_malloc_lookup"); 00781 return (-1); 00782 } 00783 00784 if (gs->att[desc].lookup) { 00785 return (0); 00786 } 00787 00788 } 00789 00790 return (-1); 00791 } 00792 00803 int gs_set_att_type(geosurf * gs, int desc, int type) 00804 { 00805 00806 G_debug(5, "gs_set_att_type(): desc=%d, type=%d", desc, type); 00807 00808 if (gs && LEGAL_TYPE(type)) { 00809 gs->att[desc].att_type = type; 00810 00811 return (0); 00812 } 00813 00814 return (-1); 00815 } 00816 00827 int gs_set_att_src(geosurf * gs, int desc, int src) 00828 { 00829 if (gs) 00830 G_debug(5, "gs_set_att_src(): id=%d desc=%d src=%d", 00831 gs->gsurf_id, desc, src); 00832 00833 /* check if old source was MAP_ATT, free buff */ 00834 if (MAP_ATT == gs_get_att_src(gs, desc)) { 00835 if (1 == gs_num_datah_reused(gs->att[desc].hdata)) { 00836 /* only reference */ 00837 G_debug(5, "gs_set_att_src(): replacing existing map"); 00838 gsds_free_datah(gs->att[desc].hdata); 00839 } 00840 00841 if (ATT_TOPO == desc) { 00842 if (gs->norms) { 00843 G_free(gs->norms); 00844 } 00845 00846 gs->norms = NULL; 00847 gs->norm_needupdate = 0; 00848 } 00849 } 00850 00851 if (gs && LEGAL_SRC(src)) { 00852 gs->att[desc].att_src = src; 00853 00854 return (0); 00855 } 00856 00857 return (-1); 00858 } 00859 00872 int gs_set_att_const(geosurf * gs, int desc, float constant) 00873 { 00874 00875 if (gs) { 00876 G_debug(5, "gs_set_att_const(): id=%d, desc=%d, const=%f", 00877 gs->gsurf_id, desc, constant); 00878 gs->att[desc].constant = constant; 00879 00880 if (ATT_MASK == desc) { 00881 gs->mask_needupdate = 1; 00882 } 00883 else { 00884 gs_set_att_src(gs, desc, CONST_ATT); 00885 } 00886 00887 Gs_update_attrange(gs, desc); 00888 00889 return (0); 00890 } 00891 00892 return (-1); 00893 } 00894 00900 void gs_set_maskmode(int invert) 00901 { 00902 Invertmask = invert; 00903 00904 return; 00905 } 00906 00915 int gs_mask_defined(geosurf * gs) 00916 { 00917 return (gs->att[ATT_MASK].att_src != NOTSET_ATT); 00918 } 00919 00933 int gs_masked(typbuff * tb, int col, int row, int offset) 00934 { 00935 int ret; 00936 00937 ret = 1; 00938 00939 if (tb->bm) { 00940 ret = BM_get(tb->bm, col, row); 00941 } 00942 else if (tb->cb) { 00943 ret = tb->cb[offset]; 00944 } 00945 else if (tb->sb) { 00946 ret = tb->sb[offset]; 00947 } 00948 else if (tb->ib) { 00949 ret = tb->ib[offset]; 00950 } 00951 else if (tb->fb) { 00952 ret = tb->fb[offset]; 00953 } 00954 00955 return (Invertmask ? ret : !ret); 00956 } 00957 00969 int gs_mapcolor(typbuff * cobuff, gsurf_att * coloratt, int offset) 00970 { 00971 if (coloratt->lookup) { 00972 /* for now, but may add larger color lookup capabilities later, 00973 so would have to use GET_MAPATT */ 00974 return (coloratt->lookup[cobuff->cb[offset]]); 00975 } 00976 00977 return (cobuff->ib[offset]); 00978 } 00979 00980 /* 00981 In the following functions, "extents" refers to translated extents for 00982 a single surface, while "range" refers to accumulated extents of all 00983 loaded surfaces 00984 */ 00985 00998 int gs_get_zextents(geosurf * gs, float *min, float *max, float *mid) 00999 { 01000 *min = gs->zmin + gs->z_trans; 01001 *max = gs->zmax + gs->z_trans; 01002 *mid = (*max + *min) / 2.; 01003 01004 return (1); 01005 } 01006 01016 int gs_get_xextents(geosurf * gs, float *min, float *max) 01017 { 01018 *min = gs->xmin + gs->x_trans; 01019 *max = gs->xmax + gs->x_trans; 01020 01021 return (1); 01022 } 01023 01033 int gs_get_yextents(geosurf * gs, float *min, float *max) 01034 { 01035 *min = gs->ymin + gs->y_trans; 01036 *max = gs->ymax + gs->y_trans; 01037 01038 return (1); 01039 } 01040 01041 01054 int gs_get_zrange0(float *min, float *max) 01055 { 01056 geosurf *gs; 01057 01058 if (Surf_top) { 01059 *min = Surf_top->zmin; 01060 *max = Surf_top->zmax; 01061 } 01062 else { 01063 return (-1); 01064 } 01065 01066 for (gs = Surf_top->next; gs; gs = gs->next) { 01067 if (gs->zmin < *min) { 01068 *min = gs->zmin; 01069 } 01070 01071 if (gs->zmax > *max) { 01072 *max = gs->zmax; 01073 } 01074 } 01075 01076 return (1); 01077 } 01078 01088 int gs_get_zrange(float *min, float *max) 01089 { 01090 geosurf *gs; 01091 float tmin, tmax, tmid; 01092 01093 if (Surf_top) { 01094 gs_get_zextents(Surf_top, &tmin, &tmax, &tmid); 01095 *min = tmin; 01096 *max = tmax; 01097 } 01098 else { 01099 return (-1); 01100 } 01101 01102 for (gs = Surf_top->next; gs; gs = gs->next) { 01103 gs_get_zextents(gs, &tmin, &tmax, &tmid); 01104 01105 if (tmin < *min) { 01106 *min = tmin; 01107 } 01108 01109 if (tmax > *max) { 01110 *max = tmax; 01111 } 01112 } 01113 01114 return (1); 01115 } 01116 01126 int gs_get_xrange(float *min, float *max) 01127 { 01128 geosurf *gs; 01129 float tmin, tmax; 01130 01131 if (Surf_top) { 01132 gs_get_xextents(Surf_top, &tmin, &tmax); 01133 *min = tmin; 01134 *max = tmax; 01135 } 01136 else { 01137 return (-1); 01138 } 01139 01140 for (gs = Surf_top->next; gs; gs = gs->next) { 01141 gs_get_xextents(gs, &tmin, &tmax); 01142 01143 if (tmin < *min) { 01144 *min = tmin; 01145 } 01146 01147 if (tmax > *max) { 01148 *max = tmax; 01149 } 01150 } 01151 01152 return (1); 01153 } 01154 01164 int gs_get_yrange(float *min, float *max) 01165 { 01166 geosurf *gs; 01167 float tmin, tmax; 01168 01169 if (Surf_top) { 01170 gs_get_yextents(Surf_top, &tmin, &tmax); 01171 *min = tmin; 01172 *max = tmax; 01173 } 01174 else { 01175 return (-1); 01176 } 01177 01178 for (gs = Surf_top->next; gs; gs = gs->next) { 01179 gs_get_yextents(gs, &tmin, &tmax); 01180 01181 if (tmin < *min) { 01182 *min = tmin; 01183 } 01184 01185 if (tmax > *max) { 01186 *max = tmax; 01187 } 01188 } 01189 01190 return (1); 01191 } 01192 01203 int gs_get_data_avg_zmax(float *azmax) 01204 { 01205 float zmax; 01206 int i; 01207 geosurf *gs; 01208 01209 zmax = *azmax = 0.0; 01210 01211 if (Surf_top) { 01212 for (i = 0, gs = Surf_top; gs; i++, gs = gs->next) { 01213 zmax += (gs->zmax + gs->z_trans); 01214 } 01215 01216 *azmax = zmax / i; 01217 01218 return (1); 01219 } 01220 01221 return (-1); 01222 } 01223 01232 int gs_get_datacenter(float *cen) 01233 { 01234 float zmin, zmax, ymin, ymax, xmin, xmax; 01235 geosurf *gs; 01236 01237 if (Surf_top) { 01238 zmin = Surf_top->zmin; 01239 zmax = Surf_top->zmax; 01240 ymin = Surf_top->ymin; 01241 ymax = Surf_top->ymax; 01242 xmin = Surf_top->xmin; 01243 xmax = Surf_top->xmax; 01244 01245 for (gs = Surf_top->next; gs; gs = gs->next) { 01246 if (gs->zmin < zmin) { 01247 zmin = gs->zmin; 01248 } 01249 01250 if (gs->zmax > zmax) { 01251 zmax = gs->zmax; 01252 } 01253 01254 if (gs->ymin < ymin) { 01255 ymin = gs->ymin; 01256 } 01257 01258 if (gs->ymax > ymax) { 01259 ymax = gs->ymax; 01260 } 01261 01262 if (gs->xmin < xmin) { 01263 xmin = gs->xmin; 01264 } 01265 01266 if (gs->xmax > xmax) { 01267 xmax = gs->xmax; 01268 } 01269 } 01270 01271 cen[X] = (xmin + xmax) / 2. - xmin; 01272 cen[Y] = (ymin + ymax) / 2. - ymin; 01273 cen[Z] = (zmin + zmax) / 2.; 01274 01275 return (1); 01276 } 01277 01278 cen[X] = cen[Y] = cen[Z] = 0.0; 01279 01280 return (-1); 01281 } 01282 01283 01290 int gs_setall_norm_needupdate(void) 01291 { 01292 geosurf *gs; 01293 01294 if (Surf_top) { 01295 Surf_top->norm_needupdate = 1; 01296 } 01297 else { 01298 return (-1); 01299 } 01300 01301 for (gs = Surf_top->next; gs; gs = gs->next) { 01302 gs->norm_needupdate = 1; 01303 } 01304 01305 return (1); 01306 } 01307 01317 int gs_point_is_masked(geosurf * gs, float *pt) 01318 { 01319 int vrow, vcol, drow, dcol; 01320 int retmask = 0, npts = 0; 01321 float p2[2]; 01322 01323 if (!gs->curmask) { 01324 return (0); 01325 } 01326 01327 vrow = Y2VROW(gs, pt[Y]); 01328 vcol = X2VCOL(gs, pt[X]); 01329 01330 /* check right & bottom edges */ 01331 if (pt[X] == VCOL2X(gs, VCOLS(gs))) { 01332 /* right edge */ 01333 vcol -= 1; 01334 } 01335 01336 if (pt[Y] == VROW2Y(gs, VROWS(gs))) { 01337 /* bottom edge */ 01338 vrow -= 1; 01339 } 01340 01341 drow = VROW2DROW(gs, vrow); 01342 dcol = VCOL2DCOL(gs, vcol); 01343 01344 if (BM_get(gs->curmask, dcol, drow)) { 01345 retmask |= MASK_TL; 01346 npts++; 01347 } 01348 01349 dcol = VCOL2DCOL(gs, vcol + 1); 01350 01351 if (BM_get(gs->curmask, dcol, drow)) { 01352 retmask |= MASK_TR; 01353 npts++; 01354 } 01355 01356 drow = VROW2DROW(gs, vrow + 1); 01357 01358 if (BM_get(gs->curmask, dcol, drow)) { 01359 retmask |= MASK_BR; 01360 npts++; 01361 } 01362 01363 dcol = VCOL2DCOL(gs, vcol); 01364 01365 if (BM_get(gs->curmask, dcol, drow)) { 01366 retmask |= MASK_BL; 01367 npts++; 01368 } 01369 01370 if (npts != 1) { 01371 /* zero or masked */ 01372 return (retmask | npts); 01373 } 01374 01375 p2[X] = VCOL2X(gs, vcol); 01376 p2[Y] = VROW2Y(gs, vrow + 1); 01377 01378 switch (retmask) { 01379 case MASK_TL: 01380 if ((pt[X] - p2[X]) / VXRES(gs) > (pt[Y] - p2[Y]) / VYRES(gs)) { 01381 /* lower triangle */ 01382 return (0); 01383 } 01384 01385 return (retmask | npts); 01386 case MASK_TR: 01387 01388 return (retmask | npts); 01389 case MASK_BR: 01390 if ((pt[X] - p2[X]) / VXRES(gs) <= (pt[Y] - p2[Y]) / VYRES(gs)) { 01391 /* upper triangle */ 01392 return (0); 01393 } 01394 01395 return (retmask | npts); 01396 case MASK_BL: 01397 01398 return (retmask | npts); 01399 } 01400 01401 /* Assume that if we get here it is an error */ 01402 return (0); 01403 } 01404 01417 int gs_distance_onsurf(geosurf * gs, float *p1, float *p2, float *dist, 01418 int use_exag) 01419 { 01420 Point3 *tmp; 01421 int np, i; 01422 float exag, length; 01423 01424 if (in_vregion(gs, p1) && in_vregion(gs, p2)) { 01425 if (NULL == (tmp = gsdrape_get_segments(gs, p1, p2, &np))) { 01426 return (0); 01427 } 01428 01429 length = 0.; 01430 01431 if (use_exag) { 01432 exag = GS_global_exag(); 01433 tmp[0][Z] *= exag; 01434 01435 for (i = 0; i < (np - 1); i++) { 01436 tmp[i + 1][Z] *= exag; 01437 length += GS_distance(tmp[i], tmp[i + 1]); 01438 } 01439 } 01440 else { 01441 for (i = 0; i < (np - 1); i++) { 01442 length += GS_distance(tmp[i], tmp[i + 1]); 01443 } 01444 } 01445 01446 *dist = length; 01447 01448 return (1); 01449 } 01450 01451 return (0); 01452 }