From d97d97d3896bc8299adf2e7aaa5cc38e2611f395 Mon Sep 17 00:00:00 2001 From: Andy Spencer Date: Sat, 16 May 2009 01:34:34 +0000 Subject: [PATCH] * Road plan (HACKING) * Removing curl * Refresh button * Better caching * More accurate RIDGE overlays * Misc cleanup --- HACKING | 29 ++++++++++ Makefile.am | 6 +- configure.ac | 1 - docs/api/Makefile.am | 5 +- gen.sh | 4 ++ src/Makefile.am | 5 +- src/aweather-gui.c | 48 ++++++++++++---- src/aweather-view.c | 27 +++++++++ src/aweather-view.h | 4 ++ src/data.c | 112 ++++++++++++++++++++----------------- src/data.h | 12 +++- src/main.c | 4 +- src/plugin-radar.c | 130 +++++++++++++++++++++++++------------------ src/plugin-ridge.c | 14 ++--- 14 files changed, 266 insertions(+), 135 deletions(-) create mode 100644 HACKING create mode 100755 gen.sh diff --git a/HACKING b/HACKING new file mode 100644 index 0000000..25a2add --- /dev/null +++ b/HACKING @@ -0,0 +1,29 @@ +Road plan +--------- +0.1 - Working + * Fix all memory leaks + * Asynchronous IO and data loading + * Pre-load textures and polys in OpenGL + * GObject integration (plugin object/interface) + * `Refresh button' (pull new level 2 data) + +0.x - Volume scans + * Display iso surfaces of volume scans + +0.x - GIS + * Replace RIDGE overlays with GIS images + * Set up LLH coordinate system + * Generic Time/Location selection + (not dependent on level 2 listings) + +0.x - More data + * Derived from Level 2: + * Composite reflectivity + * Storm relative motion + * Echo tops + * Warning/watch boxes + * Fronts + * Air pressure + +0.x - Animation + * Loop though times diff --git a/Makefile.am b/Makefile.am index 0940733..c404399 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,9 +1,9 @@ SUBDIRS = src data docs +MAINTAINERCLEANFILES = aclocal.m4 compile config.guess config.h.in gtk-doc.make \ + configure depcomp install-sh Makefile.in missing + test: all LD_LIBRARY_PATH=/usr/local/trmm/GVBOX/lib/ \ ./src/aweather -maintainer-clean-local: - rm -f aclocal.m4 compile config.guess config.h.in gtk-doc.make \ - configure depcomp install-sh Makefile.in missing diff --git a/configure.ac b/configure.ac index 8d5d34b..49ca761 100644 --- a/configure.ac +++ b/configure.ac @@ -10,7 +10,6 @@ GTK_DOC_CHECK(1.9) # Check for required packages PKG_CHECK_MODULES(GTK, gtk+-2.0 gtkglext-1.0 gmodule-export-2.0 gobject-2.0) -PKG_CHECK_MODULES(CURL, libcurl) # Define odd RSL install location #AC_SUBST(RSL_CFLAGS, "-I/usr/local/trmm/GVBOX/include/") diff --git a/docs/api/Makefile.am b/docs/api/Makefile.am index 755262f..68213ac 100644 --- a/docs/api/Makefile.am +++ b/docs/api/Makefile.am @@ -11,7 +11,6 @@ DOC_MODULE=aweather DOC_SOURCE_DIR=../../src/ DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.sgml MKDB_OPTIONS=--sgml-mode --output-format=xml +MAINTAINERCLEANFILES= \ + Makefile.in aweather-docs.sgml aweather-overrides.txt aweather.types include $(top_srcdir)/gtk-doc.make -maintainer-clean-local: - rm -f Makefile.in aweather-docs.sgml aweather-overrides.txt aweather.types - rm -rf html/ tmpl/ diff --git a/gen.sh b/gen.sh new file mode 100755 index 0000000..e2723ee --- /dev/null +++ b/gen.sh @@ -0,0 +1,4 @@ +#!/bin/bash +dir=$(dirname $(readlink -f $0)) +echo CFLAGS="-g" ./autogen.sh "--datadir=$dir/data" --enable-gtk-doc +CFLAGS="-g" ./autogen.sh "--datadir=$dir/data" --enable-gtk-doc diff --git a/src/Makefile.am b/src/Makefile.am index 8611e50..18b7fba 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,6 +1,5 @@ -AM_CPPFLAGS = -DDATADIR="\"$(datadir)\"" $(RSL_CFLAGS) $(GTK_CFLAGS) $(CURL_CFLAGS) +AM_LDFLAGS = $(RSL_LIBS) $(GTK_LIBS) AM_CFLAGS = -Wall -Werror -Wno-unused --std=gnu99 -AM_LDFLAGS = -Wl,--export-dynamic bin_PROGRAMS = aweather wsr88ddec aweather_SOURCES = main.c \ @@ -12,7 +11,7 @@ aweather_SOURCES = main.c \ plugin-radar-colormap.c \ plugin-ridge.c plugin-ridge.h \ plugin-example.c plugin-example.h -aweather_LDADD = $(RSL_LIBS) $(GTK_LIBS) $(CURL_LIBS) +aweather_CPPFLAGS = $(RSL_CFLAGS) $(GTK_CFLAGS) -DDATADIR="\"$(datadir)\"" wsr88ddec = wsr88ddec.c wsr88ddec_LDADD = -lbz2 diff --git a/src/aweather-gui.c b/src/aweather-gui.c index 2c7b5c1..555a9c2 100644 --- a/src/aweather-gui.c +++ b/src/aweather-gui.c @@ -37,6 +37,24 @@ gboolean on_window_key_press_event(GtkWidget *widget, GdkEventKey *event, gpoint return TRUE; } +void on_refresh(GtkToolButton *button, AWeatherGui *gui) +{ + AWeatherView *view = aweather_gui_get_view(gui); + aweather_view_refresh(view); +} + +void on_zoomin(GtkToolButton *button, AWeatherGui *gui) +{ + AWeatherView *view = aweather_gui_get_view(gui); + aweather_view_zoomin(view); +} + +void on_zoomout(GtkToolButton *button, AWeatherGui *gui) +{ + AWeatherView *view = aweather_gui_get_view(gui); + aweather_view_zoomout(view); +} + void on_site_changed(GtkComboBox *combo, AWeatherGui *gui) { gchar *site; @@ -62,7 +80,7 @@ void on_time_changed(GtkTreeView *view, GtkTreePath *path, g_free(time); } -static gboolean map(GtkWidget *da, GdkEventConfigure *event, AWeatherGui *gui) +static gboolean on_map(GtkWidget *da, GdkEventConfigure *event, AWeatherGui *gui) { //g_message("map:map"); AWeatherView *view = aweather_gui_get_view(gui); @@ -88,7 +106,7 @@ static gboolean map(GtkWidget *da, GdkEventConfigure *event, AWeatherGui *gui) return FALSE; } -static gboolean configure(GtkWidget *da, GdkEventConfigure *event, AWeatherGui *gui) +static gboolean on_configure(GtkWidget *da, GdkEventConfigure *event, AWeatherGui *gui) { aweather_gui_gl_begin(gui); @@ -116,12 +134,12 @@ static gboolean configure(GtkWidget *da, GdkEventConfigure *event, AWeatherGui * return FALSE; } -static gboolean expose_begin(GtkWidget *da, GdkEventExpose *event, AWeatherGui *gui) +static gboolean on_expose_begin(GtkWidget *da, GdkEventExpose *event, AWeatherGui *gui) { aweather_gui_gl_begin(gui); return FALSE; } -static gboolean expose_end(GtkWidget *da, GdkEventExpose *event, AWeatherGui *gui) +static gboolean on_expose_end(GtkWidget *da, GdkEventExpose *event, AWeatherGui *gui) { g_message("aweather:espose_end\n"); aweather_gui_gl_end(gui); @@ -238,7 +256,7 @@ static void time_setup(AWeatherGui *gui) g_signal_connect(aview, "time-changed", G_CALLBACK(update_time_widget), gui); } -gboolean opengl_setup(AWeatherGui *gui) +static void opengl_setup(AWeatherGui *gui) { GtkDrawingArea *drawing = GTK_DRAWING_AREA(aweather_gui_get_widget(gui, "drawing")); @@ -252,11 +270,20 @@ gboolean opengl_setup(AWeatherGui *gui) g_error("GL lacks required capabilities"); /* Set up OpenGL Stuff */ - g_signal_connect (drawing, "map-event", G_CALLBACK(map), gui); - g_signal_connect (drawing, "configure-event", G_CALLBACK(configure), gui); - g_signal_connect (drawing, "expose-event", G_CALLBACK(expose_begin), gui); - g_signal_connect_after(drawing, "expose-event", G_CALLBACK(expose_end), gui); - return TRUE; + g_signal_connect (drawing, "map-event", G_CALLBACK(on_map), gui); + g_signal_connect (drawing, "configure-event", G_CALLBACK(on_configure), gui); + g_signal_connect (drawing, "expose-event", G_CALLBACK(on_expose_begin), gui); + g_signal_connect_after(drawing, "expose-event", G_CALLBACK(on_expose_end), gui); +} + +static void toolbar_setup(AWeatherGui *gui) +{ + GtkWidget *refresh = aweather_gui_get_widget(gui, "refresh_button"); + GtkWidget *zoomin = aweather_gui_get_widget(gui, "zoomin_button"); + GtkWidget *zoomout = aweather_gui_get_widget(gui, "zoomout_button"); + g_signal_connect(refresh, "clicked", G_CALLBACK(on_refresh), gui); + g_signal_connect(zoomin, "clicked", G_CALLBACK(on_zoomin ), gui); + g_signal_connect(zoomout, "clicked", G_CALLBACK(on_zoomout), gui); } @@ -324,6 +351,7 @@ AWeatherGui *aweather_gui_new() gtk_builder_connect_signals(gui->builder, NULL); /* Load components */ + toolbar_setup(gui); site_setup(gui); time_setup(gui); opengl_setup(gui); diff --git a/src/aweather-view.c b/src/aweather-view.c index 5cf3534..2f240a7 100644 --- a/src/aweather-view.c +++ b/src/aweather-view.c @@ -30,6 +30,7 @@ enum { enum { SIG_TIME_CHANGED, SIG_LOCATION_CHANGED, + SIG_REFRESH, NUM_SIGNALS, }; @@ -134,6 +135,16 @@ static void aweather_view_class_init(AWeatherViewClass *klass) G_TYPE_NONE, 1, G_TYPE_STRING); + signals[SIG_REFRESH] = g_signal_new( + "refresh", + G_TYPE_FROM_CLASS(gobject_class), + G_SIGNAL_RUN_LAST, + 0, + NULL, + NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); } @@ -175,3 +186,19 @@ gchar *aweather_view_get_location(AWeatherView *view) //g_message("aweather_view_get_location"); return view->location; } + +void aweather_view_refresh(AWeatherView *view) +{ + g_message("aweather_view_refresh: .."); + g_signal_emit(view, signals[SIG_REFRESH], 0); +} + +void aweather_view_zoomin(AWeatherView *view) +{ + g_message("aweather_view_zoomin: .."); +} + +void aweather_view_zoomout(AWeatherView *view) +{ + g_message("aweather_view_zoomout: .."); +} diff --git a/src/aweather-view.h b/src/aweather-view.h index 9d3ee8d..eed4bad 100644 --- a/src/aweather-view.h +++ b/src/aweather-view.h @@ -55,4 +55,8 @@ gchar *aweather_view_get_time(AWeatherView *view); void aweather_view_set_location(AWeatherView *view, const gchar *location); gchar *aweather_view_get_location(AWeatherView *view); +void aweather_view_refresh(AWeatherView *view); +void aweather_view_zoomin(AWeatherView *view); +void aweather_view_zoomout(AWeatherView *view); + #endif diff --git a/src/data.c b/src/data.c index e4f2a8c..007c423 100644 --- a/src/data.c +++ b/src/data.c @@ -23,32 +23,11 @@ typedef struct { AWeatherCacheDoneCallback callback; - gchar *url; - gchar *local; GFile *src; GFile *dst; gchar *user_data; } cache_file_end_t; -static void cache_file_cb(GObject *source_object, GAsyncResult *res, gpointer _info) -{ - cache_file_end_t *info = _info; - GError *error = NULL; - g_file_copy_finish(G_FILE(source_object), res, &error); - if (error) { - g_message("error copying file ([%s]->[%s]): %s", - info->url, info->local, error->message); - g_error_free(error); - } else { - info->callback(info->local, info->user_data); - } - g_object_unref(info->src); - g_object_unref(info->dst); - g_free(info->url); - g_free(info->local); - g_free(info); -} - static goffset g_file_get_size(GFile *file) { GError *error = NULL; @@ -64,40 +43,41 @@ static goffset g_file_get_size(GFile *file) return size; } -/** - * Cache a image from Ridge to the local disk - * \param path Path to the Ridge file, starting after /ridge/ - * \return The local path to the cached image - */ -void cache_file(char *base, char *path, AWeatherCacheDoneCallback callback, gpointer user_data) +static void cache_file_cb(GObject *source_object, GAsyncResult *res, gpointer _info) { - gchar *url = g_strconcat(base, path, NULL); - gchar *local = g_build_filename(g_get_user_cache_dir(), PACKAGE, path, NULL); - GFile *src = g_file_new_for_uri(url); - GFile *dst = g_file_new_for_path(local); - - if (!g_file_test(local, G_FILE_TEST_EXISTS)) - g_message("Caching file: local does not exist - %s", local); - else if (g_file_get_size(src) != g_file_get_size(dst)) - g_message("Caching file: sizes mismatch - %lld != %lld", - g_file_get_size(src), g_file_get_size(dst)); - else { - callback(local, user_data); - g_object_unref(src); - g_object_unref(dst); - g_free(local); - g_free(url); - return; + cache_file_end_t *info = _info; + char *url = g_file_get_path(info->src); + char *local = g_file_get_path(info->dst); + GError *error = NULL; + g_file_copy_finish(G_FILE(source_object), res, &error); + if (error) { + g_message("error copying file ([%s]->[%s]): %s", + url, local, error->message); + g_error_free(error); + } else { + info->callback(local, TRUE, info->user_data); } + g_object_unref(info->src); + g_object_unref(info->dst); + g_free(info); + g_free(url); + g_free(local); +} + +static void do_cache(GFile *src, GFile *dst, char *reason, + AWeatherCacheDoneCallback callback, gpointer user_data) +{ + char *name = g_file_get_basename(dst); + g_message("Caching file %s: %s", name, reason); + g_free(name); + + GFile *parent = g_file_get_parent(dst); + if (!g_file_query_exists(parent, NULL)) + g_file_make_directory_with_parents(parent, NULL, NULL); + g_object_unref(parent); - char *dir = g_path_get_dirname(local); - if (!g_file_test(dir, G_FILE_TEST_IS_DIR)) - g_mkdir_with_parents(dir, 0755); - g_free(dir); cache_file_end_t *info = g_malloc0(sizeof(cache_file_end_t)); info->callback = callback; - info->url = url; - info->local = local; info->src = src; info->dst = dst; info->user_data = user_data; @@ -109,4 +89,36 @@ void cache_file(char *base, char *path, AWeatherCacheDoneCallback callback, gpoi NULL, // gpointer progress_callback_data, cache_file_cb, // GAsyncReadyCallback callback, info); // gpointer user_data + return; +} + +/** + * Cache a image from Ridge to the local disk + * \param path Path to the Ridge file, starting after /ridge/ + * \return The local path to the cached image + */ +void cache_file(char *base, char *path, AWeatherPolicyType update, + AWeatherCacheDoneCallback callback, gpointer user_data) +{ + gchar *url = g_strconcat(base, path, NULL); + gchar *local = g_build_filename(g_get_user_cache_dir(), PACKAGE, path, NULL); + GFile *src = g_file_new_for_uri(url); + GFile *dst = g_file_new_for_path(local); + + if (update == AWEATHER_ALWAYS) + return do_cache(src, dst, "cache forced", callback, user_data); + + if (!g_file_test(local, G_FILE_TEST_EXISTS)) + return do_cache(src, dst, "local does not exist", callback, user_data); + + if (update == AWEATHER_AUTOMATIC && g_file_get_size(src) != g_file_get_size(dst)) + return do_cache(src, dst, "size mismatch", callback, user_data); + + /* No nead to cache, run the callback now and clean up */ + callback(local, FALSE, user_data); + g_object_unref(src); + g_object_unref(dst); + g_free(local); + g_free(url); + return; } diff --git a/src/data.h b/src/data.h index 994384b..b0ecf61 100644 --- a/src/data.h +++ b/src/data.h @@ -18,8 +18,16 @@ #ifndef __DATA_H__ #define __DATA_H__ -typedef void (*AWeatherCacheDoneCallback)(gchar *file, gpointer user_data); +typedef enum { + AWEATHER_ALWAYS, + AWEATHER_AUTOMATIC, + AWEATHER_NEVER, +} AWeatherPolicyType; -void cache_file(char *base, char *path, AWeatherCacheDoneCallback callback, gpointer user_data); +typedef void (*AWeatherCacheDoneCallback)(gchar *file, gboolean updated, + gpointer user_data); + +void cache_file(char *base, char *path, AWeatherPolicyType update, + AWeatherCacheDoneCallback callback, gpointer user_data); #endif diff --git a/src/main.c b/src/main.c index 9bd7332..cf13c87 100644 --- a/src/main.c +++ b/src/main.c @@ -38,8 +38,8 @@ int main(int argc, char *argv[]) /* Load plugins */ //example_init(gui); - ridge_init (gui); - radar_init (gui); + ridge_init(gui); + radar_init(gui); gtk_widget_show_all(aweather_gui_get_widget(gui, "window")); gtk_main(); diff --git a/src/plugin-radar.c b/src/plugin-radar.c index 4e4376d..4d75c73 100644 --- a/src/plugin-radar.c +++ b/src/plugin-radar.c @@ -191,12 +191,13 @@ static void load_radar_rsl(GPid pid, gint status, gpointer _path) } /* decompress a radar file, then chain to the actuall loading function */ -static void load_radar(char *path, gpointer user_data) +static void load_radar(char *path, gboolean updated, gpointer user_data) { char *raw = g_strconcat(path, ".raw", NULL); - if (g_file_test(raw, G_FILE_TEST_EXISTS)) { + if (!updated) { load_radar_rsl(0, 0, raw); } else { + g_message("File updated, decompressing.."); char *argv[] = {"wsr88ddec", path, raw, NULL}; GPid pid; GError *error = NULL; @@ -220,10 +221,50 @@ static void load_radar(char *path, gpointer user_data) } } +static void update_times(char *site, char **last_time) +{ + char *list_uri = g_strdup_printf( + "http://mesonet.agron.iastate.edu/data/nexrd2/raw/K%s/dir.list", + site); + GFile *list = g_file_new_for_uri(list_uri); + g_free(list_uri); + + gchar *data; + gsize length; + GError *error = NULL; + g_file_load_contents(list, NULL, &data, &length, NULL, &error); + g_object_unref(list); + if (error) { + g_warning("Error loading list for %s: %s", site, error->message); + g_error_free(error); + return; + } + gchar **lines = g_strsplit(data, "\n", -1); + GtkTreeView *tview = GTK_TREE_VIEW(aweather_gui_get_widget(gui, "time")); + GtkListStore *lstore = GTK_LIST_STORE(gtk_tree_view_get_model(tview)); + gtk_list_store_clear(lstore); + GtkTreeIter iter; + for (int i = 0; lines[i] && lines[i][0]; i++) { + // format: `841907 KABR_20090510_0159' + //g_message("\tadding %p [%s]", lines[i], lines[i]); + char **parts = g_strsplit(lines[i], " ", 2); + char *time = parts[1]+5; + gtk_list_store_insert(lstore, &iter, 0); + gtk_list_store_set(lstore, &iter, 0, time, -1); + g_strfreev(parts); + } + + if (last_time) + gtk_tree_model_get(GTK_TREE_MODEL(lstore), &iter, 0, last_time, -1); + + g_free(data); + g_strfreev(lines); +} + /************* * Callbacks * *************/ -static gboolean expose(GtkWidget *da, GdkEventExpose *event, gpointer user_data) +static gboolean on_expose(GtkWidget *da, GdkEventExpose *event, gpointer user_data) { g_message("radar:expose"); if (cur_sweep == NULL) @@ -239,16 +280,20 @@ static gboolean expose(GtkWidget *da, GdkEventExpose *event, gpointer user_data) glDisable(GL_ALPHA_TEST); glColor4f(1,1,1,1); glBegin(GL_QUAD_STRIP); - for (int ri = 0; ri <= sweep->h.nrays+1; ri++) { - /* Do the first sweep twice to complete the last Quad */ - Ray *ray = sweep->ray[ri % sweep->h.nrays]; - - /* right and left looking out from radar */ - double left = ((ray->h.azimuth - ((double)ray->h.beam_width/2.))*M_PI)/180.0; - //double right = ((ray->h.azimuth + ((double)ray->h.beam_width/2.))*M_PI)/180.0; + for (int ri = 0; ri <= sweep->h.nrays; ri++) { + Ray *ray = NULL; + double angle = 0; + if (ri < sweep->h.nrays) { + ray = sweep->ray[ri]; + angle = ((ray->h.azimuth - ((double)ray->h.beam_width/2.))*M_PI)/180.0; + } else { + /* Do the right side of the last sweep */ + ray = sweep->ray[ri-1]; + angle = ((ray->h.azimuth + ((double)ray->h.beam_width/2.))*M_PI)/180.0; + } - double lx = sin(left); - double ly = cos(left); + 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; @@ -299,63 +344,39 @@ static gboolean expose(GtkWidget *da, GdkEventExpose *event, gpointer user_data) return FALSE; } -static void set_time(AWeatherView *view, char *time, gpointer user_data) +static void on_time_changed(AWeatherView *view, char *time, gpointer user_data) { g_message("radar:setting time"); // format: http://mesonet.agron.iastate.edu/data/nexrd2/raw/KABR/KABR_20090510_0323 char *site = aweather_view_get_location(view); char *base = "http://mesonet.agron.iastate.edu/data/"; char *path = g_strdup_printf("nexrd2/raw/K%s/K%s_%s", site, site, time); - //g_message("caching %s/%s", base, path); + + radar = NULL; cur_sweep = NULL; // Clear radar gtk_widget_queue_draw(aweather_gui_get_widget(gui, "drawing")); - cache_file(base, path, load_radar, NULL); + + cache_file(base, path, AWEATHER_AUTOMATIC, load_radar, NULL); g_free(path); } -static void set_site(AWeatherView *view, char *site, gpointer user_data) +static void on_location_changed(AWeatherView *view, char *site, gpointer user_data) { g_message("Loading wsr88d list for %s", site); - cur_sweep = NULL; // Clear radar + char *time = NULL; + update_times(site, &time); + aweather_view_set_time(view, time); - char *list_uri = g_strdup_printf( - "http://mesonet.agron.iastate.edu/data/nexrd2/raw/K%s/dir.list", - site); - GFile *list = g_file_new_for_uri(list_uri); - g_free(list_uri); + g_free(time); +} - gchar *data; - gsize length; - GError *error = NULL; - gtk_widget_queue_draw(aweather_gui_get_widget(gui, "drawing")); - g_file_load_contents(list, NULL, &data, &length, NULL, &error); - g_object_unref(list); - if (error) { - g_warning("Error loading list for %s: %s", site, error->message); - g_error_free(error); - return; - } - gchar **lines = g_strsplit(data, "\n", -1); - GtkTreeView *tview = GTK_TREE_VIEW(aweather_gui_get_widget(gui, "time")); - GtkListStore *lstore = GTK_LIST_STORE(gtk_tree_view_get_model(tview)); - gtk_list_store_clear(lstore); - radar = NULL; - GtkTreeIter iter; - for (int i = 0; lines[i] && lines[i][0]; i++) { - // format: `841907 KABR_20090510_0159' - //g_message("\tadding %p [%s]", lines[i], lines[i]); - char **parts = g_strsplit(lines[i], " ", 2); - char *time = parts[1]+5; - gtk_list_store_insert(lstore, &iter, 0); - gtk_list_store_set(lstore, &iter, 0, time, -1); - g_strfreev(parts); - } +static void on_refresh(AWeatherView *view, gpointer user_data) +{ + char *site = aweather_view_get_location(view); char *time = NULL; - gtk_tree_model_get(GTK_TREE_MODEL(lstore), &iter, 0, &time, -1); + update_times(site, &time); aweather_view_set_time(view, time); g_free(time); - g_free(data); - g_strfreev(lines); } /* Init */ @@ -376,9 +397,10 @@ gboolean radar_init(AWeatherGui *_gui) config_body, gtk_label_new("Radar")); /* Set up OpenGL Stuff */ - g_signal_connect(drawing, "expose-event", G_CALLBACK(expose), NULL); - g_signal_connect(view, "location-changed", G_CALLBACK(set_site), NULL); - g_signal_connect(view, "time-changed", G_CALLBACK(set_time), NULL); + g_signal_connect(drawing, "expose-event", G_CALLBACK(on_expose), NULL); + g_signal_connect(view, "location-changed", G_CALLBACK(on_location_changed), NULL); + g_signal_connect(view, "time-changed", G_CALLBACK(on_time_changed), NULL); + g_signal_connect(view, "refresh", G_CALLBACK(on_refresh), NULL); return TRUE; } diff --git a/src/plugin-ridge.c b/src/plugin-ridge.c index 77bffe9..11d716c 100644 --- a/src/plugin-ridge.c +++ b/src/plugin-ridge.c @@ -46,7 +46,7 @@ static layer_t layers[] = { [LAYER_TOPO] = {"Topo", "Overlays/Topo/Short/%s_Topo_Short.jpg", TRUE, 1, 0}, [LAYER_COUNTY] = {"Counties", "Overlays/County/Short/%s_County_Short.gif", TRUE, 3, 0}, [LAYER_RIVERS] = {"Rivers", "Overlays/Rivers/Short/%s_Rivers_Short.gif", FALSE, 4, 0}, - [LAYER_HIGHWAYS] = {"Highways", "Overlays/Highways/Short/%s_Highways_Short.gif", TRUE, 5, 0}, + [LAYER_HIGHWAYS] = {"Highways", "Overlays/Highways/Short/%s_Highways_Short.gif", FALSE, 5, 0}, [LAYER_CITY] = {"Cities", "Overlays/Cities/Short/%s_City_Short.gif", TRUE, 6, 0}, }; @@ -57,7 +57,7 @@ static AWeatherGui *gui = NULL; * \param filename Path to the image file * \return The OpenGL identifier for the texture */ -void load_texture(gchar *filename, gpointer _layer) +void load_texture(gchar *filename, gboolean updated, gpointer _layer) { layer_t *layer = _layer; aweather_gui_gl_begin(gui); @@ -102,7 +102,7 @@ static void set_site(AWeatherView *view, gchar *site, gpointer user_data) for (int i = 0; i < LAYER_COUNT; i++) { gchar *base = "http://radar.weather.gov/ridge/"; gchar *path = g_strdup_printf(layers[i].fmt, site); - cache_file(base, path, load_texture, &layers[i]); + cache_file(base, path, AWEATHER_NEVER, load_texture, &layers[i]); g_free(path); } } @@ -119,10 +119,10 @@ static gboolean expose(GtkWidget *da, GdkEventExpose *event, gpointer user_data) continue; glBindTexture(GL_TEXTURE_2D, layers[i].tex); glBegin(GL_POLYGON); - glTexCoord2f(0.0, 0.0); glVertex3f(250*1000*-1.0, 250*1000* 1.0, layers[i].z); - glTexCoord2f(0.0, 1.0); glVertex3f(250*1000*-1.0, 250*1000*-1.0, layers[i].z); - glTexCoord2f(1.0, 1.0); glVertex3f(250*1000* 1.0, 250*1000*-1.0, layers[i].z); - glTexCoord2f(1.0, 0.0); glVertex3f(250*1000* 1.0, 250*1000* 1.0, layers[i].z); + glTexCoord2f(0.0, 0.0); glVertex3f(240*1000*-1.0, 282*1000* 1.0, layers[i].z); + glTexCoord2f(0.0, 1.0); glVertex3f(240*1000*-1.0, 282*1000*-1.0, layers[i].z); + glTexCoord2f(1.0, 1.0); glVertex3f(240*1000* 1.0, 282*1000*-1.0, layers[i].z); + glTexCoord2f(1.0, 0.0); glVertex3f(240*1000* 1.0, 282*1000* 1.0, layers[i].z); glEnd(); } -- 2.43.2