static int load_data(Xdf_t *This, off_t begin, off_t end, int retries) { int ptr, nr, bytes; RawRequest_t requests[100]; Compactify_t compactify; adjust_bounds(This, &begin, &end); ptr = begin; nr = 0; for(ptr=REC.begin; ptr < end ; ptr = REC.end) add_to_request_if_invalid(This, ptr, requests, &nr, &compactify); bytes = send_cmd(This->fd,requests, nr, "reading", retries); if(bytes < 0) return bytes; ptr = begin; for(ptr=REC.begin; ptr < end ; ptr = REC.end) { if(!REC.valid) { if(bytes >= REC.end - REC.begin) { bytes -= REC.end - REC.begin; REC.valid = 1; } else if(ptr > begin) return ptr * This->sector_size; else return -1; } } return end * This->sector_size; }
static int load_bounds(Xdf_t *This, off_t begin, off_t end) { off_t lbegin, lend; int endp1, endp2; lbegin = begin; lend = end; adjust_bounds(This, &lbegin, &lend); if(begin != BEGIN(lbegin) * This->sector_size && end != BEGIN(lend) * This->sector_size && lend < END(END(lbegin))) /* contiguous end & begin, load them in one go */ return load_data(This, begin, end, 4); if(begin != BEGIN(lbegin) * This->sector_size) { endp1 = load_data(This, begin, begin, 4); if(endp1 < 0) return endp1; } if(end != BEGIN(lend) * This->sector_size) { endp2 = load_data(This, end, end, 4); if(endp2 < 0) return BEGIN(lend) * This->sector_size; } return lend * This->sector_size; }
/*! * \brief Split a node according to clusters. */ static void split_node (struct rtree_node *node) { int i; struct rtree_node *new_node; assert (node); assert (node->flags.is_leaf ? (void *) node->u.rects[M_SIZE]. bptr : (void *) node->u.kids[M_SIZE]); new_node = find_clusters (node); if (node->parent == NULL) /* split root node */ { struct rtree_node *second; second = (struct rtree_node *)calloc (1, sizeof (*second)); *second = *node; if (!second->flags.is_leaf) for (i = 0; i < M_SIZE; i++) if (second->u.kids[i]) second->u.kids[i]->parent = second; node->flags.is_leaf = 0; node->flags.manage = 0; second->parent = new_node->parent = node; node->u.kids[0] = new_node; node->u.kids[1] = second; for (i = 2; i < M_SIZE + 1; i++) node->u.kids[i] = NULL; adjust_bounds (node); sort_node (node); #ifdef SLOW_ASSERTS assert (__r_tree_is_good (node)); #endif return; } for (i = 0; i < M_SIZE; i++) if (!node->parent->u.kids[i]) break; node->parent->u.kids[i] = new_node; #ifdef SLOW_ASSERTS assert (__r_node_is_good (node)); assert (__r_node_is_good (new_node)); #endif if (i < M_SIZE) { #ifdef SLOW_ASSERTS assert (__r_node_is_good (node->parent)); #endif sort_node (node->parent); return; } split_node (node->parent); }
static void mark_dirty(Xdf_t *This, off_t begin, off_t end) { int ptr; adjust_bounds(This, &begin, &end); ptr = begin; for(ptr=REC.begin; ptr < end ; ptr = REC.end) { REC.valid = 1; if(!REC.phantom) REC.dirty = 1; } }
void highlight_contour (MISC *misc, OPTIONS *options, NV_FLOAT64 lat, NV_FLOAT64 lon, nvMap *map) { // Save the MISP depth for drawing contours (depending on the type of MISP surface) NV_F64_COORD2 xy; BIN_RECORD bin; xy.y = lat; xy.x = lon; // Try to find the highest layer with a valid value to grab the contour level. for (NV_INT32 pfm = 0 ; pfm < misc->abe_share->pfm_count ; pfm++) { if (bin_inside_ptr (&misc->abe_share->open_args[pfm].head, xy)) { read_bin_record_xy (misc->pfm_handle[pfm], xy, &bin); // Check the validity. if ((bin.validity & PFM_DATA) || (bin.validity & PFM_INTERPOLATED)) break; } } NV_FLOAT32 save_level = (NV_FLOAT32) (NINT (bin.avg_filtered_depth)); // Custom contour levels... if (misc->abe_share->cint == 0.0) { NV_FLOAT32 mindiff = 999999999.0; NV_INT32 j = 0; for (NV_INT32 i = 0 ; i < misc->abe_share->num_levels ; i++) { NV_FLOAT32 diff = fabs (save_level - misc->abe_share->contour_levels[i]); if (diff < mindiff) { diff = mindiff; j = i; } } misc->draw_contour_level = misc->abe_share->contour_levels[j]; } // Normal contour interval... else { NV_INT32 mult = NINT ((save_level * options->z_factor + options->z_offset) / misc->abe_share->cint); misc->draw_contour_level = misc->abe_share->cint * (NV_FLOAT32) mult; } // Draw the current contours in highlight color so the "artist" can see where he can connect // his/her drawn contour if (options->contour) { for (NV_INT32 pfm = misc->abe_share->pfm_count - 1 ; pfm >= 0 ; pfm--) { if (misc->abe_share->display_pfm[pfm]) { // Adjust bounds to nearest grid point adjust_bounds (misc, pfm); misc->hatchr_start_x = 0; misc->hatchr_end_x = misc->displayed_area_width[pfm]; misc->hatchr_start_y = 0; misc->hatchr_end_y = misc->displayed_area_height[pfm]; // Allocate the needed arrays. NV_INT32 size; NV_FLOAT32 *ar = NULL; size = misc->displayed_area_width[pfm] * misc->displayed_area_height[pfm]; ar = (NV_FLOAT32 *) calloc (size, sizeof (NV_FLOAT32)); if (ar == NULL) { perror (pfmView::tr ("Allocating ar array in highlight_contour").toAscii ()); exit (-1); } BIN_RECORD *current_record = (BIN_RECORD *) calloc (misc->displayed_area_width[pfm], sizeof (BIN_RECORD)); if (current_record == NULL) { perror (pfmView::tr ("Allocating current_record array in highlight_contour").toAscii ()); exit (-1); } misc->current_row = (NV_FLOAT32 *) calloc (misc->displayed_area_width[pfm], sizeof (NV_FLOAT32)); misc->current_flags = (NV_U_CHAR *) calloc (misc->displayed_area_width[pfm], sizeof (NV_CHAR)); // If the calloc failed, error out. if (misc->current_flags == NULL) { perror (pfmView::tr (" Unable to allocate current_flags in highlight_contour.\n").toAscii ()); exit (-1); } // Read input data row by row and allot data to appropriate // subplot files until current row of subplots is complete. for (NV_INT32 jj = misc->hatchr_start_y ; jj < misc->hatchr_end_y ; jj++) { // Read data from disk. read_bin_row (misc->pfm_handle[pfm], misc->displayed_area_width[pfm], misc->displayed_area_row[pfm] + jj, misc->displayed_area_column[pfm], current_record); loadArrays (misc->abe_share->layer_type, misc->displayed_area_width[pfm], current_record, misc->current_row, NULL, 0, misc->current_flags, options->highlight, options->h_count, misc->pfm_handle[pfm], misc->abe_share->open_args[pfm], options->highlight_percent, misc->surface_val); for (NV_INT32 i = 0 ; i < misc->displayed_area_width[pfm] ; i++) { ar[(jj - misc->hatchr_start_y) * misc->displayed_area_width[pfm] + i] = misc->current_row[i] * options->z_factor + options->z_offset; } } free (current_record); free (misc->current_row); free (misc->current_flags); scribe (map, options, misc, pfm, ar, misc->draw_contour_level); free (ar); } } } }
/*! * \brief Split the node into two nodes putting clusters in each use the * k-means clustering algorithm. */ struct rtree_node * find_clusters (struct rtree_node *node) { float total_a, total_b; float a_X, a_Y, b_X, b_Y; bool belong[M_SIZE + 1]; struct centroid center[M_SIZE + 1]; int clust_a, clust_b, tries; int a_manage = 0, b_manage = 0; int i, old_ax, old_ay, old_bx, old_by; struct rtree_node *new_node; BoxType *b; for (i = 0; i < M_SIZE + 1; i++) { if (node->flags.is_leaf) b = &(node->u.rects[i].bounds); else b = &(node->u.kids[i]->box); center[i].x = 0.5 * (b->X1 + b->X2); center[i].y = 0.5 * (b->Y1 + b->Y2); /* adding 1 prevents zero area */ center[i].area = 1. + (float) (b->X2 - b->X1) * (float) (b->Y2 - b->Y1); } /* starting 'A' cluster center */ a_X = center[0].x; a_Y = center[0].y; /* starting 'B' cluster center */ b_X = center[M_SIZE].x; b_Y = center[M_SIZE].y; /* don't allow the same cluster centers */ if (b_X == a_X && b_Y == a_Y) { b_X += 10000; a_Y -= 10000; } for (tries = 0; tries < M_SIZE; tries++) { old_ax = (int) a_X; old_ay = (int) a_Y; old_bx = (int) b_X; old_by = (int) b_Y; clust_a = clust_b = 0; for (i = 0; i < M_SIZE + 1; i++) { float dist1, dist2; dist1 = SQUARE (a_X - center[i].x) + SQUARE (a_Y - center[i].y); dist2 = SQUARE (b_X - center[i].x) + SQUARE (b_Y - center[i].y); if (dist1 * (clust_a + M_SIZE / 2) < dist2 * (clust_b + M_SIZE / 2)) { belong[i] = true; clust_a++; } else { belong[i] = false; clust_b++; } } /* kludge to fix degenerate cases */ if (clust_a == M_SIZE + 1) belong[M_SIZE / 2] = false; else if (clust_b == M_SIZE + 1) belong[M_SIZE / 2] = true; /* compute new center of gravity of clusters */ total_a = total_b = 0; a_X = a_Y = b_X = b_Y = 0; for (i = 0; i < M_SIZE + 1; i++) { if (belong[i]) { a_X += center[i].x * center[i].area; a_Y += center[i].y * center[i].area; total_a += center[i].area; } else { b_X += center[i].x * center[i].area; b_Y += center[i].y * center[i].area; total_b += center[i].area; } } a_X /= total_a; a_Y /= total_a; b_X /= total_b; b_Y /= total_b; if (old_ax == (int) a_X && old_ay == (int) a_Y && old_bx == (int) b_X && old_by == (int) b_Y) break; } /* Now 'belong' has the partition map */ new_node = (struct rtree_node *)calloc (1, sizeof (*new_node)); new_node->parent = node->parent; new_node->flags.is_leaf = node->flags.is_leaf; clust_a = clust_b = 0; if (node->flags.is_leaf) { int flag, a_flag, b_flag; flag = a_flag = b_flag = 1; for (i = 0; i < M_SIZE + 1; i++) { if (belong[i]) { node->u.rects[clust_a++] = node->u.rects[i]; if (node->flags.manage & flag) a_manage |= a_flag; a_flag <<= 1; } else { new_node->u.rects[clust_b++] = node->u.rects[i]; if (node->flags.manage & flag) b_manage |= b_flag; b_flag <<= 1; } flag <<= 1; } } else { for (i = 0; i < M_SIZE + 1; i++) { if (belong[i]) node->u.kids[clust_a++] = node->u.kids[i]; else { node->u.kids[i]->parent = new_node; new_node->u.kids[clust_b++] = node->u.kids[i]; } } } node->flags.manage = a_manage; new_node->flags.manage = b_manage; assert (clust_a != 0); assert (clust_b != 0); if (node->flags.is_leaf) for (; clust_a < M_SIZE + 1; clust_a++) node->u.rects[clust_a].bptr = NULL; else for (; clust_a < M_SIZE + 1; clust_a++) node->u.kids[clust_a] = NULL; adjust_bounds (node); sort_node (node); adjust_bounds (new_node); sort_node (new_node); return (new_node); }
bool __r_delete (struct rtree_node *node, const BoxType * query) { int i, flag, mask, a; /* the tree might be inconsistent during delete */ if (query->X1 < node->box.X1 || query->Y1 < node->box.Y1 || query->X2 > node->box.X2 || query->Y2 > node->box.Y2) return false; if (!node->flags.is_leaf) { for (i = 0; i < M_SIZE; i++) { /* if this is us being removed, free and copy over */ if (node->u.kids[i] == (struct rtree_node *) query) { free ((void *) query); for (; i < M_SIZE; i++) { node->u.kids[i] = node->u.kids[i + 1]; if (!node->u.kids[i]) break; } /* nobody home here now ? */ if (!node->u.kids[0]) { if (!node->parent) { /* wow, the root is empty! */ node->flags.is_leaf = 1; /* changing type of node, be sure it's all zero */ for (i = 1; i < M_SIZE + 1; i++) node->u.rects[i].bptr = NULL; return true; } return (__r_delete (node->parent, &node->box)); } else /* propegate boundary adjust upward */ while (node) { adjust_bounds (node); node = node->parent; } return true; } if (node->u.kids[i]) { if (__r_delete (node->u.kids[i], query)) return true; } else break; } return false; } /* leaf node here */ mask = 0; a = 1; for (i = 0; i < M_SIZE; i++) { #ifdef DELETE_BY_POINTER if (!node->u.rects[i].bptr || node->u.rects[i].bptr == query) #else if (node->u.rects[i].bounds.X1 == query->X1 && node->u.rects[i].bounds.X2 == query->X2 && node->u.rects[i].bounds.Y1 == query->Y1 && node->u.rects[i].bounds.Y2 == query->Y2) #endif break; mask |= a; a <<= 1; } if (!node->u.rects[i].bptr) return false; /* not at this leaf */ if (node->flags.manage & a) { free ((void *) node->u.rects[i].bptr); node->u.rects[i].bptr = NULL; } /* squeeze the manage flags together */ flag = node->flags.manage & mask; mask = (~mask) << 1; node->flags.manage = flag | ((node->flags.manage & mask) >> 1); /* remove the entry */ for (; i < M_SIZE; i++) { node->u.rects[i] = node->u.rects[i + 1]; if (!node->u.rects[i].bptr) break; } if (!node->u.rects[0].bptr) { if (node->parent) __r_delete (node->parent, &node->box); return true; } else /* propagate boundary adjustment upward */ while (node) { adjust_bounds (node); node = node->parent; } return true; }
void paint_surface (MISC *misc, OPTIONS *options, nvMap *map, NVMAP_DEF *mapdef, NV_BOOL cov_area_defined) { static NV_FLOAT32 prev_min = CHRTRNULL, prev_max = -CHRTRNULL; NV_FLOAT32 *next_attr = NULL; NV_U_CHAR *next_flags = NULL; NV_BOOL compute_layer_min_max (MISC *misc, OPTIONS *options); void hatchr (nvMap *map, OPTIONS *options, NV_BOOL clear, NV_F64_XYMBR mbr, NV_F64_XYMBR edit_mbr, NV_FLOAT32 min_z, NV_FLOAT32 max_z, NV_FLOAT32 range, NV_FLOAT64 x_bin_size, NV_FLOAT64 y_bin_size, NV_INT32 height, NV_INT32 start_x, NV_INT32 end_x, NV_FLOAT32 ss_null, NV_FLOAT64 cell_size_x, NV_FLOAT64 cell_size_y, NV_FLOAT32 *current_row, NV_FLOAT32 *next_row, NV_FLOAT32 *current_attr, NV_U_CHAR *current_flags, NV_U_BYTE alpha, NV_INT32 row, NV_INT32 attribute); void geotiff (nvMap *map, MISC *misc, OPTIONS *options); void overlayData (nvMap *map, MISC *misc, OPTIONS *options); if (!cov_area_defined) return; misc->total_displayed_area.min_y = mapdef->bounds[mapdef->zoom_level].min_y; misc->total_displayed_area.min_x = mapdef->bounds[mapdef->zoom_level].min_x; misc->total_displayed_area.max_y = mapdef->bounds[mapdef->zoom_level].max_y; misc->total_displayed_area.max_x = mapdef->bounds[mapdef->zoom_level].max_x; if (misc->total_displayed_area.min_x > misc->total_displayed_area.max_x) { // Only adjust the lons if the displayed area does not cross the dateline. if ((misc->total_displayed_area.max_x > 0.0 && misc->total_displayed_area.min_x > 0.0) || (misc->total_displayed_area.max_x < 0.0 && misc->total_displayed_area.min_x < 0.0)) { NV_FLOAT64 temp = misc->total_displayed_area.min_x; misc->total_displayed_area.min_x = misc->total_displayed_area.max_x; misc->total_displayed_area.max_x = temp; } } // Save the displayed area for other ABE programs. Some key off of the editor/viewer area (displayed_area) // and some key off of just the viewer area (viewer_displayed_area) so, at this point, we set them both. misc->abe_share->displayed_area = misc->abe_share->viewer_displayed_area = misc->total_displayed_area; // Compute center point for sun angle arrow NV_FLOAT64 center_map_x = misc->total_displayed_area.min_x + (misc->total_displayed_area.max_x - misc->total_displayed_area.min_x) / 2.0; NV_FLOAT64 center_map_y = misc->total_displayed_area.min_y + (misc->total_displayed_area.max_y - misc->total_displayed_area.min_y) / 2.0; NV_FLOAT64 dum_map_z; NV_INT32 dum_z; map->map_to_screen (1, ¢er_map_x, ¢er_map_y, &dum_map_z, &misc->center_point.x, &misc->center_point.y, &dum_z); // Compute the min and max for the displayed area (using values from all PFM layers). if (!compute_layer_min_max (misc, options)) return; // Check to see if we want to force clearing because the min and/or max value changed. if (misc->color_by_attribute) { if (prev_min != misc->displayed_area_attr_min || prev_max != misc->displayed_area_attr_max) misc->clear = NVTrue; prev_min = misc->displayed_area_attr_min; prev_max = misc->displayed_area_attr_max; } else { if (prev_min != misc->displayed_area_min || prev_max != misc->displayed_area_max) misc->clear = NVTrue; prev_min = misc->displayed_area_min; prev_max = misc->displayed_area_max; } // Fill the background with the background color so we don't have to paint the background in hatchr. // Also so we can display the GeoTIFF under the data if requested. // Whole area if (misc->clear) { map->fillRectangle (misc->total_displayed_area.min_x, misc->total_displayed_area.min_y, misc->total_displayed_area.max_x, misc->total_displayed_area.max_y, options->background_color, NVFalse); } // Partial area (edited area) else { map->fillRectangle (misc->abe_share->edit_area.min_x, misc->abe_share->edit_area.min_y, misc->abe_share->edit_area.max_x, misc->abe_share->edit_area.max_y, options->background_color, NVFalse); } for (NV_INT32 pfm = misc->abe_share->pfm_count - 1 ; pfm >= 0 ; pfm--) { // Only if we want to display it. if (misc->abe_share->display_pfm[pfm]) { // Adjust bounds to nearest grid point adjust_bounds (misc, pfm); // Redraw everything if (misc->clear) { misc->hatchr_start_x = 0; misc->hatchr_end_x = misc->displayed_area_width[pfm]; misc->hatchr_start_y = 0; misc->hatchr_end_y = misc->displayed_area_height[pfm]; } // Redraw a portion (what we edited) else { NV_F64_XYMBR tmp_mbr = misc->abe_share->edit_area; // Adjust edit bounds to nearest grid point (with a border of 1 grid point to clean up the edges). tmp_mbr.min_y = misc->abe_share->open_args[pfm].head.mbr.min_y + (NINT ((misc->abe_share->edit_area.min_y - misc->abe_share->open_args[pfm].head.mbr.min_y) / misc->abe_share->open_args[pfm].head.y_bin_size_degrees) - 1) * misc->abe_share->open_args[pfm].head.y_bin_size_degrees; tmp_mbr.max_y = misc->abe_share->open_args[pfm].head.mbr.min_y + (NINT ((misc->abe_share->edit_area.max_y - misc->abe_share->open_args[pfm].head.mbr.min_y) / misc->abe_share->open_args[pfm].head.y_bin_size_degrees) + 1) * misc->abe_share->open_args[pfm].head.y_bin_size_degrees; tmp_mbr.min_x = misc->abe_share->open_args[pfm].head.mbr.min_x + (NINT ((misc->abe_share->edit_area.min_x - misc->abe_share->open_args[pfm].head.mbr.min_x) / misc->abe_share->open_args[pfm].head.x_bin_size_degrees) - 1) * misc->abe_share->open_args[pfm].head.x_bin_size_degrees; tmp_mbr.max_x = misc->abe_share->open_args[pfm].head.mbr.min_x + (NINT ((misc->abe_share->edit_area.max_x - misc->abe_share->open_args[pfm].head.mbr.min_x) / misc->abe_share->open_args[pfm].head.x_bin_size_degrees) + 1) * misc->abe_share->open_args[pfm].head.x_bin_size_degrees; tmp_mbr.min_y = qMax (tmp_mbr.min_y, misc->abe_share->open_args[pfm].head.mbr.min_y); tmp_mbr.max_y = qMin (tmp_mbr.max_y, misc->abe_share->open_args[pfm].head.mbr.max_y); tmp_mbr.min_x = qMax (tmp_mbr.min_x, misc->abe_share->open_args[pfm].head.mbr.min_x); tmp_mbr.max_x = qMin (tmp_mbr.max_x, misc->abe_share->open_args[pfm].head.mbr.max_x); misc->hatchr_start_x = NINT ((tmp_mbr.min_x - misc->displayed_area[pfm].min_x) / misc->abe_share->open_args[pfm].head.x_bin_size_degrees); misc->hatchr_end_x = misc->hatchr_start_x + (NINT ((tmp_mbr.max_x - tmp_mbr.min_x) / misc->abe_share->open_args[pfm].head.x_bin_size_degrees)); misc->hatchr_start_y = NINT ((tmp_mbr.min_y - misc->displayed_area[pfm].min_y) / misc->abe_share->open_args[pfm].head.y_bin_size_degrees); misc->hatchr_end_y = misc->hatchr_start_y + (NINT ((tmp_mbr.max_y - tmp_mbr.min_y) / misc->abe_share->open_args[pfm].head.y_bin_size_degrees)); } // If the width or height is 0 we have asked for an area outside of the PFM's MBR so we don't want to do anything. if (misc->displayed_area_width[pfm] > 0 && misc->displayed_area_height[pfm] > 0) { // If misc->display_GeoTIFF is -1 we want to draw the GeoTIFF first. if (pfm == misc->abe_share->pfm_count - 1 && misc->display_GeoTIFF < 0) geotiff (map, misc, options); // The only time we don't want to go through here is when we have an open GeoTIFF file, we are displaying // the GeoTIFF surface, and the GeoTIFF alpha value (transparency) is 255. if (misc->display_GeoTIFF <= 0 || options->GeoTIFF_alpha < 255) { // We only want to do attributes if we're coloring by non-PFM attributes (like number or stddev), or if we're on the top level. NV_INT32 attribute = 0; if ((misc->color_by_attribute > 0 && misc->color_by_attribute < PRE_ATTR) || (!pfm && misc->color_by_attribute)) attribute = misc->color_by_attribute; // Allocate the needed arrays. NV_INT32 size; NV_FLOAT32 *ar = NULL; if (options->contour) { size = (misc->displayed_area_width[pfm] + 1) * (misc->displayed_area_height[pfm] + 1); ar = (NV_FLOAT32 *) calloc (size, sizeof (NV_FLOAT32)); if (ar == NULL) { perror (pfmView::tr ("Allocating ar array in paint_surface").toAscii ()); exit (-1); } } BIN_RECORD *current_record = (BIN_RECORD *) calloc (misc->displayed_area_width[pfm], sizeof (BIN_RECORD)); if (current_record == NULL) { perror (pfmView::tr ("Allocating current_record in paint_surface").toAscii ()); exit (-1); } misc->next_row = (NV_FLOAT32 *) calloc (misc->displayed_area_width[pfm], sizeof (NV_FLOAT32)); if (misc->next_row == NULL) { perror (pfmView::tr ("Allocating next_row in paint_surface").toAscii ()); exit (-1); } if (attribute) { next_attr = (NV_FLOAT32 *) calloc (misc->displayed_area_width[pfm], sizeof (NV_FLOAT32)); if (next_attr == NULL) { perror (pfmView::tr ("Allocating next_attr in paint_surface").toAscii ()); exit (-1); } } next_flags = (NV_U_CHAR *) calloc (misc->displayed_area_width[pfm], sizeof (NV_CHAR)); if (next_flags == NULL) { perror (pfmView::tr ("Allocating next_flags in paint_surface").toAscii ()); exit (-1); } misc->current_row = (NV_FLOAT32 *) calloc (misc->displayed_area_width[pfm], sizeof (NV_FLOAT32)); if (misc->current_row == NULL) { perror (pfmView::tr ("Allocating current_row in paint_surface").toAscii ()); exit (-1); } if (attribute) { misc->current_attr = (NV_FLOAT32 *) calloc (misc->displayed_area_width[pfm], sizeof (NV_FLOAT32)); if (misc->current_attr == NULL) { perror (pfmView::tr ("Allocating current_attr in paint_surface").toAscii ()); exit (-1); } } misc->current_flags = (NV_U_CHAR *) calloc (misc->displayed_area_width[pfm], sizeof (NV_CHAR)); if (misc->current_flags == NULL) { perror (pfmView::tr ("Allocating current_flags in paint_surface").toAscii ()); exit (-1); } // Read input data row by row. Note that hatchr_start_y and hatchr_end_y may not be the same as the // entire displayed area since we may only be redrawing a small edited portion of the display. for (NV_INT32 jj = misc->hatchr_start_y ; jj <= misc->hatchr_end_y ; jj++) { // Read data from disk. if (jj == misc->hatchr_start_y) { read_bin_row (misc->pfm_handle[pfm], misc->displayed_area_width[pfm], misc->displayed_area_row[pfm] + jj, misc->displayed_area_column[pfm], current_record); loadArrays (misc->abe_share->layer_type, misc->displayed_area_width[pfm], current_record, misc->current_row, misc->current_attr, attribute, misc->current_flags, options->highlight, options->h_count, misc->pfm_handle[pfm], misc->abe_share->open_args[pfm], options->highlight_percent, misc->surface_val); memcpy (misc->next_row, misc->current_row, misc->displayed_area_width[pfm] * sizeof (NV_FLOAT32)); if (attribute) memcpy (next_attr, misc->current_attr, misc->displayed_area_width[pfm] * sizeof (NV_FLOAT32)); memcpy (next_flags, misc->current_flags, misc->displayed_area_width[pfm] * sizeof (NV_CHAR)); } else { memcpy (misc->current_row, misc->next_row, misc->displayed_area_width[pfm] * sizeof (NV_FLOAT32)); if (attribute) memcpy (misc->current_attr, next_attr, misc->displayed_area_width[pfm] * sizeof (NV_FLOAT32)); memcpy (misc->current_flags, next_flags, misc->displayed_area_width[pfm] * sizeof (NV_CHAR)); // If not at top edge, read another row. if (jj < misc->abe_share->open_args[pfm].head.bin_height) { read_bin_row (misc->pfm_handle[pfm], misc->displayed_area_width[pfm], misc->displayed_area_row[pfm] + jj, misc->displayed_area_column[pfm], current_record); loadArrays (misc->abe_share->layer_type, misc->displayed_area_width[pfm], current_record, misc->next_row, next_attr, attribute, next_flags, options->highlight, options->h_count, misc->pfm_handle[pfm], misc->abe_share->open_args[pfm], options->highlight_percent, misc->surface_val); } } // HSV fill and sunshade. hatchr (map, options, misc->clear, misc->displayed_area[pfm], misc->abe_share->edit_area, misc->color_min, misc->color_max, misc->color_range, misc->abe_share->open_args[pfm].head.x_bin_size_degrees, misc->abe_share->open_args[pfm].head.y_bin_size_degrees, misc->abe_share->open_args[pfm].head.bin_height, misc->hatchr_start_x, misc->hatchr_end_x, misc->abe_share->open_args[pfm].head.null_depth, misc->ss_cell_size_x[pfm], misc->ss_cell_size_y[pfm], misc->current_row, misc->next_row, misc->current_attr, misc->current_flags, misc->pfm_alpha[pfm], jj, attribute); if (options->contour) { for (NV_INT32 i = 0 ; i < misc->displayed_area_width[pfm] ; i++) { // We use next_row for sunshading on all but the first row to send to scribe. if (i) { ar[(jj - misc->hatchr_start_y) * misc->displayed_area_width[pfm] + i] = misc->next_row[i] * options->z_factor + options->z_offset; } else { ar[(jj - misc->hatchr_start_y) * misc->displayed_area_width[pfm] + i] = misc->current_row[i] * options->z_factor + options->z_offset; } } } if (qApp->hasPendingEvents ()) { qApp->processEvents(); if (misc->drawing_canceled) break; } } // Flush all of the saved fillRectangles from hatchr to screen map->flush (); // Free allocated memory. free (current_record); free (misc->next_row); if (attribute) free (next_attr); free (next_flags); free (misc->current_row); if (attribute) free (misc->current_attr); free (misc->current_flags); if (!misc->drawing_canceled) { // If you asked for contours, do it. if (options->contour) { if (misc->function == DRAW_CONTOUR) { scribe (map, options, misc, pfm, ar, misc->draw_contour_level); } else { scribe (map, options, misc, pfm, ar, 99999.0); } } } // Free allocated scribe memory. if (options->contour) free (ar); } // Issue a warning when the user is displaying more bins than pixels if (!misc->tposiafps && (misc->clear && (misc->displayed_area_width[pfm] > mapdef->draw_width || misc->displayed_area_height[pfm] > mapdef->draw_height))) { QString warning_message = pfmView::tr ("Number of bins displayed exceeds number of pixels.\n"); warning_message += pfmView::tr ("Some data masking will occur.\n"); warning_message += pfmView::tr ("Increase window size or decrease area size.\n\n"); warning_message += QString (pfmView::tr ("Bin width = %1 , Pixel width = %2\n")).arg (misc->displayed_area_width[pfm]).arg (mapdef->draw_width); warning_message += QString (pfmView::tr ("Bin height = %1 , Pixel height = %2\n")).arg (misc->displayed_area_height[pfm]).arg (mapdef->draw_height); QMessageBox msgBox (QMessageBox::Warning, pfmView::tr ("pfmView TPOSIAFPS"), warning_message); msgBox.setStandardButtons (QMessageBox::Close); msgBox.setDefaultButton (QMessageBox::Close); QCheckBox dontShow (pfmView::tr ("I understand that I can't see everything due to resolution but don't show this again!"), &msgBox); msgBox.addButton (&dontShow, QMessageBox::HelpRole); msgBox.exec (); misc->tposiafps = ((bool) dontShow.checkState ()); } } } } if (!misc->drawing_canceled) { // Display GeoTIFF data if available. if (misc->display_GeoTIFF == 1) geotiff (map, misc, options); // Overlay any files that have been requested. overlayData (map, misc, options); // Display suspect, feature, selected, or reference info if enabled. if (options->display_suspect || options->display_feature || options->display_selected || options->display_reference) overlayFlag (map, options, misc, NVTrue, NVTrue, NVTrue); // Display filter masks if any are defined. for (NV_INT32 i = 0 ; i < misc->poly_filter_mask_count ; i++) { if (!misc->poly_filter_mask[i].displayed) { // Check to see if this mask (that we are going to redraw) overlaps another (that we weren't planning on redrawing). // If so, set the flag to redraw the other one. for (NV_INT32 j = 0 ; j < misc->poly_filter_mask_count ; j++) { if (j != i && misc->poly_filter_mask[j].displayed) { if (polygon_collision2 (misc->poly_filter_mask[i].x, misc->poly_filter_mask[i].y, misc->poly_filter_mask[i].count, misc->poly_filter_mask[j].x, misc->poly_filter_mask[j].y, misc->poly_filter_mask[j].count)) misc->poly_filter_mask[j].displayed = NVFalse; } } } } for (NV_INT32 i = 0 ; i < misc->poly_filter_mask_count ; i++) { if (!misc->poly_filter_mask[i].displayed) { if (options->poly_filter_mask_color.alpha () < 255) { map->fillPolygon (misc->poly_filter_mask[i].count, misc->poly_filter_mask[i].x, misc->poly_filter_mask[i].y, options->poly_filter_mask_color, NVTrue); } else { // We don't have to worry about clipping this because moving the area discards the mask areas. map->drawPolygon (misc->poly_filter_mask[i].count, misc->poly_filter_mask[i].x, misc->poly_filter_mask[i].y, options->poly_filter_mask_color, 2, NVTrue, Qt::SolidLine, NVTrue); } misc->poly_filter_mask[i].displayed = NVTrue; } } if (options->landmask && misc->total_displayed_area.max_x - misc->total_displayed_area.min_x < 5.0 && misc->total_displayed_area.max_y - misc->total_displayed_area.min_y < 5.0) { map->setLandmask (NVTrue); } else { map->setLandmask (NVFalse); } // Flag minimum, maximum, and maximum std dev if enabled. if (options->display_minmax) displayMinMax (map, options, misc); } }