X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=src%2Fplugins%2Flevel2.c;h=b5ac6f5b3976ee63689b3b80dcaf4fb07f544d4c;hb=f0ba5456156edc1aef2be749fbccd732193fe54c;hp=3fa7d4e627628b260b41f7851afe76d2c8171813;hpb=c0e52fc233205fb646326a0efd86e4359f51d96c;p=aweather diff --git a/src/plugins/level2.c b/src/plugins/level2.c index 3fa7d4e..b5ac6f5 100644 --- a/src/plugins/level2.c +++ b/src/plugins/level2.c @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include "level2.h" @@ -68,20 +68,29 @@ static void _bscan_sweep(Sweep *sweep, AWeatherColormap *colormap, } /* Load a sweep into an OpenGL texture */ -static void _load_sweep_gl(Sweep *sweep, AWeatherColormap *colormap, guint *tex) +static void _load_sweep_gl(AWeatherLevel2 *self) { g_debug("AWeatherLevel2: _load_sweep_gl"); - int height, width; guint8 *data; - _bscan_sweep(sweep, colormap, &data, &width, &height); - glGenTextures(1, tex); - glBindTexture(GL_TEXTURE_2D, *tex); + gint width, height; + _bscan_sweep(self->sweep, self->sweep_colors, &data, &width, &height); + gint tex_width = pow(2, ceil(log(width )/log(2))); + gint tex_height = pow(2, ceil(log(height)/log(2))); + self->sweep_coords[0] = (double)width / tex_width; + self->sweep_coords[1] = (double)height / tex_height; + + if (!self->sweep_tex) + glGenTextures(1, &self->sweep_tex); + glBindTexture(GL_TEXTURE_2D, self->sweep_tex); glPixelStorei(GL_PACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, tex_width, tex_height, 0, + GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0,0, width,height, + GL_RGBA, GL_UNSIGNED_BYTE, data); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, - GL_RGBA, GL_UNSIGNED_BYTE, data); + g_free(data); } @@ -121,20 +130,14 @@ static gboolean _decompress_radar(const gchar *file, const gchar *raw) /********************* * Drawing functions * *********************/ -static gpointer _draw_radar(GisCallback *_self, gpointer _viewer) +void aweather_level2_draw(GritsObject *_self, GritsOpenGL *opengl) { AWeatherLevel2 *self = AWEATHER_LEVEL2(_self); if (!self->sweep || !self->sweep_tex) - return NULL; + return; /* Draw wsr88d */ Sweep *sweep = self->sweep; - Radar_header *h = &self->radar->h; - gdouble lat = (double)h->latd + (double)h->latm/60 + (double)h->lats/(60*60); - gdouble lon = (double)h->lond + (double)h->lonm/60 + (double)h->lons/(60*60); - gdouble elev = h->height; - gis_viewer_center_position(self->viewer, lat, lon, elev); - glDisable(GL_ALPHA_TEST); glDisable(GL_CULL_FACE); glDisable(GL_LIGHTING); @@ -144,8 +147,9 @@ static gpointer _draw_radar(GisCallback *_self, gpointer _viewer) glColor4f(1,1,1,1); /* Draw the rays */ + gdouble xscale = self->sweep_coords[0]; + gdouble yscale = self->sweep_coords[1]; glBindTexture(GL_TEXTURE_2D, self->sweep_tex); - g_message("Tex = %d", self->sweep_tex); glBegin(GL_TRIANGLE_STRIP); for (int ri = 0; ri <= sweep->h.nrays; ri++) { Ray *ray = NULL; @@ -162,18 +166,18 @@ static gpointer _draw_radar(GisCallback *_self, gpointer _viewer) double lx = sin(angle); double ly = cos(angle); - double near_dist = ray->h.range_bin1; - double far_dist = ray->h.nbins*ray->h.gate_size + ray->h.range_bin1; + double near_dist = ray->h.range_bin1 - ((double)ray->h.gate_size/2.); + double far_dist = near_dist + (double)ray->h.nbins*ray->h.gate_size; /* (find middle of bin) / scale for opengl */ // near left - glTexCoord2f(0.0, (double)ri/sweep->h.nrays-0.01); + glTexCoord2f(0.0, ((double)ri/sweep->h.nrays)*yscale); glVertex3f(lx*near_dist, ly*near_dist, 2.0); // far left // todo: correct range-height function double height = sin(deg2rad(ray->h.elev)) * far_dist; - glTexCoord2f(1.0, (double)ri/sweep->h.nrays-0.01); + glTexCoord2f(xscale, ((double)ri/sweep->h.nrays)*yscale); glVertex3f(lx*far_dist, ly*far_dist, height); } glEnd(); @@ -186,8 +190,6 @@ static gpointer _draw_radar(GisCallback *_self, gpointer _viewer) //glTexCoord2d( 1., 1.); glVertex3f( 0., 500., 3.); // top right //glTexCoord2d( 1., 0.); glVertex3f( 0., 0., 3.); // bot right //glEnd(); - - return NULL; } @@ -198,10 +200,9 @@ static gboolean _set_sweep_cb(gpointer _self) { g_debug("AWeatherLevel2: _set_sweep_cb"); AWeatherLevel2 *self = _self; - if (self->sweep_tex) - glDeleteTextures(1, &self->sweep_tex); - _load_sweep_gl(self->sweep, self->sweep_colors, &self->sweep_tex); + _load_sweep_gl(self); gtk_widget_queue_draw(GTK_WIDGET(self->viewer)); + g_object_unref(self); return FALSE; } void aweather_level2_set_sweep(AWeatherLevel2 *self, @@ -223,22 +224,30 @@ void aweather_level2_set_sweep(AWeatherLevel2 *self, if (!self->sweep_colors) return; /* Load data */ + g_object_ref(self); g_idle_add(_set_sweep_cb, self); } -AWeatherLevel2 *aweather_level2_new(GisViewer *viewer, +AWeatherLevel2 *aweather_level2_new(GritsViewer *viewer, AWeatherColormap *colormap, Radar *radar) { - g_debug("AWeatherLevel2: new"); + g_debug("AWeatherLevel2: new - %s", radar->h.radar_name); AWeatherLevel2 *self = g_object_new(AWEATHER_TYPE_LEVEL2, NULL); self->viewer = viewer; self->radar = radar; self->colormap = colormap; aweather_level2_set_sweep(self, DZ_INDEX, 0); + + GritsPoint center; + Radar_header *h = &radar->h; + center.lat = (double)h->latd + (double)h->latm/60 + (double)h->lats/(60*60); + center.lon = (double)h->lond + (double)h->lonm/60 + (double)h->lons/(60*60); + center.elev = h->height; + GRITS_OBJECT(self)->center = center; return self; } -AWeatherLevel2 *aweather_level2_new_from_file(GisViewer *viewer, +AWeatherLevel2 *aweather_level2_new_from_file(GritsViewer *viewer, AWeatherColormap *colormap, const gchar *file, const gchar *site) { @@ -250,7 +259,7 @@ AWeatherLevel2 *aweather_level2_new_from_file(GisViewer *viewer, struct stat files, raws; g_stat(file, &files); g_stat(raw, &raws); - if (files.st_mtime < raws.st_mtime) + if (files.st_mtime > raws.st_mtime) if (!_decompress_radar(file, raw)) return NULL; } else { @@ -260,7 +269,9 @@ AWeatherLevel2 *aweather_level2_new_from_file(GisViewer *viewer, /* Load the radar file */ RSL_read_these_sweeps("all", NULL); + g_message("read start"); Radar *radar = RSL_wsr88d_to_radar(raw, (gchar*)site); + g_message("read done"); g_free(raw); if (!radar) return NULL; @@ -268,18 +279,110 @@ AWeatherLevel2 *aweather_level2_new_from_file(GisViewer *viewer, return aweather_level2_new(viewer, colormaps, radar); } +static void _on_sweep_clicked(GtkRadioButton *button, gpointer _level2) +{ + AWeatherLevel2 *level2 = _level2; + gint type = (gint)g_object_get_data(G_OBJECT(button), "type"); + gint elev = (gint)g_object_get_data(G_OBJECT(button), "elev"); + aweather_level2_set_sweep(level2, type, (float)elev/100); + //self->colormap = level2->sweep_colors; +} + +GtkWidget *aweather_level2_get_config(AWeatherLevel2 *level2) +{ + Radar *radar = level2->radar; + g_debug("AWeatherLevel2: get_config - %p, %p", level2, radar); + /* Clear existing items */ + gfloat elev; + guint rows = 1, cols = 1, cur_cols; + gchar row_label_str[64], col_label_str[64], button_str[64]; + GtkWidget *row_label, *col_label, *button = NULL, *elev_box = NULL; + GtkWidget *table = gtk_table_new(rows, cols, FALSE); + + /* Add date */ + gchar *date_str = g_strdup_printf("%04d-%02d-%02d %02d:%02d", + radar->h.year, radar->h.month, radar->h.day, + radar->h.hour, radar->h.minute); + GtkWidget *date_label = gtk_label_new(date_str); + gtk_label_set_use_markup(GTK_LABEL(date_label), TRUE); + gtk_table_attach(GTK_TABLE(table), date_label, + 0,1, 0,1, GTK_FILL,GTK_FILL, 5,0); + g_free(date_str); + + for (guint vi = 0; vi < radar->h.nvolumes; vi++) { + Volume *vol = radar->v[vi]; + if (vol == NULL) continue; + rows++; cols = 1; elev = 0; + + /* Row label */ + g_snprintf(row_label_str, 64, "%s:", vol->h.type_str); + row_label = gtk_label_new(row_label_str); + gtk_label_set_use_markup(GTK_LABEL(row_label), TRUE); + gtk_misc_set_alignment(GTK_MISC(row_label), 1, 0.5); + gtk_table_attach(GTK_TABLE(table), row_label, + 0,1, rows-1,rows, GTK_FILL,GTK_FILL, 5,0); + + for (guint si = 0; si < vol->h.nsweeps; si++) { + Sweep *sweep = vol->sweep[si]; + if (sweep == NULL || sweep->h.elev == 0) continue; + if (sweep->h.elev != elev) { + cols++; + elev = sweep->h.elev; + + /* Column label */ + g_object_get(table, "n-columns", &cur_cols, NULL); + if (cols > cur_cols) { + g_snprintf(col_label_str, 64, "%.2f°", elev); + col_label = gtk_label_new(col_label_str); + gtk_label_set_use_markup(GTK_LABEL(col_label), TRUE); + gtk_widget_set_size_request(col_label, 50, -1); + gtk_table_attach(GTK_TABLE(table), col_label, + cols-1,cols, 0,1, GTK_FILL,GTK_FILL, 0,0); + } + + elev_box = gtk_hbox_new(TRUE, 0); + gtk_table_attach(GTK_TABLE(table), elev_box, + cols-1,cols, rows-1,rows, GTK_FILL,GTK_FILL, 0,0); + } + + + /* Button */ + g_snprintf(button_str, 64, "%3.2f", elev); + button = gtk_radio_button_new_with_label_from_widget( + GTK_RADIO_BUTTON(button), button_str); + gtk_widget_set_size_request(button, -1, 26); + //button = gtk_radio_button_new_from_widget(GTK_RADIO_BUTTON(button)); + //gtk_widget_set_size_request(button, -1, 22); + g_object_set(button, "draw-indicator", FALSE, NULL); + gtk_box_pack_end(GTK_BOX(elev_box), button, TRUE, TRUE, 0); + + g_object_set_data(G_OBJECT(button), "level2", (gpointer)level2); + g_object_set_data(G_OBJECT(button), "type", (gpointer)vi); + g_object_set_data(G_OBJECT(button), "elev", (gpointer)(int)(elev*100)); + g_signal_connect(button, "clicked", G_CALLBACK(_on_sweep_clicked), level2); + } + } + return table; +} /**************** * GObject code * ****************/ -G_DEFINE_TYPE(AWeatherLevel2, aweather_level2, GIS_TYPE_CALLBACK); +G_DEFINE_TYPE(AWeatherLevel2, aweather_level2, GRITS_TYPE_OBJECT); static void aweather_level2_init(AWeatherLevel2 *self) { - GIS_CALLBACK(self)->callback = _draw_radar; - GIS_CALLBACK(self)->user_data = self; } - +static void aweather_level2_finalize(GObject *_self) +{ + AWeatherLevel2 *self = AWEATHER_LEVEL2(_self); + g_debug("AWeatherLevel2: finalize - %p", _self); + RSL_free_radar(self->radar); + if (self->sweep_tex) + glDeleteTextures(1, &self->sweep_tex); + G_OBJECT_CLASS(aweather_level2_parent_class)->finalize(_self); +} static void aweather_level2_class_init(AWeatherLevel2Class *klass) { + G_OBJECT_CLASS(klass)->finalize = aweather_level2_finalize; + GRITS_OBJECT_CLASS(klass)->draw = aweather_level2_draw; } -