From 00413dbcb8af54c99011668be8975e9f3a3a3646 Mon Sep 17 00:00:00 2001 From: Andy Spencer Date: Sat, 24 Oct 2009 21:47:44 +0000 Subject: [PATCH] Splitting out libgis --- TODO | 5 - configure.ac | 7 +- docs/Makefile.am | 2 +- docs/api/.gitignore | 1 - docs/api/Makefile.am | 18 -- examples/.gitignore | 2 - examples/plugin/.gitignore | 1 - examples/plugin/mkfile | 14 - examples/plugin/teapot.c | 132 --------- examples/plugin/teapot.h | 52 ---- examples/tex/.gitignore | 1 - examples/tex/mkfile | 6 - examples/tex/tex.c | 143 --------- examples/tex/tex.png | Bin 187 -> 0 bytes examples/tex/texl.png | Bin 182 -> 0 bytes examples/tex/texls.png | Bin 175 -> 0 bytes examples/tex/texr.png | Bin 178 -> 0 bytes examples/tex/texrs.png | Bin 174 -> 0 bytes gen.sh | 4 +- src/Makefile.am | 13 +- src/gis/.gitignore | 4 - src/gis/.vimrc | 2 - src/gis/Makefile.am | 74 ----- src/gis/gis-data.c | 151 ---------- src/gis/gis-data.h | 40 --- src/gis/gis-marshal.list | 2 - src/gis/gis-opengl.c | 588 ------------------------------------ src/gis/gis-opengl.h | 74 ----- src/gis/gis-plugin.c | 156 ---------- src/gis/gis-plugin.h | 64 ---- src/gis/gis-prefs.c | 166 ----------- src/gis/gis-prefs.h | 72 ----- src/gis/gis-view.c | 297 ------------------- src/gis/gis-view.h | 71 ----- src/gis/gis-world.c | 168 ----------- src/gis/gis-world.h | 129 -------- src/gis/gis.h | 33 --- src/gis/gis_test.c | 72 ----- src/gis/gpqueue.c | 591 ------------------------------------- src/gis/gpqueue.h | 63 ---- src/gis/libgis.pc.in | 11 - src/gis/roam.c | 564 ----------------------------------- src/gis/roam.h | 122 -------- src/gis/wms.c | 541 --------------------------------- src/gis/wms.h | 121 -------- src/gis/wms_test.c | 84 ------ src/plugins/Makefile.am | 4 +- src/plugins/gis | 1 - 48 files changed, 12 insertions(+), 4654 deletions(-) delete mode 100644 docs/api/.gitignore delete mode 100644 docs/api/Makefile.am delete mode 100644 examples/.gitignore delete mode 100644 examples/plugin/.gitignore delete mode 100644 examples/plugin/mkfile delete mode 100644 examples/plugin/teapot.c delete mode 100644 examples/plugin/teapot.h delete mode 100644 examples/tex/.gitignore delete mode 100644 examples/tex/mkfile delete mode 100644 examples/tex/tex.c delete mode 100644 examples/tex/tex.png delete mode 100644 examples/tex/texl.png delete mode 100644 examples/tex/texls.png delete mode 100644 examples/tex/texr.png delete mode 100644 examples/tex/texrs.png delete mode 100644 src/gis/.gitignore delete mode 100644 src/gis/.vimrc delete mode 100644 src/gis/Makefile.am delete mode 100644 src/gis/gis-data.c delete mode 100644 src/gis/gis-data.h delete mode 100644 src/gis/gis-marshal.list delete mode 100644 src/gis/gis-opengl.c delete mode 100644 src/gis/gis-opengl.h delete mode 100644 src/gis/gis-plugin.c delete mode 100644 src/gis/gis-plugin.h delete mode 100644 src/gis/gis-prefs.c delete mode 100644 src/gis/gis-prefs.h delete mode 100644 src/gis/gis-view.c delete mode 100644 src/gis/gis-view.h delete mode 100644 src/gis/gis-world.c delete mode 100644 src/gis/gis-world.h delete mode 100644 src/gis/gis.h delete mode 100644 src/gis/gis_test.c delete mode 100644 src/gis/gpqueue.c delete mode 100644 src/gis/gpqueue.h delete mode 100644 src/gis/libgis.pc.in delete mode 100644 src/gis/roam.c delete mode 100644 src/gis/roam.h delete mode 100644 src/gis/wms.c delete mode 100644 src/gis/wms.h delete mode 100644 src/gis/wms_test.c delete mode 120000 src/plugins/gis diff --git a/TODO b/TODO index da68a8c..463fba4 100644 --- a/TODO +++ b/TODO @@ -10,11 +10,6 @@ Road plan * GTK docs 0.x - GIS - * Use Vertex Arrays/ - VertexBufferObjects/ - DisplayLists/ - glInterleavedArrays - * States/cities/roads overlays * NEXRAD LLE listings, click to center 0.x - Volume scans diff --git a/configure.ac b/configure.ac index 0f21b08..3bf3fe4 100644 --- a/configure.ac +++ b/configure.ac @@ -12,9 +12,7 @@ PKG_PROG_PKG_CONFIG GTK_DOC_CHECK(1.9) # Check for required packages -PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.14 gobject-2.0 gthread-2.0 gmodule-export-2.0) -PKG_CHECK_MODULES(GTK, gtk+-2.0 >= 2.16 gtkglext-1.0) -PKG_CHECK_MODULES(SOUP, libsoup-2.4 >= 2.26) +PKG_CHECK_MODULES(GIS, libgis) # Define odd RSL install location AC_CHECK_LIB(rsl, RSL_wsr88d_to_radar, RSL_LIBS="-lrsl") @@ -25,12 +23,9 @@ AC_SUBST(RSL_LIBS) AC_CONFIG_FILES([ Makefile src/Makefile - src/gis/Makefile - src/gis/libgis.pc src/plugins/Makefile data/Makefile docs/Makefile - docs/api/Makefile ]) AC_OUTPUT diff --git a/docs/Makefile.am b/docs/Makefile.am index e998555..2b6c157 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = api +# TODO: write man pages maintainer-clean-local: rm -f Makefile.in diff --git a/docs/api/.gitignore b/docs/api/.gitignore deleted file mode 100644 index 72e8ffc..0000000 --- a/docs/api/.gitignore +++ /dev/null @@ -1 +0,0 @@ -* diff --git a/docs/api/Makefile.am b/docs/api/Makefile.am deleted file mode 100644 index 4c995bf..0000000 --- a/docs/api/Makefile.am +++ /dev/null @@ -1,18 +0,0 @@ -AM_CPPFLAGS=$(SOUP_CFLAGS) $(GLIB_CFLAGS) $(GTK_CFLAGS) -GTKDOC_LIBS=$(SOUP_LIBS) $(GLIB_LIBS) $(GTK_LIBS) \ - $(top_srcdir)/src/aweather-aweather-*.o \ - $(top_srcdir)/src/gis/libgis*.o -IGNORE_HFILES= -if HAVE_RSL -GTKDOC_LIBS += $(RSL_LIBS) $(top_srcdir)/src/plugins/*.o -else -IGNORE_HFILES += radar.h -endif -DOC_MODULE=aweather -DOC_SOURCE_DIR=$(top_srcdir)/src/ -DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.sgml -MKDB_OPTIONS=--sgml-mode --output-format=xml -include $(top_srcdir)/gtk-doc.make -CLEANFILES += aweather-sections.txt -MAINTAINERCLEANFILES=\ - tmpl/* Makefile.in aweather-docs.sgml aweather-overrides.txt aweather.types aweather-scan.* diff --git a/examples/.gitignore b/examples/.gitignore deleted file mode 100644 index 9d22eb4..0000000 --- a/examples/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*.o -*.so diff --git a/examples/plugin/.gitignore b/examples/plugin/.gitignore deleted file mode 100644 index 328130b..0000000 --- a/examples/plugin/.gitignore +++ /dev/null @@ -1 +0,0 @@ -teapot diff --git a/examples/plugin/mkfile b/examples/plugin/mkfile deleted file mode 100644 index 2c63d6d..0000000 --- a/examples/plugin/mkfile +++ /dev/null @@ -1,14 +0,0 @@ -CFLAGS=`{pkg-config --cflags libgis} -LDFLAGS=`{pkg-config --libs libgis} -LIB=teapot.so -default:V: $LIB -%.so: %.o - gcc $CFLAGS -fPIC -shared -o $target $prereq $LDFLAGS -%.o: %.c - gcc $CFLAGS -fPIC -c -o $target $prereq -clean:V: - rm -f *.o *.so -install:V: - cp $LIB /usr/lib/gis/ -uninstall:V: - rm /usr/lib/gis/$LIB diff --git a/examples/plugin/teapot.c b/examples/plugin/teapot.c deleted file mode 100644 index fd551cc..0000000 --- a/examples/plugin/teapot.c +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright (C) 2009 Andy Spencer - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include - -#include - -#include "teapot.h" - -/*********** - * Helpers * - ***********/ -static gboolean rotate(gpointer _self) -{ - GisPluginTeapot *self = _self; - if (gtk_toggle_button_get_active(self->button)) { - self->rotation += 1.0; - gis_opengl_redraw(self->opengl); - } - return TRUE; -} - - -/*********** - * Methods * - ***********/ -GisPluginTeapot *gis_plugin_teapot_new(GisWorld *world, GisView *view, GisOpenGL *opengl) -{ - g_debug("GisPluginTeapot: new"); - GisPluginTeapot *self = g_object_new(GIS_TYPE_PLUGIN_TEAPOT, NULL); - self->opengl = opengl; - - return self; -} - -static GtkWidget *gis_plugin_teapot_get_config(GisPlugin *_self) -{ - GisPluginTeapot *self = GIS_PLUGIN_TEAPOT(_self); - return GTK_WIDGET(self->button); -} - -static void gis_plugin_teapot_expose(GisPlugin *_self) -{ - GisPluginTeapot *self = GIS_PLUGIN_TEAPOT(_self); - g_debug("GisPluginTeapot: expose"); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(1,-1, -1,1, -10,10); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - - float light_ambient[] = {0.1f, 0.1f, 0.0f, 1.0f}; - float light_diffuse[] = {0.9f, 0.9f, 0.9f, 1.0f}; - float light_position[] = {-30.0f, 50.0f, 40.0f, 1.0f}; - glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); - glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); - glLightfv(GL_LIGHT0, GL_POSITION, light_position); - glEnable(GL_COLOR_MATERIAL); - - glTranslatef(-0.5, -0.5, -2); - glRotatef(self->rotation, 1, 1, 0); - glColor4f(0.9, 0.9, 0.7, 1.0); - glDisable(GL_CULL_FACE); - gdk_gl_draw_teapot(TRUE, 0.25); -} - - -/**************** - * GObject code * - ****************/ -/* Plugin init */ -static void gis_plugin_teapot_plugin_init(GisPluginInterface *iface); -G_DEFINE_TYPE_WITH_CODE(GisPluginTeapot, gis_plugin_teapot, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE(GIS_TYPE_PLUGIN, - gis_plugin_teapot_plugin_init)); -static void gis_plugin_teapot_plugin_init(GisPluginInterface *iface) -{ - g_debug("GisPluginTeapot: plugin_init"); - /* Add methods to the interface */ - iface->expose = gis_plugin_teapot_expose; - iface->get_config = gis_plugin_teapot_get_config; -} -/* Class/Object init */ -static void gis_plugin_teapot_init(GisPluginTeapot *self) -{ - g_debug("GisPluginTeapot: init"); - /* Set defaults */ - self->button = GTK_TOGGLE_BUTTON(gtk_toggle_button_new_with_label("Rotate")); - self->rotate_id = g_timeout_add(1000/60, rotate, self); - self->rotation = 30.0; - self->opengl = NULL; -} -static void gis_plugin_teapot_dispose(GObject *gobject) -{ - g_debug("GisPluginTeapot: dispose"); - GisPluginTeapot *self = GIS_PLUGIN_TEAPOT(gobject); - g_source_remove(self->rotate_id); - /* Drop references */ - G_OBJECT_CLASS(gis_plugin_teapot_parent_class)->dispose(gobject); -} -static void gis_plugin_teapot_finalize(GObject *gobject) -{ - g_debug("GisPluginTeapot: finalize"); - GisPluginTeapot *self = GIS_PLUGIN_TEAPOT(gobject); - /* Free data */ - G_OBJECT_CLASS(gis_plugin_teapot_parent_class)->finalize(gobject); - -} -static void gis_plugin_teapot_class_init(GisPluginTeapotClass *klass) -{ - g_debug("GisPluginTeapot: class_init"); - GObjectClass *gobject_class = (GObjectClass*)klass; - gobject_class->dispose = gis_plugin_teapot_dispose; - gobject_class->finalize = gis_plugin_teapot_finalize; -} diff --git a/examples/plugin/teapot.h b/examples/plugin/teapot.h deleted file mode 100644 index 5008e04..0000000 --- a/examples/plugin/teapot.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2009 Andy Spencer - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef __TEAPOT_H__ -#define __TEAPOT_H__ - -#include - -#define GIS_TYPE_PLUGIN_TEAPOT (gis_plugin_teapot_get_type ()) -#define GIS_PLUGIN_TEAPOT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GIS_TYPE_PLUGIN_TEAPOT, GisPluginTeapot)) -#define GIS_IS_PLUGIN_TEAPOT(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GIS_TYPE_PLUGIN_TEAPOT)) -#define GIS_PLUGIN_TEAPOT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIS_TYPE_PLUGIN_TEAPOT, GisPluginTeapotClass)) -#define GIS_IS_PLUGIN_TEAPOT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIS_TYPE_PLUGIN_TEAPOT)) -#define GIS_PLUGIN_TEAPOT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIS_TYPE_PLUGIN_TEAPOT, GisPluginTeapotClass)) - -typedef struct _GisPluginTeapot GisPluginTeapot; -typedef struct _GisPluginTeapotClass GisPluginTeapotClass; - -struct _GisPluginTeapot { - GObject parent_instance; - - /* instance members */ - GtkToggleButton *button; - guint rotate_id; - float rotation; - GisOpenGL *opengl; -}; - -struct _GisPluginTeapotClass { - GObjectClass parent_class; -}; - -GType gis_plugin_teapot_get_type(); - -/* Methods */ -GisPluginTeapot *gis_plugin_teapot_new(GisWorld *world, GisView *view, GisOpenGL *opengl); - -#endif diff --git a/examples/tex/.gitignore b/examples/tex/.gitignore deleted file mode 100644 index e246454..0000000 --- a/examples/tex/.gitignore +++ /dev/null @@ -1 +0,0 @@ -tex diff --git a/examples/tex/mkfile b/examples/tex/mkfile deleted file mode 100644 index 3036c6c..0000000 --- a/examples/tex/mkfile +++ /dev/null @@ -1,6 +0,0 @@ -MKSHELL=/usr/lib/plan9/bin/rc -PROGS=tex -tex_libs=`{pkg-config --libs gtkglext-1.0} -tex_cflags=`{pkg-config --cflags gtkglext-1.0} -default:V: tex-run -<$HOME/lib/mkcommon diff --git a/examples/tex/tex.c b/examples/tex/tex.c deleted file mode 100644 index 76bfb2c..0000000 --- a/examples/tex/tex.c +++ /dev/null @@ -1,143 +0,0 @@ -#include -#include -#include -#include -#include - -guint tex, texl, texr; - -gboolean on_key_press(GtkWidget *widget, GdkEventKey *event, gpointer _) -{ - if (event->keyval == GDK_q) - gtk_main_quit(); - return FALSE; -} - -gboolean on_expose(GtkWidget *drawing, GdkEventExpose *event, gpointer _) -{ - glClearColor(0.5, 0.5, 1.0, 1.0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(-1,1, -1,1, 10,-10); - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glTranslatef(0, 0, -5); - - glEnable(GL_COLOR_MATERIAL); - glDisable(GL_TEXTURE_2D); - glColor3f(1.0, 1.0, 1.0); - glBegin(GL_QUADS); - glVertex3f(-0.25, -0.75, 0.0); - glVertex3f(-0.25, 0.75, 0.0); - glVertex3f( 0.25, 0.75, 0.0); - glVertex3f( 0.25, -0.75, 0.0); - glEnd(); - - /* Textures */ - glDisable(GL_COLOR_MATERIAL); - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - - gdouble y = 0.875; - - /* Left */ - glBlendFunc(GL_ONE, GL_ZERO); - glBindTexture(GL_TEXTURE_2D, texl); - glBegin(GL_QUADS); - glTexCoord2f(0.0, y); glVertex3f(-0.75, 0.0, 0.0); - glTexCoord2f(0.0, 1.0); glVertex3f(-0.75, 0.5, 0.0); - glTexCoord2f(2.0, 1.0); glVertex3f( 0.75, 0.5, 0.0); - glTexCoord2f(2.0, y); glVertex3f( 0.75, 0.0, 0.0); - glEnd(); - - /* Right */ - glBlendFunc(GL_ONE, GL_ONE); - glBindTexture(GL_TEXTURE_2D, texr); - glBegin(GL_QUADS); - glTexCoord2f(-1.0, y); glVertex3f(-0.75, 0.0, 0.0); - glTexCoord2f(-1.0, 1.0); glVertex3f(-0.75, 0.5, 0.0); - glTexCoord2f( 1.0, 1.0); glVertex3f( 0.75, 0.5, 0.0); - glTexCoord2f( 1.0, y); glVertex3f( 0.75, 0.0, 0.0); - glEnd(); - - /* Bottom */ - glBlendFunc(GL_ONE, GL_ZERO); - glBindTexture(GL_TEXTURE_2D, tex); - glBegin(GL_QUADS); - glTexCoord2f(0.0, 0.0); glVertex3f(-0.75, -0.5, 0.0); - glTexCoord2f(0.0, 1.0-y); glVertex3f(-0.75, -0.0, 0.0); - glTexCoord2f(1.0, 1.0-y); glVertex3f( 0.75, -0.0, 0.0); - glTexCoord2f(1.0, 0.0); glVertex3f( 0.75, -0.5, 0.0); - glEnd(); - - - /* Flush */ - GdkGLDrawable *gldrawable = gdk_gl_drawable_get_current(); - if (gdk_gl_drawable_is_double_buffered(gldrawable)) - gdk_gl_drawable_swap_buffers(gldrawable); - else - glFlush(); - return FALSE; -} -gboolean on_configure(GtkWidget *drawing, GdkEventConfigure *event, gpointer _) -{ - glViewport(0, 0, - drawing->allocation.width, - drawing->allocation.height); - return FALSE; -} - -guint load_tex(gchar *filename) -{ - GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(filename, NULL); - guchar *pixels = gdk_pixbuf_get_pixels(pixbuf); - int width = gdk_pixbuf_get_width(pixbuf); - int height = gdk_pixbuf_get_height(pixbuf); - int alpha = gdk_pixbuf_get_has_alpha(pixbuf); - guint tex; - glGenTextures(1, &tex); - glBindTexture(GL_TEXTURE_2D, tex); - glTexImage2D(GL_TEXTURE_2D, 0, 4, width, height, 0, - (alpha ? GL_RGBA : GL_RGB), GL_UNSIGNED_BYTE, pixels); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); - g_object_unref(pixbuf); - return tex; -} - -int main(int argc, char **argv) -{ - gtk_init(&argc, &argv); - - GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL); - GtkWidget *drawing = gtk_drawing_area_new(); - GdkGLConfig *glconfig = gdk_gl_config_new_by_mode((GdkGLConfigMode)( - GDK_GL_MODE_RGBA | GDK_GL_MODE_DEPTH | - GDK_GL_MODE_DOUBLE | GDK_GL_MODE_ALPHA)); - g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); - g_signal_connect(window, "key-press-event", G_CALLBACK(on_key_press), NULL); - g_signal_connect(drawing, "expose-event", G_CALLBACK(on_expose), NULL); - g_signal_connect(drawing, "configure-event", G_CALLBACK(on_configure), NULL); - gtk_widget_set_gl_capability(drawing, glconfig, NULL, TRUE, GDK_GL_RGBA_TYPE); - gtk_container_add(GTK_CONTAINER(window), drawing); - gtk_widget_show_all(window); - - /* OpenGL setup */ - GdkGLContext *glcontext = gtk_widget_get_gl_context(GTK_WIDGET(drawing)); - GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(GTK_WIDGET(drawing)); - gdk_gl_drawable_gl_begin(gldrawable, glcontext); - - /* Load texture */ - texl = load_tex("texls.png"); - texr = load_tex("texrs.png"); - tex = load_tex("tex.png"); - - gtk_main(); - - gdk_gl_drawable_gl_end(gldrawable); -} diff --git a/examples/tex/tex.png b/examples/tex/tex.png deleted file mode 100644 index af375cb9a96eaee2e5e9d6e2f4582db25d776bdb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 187 zcmeAS@N?(olHy`uVBq!ia0vp^Y(UJy0V3D3_&Eb9#^NA%Cx&(BWL^R}oCO|{#S9GG z!XV7ZFl&wkP>{XE)7O>#CMP4enB21NR*+uF64!_l=ltB<)VvY~=c3falGGH1^30M9 z1$R&1fbd2>aiAg%PZ!4!j_XrTZ{%b!;5lGWKkfhjlk50e-_7M=N_S6mU!-Dt=J4(N aj~RY!GiN^V<+LeK4}+(xpUXO@geCww)HLD% diff --git a/examples/tex/texl.png b/examples/tex/texl.png deleted file mode 100644 index 7fc714195a27873a0c11be21276e3513930da08c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 182 zcmeAS@N?(olHy`uVBq!ia0vp^EFjFm1|(O0oL2{=7>k44ofy`glX(f`a29w(7Bet# z3xhBt!>lLpZLto?6JuV8C-=L(R4S|24~RzF43dej`xB_KnA{K4y7E Wb>VrZYMOz{89ZJ6T-G@yGywoJEi+00 diff --git a/examples/tex/texls.png b/examples/tex/texls.png deleted file mode 100644 index c3de39b0981e3550dd9c6dc227f18645afc6884f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 175 zcmeAS@N?(olHy`uVBq!ia0vp^%s|Y-!3HF~bz9ki6k~CayA#8@b22Z19L@rd$YKTt zZeb8+WSBKa0w~B{;_2(kev^}t+dx{>{?l5ZkYtH#M2T~LZfk&LH{V+hCf0}=vK(|H*9XUa?8{P2|n PsE)zY)z4*}Q$iB}(|<07 diff --git a/examples/tex/texr.png b/examples/tex/texr.png deleted file mode 100644 index a421a5de0843aaf0fc41cc05eed6e74db7fccef0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 178 zcmeAS@N?(olHy`uVBq!ia0vp^EFjFm1|(O0oL2{=7>k44ofy`glX(f`a29w(7Bet# z3xhBt!>l?U@}#8R~kJ+@~mV R<^q*6c)I$ztaD0e0suF7FMI$1 diff --git a/examples/tex/texrs.png b/examples/tex/texrs.png deleted file mode 100644 index 49765d2a4bb17c95b02c1afd53502d0026118957..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 174 zcmeAS@N?(olHy`uVBq!ia0vp^%s|Y-!3HF~bz9ki6k~CayA#8@b22Z19L@rd$YKTt zZeb8+WSBKa0w~B{;_2(kev^}t+kp4sYxh4uA;}Wgh!W@g+}zZ>5(ej@)Wnk16ovB4 zk_-iRPv3y>Mm}+%B56+-#}JO|$v@5?_%Q#W{o()rd3XfWd>R;+^Dv~p5Pw;C_udPj OG6qjqKbLh*2~7YNN-$mk diff --git a/gen.sh b/gen.sh index 8c2b18f..e1ad515 100755 --- a/gen.sh +++ b/gen.sh @@ -1,8 +1,8 @@ #!/bin/bash dir=$(dirname $(readlink -f $0)) +# "--libdir=$dir/src/plugins" +# "--datadir=$dir/data" ./autogen.sh \ - "--libdir=$dir/src/plugins" \ - "--datadir=$dir/data" \ --enable-gtk-doc \ CFLAGS="-g -Werror -Wno-unused $CFLAGS" \ LDFLAGS="-Wl,-z,defs" diff --git a/src/Makefile.am b/src/Makefile.am index f8c79e8..3552e30 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,15 +1,14 @@ -SUBDIRS = gis plugins +SUBDIRS = plugins AM_CFLAGS = -Wall --std=gnu99 -AM_CPPFLAGS = $(GLIB_CFLAGS) $(GTK_CFLAGS) $(SOUP_CFLAGS) -AM_LDADD = $(GLIB_LIBS) $(GTK_LIBS) $(SOUP_LIBS) +AM_CPPFLAGS = $(GIS_CFLAGS) +LIBS = $(GIS_LIBS) bin_PROGRAMS = aweather wsr88ddec aweather_SOURCES = main.c \ aweather-gui.c aweather-gui.h \ aweather-location.c aweather-location.h aweather_CPPFLAGS = $(AM_CPPFLAGS) -DDATADIR="\"$(datadir)\"" -aweather_LDADD = $(AM_LDADD) gis/libgis.la wsr88ddec = wsr88ddec.c wsr88ddec_LDADD = -lbz2 @@ -18,10 +17,10 @@ CLEANFILES = gmon.out valgrind.out MAINTAINERCLEANFILES = Makefile.in test: all - LD_LIBRARY_PATH=gis/.libs .libs/aweather -o -d 7 -s KVNX + aweather -o -d 7 -s KVNX gdb: all - LD_LIBRARY_PATH=gis/.libs gdb .libs/aweather + gdb aweather ddd: all - LD_LIBRARY_PATH=gis/.libs ddd .libs/aweather + ddd aweather diff --git a/src/gis/.gitignore b/src/gis/.gitignore deleted file mode 100644 index 68820ba..0000000 --- a/src/gis/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -*.pc -gis-marshal.* -gis_test -wms_test diff --git a/src/gis/.vimrc b/src/gis/.vimrc deleted file mode 100644 index 5de2904..0000000 --- a/src/gis/.vimrc +++ /dev/null @@ -1,2 +0,0 @@ -set makeprg=make\ test -set tw=100 diff --git a/src/gis/Makefile.am b/src/gis/Makefile.am deleted file mode 100644 index 84e57d2..0000000 --- a/src/gis/Makefile.am +++ /dev/null @@ -1,74 +0,0 @@ -AM_CFLAGS = -Wall --std=gnu99 -AM_CPPFLAGS = $(GLIB_CFLAGS) $(GTK_CFLAGS) $(SOUP_CFLAGS) -AM_LDADD = $(GLIB_LIBS) $(GTK_LIBS) $(SOUP_LIBS) - -# Library -BUILT_SOURCES = gis-marshal.c gis-marshal.h -lib_LTLIBRARIES = libgis.la -gis_includedir = $(includedir)/gis -gis_include_HEADERS = \ - gis.h \ - gis-world.h \ - gis-view.h \ - gis-prefs.h \ - gis-opengl.h \ - gis-plugin.h \ - gis-data.h \ - gpqueue.h \ - roam.h \ - wms.h -libgis_la_SOURCES = \ - gis-world.c gis-world.h \ - gis-view.c gis-view.h \ - gis-prefs.c gis-prefs.h \ - gis-opengl.c gis-opengl.h \ - gis-plugin.c gis-plugin.h \ - gis-marshal.c gis-marshal.h \ - gis-data.c gis-data.h \ - roam.c roam.h \ - wms.c wms.h \ - gpqueue.c gpqueue.h -libgis_la_CPPFLAGS = $(AM_CPPFLAGS) \ - -DDATADIR="\"$(datadir)\"" -DPLUGINDIR="\"$(libdir)/gis\"" -libgis_la_LIBADD = $(AM_LDADD) - -pkgconfigdir = $(libdir)/pkgconfig -pkgconfig_DATA = libgis.pc - -# Test programs -bin_PROGRAMS = gis_test wms_test - -gis_test_SOURCES = gis_test.c gis.h -gis_test_LDADD = $(AM_LDADD) .libs/libgis.a - -wms_test_SOURCES = wms_test.c gis-world.c gis-world.h wms.c wms.h -wms_test_LDADD = $(AM_LDADD) - -MAINTAINERCLEANFILES = Makefile.in - -.list.c: - glib-genmarshal --prefix=gis_cclosure_marshal --body $< > $@ -.list.h: - glib-genmarshal --prefix=gis_cclosure_marshal --header $< > $@ - -test: all - make -C ../plugins all - ./gis_test - -gdb: all - LD_LIBRARY_PATH=.libs gdb .libs/gis_test - -ddd: all - LD_LIBRARY_PATH=.libs ddd .libs/gis_test - -memcheck: all - LD_LIBRARY_PATH=.libs \ - G_SLICE=always-malloc \ - G_DEBUG=gc-friendly,resident-modules \ - valgrind --track-origins=yes \ - --leak-check=full \ - --leak-resolution=high \ - --num-callers=100 \ - --suppressions=../gtk.suppression \ - .libs/gis_test \ - 2> valgrind.out diff --git a/src/gis/gis-data.c b/src/gis/gis-data.c deleted file mode 100644 index 56c39b4..0000000 --- a/src/gis/gis-data.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (C) 2009 Andy Spencer - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include - -#include "gis-data.h" - -typedef struct { - gchar *uri; - gchar *local; - FILE *fp; - GisDataCacheDoneCallback user_done_cb; - GisDataCacheChunkCallback user_chunk_cb; - gpointer user_data; -} cache_file_end_t; - -/* - * Open a file, creating parent directories if needed - */ -static FILE *fopen_p(const gchar *path, const gchar *mode) -{ - gchar *parent = g_path_get_dirname(path); - if (!g_file_test(parent, G_FILE_TEST_EXISTS)) - g_mkdir_with_parents(parent, 0755); - g_free(parent); - return fopen(path, mode); -} - -static void done_cb(SoupSession *session, SoupMessage *message, gpointer _info) -{ - cache_file_end_t *info = _info; - g_debug("data: done_cb"); - - if (message->status_code == 416) - /* Range unsatisfiable, file already complete */ - info->user_done_cb(info->local, FALSE, info->user_data); - else if (SOUP_STATUS_IS_SUCCESSFUL(message->status_code)) - info->user_done_cb(info->local, TRUE, info->user_data); - else - g_warning("data: done_cb - error copying file, status=%d\n" - "\tsrc=%s\n" - "\tdst=%s", - message->status_code, info->uri, info->local); - g_free(info->uri); - g_free(info->local); - fclose(info->fp); - g_free(info); - //g_object_unref(session); This is probably leaking -} - -void chunk_cb(SoupMessage *message, SoupBuffer *chunk, gpointer _info) -{ - cache_file_end_t *info = _info; - if (!SOUP_STATUS_IS_SUCCESSFUL(message->status_code)) - return; - - if (!fwrite(chunk->data, chunk->length, 1, info->fp)) - g_error("data: chunk_cb - Unable to write data"); - goffset cur = ftell(info->fp); - //goffset total = soup_message_headers_get_range(message->response_headers); - goffset start=0, end=0, total=0; - soup_message_headers_get_content_range(message->response_headers, - &start, &end, &total); - - if (info->user_chunk_cb) - info->user_chunk_cb(info->local, cur, total, info->user_data); -} - -static SoupSession *do_cache(cache_file_end_t *info, gboolean truncate, gchar *reason) -{ - char *name = g_path_get_basename(info->uri); - g_debug("data: do_cache - Caching file %s: %s", name, reason); - g_free(name); - - /* TODO: move this to callback so we don't end up with 0 byte files - * Then change back to check for valid file after download */ - if (truncate) info->fp = fopen_p(info->local, "w"); - else info->fp = fopen_p(info->local, "a"); - long bytes = ftell(info->fp); - - SoupSession *session = soup_session_async_new(); - g_object_set(session, "user-agent", PACKAGE_STRING, NULL); - SoupMessage *message = soup_message_new("GET", info->uri); - if (message == NULL) - g_error("message is null, cannot parse uri"); - g_signal_connect(message, "got-chunk", G_CALLBACK(chunk_cb), info); - soup_message_headers_set_range(message->request_headers, bytes, -1); - soup_session_queue_message(session, message, done_cb, info); - return session; -} - -/* - * 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 - */ -SoupSession *cache_file(char *base, char *path, GisDataCacheType update, - GisDataCacheChunkCallback user_chunk_cb, - GisDataCacheDoneCallback user_done_cb, - gpointer user_data) -{ - g_debug("GisData: cache_file - base=%s, path=%s", base, path); - if (base == NULL) { - g_warning("GisData: cache_file - base is null"); - return NULL; - } - if (path == NULL) { - g_warning("GisData: cache_file - base is null"); - return NULL; - } - cache_file_end_t *info = g_malloc0(sizeof(cache_file_end_t)); - info->uri = g_strconcat(base, path, NULL); - info->local = g_build_filename(g_get_user_cache_dir(), PACKAGE, path, NULL); - info->fp = NULL; - info->user_chunk_cb = user_chunk_cb; - info->user_done_cb = user_done_cb; - info->user_data = user_data; - - if (update == GIS_REFRESH) - return do_cache(info, TRUE, "cache forced"); - - if (update == GIS_UPDATE) - return do_cache(info, FALSE, "attempting updating"); - - if (update == GIS_ONCE && !g_file_test(info->local, G_FILE_TEST_EXISTS)) - return do_cache(info, TRUE, "local does not exist"); - - /* No nead to cache, run the callback now and clean up */ - user_done_cb(info->local, FALSE, user_data); - g_free(info->uri); - g_free(info->local); - g_free(info); - return NULL; -} diff --git a/src/gis/gis-data.h b/src/gis/gis-data.h deleted file mode 100644 index 5fe9067..0000000 --- a/src/gis/gis-data.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2009 Andy Spencer - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef __DATA_H__ -#define __DATA_H__ - -#include - -typedef enum { - GIS_ONCE, // Cache the file if it does not exist - GIS_UPDATE, // Append additional data to cached copy (resume) - GIS_REFRESH, // Delete existing file and cache a new copy -} GisDataCacheType; - -typedef void (*GisDataCacheDoneCallback)(gchar *file, gboolean updated, - gpointer user_data); - -typedef void (*GisDataCacheChunkCallback)(gchar *file, goffset cur, - goffset total, gpointer user_data); - -SoupSession *cache_file(char *base, char *path, GisDataCacheType update, - GisDataCacheChunkCallback user_chunk_cb, - GisDataCacheDoneCallback user_done_cb, - gpointer user_data); - -#endif diff --git a/src/gis/gis-marshal.list b/src/gis/gis-marshal.list deleted file mode 100644 index f588897..0000000 --- a/src/gis/gis-marshal.list +++ /dev/null @@ -1,2 +0,0 @@ -VOID:DOUBLE,DOUBLE,DOUBLE -VOID:STRING,UINT,POINTER diff --git a/src/gis/gis-opengl.c b/src/gis/gis-opengl.c deleted file mode 100644 index 78491b8..0000000 --- a/src/gis/gis-opengl.c +++ /dev/null @@ -1,588 +0,0 @@ -/* - * Copyright (C) 2009 Andy Spencer - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/* Tessellation, "finding intersecting triangles" */ -/* http://research.microsoft.com/pubs/70307/tr-2006-81.pdf */ -/* http://www.opengl.org/wiki/Alpha_Blending */ - -#include -#include -#include -#include -#include -#include -#include - -#include "gis-opengl.h" -#include "roam.h" -#include "wms.h" - -#define FOV_DIST 2000.0 -#define MPPX(dist) (4*dist/FOV_DIST) - -// #define ROAM_DEBUG - -/************* - * ROAM Code * - *************/ -void roam_queue_draw(WmsCacheNode *node, gpointer _self) -{ - gtk_widget_queue_draw(GTK_WIDGET(_self)); -} - -void roam_height_func(RoamPoint *point, gpointer _self) -{ - GisOpenGL *self = _self; - - gdouble lat, lon, elev; - xyz2lle(point->x, point->y, point->z, &lat, &lon, &elev); - -#ifdef ROAM_DEBUG - lle2xyz(lat, lon, 0, &point->x, &point->y, &point->z); - return; -#endif - - gdouble cam_lle[3], cam_xyz[3]; - gis_view_get_location(self->view, &cam_lle[0], &cam_lle[1], &cam_lle[2]); - lle2xyz(cam_lle[0], cam_lle[1], cam_lle[2], &cam_xyz[0], &cam_xyz[1], &cam_xyz[2]); - - gdouble res = MPPX(distd(cam_xyz, (double*)point)); - //g_message("lat=%f, lon=%f, res=%f", lat, lon, res); - - point->node = wms_info_fetch_cache(self->srtm, point->node, - res, lat, lon, NULL, roam_queue_draw, self); - - if (point->node) { - WmsBil *bil = point->node->data; - - gint w = bil->width; - gint h = bil->height; - - gdouble xmin = point->node->latlon[0]; - gdouble ymin = point->node->latlon[1]; - gdouble xmax = point->node->latlon[2]; - gdouble ymax = point->node->latlon[3]; - - gdouble xdist = xmax - xmin; - gdouble ydist = ymax - ymin; - - gdouble x = (lon-xmin)/xdist * w; - gdouble y = (1-(lat-ymin)/ydist) * h; - - gdouble x_rem = x - (int)x; - gdouble y_rem = y - (int)y; - guint x_flr = (int)x; - guint y_flr = (int)y; - - /* TODO: Fix interpolation at edges: - * - Pad these at the edges instead of wrapping/truncating - * - Figure out which pixels to index (is 0,0 edge, center, etc) */ - gint16 px00 = bil->data[MIN((y_flr ),h-1)*w + MIN((x_flr ),w-1)]; - gint16 px10 = bil->data[MIN((y_flr ),h-1)*w + MIN((x_flr+1),w-1)]; - gint16 px01 = bil->data[MIN((y_flr+1),h-1)*w + MIN((x_flr ),w-1)]; - gint16 px11 = bil->data[MIN((y_flr+1),h-1)*w + MIN((x_flr+1),w-1)]; - - elev = px00 * (1-x_rem) * (1-y_rem) + - px10 * ( x_rem) * (1-y_rem) + - px01 * (1-x_rem) * ( y_rem) + - px11 * ( x_rem) * ( y_rem); - //g_message("elev=%f -- %hd %hd %hd %hd", - // elev, px00, px10, px01, px11); - } else { - elev = 0; - } - - lle2xyz(lat, lon, elev, &point->x, &point->y, &point->z); -} - -void roam_tri_func(RoamTriangle *tri, gpointer _self) -{ -#ifdef ROAM_DEBUG - glBegin(GL_TRIANGLES); - glNormal3dv(tri->p.r->norm); glVertex3dv((double*)tri->p.r); - glNormal3dv(tri->p.m->norm); glVertex3dv((double*)tri->p.m); - glNormal3dv(tri->p.l->norm); glVertex3dv((double*)tri->p.l); - glEnd(); - return; -#endif - - GisOpenGL *self = _self; - if (tri->error < 0) return; - - /* Get lat-lon min and maxes for the triangle */ - gdouble lat[3], lon[3], elev[3]; - xyz2lle(tri->p.r->x, tri->p.r->y, tri->p.r->z, &lat[0], &lon[0], &elev[0]); - xyz2lle(tri->p.m->x, tri->p.m->y, tri->p.m->z, &lat[1], &lon[1], &elev[1]); - xyz2lle(tri->p.l->x, tri->p.l->y, tri->p.l->z, &lat[2], &lon[2], &elev[2]); - gdouble lat_max = MAX(MAX(lat[0], lat[1]), lat[2]); - gdouble lat_min = MIN(MIN(lat[0], lat[1]), lat[2]); - gdouble lat_avg = (lat_min+lat_max)/2; - gdouble lon_max = MAX(MAX(lon[0], lon[1]), lon[2]); - gdouble lon_min = MIN(MIN(lon[0], lon[1]), lon[2]); - gdouble lon_avg = (lon_min+lon_max)/2; - - /* Get target resolution */ - gdouble cam_lle[3], cam_xyz[3]; - gis_view_get_location(self->view, &cam_lle[0], &cam_lle[1], &cam_lle[2]); - lle2xyz(cam_lle[0], cam_lle[1], cam_lle[2], &cam_xyz[0], &cam_xyz[1], &cam_xyz[2]); - gdouble distr = distd(cam_xyz, (double*)tri->p.r); - gdouble distm = distd(cam_xyz, (double*)tri->p.m); - gdouble distl = distd(cam_xyz, (double*)tri->p.l); - double res = MPPX(MIN(MIN(distr, distm), distl)); - - /* TODO: - * - Fetch needed textures, not all corners - * - Also fetch center textures that aren't touched by a corner - * - Idea: send {lat,lon}{min,max} to fetch_cache and handle it in the recursion */ - /* Fetch textures */ - tri->nodes[0] = wms_info_fetch_cache(self->bmng, tri->nodes[0], res, lat_min, lon_min, NULL, roam_queue_draw, self); - tri->nodes[1] = wms_info_fetch_cache(self->bmng, tri->nodes[1], res, lat_max, lon_min, NULL, roam_queue_draw, self); - tri->nodes[2] = wms_info_fetch_cache(self->bmng, tri->nodes[2], res, lat_min, lon_max, NULL, roam_queue_draw, self); - tri->nodes[3] = wms_info_fetch_cache(self->bmng, tri->nodes[3], res, lat_max, lon_max, NULL, roam_queue_draw, self); - tri->nodes[4] = wms_info_fetch_cache(self->bmng, tri->nodes[4], res, lat_avg, lon_avg, NULL, roam_queue_draw, self); - /* Hopefully get all textures at the same resolution to prevent overlaps */ - //gdouble maxres = 0; - //for (int i = 0; i < 5; i++) - // if (tri->nodes[i] && tri->nodes[i]->res > maxres) - // maxres = tri->nodes[i]->res; - //if (maxres != 0) { - // tri->nodes[0] = wms_info_fetch_cache(self->bmng, tri->nodes[0], maxres, lat_min, lon_min, NULL, roam_queue_draw, self); - // tri->nodes[1] = wms_info_fetch_cache(self->bmng, tri->nodes[1], maxres, lat_max, lon_min, NULL, roam_queue_draw, self); - // tri->nodes[2] = wms_info_fetch_cache(self->bmng, tri->nodes[2], maxres, lat_min, lon_max, NULL, roam_queue_draw, self); - // tri->nodes[3] = wms_info_fetch_cache(self->bmng, tri->nodes[3], maxres, lat_max, lon_max, NULL, roam_queue_draw, self); - // tri->nodes[4] = wms_info_fetch_cache(self->bmng, tri->nodes[4], maxres, lat_avg, lon_avg, NULL, roam_queue_draw, self); - //} - - /* Vertex color for hieght map viewing, 8848m == Everest */ - gfloat colors[] = { - (elev[0]-EARTH_R)/8848, - (elev[1]-EARTH_R)/8848, - (elev[2]-EARTH_R)/8848, - }; - - /* Draw each texture */ - /* TODO: Prevent double exposure when of hi-res textures on top of - * low-res textures when some high-res textures are not yet loaded. */ - glBlendFunc(GL_ONE, GL_ZERO); - for (int i = 0; i < 5; i++) { - /* Skip missing textures */ - if (tri->nodes[i] == NULL) - continue; - /* Skip already drawn textures */ - switch (i) { - case 4: if (tri->nodes[i] == tri->nodes[3]) continue; - case 3: if (tri->nodes[i] == tri->nodes[2]) continue; - case 2: if (tri->nodes[i] == tri->nodes[1]) continue; - case 1: if (tri->nodes[i] == tri->nodes[0]) continue; - } - - WmsCacheNode *node = tri->nodes[i]; - - if (node->latlon[0] == -180) { - if (lon[0] < -90 || lon[1] < -90 || lon[2] < -90) { - if (lon[0] > 90) lon[0] -= 360; - if (lon[1] > 90) lon[1] -= 360; - if (lon[2] > 90) lon[2] -= 360; - } - } else if (node->latlon[2] == 180.0) { - if (lon[0] < -90) lon[0] += 360; - if (lon[1] < -90) lon[1] += 360; - if (lon[2] < -90) lon[2] += 360; - } - - gdouble xmin = node->latlon[0]; - gdouble ymin = node->latlon[1]; - gdouble xmax = node->latlon[2]; - gdouble ymax = node->latlon[3]; - - gdouble xdist = xmax - xmin; - gdouble ydist = ymax - ymin; - - gdouble xy[][3] = { - {(lon[0]-xmin)/xdist, 1-(lat[0]-ymin)/ydist}, - {(lon[1]-xmin)/xdist, 1-(lat[1]-ymin)/ydist}, - {(lon[2]-xmin)/xdist, 1-(lat[2]-ymin)/ydist}, - }; - - glBindTexture(GL_TEXTURE_2D, *(guint*)node->data); - - glBegin(GL_TRIANGLES); - glColor3fv(colors); glNormal3dv(tri->p.r->norm); glTexCoord2dv(xy[0]); glVertex3dv((double*)tri->p.r); - glColor3fv(colors); glNormal3dv(tri->p.m->norm); glTexCoord2dv(xy[1]); glVertex3dv((double*)tri->p.m); - glColor3fv(colors); glNormal3dv(tri->p.l->norm); glTexCoord2dv(xy[2]); glVertex3dv((double*)tri->p.l); - glEnd(); - glBlendFunc(GL_ONE, GL_ONE); - } -} - -static void set_camera(GisOpenGL *self) -{ - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - double lat, lon, elev, rx, ry, rz; - gis_view_get_location(self->view, &lat, &lon, &elev); - gis_view_get_rotation(self->view, &rx, &ry, &rz); - glRotatef(rx, 1, 0, 0); - glRotatef(rz, 0, 0, 1); - glTranslatef(0, 0, -elev2rad(elev)); - glRotatef(lat, 1, 0, 0); - glRotatef(-lon, 0, 1, 0); -} - -static void set_visuals(GisOpenGL *self) -{ - /* Lighting */ - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); -#ifdef ROAM_DEBUG - float light_ambient[] = {0.7f, 0.7f, 0.7f, 1.0f}; - float light_diffuse[] = {2.0f, 2.0f, 2.0f, 1.0f}; -#else - float light_ambient[] = {0.2f, 0.2f, 0.2f, 1.0f}; - float light_diffuse[] = {5.0f, 5.0f, 5.0f, 1.0f}; -#endif - float light_position[] = {-13*EARTH_R, 1*EARTH_R, 3*EARTH_R, 1.0f}; - glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); - glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); - glLightfv(GL_LIGHT0, GL_POSITION, light_position); - glEnable(GL_LIGHT0); - glEnable(GL_LIGHTING); - - float material_ambient[] = {0.2, 0.2, 0.2, 1.0}; - float material_diffuse[] = {0.8, 0.8, 0.8, 1.0}; - float material_specular[] = {0.0, 0.0, 0.0, 1.0}; - float material_emission[] = {0.0, 0.0, 0.0, 1.0}; - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, material_ambient); - glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, material_diffuse); - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, material_specular); - glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, material_emission); - glDisable(GL_TEXTURE_2D); - glDisable(GL_COLOR_MATERIAL); - - /* Camera */ - set_camera(self); - - /* Misc */ - gdouble lat, lon, elev; - gis_view_get_location(self->view, &lat, &lon, &elev); - gdouble rg = MAX(0, 1-(elev/20000)); - gdouble blue = MAX(0, 1-(elev/50000)); - glClearColor(MIN(0.65,rg), MIN(0.65,rg), MIN(1,blue), 1.0f); - - glDisable(GL_ALPHA_TEST); - - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); - -#ifndef ROAM_DEBUG - glCullFace(GL_BACK); - glEnable(GL_CULL_FACE); -#endif - - glClearDepth(1.0); - glDepthFunc(GL_LEQUAL); - glEnable(GL_DEPTH_TEST); - - glEnable(GL_LINE_SMOOTH); - - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - //glShadeModel(GL_FLAT); -} - - -/************* - * Callbacks * - *************/ -static void on_realize(GisOpenGL *self, gpointer _) -{ - set_visuals(self); -} -static gboolean on_configure(GisOpenGL *self, GdkEventConfigure *event, gpointer _) -{ - g_debug("GisOpenGL: on_confiure"); - gis_opengl_begin(self); - - double width = GTK_WIDGET(self)->allocation.width; - double height = GTK_WIDGET(self)->allocation.height; - glViewport(0, 0, width, height); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - double ang = atan(height/FOV_DIST); - gluPerspective(rad2deg(ang)*2, width/height, 1, 20*EARTH_R); - -#ifndef ROAM_DEBUG - roam_sphere_update(self->sphere); -#endif - - gis_opengl_end(self); - return FALSE; -} - -static void on_expose_plugin(GisPlugin *plugin, gchar *name, GisOpenGL *self) -{ - set_visuals(self); - glMatrixMode(GL_PROJECTION); glPushMatrix(); - glMatrixMode(GL_MODELVIEW); glPushMatrix(); - gis_plugin_expose(plugin); - glMatrixMode(GL_PROJECTION); glPopMatrix(); - glMatrixMode(GL_MODELVIEW); glPopMatrix(); -} -static gboolean on_expose(GisOpenGL *self, GdkEventExpose *event, gpointer _) -{ - g_debug("GisOpenGL: on_expose - begin"); - gis_opengl_begin(self); - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - -#ifndef ROAM_DEBUG - set_visuals(self); - glEnable(GL_TEXTURE_2D); - roam_sphere_draw(self->sphere); -#endif - -#ifdef ROAM_DEBUG - set_visuals(self); - glColor4f(0.0, 0.0, 9.0, 0.6); - glDisable(GL_TEXTURE_2D); - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - roam_sphere_draw(self->sphere); -#endif - - //glDisable(GL_TEXTURE_2D); - //glEnable(GL_COLOR_MATERIAL); - //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - //roam_sphere_draw(self->sphere); - - gis_plugins_foreach(self->plugins, G_CALLBACK(on_expose_plugin), self); - - set_visuals(self); - gis_opengl_end(self); - gis_opengl_flush(self); - g_debug("GisOpenGL: on_expose - end\n"); - return FALSE; -} - -static gboolean on_button_press(GisOpenGL *self, GdkEventButton *event, gpointer _) -{ - g_debug("GisOpenGL: on_button_press - Grabbing focus"); - gtk_widget_grab_focus(GTK_WIDGET(self)); - return TRUE; -} - -static gboolean on_key_press(GisOpenGL *self, GdkEventKey *event, gpointer _) -{ - g_debug("GisOpenGL: on_key_press - key=%x, state=%x, plus=%x", - event->keyval, event->state, GDK_plus); - - double lat, lon, elev, pan; - gis_view_get_location(self->view, &lat, &lon, &elev); - pan = MIN(elev/(EARTH_R/2), 30); - guint kv = event->keyval; - if (kv == GDK_Left || kv == GDK_h) gis_view_pan(self->view, 0, -pan, 0); - else if (kv == GDK_Down || kv == GDK_j) gis_view_pan(self->view, -pan, 0, 0); - else if (kv == GDK_Up || kv == GDK_k) gis_view_pan(self->view, pan, 0, 0); - else if (kv == GDK_Right || kv == GDK_l) gis_view_pan(self->view, 0, pan, 0); - else if (kv == GDK_minus || kv == GDK_o) gis_view_zoom(self->view, 10./9); - else if (kv == GDK_plus || kv == GDK_i) gis_view_zoom(self->view, 9./10); - else if (kv == GDK_H) gis_view_rotate(self->view, 0, 0, -10); - else if (kv == GDK_J) gis_view_rotate(self->view, 10, 0, 0); - else if (kv == GDK_K) gis_view_rotate(self->view, -10, 0, 0); - else if (kv == GDK_L) gis_view_rotate(self->view, 0, 0, 10); - - /* Testing */ -#ifdef ROAM_DEBUG - else if (kv == GDK_n) roam_sphere_split_one(self->sphere); - else if (kv == GDK_p) roam_sphere_merge_one(self->sphere); - else if (kv == GDK_r) roam_sphere_split_merge(self->sphere); - else if (kv == GDK_u) roam_sphere_update(self->sphere); - gtk_widget_queue_draw(GTK_WIDGET(self)); -#endif - - return TRUE; -} - -static void on_view_changed(GisView *view, - gdouble _1, gdouble _2, gdouble _3, GisOpenGL *self) -{ - gis_opengl_begin(self); - set_visuals(self); -#ifndef ROAM_DEBUG - roam_sphere_update(self->sphere); -#endif - gis_opengl_redraw(self); - gis_opengl_end(self); -} - -static gboolean on_idle(GisOpenGL *self) -{ - gis_opengl_begin(self); - if (roam_sphere_split_merge(self->sphere)) - gis_opengl_redraw(self); - gis_opengl_end(self); - return TRUE; -} - - -/*********** - * Methods * - ***********/ -GisOpenGL *gis_opengl_new(GisWorld *world, GisView *view, GisPlugins *plugins) -{ - g_debug("GisOpenGL: new"); - GisOpenGL *self = g_object_new(GIS_TYPE_OPENGL, NULL); - self->world = world; - self->view = view; - self->plugins = plugins; - g_object_ref(world); - g_object_ref(view); - - g_signal_connect(self->view, "location-changed", G_CALLBACK(on_view_changed), self); - g_signal_connect(self->view, "rotation-changed", G_CALLBACK(on_view_changed), self); - - /* TODO: update point eights sometime later so we have heigh-res heights for them */ - self->sphere = roam_sphere_new(roam_tri_func, roam_height_func, self); - - return g_object_ref(self); -} - -void gis_opengl_center_position(GisOpenGL *self, gdouble lat, gdouble lon, gdouble elev) -{ - set_camera(self); - glRotatef(lon, 0, 1, 0); - glRotatef(-lat, 1, 0, 0); - glTranslatef(0, 0, elev2rad(elev)); -} - -void gis_opengl_redraw(GisOpenGL *self) -{ - g_debug("GisOpenGL: gl_redraw"); - gtk_widget_queue_draw(GTK_WIDGET(self)); -} -void gis_opengl_begin(GisOpenGL *self) -{ - g_assert(GIS_IS_OPENGL(self)); - - GdkGLContext *glcontext = gtk_widget_get_gl_context(GTK_WIDGET(self)); - GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(GTK_WIDGET(self)); - - if (!gdk_gl_drawable_gl_begin(gldrawable, glcontext)) - g_assert_not_reached(); -} -void gis_opengl_end(GisOpenGL *self) -{ - g_assert(GIS_IS_OPENGL(self)); - GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(GTK_WIDGET(self)); - gdk_gl_drawable_gl_end(gldrawable); -} -void gis_opengl_flush(GisOpenGL *self) -{ - g_assert(GIS_IS_OPENGL(self)); - GdkGLDrawable *gldrawable = gtk_widget_get_gl_drawable(GTK_WIDGET(self)); - if (gdk_gl_drawable_is_double_buffered(gldrawable)) - gdk_gl_drawable_swap_buffers(gldrawable); - else - glFlush(); - gdk_gl_drawable_gl_end(gldrawable); -} - - -/**************** - * GObject code * - ****************/ -G_DEFINE_TYPE(GisOpenGL, gis_opengl, GTK_TYPE_DRAWING_AREA); -static void gis_opengl_init(GisOpenGL *self) -{ - g_debug("GisOpenGL: init"); - self->bmng = wms_info_new_for_bmng(NULL, NULL); - self->srtm = wms_info_new_for_srtm(NULL, NULL); - - /* OpenGL setup */ - GdkGLConfig *glconfig = gdk_gl_config_new_by_mode( - GDK_GL_MODE_RGBA | GDK_GL_MODE_DEPTH | - GDK_GL_MODE_DOUBLE | GDK_GL_MODE_ALPHA); - if (!glconfig) - g_error("Failed to create glconfig"); - if (!gtk_widget_set_gl_capability(GTK_WIDGET(self), - glconfig, NULL, TRUE, GDK_GL_RGBA_TYPE)) - g_error("GL lacks required capabilities"); - g_object_unref(glconfig); - - gtk_widget_set_size_request(GTK_WIDGET(self), 600, 550); - gtk_widget_set_events(GTK_WIDGET(self), - GDK_BUTTON_PRESS_MASK | - GDK_ENTER_NOTIFY_MASK | - GDK_KEY_PRESS_MASK); - g_object_set(self, "can-focus", TRUE, NULL); - -#ifndef ROAM_DEBUG - self->sm_source = g_timeout_add(10, (GSourceFunc)on_idle, self); -#endif - - g_signal_connect(self, "realize", G_CALLBACK(on_realize), NULL); - g_signal_connect(self, "configure-event", G_CALLBACK(on_configure), NULL); - g_signal_connect(self, "expose-event", G_CALLBACK(on_expose), NULL); - - g_signal_connect(self, "button-press-event", G_CALLBACK(on_button_press), NULL); - g_signal_connect(self, "enter-notify-event", G_CALLBACK(on_button_press), NULL); - g_signal_connect(self, "key-press-event", G_CALLBACK(on_key_press), NULL); -} -static GObject *gis_opengl_constructor(GType gtype, guint n_properties, - GObjectConstructParam *properties) -{ - g_debug("GisOpengl: constructor"); - GObjectClass *parent_class = G_OBJECT_CLASS(gis_opengl_parent_class); - return parent_class->constructor(gtype, n_properties, properties); -} -static void gis_opengl_dispose(GObject *_self) -{ - g_debug("GisOpenGL: dispose"); - GisOpenGL *self = GIS_OPENGL(_self); - if (self->sm_source) { - g_source_remove(self->sm_source); - self->sm_source = 0; - } - if (self->sphere) { - roam_sphere_free(self->sphere); - self->sphere = NULL; - } - if (self->world) { - g_object_unref(self->world); - self->world = NULL; - } - if (self->view) { - g_object_unref(self->view); - self->view = NULL; - } - G_OBJECT_CLASS(gis_opengl_parent_class)->dispose(_self); -} -static void gis_opengl_finalize(GObject *_self) -{ - g_debug("GisOpenGL: finalize"); - GisOpenGL *self = GIS_OPENGL(_self); - wms_info_free(self->bmng); - wms_info_free(self->srtm); - G_OBJECT_CLASS(gis_opengl_parent_class)->finalize(_self); -} -static void gis_opengl_class_init(GisOpenGLClass *klass) -{ - g_debug("GisOpenGL: class_init"); - GObjectClass *gobject_class = G_OBJECT_CLASS(klass); - gobject_class->constructor = gis_opengl_constructor; - gobject_class->dispose = gis_opengl_dispose; - gobject_class->finalize = gis_opengl_finalize; -} diff --git a/src/gis/gis-opengl.h b/src/gis/gis-opengl.h deleted file mode 100644 index fcaaa0e..0000000 --- a/src/gis/gis-opengl.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2009 Andy Spencer - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef __GIS_OPENGL_H__ -#define __GIS_OPENGL_H__ - -#include -#include -#include - -/* Type macros */ -#define GIS_TYPE_OPENGL (gis_opengl_get_type()) -#define GIS_OPENGL(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GIS_TYPE_OPENGL, GisOpenGL)) -#define GIS_IS_OPENGL(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GIS_TYPE_OPENGL)) -#define GIS_OPENGL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIS_TYPE_OPENGL, GisOpenGLClass)) -#define GIS_IS_OPENGL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIS_TYPE_OPENGL)) -#define GIS_OPENGL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIS_TYPE_OPENGL, GisOpenGLClass)) - -typedef struct _GisOpenGL GisOpenGL; -typedef struct _GisOpenGLClass GisOpenGLClass; - -#include "gis-view.h" -#include "gis-world.h" -#include "gis-plugin.h" -#include "roam.h" -#include "wms.h" - -struct _GisOpenGL { - GtkDrawingArea parent_instance; - - /* instance members */ - GisWorld *world; - GisView *view; - GisPlugins *plugins; - RoamSphere *sphere; - WmsInfo *bmng; - WmsInfo *srtm; - guint sm_source; -}; - -struct _GisOpenGLClass { - GtkDrawingAreaClass parent_class; - - /* class members */ -}; - -GType gis_opengl_get_type(void); - -/* Methods */ -GisOpenGL *gis_opengl_new(GisWorld *world, GisView *view, GisPlugins *plugins); - -void gis_opengl_center_position(GisOpenGL *gis, gdouble lat, gdouble lon, gdouble elev); - -void gis_opengl_redraw(GisOpenGL *gis); - -void gis_opengl_begin(GisOpenGL *gis); -void gis_opengl_end(GisOpenGL *gis); -void gis_opengl_flush(GisOpenGL *gis); - -#endif diff --git a/src/gis/gis-plugin.c b/src/gis/gis-plugin.c deleted file mode 100644 index 4bfab58..0000000 --- a/src/gis/gis-plugin.c +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright (C) 2009 Andy Spencer - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include - -#include "gis-plugin.h" - -/******************** - * Plugin interface * - ********************/ -static void gis_plugin_base_init(gpointer g_class) -{ - static gboolean is_initialized = FALSE; - if (!is_initialized) { - /* add properties and signals to the interface here */ - is_initialized = TRUE; - } -} - -GType gis_plugin_get_type() -{ - static GType type = 0; - if (type == 0) { - static const GTypeInfo info = { - sizeof(GisPluginInterface), - gis_plugin_base_init, - NULL, - }; - type = g_type_register_static(G_TYPE_INTERFACE, - "GisPlugin", &info, 0); - } - return type; -} - -void gis_plugin_expose(GisPlugin *self) -{ - g_return_if_fail(GIS_IS_PLUGIN(self)); - GIS_PLUGIN_GET_INTERFACE(self)->expose(self); -} - -GtkWidget *gis_plugin_get_config(GisPlugin *self) -{ - g_return_val_if_fail(GIS_IS_PLUGIN(self), NULL); - return GIS_PLUGIN_GET_INTERFACE(self)->get_config(self); -} - - -/*************** - * Plugins API * - ***************/ -typedef struct { - gchar *name; - GisPlugin *plugin; -} GisPluginStore; - -GisPlugins *gis_plugins_new() -{ - return g_ptr_array_new(); -} - -void gis_plugins_free(GisPlugins *self) -{ - for (int i = 0; i < self->len; i++) { - GisPluginStore *store = g_ptr_array_index(self, i); - g_object_unref(store->plugin); - g_free(store->name); - g_free(store); - g_ptr_array_remove_index(self, i); - } - g_ptr_array_free(self, TRUE); -} - -GList *gis_plugins_available() -{ - GDir *dir = g_dir_open(PLUGINDIR, 0, NULL); - if (dir == NULL) - return NULL; - GList *list = NULL; - const gchar *name; - while ((name = g_dir_read_name(dir))) { - if (g_pattern_match_simple("*.so", name)) { - gchar **parts = g_strsplit(name, ".", 2); - list = g_list_prepend(list, g_strdup(parts[0])); - g_strfreev(parts); - } - } - return list; -} - -GisPlugin *gis_plugins_load(GisPlugins *self, const char *name, - GisWorld *world, GisView *view, GisOpenGL *opengl, GisPrefs *prefs) -{ - gchar *path = g_strdup_printf("%s/%s.%s", PLUGINDIR, name, G_MODULE_SUFFIX); - GModule *module = g_module_open(path, 0); - g_free(path); - if (module == NULL) { - g_warning("Unable to load module %s: %s", name, g_module_error()); - return NULL; - } - - gpointer constructor_ptr; // GCC 4.1 fix? - gchar *constructor_str = g_strconcat("gis_plugin_", name, "_new", NULL); - if (!g_module_symbol(module, constructor_str, &constructor_ptr)) { - g_warning("Unable to load symbol %s from %s: %s", - constructor_str, name, g_module_error()); - g_module_close(module); - g_free(constructor_str); - return NULL; - } - g_free(constructor_str); - GisPluginConstructor constructor = constructor_ptr; - - GisPluginStore *store = g_malloc(sizeof(GisPluginStore)); - store->name = g_strdup(name); - store->plugin = constructor(world, view, opengl, prefs); - g_ptr_array_add(self, store); - return store->plugin; -} - -gboolean gis_plugins_unload(GisPlugins *self, const char *name) -{ - for (int i = 0; i < self->len; i++) { - GisPluginStore *store = g_ptr_array_index(self, i); - if (g_str_equal(store->name, name)) { - g_object_unref(store->plugin); - g_free(store->name); - g_free(store); - g_ptr_array_remove_index(self, i); - } - } - return FALSE; -} -void gis_plugins_foreach(GisPlugins *self, GCallback _callback, gpointer user_data) -{ - typedef void (*CBFunc)(GisPlugin *, const gchar *, gpointer); - CBFunc callback = (CBFunc)_callback; - for (int i = 0; i < self->len; i++) { - GisPluginStore *store = g_ptr_array_index(self, i); - callback(store->plugin, store->name, user_data); - } -} diff --git a/src/gis/gis-plugin.h b/src/gis/gis-plugin.h deleted file mode 100644 index a667fba..0000000 --- a/src/gis/gis-plugin.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2009 Andy Spencer - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef __GIS_PLUGIN_H__ -#define __GIS_PLUGIN_H__ - -#include -#include - -#define GIS_TYPE_PLUGIN (gis_plugin_get_type()) -#define GIS_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIS_TYPE_PLUGIN, GisPlugin)) -#define GIS_IS_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIS_TYPE_PLUGIN)) -#define GIS_PLUGIN_GET_INTERFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE((inst), GIS_TYPE_PLUGIN, GisPluginInterface)) - -typedef struct _GisPlugin GisPlugin; -typedef struct _GisPluginInterface GisPluginInterface; -typedef GPtrArray GisPlugins; - -struct _GisPluginInterface -{ - GTypeInterface parent_iface; - - /* Virtual functions */ - void (*expose )(GisPlugin *self); - GtkWidget *(*get_config)(GisPlugin *self); -}; - -GType gis_plugin_get_type(); - -/* Methods */ -void gis_plugin_expose(GisPlugin *self); -GtkWidget *gis_plugin_get_config(GisPlugin *self); - -/* Plugins API */ -#include "gis-world.h" -#include "gis-view.h" -#include "gis-opengl.h" -#include "gis-prefs.h" - -typedef GisPlugin *(*GisPluginConstructor)(GisWorld *world, GisView *view, GisOpenGL *opengl, GisPrefs *prefs); - -GisPlugins *gis_plugins_new(); -void gis_plugins_free(); -GList *gis_plugins_available(); -GisPlugin *gis_plugins_load(GisPlugins *self, const char *name, - GisWorld *world, GisView *view, GisOpenGL *opengl, GisPrefs *prefs); -gboolean gis_plugins_unload(GisPlugins *self, const char *name); -void gis_plugins_foreach(GisPlugins *self, GCallback callback, gpointer user_data); - -#endif diff --git a/src/gis/gis-prefs.c b/src/gis/gis-prefs.c deleted file mode 100644 index abae1a2..0000000 --- a/src/gis/gis-prefs.c +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (C) 2009 Andy Spencer - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include "gis-marshal.h" -#include "gis-prefs.h" - - -enum { - SIG_PREF_CHANGED, - NUM_SIGNALS, -}; -static guint signals[NUM_SIGNALS]; - - -/*********** - * Methods * - ***********/ -GisPrefs *gis_prefs_new(const gchar *prog) -{ - g_debug("GisPrefs: new - %s", prog); - GisPrefs *self = g_object_new(GIS_TYPE_PREFS, NULL); - self->key_path = g_build_filename(g_get_user_config_dir(), - prog, "config.ini", NULL); - GError *error = NULL; - g_key_file_load_from_file(self->key_file, self->key_path, - G_KEY_FILE_KEEP_COMMENTS, &error); - if (error) { - g_debug("GisPrefs: new - Trying %s defaults", prog); - g_clear_error(&error); - gchar *tmp = g_build_filename(DATADIR, prog, "defaults.ini", NULL); - g_key_file_load_from_file(self->key_file, tmp, - G_KEY_FILE_KEEP_COMMENTS, &error); - g_free(tmp); - } - if (error) { - g_debug("GisPrefs: new - Trying GIS defaults"); - g_clear_error(&error); - gchar *tmp = g_build_filename(DATADIR, "gis", "defaults.ini", NULL); - g_key_file_load_from_file(self->key_file, tmp, - G_KEY_FILE_KEEP_COMMENTS, &error); - g_free(tmp); - } - if (error) { - g_clear_error(&error); - g_warning("GisPrefs: new - Unable to load key file `%s': %s", - self->key_path, error->message); - } - return self; -} - -#define make_pref_type(name, c_type, g_type) \ -c_type gis_prefs_get_##name##_v(GisPrefs *self, \ - const gchar *group, const gchar *key) \ -{ \ - GError *error = NULL; \ - c_type value = g_key_file_get_##name(self->key_file, group, key, &error); \ - if (error && error->code != G_KEY_FILE_ERROR_GROUP_NOT_FOUND) \ - g_warning("GisPrefs: get_value_##name - error getting key %s: %s\n", \ - key, error->message); \ - return value; \ -} \ -c_type gis_prefs_get_##name(GisPrefs *self, const gchar *key) \ -{ \ - gchar **keys = g_strsplit(key, "/", 2); \ - c_type value = gis_prefs_get_##name##_v(self, keys[0], keys[1]); \ - g_strfreev(keys); \ - return value; \ -} \ - \ -void gis_prefs_set_##name##_v(GisPrefs *self, \ - const gchar *group, const gchar *key, const c_type value) \ -{ \ - g_key_file_set_##name(self->key_file, group, key, value); \ - gchar *all = g_strconcat(group, "/", key, NULL); \ - g_signal_emit(self, signals[SIG_PREF_CHANGED], 0, \ - all, g_type, &value); \ - g_free(all); \ -} \ -void gis_prefs_set_##name(GisPrefs *self, const gchar *key, const c_type value) \ -{ \ - gchar **keys = g_strsplit(key, "/", 2); \ - gis_prefs_set_##name##_v(self, keys[0], keys[1], value); \ - g_strfreev(keys); \ -} \ - -make_pref_type(string, gchar*, G_TYPE_STRING) -make_pref_type(boolean, gboolean, G_TYPE_BOOLEAN) -make_pref_type(integer, gint, G_TYPE_INT) -make_pref_type(double, gdouble, G_TYPE_DOUBLE) - - -/**************** - * GObject code * - ****************/ -G_DEFINE_TYPE(GisPrefs, gis_prefs, G_TYPE_OBJECT); -static void gis_prefs_init(GisPrefs *self) -{ - g_debug("GisPrefs: init"); - self->key_file = g_key_file_new(); -} -static GObject *gis_prefs_constructor(GType gtype, guint n_properties, - GObjectConstructParam *properties) -{ - g_debug("gis_prefs: constructor"); - GObjectClass *parent_class = G_OBJECT_CLASS(gis_prefs_parent_class); - return parent_class->constructor(gtype, n_properties, properties); -} -static void gis_prefs_dispose(GObject *_self) -{ - g_debug("GisPrefs: dispose"); - GisPrefs *self = GIS_PREFS(_self); - if (self->key_file) { - gsize length; - gchar *dir = g_path_get_dirname(self->key_path); - g_mkdir_with_parents(dir, 0755); - gchar *data = g_key_file_to_data(self->key_file, &length, NULL); - g_file_set_contents(self->key_path, data, length, NULL); - g_key_file_free(self->key_file); - g_free(self->key_path); - g_free(dir); - g_free(data); - self->key_file = NULL; - } - G_OBJECT_CLASS(gis_prefs_parent_class)->dispose(_self); -} -static void gis_prefs_finalize(GObject *_self) -{ - g_debug("GisPrefs: finalize"); - G_OBJECT_CLASS(gis_prefs_parent_class)->finalize(_self); -} -static void gis_prefs_class_init(GisPrefsClass *klass) -{ - g_debug("GisPrefs: class_init"); - GObjectClass *gobject_class = G_OBJECT_CLASS(klass); - gobject_class->constructor = gis_prefs_constructor; - gobject_class->dispose = gis_prefs_dispose; - gobject_class->finalize = gis_prefs_finalize; - signals[SIG_PREF_CHANGED] = g_signal_new( - "pref-changed", - G_TYPE_FROM_CLASS(gobject_class), - G_SIGNAL_RUN_LAST, - 0, - NULL, - NULL, - gis_cclosure_marshal_VOID__STRING_UINT_POINTER, - G_TYPE_NONE, - 1, - G_TYPE_STRING, - G_TYPE_UINT, - G_TYPE_POINTER); -} diff --git a/src/gis/gis-prefs.h b/src/gis/gis-prefs.h deleted file mode 100644 index 1645734..0000000 --- a/src/gis/gis-prefs.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2009 Andy Spencer - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef __GIS_PREFS_H__ -#define __GIS_PREFS_H__ - -#include - -/* Type macros */ -#define GIS_TYPE_PREFS (gis_prefs_get_type()) -#define GIS_PREFS(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GIS_TYPE_PREFS, GisPrefs)) -#define GIS_IS_PREFS(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GIS_TYPE_PREFS)) -#define GIS_PREFS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIS_TYPE_PREFS, GisPrefsClass)) -#define GIS_IS_PREFS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIS_TYPE_PREFS)) -#define GIS_PREFS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIS_TYPE_PREFS, GisPrefsClass)) - -typedef struct _GisPrefs GisPrefs; -typedef struct _GisPrefsClass GisPrefsClass; - -struct _GisPrefs { - GObject parent_instance; - - /* instance members */ - gchar *key_path; - GKeyFile *key_file; -}; - -struct _GisPrefsClass { - GObjectClass parent_class; - - /* class members */ -}; - -GType gis_prefs_get_type(void); - -/* Methods */ -GisPrefs *gis_prefs_new(const gchar *prog); - -gchar *gis_prefs_get_string (GisPrefs *prefs, const gchar *key); -gboolean gis_prefs_get_boolean (GisPrefs *prefs, const gchar *key); -gint gis_prefs_get_integer (GisPrefs *prefs, const gchar *key); -gdouble gis_prefs_get_double (GisPrefs *prefs, const gchar *key); - -gchar *gis_prefs_get_string_v (GisPrefs *prefs, const gchar *group, const gchar *key); -gboolean gis_prefs_get_boolean_v(GisPrefs *prefs, const gchar *group, const gchar *key); -gint gis_prefs_get_integer_v(GisPrefs *prefs, const gchar *group, const gchar *key); -gdouble gis_prefs_get_double_v (GisPrefs *prefs, const gchar *group, const gchar *key); - -void gis_prefs_set_string (GisPrefs *prefs, const gchar *key, const gchar *string); -void gis_prefs_set_boolean (GisPrefs *prefs, const gchar *key, gboolean value); -void gis_prefs_set_integer (GisPrefs *prefs, const gchar *key, gint value); -void gis_prefs_set_double (GisPrefs *prefs, const gchar *key, gdouble value); - -void gis_prefs_set_string_v (GisPrefs *prefs, const gchar *group, const gchar *key, const gchar *string); -void gis_prefs_set_boolean_v(GisPrefs *prefs, const gchar *group, const gchar *key, gboolean value); -void gis_prefs_set_integer_v(GisPrefs *prefs, const gchar *group, const gchar *key, gint value); -void gis_prefs_set_double_v (GisPrefs *prefs, const gchar *group, const gchar *key, gdouble value); -#endif diff --git a/src/gis/gis-view.c b/src/gis/gis-view.c deleted file mode 100644 index 0caf3f0..0000000 --- a/src/gis/gis-view.c +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Copyright (C) 2009 Andy Spencer - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include - -#include "gis-marshal.h" -#include "gis-view.h" -#include "gis-world.h" - -/* Constants */ -enum { - PROP_0, - PROP_TIME, - PROP_SITE, -}; -enum { - SIG_TIME_CHANGED, - SIG_SITE_CHANGED, - SIG_LOCATION_CHANGED, - SIG_ROTATION_CHANGED, - NUM_SIGNALS, -}; -static guint signals[NUM_SIGNALS]; - - -/* Signal helpers */ -static void _gis_view_emit_location_changed(GisView *view) -{ - g_signal_emit(view, signals[SIG_LOCATION_CHANGED], 0, - view->location[0], - view->location[1], - view->location[2]); -} -static void _gis_view_emit_rotation_changed(GisView *view) -{ - g_signal_emit(view, signals[SIG_ROTATION_CHANGED], 0, - view->rotation[0], - view->rotation[1], - view->rotation[2]); -} -static void _gis_view_emit_time_changed(GisView *view) -{ - g_signal_emit(view, signals[SIG_TIME_CHANGED], 0, - view->time); -} -static void _gis_view_emit_site_changed(GisView *view) -{ - g_signal_emit(view, signals[SIG_SITE_CHANGED], 0, - view->site); -} - - -/*********** - * Methods * - ***********/ -GisView *gis_view_new() -{ - g_debug("GisView: new"); - return g_object_new(GIS_TYPE_VIEW, NULL); -} - -void gis_view_set_time(GisView *view, const char *time) -{ - g_assert(GIS_IS_VIEW(view)); - g_debug("GisView: set_time - time=%s", time); - g_free(view->time); - view->time = g_strdup(time); - _gis_view_emit_time_changed(view); -} - -gchar *gis_view_get_time(GisView *view) -{ - g_assert(GIS_IS_VIEW(view)); - g_debug("GisView: get_time"); - return view->time; -} - -void gis_view_set_location(GisView *view, gdouble lat, gdouble lon, gdouble elev) -{ - g_assert(GIS_IS_VIEW(view)); - g_debug("GisView: set_location"); - view->location[0] = lat; - view->location[1] = lon; - view->location[2] = elev; - _gis_view_emit_location_changed(view); -} - -void gis_view_get_location(GisView *view, gdouble *lat, gdouble *lon, gdouble *elev) -{ - g_assert(GIS_IS_VIEW(view)); - //g_debug("GisView: get_location"); - *lat = view->location[0]; - *lon = view->location[1]; - *elev = view->location[2]; -} - -void gis_view_pan(GisView *view, gdouble lat, gdouble lon, gdouble elev) -{ - g_assert(GIS_IS_VIEW(view)); - g_debug("GisView: pan - lat=%8.3f, lon=%8.3f, elev=%8.3f", lat, lon, elev); - view->location[0] += lat; - view->location[1] += lon; - view->location[2] += elev; - _gis_view_emit_location_changed(view); -} - -void gis_view_zoom(GisView *view, gdouble scale) -{ - g_assert(GIS_IS_VIEW(view)); - g_debug("GisView: zoom"); - view->location[2] *= scale; - _gis_view_emit_location_changed(view); -} - -void gis_view_set_rotation(GisView *view, gdouble x, gdouble y, gdouble z) -{ - g_assert(GIS_IS_VIEW(view)); - g_debug("GisView: set_rotation"); - view->rotation[0] = x; - view->rotation[1] = y; - view->rotation[2] = z; - _gis_view_emit_rotation_changed(view); -} - -void gis_view_get_rotation(GisView *view, gdouble *x, gdouble *y, gdouble *z) -{ - g_assert(GIS_IS_VIEW(view)); - g_debug("GisView: get_rotation"); - *x = view->rotation[0]; - *y = view->rotation[1]; - *z = view->rotation[2]; -} - -void gis_view_rotate(GisView *view, gdouble x, gdouble y, gdouble z) -{ - g_assert(GIS_IS_VIEW(view)); - g_debug("GisView: rotate - x=%.0f, y=%.0f, z=%.0f", x, y, z); - view->rotation[0] += x; - view->rotation[1] += y; - view->rotation[2] += z; - _gis_view_emit_rotation_changed(view); -} - -/* To be deprecated, use {get,set}_location */ -void gis_view_set_site(GisView *view, const gchar *site) -{ - g_assert(GIS_IS_VIEW(view)); - g_debug("GisView: set_site"); - g_free(view->site); - view->site = g_strdup(site); - _gis_view_emit_site_changed(view); -} - -gchar *gis_view_get_site(GisView *view) -{ - g_assert(GIS_IS_VIEW(view)); - g_debug("GisView: get_site - %s", view->site); - return view->site; -} - - -/**************** - * GObject code * - ****************/ -G_DEFINE_TYPE(GisView, gis_view, G_TYPE_OBJECT); -static void gis_view_init(GisView *self) -{ - g_debug("GisView: init"); - /* Default values */ - self->time = g_strdup(""); - self->site = g_strdup(""); - self->location[0] = 40; - self->location[1] = -100; - self->location[2] = 1.5*EARTH_R; - self->rotation[0] = 0; - self->rotation[1] = 0; - self->rotation[2] = 0; -} -static void gis_view_dispose(GObject *gobject) -{ - g_debug("GisView: dispose"); - /* Drop references to other GObjects */ - G_OBJECT_CLASS(gis_view_parent_class)->dispose(gobject); -} -static void gis_view_finalize(GObject *gobject) -{ - g_debug("GisView: finalize"); - GisView *self = GIS_VIEW(gobject); - g_free(self->time); - g_free(self->site); - G_OBJECT_CLASS(gis_view_parent_class)->finalize(gobject); -} -static void gis_view_set_property(GObject *object, guint property_id, - const GValue *value, GParamSpec *pspec) -{ - g_debug("GisView: set_property"); - GisView *self = GIS_VIEW(object); - switch (property_id) { - case PROP_TIME: gis_view_set_time(self, g_value_get_string(value)); break; - case PROP_SITE: gis_view_set_site(self, g_value_get_string(value)); break; - default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); - } -} -static void gis_view_get_property(GObject *object, guint property_id, - GValue *value, GParamSpec *pspec) -{ - g_debug("GisView: get_property"); - GisView *self = GIS_VIEW(object); - switch (property_id) { - case PROP_TIME: g_value_set_string(value, gis_view_get_time(self)); break; - case PROP_SITE: g_value_set_string(value, gis_view_get_site(self)); break; - default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec); - } -} -static void gis_view_class_init(GisViewClass *klass) -{ - g_debug("GisView: class_init"); - GObjectClass *gobject_class = G_OBJECT_CLASS(klass); - gobject_class->dispose = gis_view_dispose; - gobject_class->finalize = gis_view_finalize; - gobject_class->get_property = gis_view_get_property; - gobject_class->set_property = gis_view_set_property; - g_object_class_install_property(gobject_class, PROP_TIME, - g_param_spec_pointer( - "time", - "time of the current frame", - "(format unknown)", - G_PARAM_READWRITE)); - g_object_class_install_property(gobject_class, PROP_SITE, - g_param_spec_pointer( - "site", - "site seen by the viewport", - "Site of the viewport. Currently this is the name of the radar site.", - G_PARAM_READWRITE)); - signals[SIG_TIME_CHANGED] = g_signal_new( - "time-changed", - G_TYPE_FROM_CLASS(gobject_class), - G_SIGNAL_RUN_LAST, - 0, - NULL, - NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, - 1, - G_TYPE_STRING); - signals[SIG_SITE_CHANGED] = g_signal_new( - "site-changed", - G_TYPE_FROM_CLASS(gobject_class), - G_SIGNAL_RUN_LAST, - 0, - NULL, - NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, - 1, - G_TYPE_STRING); - signals[SIG_LOCATION_CHANGED] = g_signal_new( - "location-changed", - G_TYPE_FROM_CLASS(gobject_class), - G_SIGNAL_RUN_LAST, - 0, - NULL, - NULL, - gis_cclosure_marshal_VOID__DOUBLE_DOUBLE_DOUBLE, - G_TYPE_NONE, - 3, - G_TYPE_DOUBLE, - G_TYPE_DOUBLE, - G_TYPE_DOUBLE); - signals[SIG_ROTATION_CHANGED] = g_signal_new( - "rotation-changed", - G_TYPE_FROM_CLASS(gobject_class), - G_SIGNAL_RUN_LAST, - 0, - NULL, - NULL, - gis_cclosure_marshal_VOID__DOUBLE_DOUBLE_DOUBLE, - G_TYPE_NONE, - 3, - G_TYPE_DOUBLE, - G_TYPE_DOUBLE, - G_TYPE_DOUBLE); -} diff --git a/src/gis/gis-view.h b/src/gis/gis-view.h deleted file mode 100644 index 3eb57ad..0000000 --- a/src/gis/gis-view.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2009 Andy Spencer - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef __GIS_VIEW_H__ -#define __GIS_VIEW_H__ - -#include - -/* Type macros */ -#define GIS_TYPE_VIEW (gis_view_get_type()) -#define GIS_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GIS_TYPE_VIEW, GisView)) -#define GIS_IS_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GIS_TYPE_VIEW)) -#define GIS_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIS_TYPE_VIEW, GisViewClass)) -#define GIS_IS_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIS_TYPE_VIEW)) -#define GIS_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIS_TYPE_VIEW, GisViewClass)) - -typedef struct _GisView GisView; -typedef struct _GisViewClass GisViewClass; - -struct _GisView { - GObject parent_instance; - - /* instance members */ - gchar *time; - gchar *site; - gdouble location[3]; - gdouble rotation[3]; -}; - -struct _GisViewClass { - GObjectClass parent_class; - - /* class members */ -}; - -GType gis_view_get_type(void); - -/* Methods */ -GisView *gis_view_new(); - -void gis_view_set_time(GisView *view, const gchar *time); -gchar *gis_view_get_time(GisView *view); - -void gis_view_set_location(GisView *view, gdouble lat, gdouble lon, gdouble elev); -void gis_view_get_location(GisView *view, gdouble *lat, gdouble *lon, gdouble *elev); -void gis_view_pan (GisView *view, gdouble lat, gdouble lon, gdouble elev); -void gis_view_zoom (GisView *view, gdouble scale); - -void gis_view_set_rotation(GisView *view, gdouble x, gdouble y, gdouble z); -void gis_view_get_rotation(GisView *view, gdouble *x, gdouble *y, gdouble *z); -void gis_view_rotate (GisView *view, gdouble x, gdouble y, gdouble z); - -/* To be deprecated, use {get,set}_location */ -void gis_view_set_site(GisView *view, const gchar *site); -gchar *gis_view_get_site(GisView *view); - -#endif diff --git a/src/gis/gis-world.c b/src/gis/gis-world.c deleted file mode 100644 index b8611ab..0000000 --- a/src/gis/gis-world.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (C) 2009 Andy Spencer - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include - -#include "gis-marshal.h" -#include "gis-world.h" - -/* Constants */ -double WGS884_SEMI_MAJOR = 6378137.0; // a -double WGS884_SEMI_MINOR = 6356752.314245; // b -double WGS884_INV_FLAT = 298.257223563; // 1/f - -enum { - SIG_REFRESH, - SIG_OFFLINE, - NUM_SIGNALS, -}; -static guint signals[NUM_SIGNALS]; - - -/* Signal helpers */ -static void _gis_world_emit_refresh(GisWorld *world) -{ - g_signal_emit(world, signals[SIG_REFRESH], 0); -} -static void _gis_world_emit_offline(GisWorld *world) -{ - g_signal_emit(world, signals[SIG_OFFLINE], 0, - world->offline); -} - -/*********** - * Methods * - ***********/ -GisWorld *gis_world_new() -{ - g_debug("GisWorld: new"); - return g_object_new(GIS_TYPE_WORLD, NULL); -} - -void gis_world_refresh(GisWorld *world) -{ - g_debug("GisWorld: refresh"); - _gis_world_emit_refresh(world); -} - -void gis_world_set_offline(GisWorld *world, gboolean offline) -{ - g_assert(GIS_IS_WORLD(world)); - g_debug("GisWorld: set_offline - %d", offline); - world->offline = offline; - _gis_world_emit_offline(world); -} - -gboolean gis_world_get_offline(GisWorld *world) -{ - g_assert(GIS_IS_WORLD(world)); - g_debug("GisWorld: get_offline - %d", world->offline); - return world->offline; -} - - -/**************** - * GObject code * - ****************/ -G_DEFINE_TYPE(GisWorld, gis_world, G_TYPE_OBJECT); -static void gis_world_init(GisWorld *self) -{ - g_debug("GisWorld: init"); - /* Default values */ - self->offline = FALSE; -} -static void gis_world_dispose(GObject *gobject) -{ - g_debug("GisWorld: dispose"); - /* Drop references to other GObjects */ - G_OBJECT_CLASS(gis_world_parent_class)->dispose(gobject); -} -static void gis_world_finalize(GObject *gobject) -{ - g_debug("GisWorld: finalize"); - GisWorld *self = GIS_WORLD(gobject); - G_OBJECT_CLASS(gis_world_parent_class)->finalize(gobject); -} -static void gis_world_class_init(GisWorldClass *klass) -{ - g_debug("GisWorld: class_init"); - GObjectClass *gobject_class = G_OBJECT_CLASS(klass); - gobject_class->dispose = gis_world_dispose; - gobject_class->finalize = gis_world_finalize; - 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); - signals[SIG_OFFLINE] = g_signal_new( - "offline", - G_TYPE_FROM_CLASS(gobject_class), - G_SIGNAL_RUN_LAST, - 0, - NULL, - NULL, - g_cclosure_marshal_VOID__BOOLEAN, - G_TYPE_NONE, - 1, - G_TYPE_BOOLEAN); -} - - -/****************** - * Global helpers * - ******************/ -void lle2xyz(gdouble lat, gdouble lon, gdouble elev, - gdouble *x, gdouble *y, gdouble *z) -{ - gdouble rad = elev2rad(elev); - gdouble azim = lon2azim(lon); - gdouble incl = lat2incl(lat); - *z = rad * cos(azim) * sin(incl); - *x = rad * sin(azim) * sin(incl); - *y = rad * cos(incl); -} - -void xyz2lle(gdouble x, gdouble y, gdouble z, - gdouble *lat, gdouble *lon, gdouble *elev) -{ - gdouble rad = sqrt(x*x + y*y + z*z); - *lat = incl2lat(acos(y / rad)); - *lon = azim2lon(atan2(x,z)); - *elev = rad2elev(rad); -} - - -gdouble ll2m(gdouble lon_dist, gdouble lat) -{ - gdouble azim = (-lat+90)/180*M_PI; - gdouble rad = sin(azim) * EARTH_R; - gdouble circ = 2 * M_PI * rad; - return lon_dist/360 * circ; -} - -gdouble distd(gdouble *a, gdouble *b) -{ - return sqrt((a[0]-b[0])*(a[0]-b[0]) + - (a[1]-b[1])*(a[1]-b[1]) + - (a[2]-b[2])*(a[2]-b[2])); -} diff --git a/src/gis/gis-world.h b/src/gis/gis-world.h deleted file mode 100644 index 78ca130..0000000 --- a/src/gis/gis-world.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (C) 2009 Andy Spencer - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef __GIS_WORLD_H__ -#define __GIS_WORLD_H__ - -#include - -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif - -#define EARTH_R (6371000) -#define EARTH_C (2*M_PI*EARTH_R) - -/** - * Terms - * ----- - * deg - Degrees - * rad - Radians, also radius - * m - Meters, for earth-based distances - * px - Pixels, for screen-based distances - * - * height - Height, the distance above the geoid (ground) - * elev - Elevation, the distance above the spheroid - * rad - Radius, the distance from the center of the earth - * - * lat - Latitude, amount north-south, -90 (S) .. 90 (N) - * lon - Longitude, amount east-west, -180 (W) .. 180 (E) - * incl - Inclination, polar equiv of latitude, Pi .. 0 - * azim - Azimuth, polar equiv of longitude, -Pi .. Pi - * - * x - 0° lon is positive - * y - 90° lon is positive - * z - North pole is positive - * - * llh - lat,lon,height - * lle - lat,lon,elev - * llr - lat,lon,rad - * pol - incl,azim,rad - * xyz - x,y,z - */ - -/** - * lat lon elev -> x y z - * lle2xyz: 0.0, 0.0, 0.0 -> 0.0, 0.0, 10.0 - * lle2xyz: 90.0, 0.0, 0.0 -> 0.0, 10.0, 0.0 - * lle2xyz: 0.0, 90.0, 0.0 -> 10.0, 0.0, 0.0 - * - * x y z -> lat lon elev - * xyz2lle: 10.0, 0.0, 0.0 -> 0.0, 90.0, 0.0 - * xyz2lle: 0.0, 10.0, 0.0 -> 90.0, 0.0, 0.0 - * xyz2lle: 0.0, 0.0, 10.0 -> 0.0, 0.0, 0.0 - */ - -#define azim2lon(azim) ((azim)*180/M_PI) -#define lon2azim(lon) ((lon)*M_PI/180) -#define incl2lat(incl) (90-(incl)*180/M_PI) -#define lat2incl(lat) ((90-(lat))*M_PI/180) -#define rad2elev(rad) ((rad)-EARTH_R) -#define elev2rad(elev) ((elev)+EARTH_R) - -#define deg2rad(deg) (((deg)*M_PI)/180.0) -#define rad2deg(rad) (((rad)*180.0)/M_PI) - -#define FOV_DIST 2000.0 -#define MPPX(dist) (4*dist/FOV_DIST) - -void lle2xyz(gdouble lat, gdouble lon, gdouble elev, - gdouble *x, gdouble *y, gdouble *z); - -void xyz2lle(gdouble x, gdouble y, gdouble z, - gdouble *lat, gdouble *lon, gdouble *elev); - -gdouble ll2m(gdouble lon_dist, gdouble lat); - -gdouble distd(gdouble *a, gdouble *b); - -/************ - * GisWorld * - ************/ -#define GIS_TYPE_WORLD (gis_world_get_type()) -#define GIS_WORLD(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GIS_TYPE_WORLD, GisWorld)) -#define GIS_IS_WORLD(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GIS_TYPE_WORLD)) -#define GIS_WORLD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIS_TYPE_WORLD, GisWorldClass)) -#define GIS_IS_WORLD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIS_TYPE_WORLD)) -#define GIS_WORLD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIS_TYPE_WORLD, GisWorldClass)) - -typedef struct _GisWorld GisWorld; -typedef struct _GisWorldClass GisWorldClass; - -struct _GisWorld { - GObject parent_instance; - - /* instance members */ - gboolean offline; -}; - -struct _GisWorldClass { - GObjectClass parent_class; - - /* class members */ -}; - -GType gis_world_get_type(void); - -/* Methods */ -GisWorld *gis_world_new(); - -void gis_world_refresh(GisWorld *world); - -void gis_world_set_offline(GisWorld *world, gboolean offline); -gboolean gis_world_get_offline(GisWorld *world); - -#endif diff --git a/src/gis/gis.h b/src/gis/gis.h deleted file mode 100644 index 772c239..0000000 --- a/src/gis/gis.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2009 Andy Spencer - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef __GIS_H__ -#define __GIS_H__ - -/* GIS Core */ -#include "gis-world.h" -#include "gis-view.h" -#include "gis-opengl.h" -#include "gis-prefs.h" - -/* GIS helprs */ -#include "gis-data.h" - -/* Plugins */ -#include "gis-plugin.h" - -#endif diff --git a/src/gis/gis_test.c b/src/gis/gis_test.c deleted file mode 100644 index fbe46a9..0000000 --- a/src/gis/gis_test.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2009 Andy Spencer - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include - -#include "gis.h" - -/************* - * Callbacks * - *************/ -static gboolean on_key_press(GtkWidget *widget, GdkEventKey *event, gpointer _) -{ - g_debug("gis: on_key_press - key=%x, state=%x", - event->keyval, event->state); - switch (event->keyval) { - case GDK_q: - gtk_widget_destroy(widget); - return TRUE; - } - return FALSE; -} - -/*********** - * Methods * - ***********/ -int main(int argc, char **argv) -{ - gtk_init(&argc, &argv); - g_thread_init(NULL); - - GisPrefs *prefs = gis_prefs_new("aweather"); - GisPlugins *plugins = gis_plugins_new(); - GisWorld *world = gis_world_new(); - GisView *view = gis_view_new(); - GisOpenGL *opengl = gis_opengl_new(world, view, plugins); - - //gis_plugins_load(plugins, "radar", world, view, opengl, prefs); - //gis_plugins_load(plugins, "ridge", world, view, opengl, prefs); - //gis_plugins_load(plugins, "example", world, view, opengl, prefs); - - GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL); - g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); - g_signal_connect(window, "key-press-event", G_CALLBACK(on_key_press), NULL); - gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(opengl)); - gtk_widget_show_all(window); - - gis_view_set_site(view, "KLSX"); - gtk_main(); - - g_object_unref(prefs); - g_object_unref(world); - g_object_unref(view); - g_object_unref(opengl); - gis_plugins_free(plugins); - return 0; -} diff --git a/src/gis/gpqueue.c b/src/gis/gpqueue.c deleted file mode 100644 index 5989987..0000000 --- a/src/gis/gpqueue.c +++ /dev/null @@ -1,591 +0,0 @@ -#include -#include "gpqueue.h" - -/** - * SECTION:priority_queues - * @short_description: a collection of data entries with associated priority - * values that returns entries one by one in order of priority - * - * - * The #GPQueue structure and its associated functions provide a sorted - * collection of objects. Entries can be inserted in any order and at any time, - * and an entry's priority can be changed after it has been inserted into the - * queue. Entries are supposed to be removed one at a time in order of priority - * with g_pqueue_pop(), but deleting entries out of order is possible. - * - * - * The entries cannot be iterated over in any way other - * than removing them one by one in order of priority, but when doing that, - * this structure is far more efficient than sorted lists or balanced trees, - * which on the other hand do not suffer from this restriction. - * - * - * You will want to be very careful with calls that use #GPQueueHandle. - * Handles immediately become invalid when an entry is removed from a #GPQueue, - * but the current implementation cannot detect this and will do unfortunate - * things to undefined memory locations if you try to use an invalid handle. - * - * - * - * Internally, #GPQueue currently uses a Fibonacci heap to store - * the entries. This implementation detail may change. - * - * - **/ - -struct _GPQueueNode { - GPQueueNode *next; - GPQueueNode *prev; - GPQueueNode *parent; - GPQueueNode *child; - - gpointer data; - - gint degree; - gboolean marked; -}; - -struct _GPQueue { - GPQueueNode *root; - GCompareDataFunc cmp; - gpointer *cmpdata; -}; - -/** - * g_pqueue_new: - * @compare_func: the #GCompareDataFunc used to sort the new priority queue. - * This function is passed two elements of the queue and should return 0 if - * they are equal, a negative value if the first comes before the second, and - * a positive value if the second comes before the first. - * @compare_userdata: user data passed to @compare_func - * - * Creates a new #GPQueue. - * - * Returns: a new #GPQueue. - * - * Since: 2.x - **/ -GPQueue* -g_pqueue_new (GCompareDataFunc compare_func, - gpointer *compare_userdata) -{ - g_return_val_if_fail (compare_func != NULL, NULL); - - GPQueue *pqueue = g_slice_new (GPQueue); - pqueue->root = NULL; - pqueue->cmp = compare_func; - pqueue->cmpdata = compare_userdata; - return pqueue; -} - -/** - * g_pqueue_is_empty: - * @pqueue: a #GPQueue. - * - * Returns %TRUE if the queue is empty. - * - * Returns: %TRUE if the queue is empty. - * - * Since: 2.x - **/ -gboolean -g_pqueue_is_empty (GPQueue *pqueue) -{ - return (pqueue->root == NULL); -} - -static void -g_pqueue_node_foreach (GPQueueNode *node, - GPQueueNode *stop, - GFunc func, - gpointer user_data) -{ - if (node == NULL || node == stop) return; - func(node->data, user_data); - if (stop == NULL) stop = node; - g_pqueue_node_foreach (node->next, stop, func, user_data); - g_pqueue_node_foreach (node->child, NULL, func, user_data); -} - -/** - * g_pqueue_foreach: - * @pqueue: a #GQueue. - * @func: the function to call for each element's data - * @user_data: user data to pass to func - * - * Calls func for each element in the pqueue passing user_data to the function. - * - * Since: 2.x - */ -void -g_pqueue_foreach (GPQueue *pqueue, - GFunc func, - gpointer user_data) -{ - g_pqueue_node_foreach (pqueue->root, NULL, func, user_data); -} - -static void -g_pqueue_add_ptr_cb (gpointer obj, GPtrArray *ptrs) -{ - g_ptr_array_add(ptrs, obj); -} -/** - * g_pqueue_get_array: - * @pqueue: a #GQueue. - * - * Construct a GPtrArray for the items in pqueue. This can be useful when - * updating the priorities of all the elements in pqueue. - * - * Returns: A GPtrArray containing a pointer to each item in pqueue - * - * Since: 2.x - */ -GPtrArray * -g_pqueue_get_array (GPQueue *pqueue) -{ - GPtrArray *ptrs = g_ptr_array_new(); - g_pqueue_foreach(pqueue, (GFunc)g_pqueue_add_ptr_cb, ptrs); - return ptrs; -} - -static inline gint -cmp (GPQueue *pqueue, - GPQueueNode *a, - GPQueueNode *b) -{ - return pqueue->cmp (a->data, b->data, pqueue->cmpdata); -} - -static inline void -g_pqueue_node_cut (GPQueueNode *src) -{ - src->prev->next = src->next; - src->next->prev = src->prev; - src->next = src; - src->prev = src; -} - -static inline void -g_pqueue_node_insert_before (GPQueueNode *dest, - GPQueueNode *src) -{ - GPQueueNode *prev; - - prev = dest->prev; - dest->prev = src->prev; - src->prev->next = dest; - src->prev = prev; - prev->next = src; -} - -static inline void -g_pqueue_node_insert_after (GPQueueNode *dest, - GPQueueNode *src) -{ - GPQueueNode *next; - - next = dest->next; - dest->next = src; - src->prev->next = next; - next->prev = src->prev; - src->prev = dest; -} - -/** - * g_pqueue_push: - * @pqueue: a #GPQueue. - * @data: the object to insert into the priority queue. - * - * Inserts a new entry into a #GPQueue. - * - * The returned handle can be used in calls to g_pqueue_remove() and - * g_pqueue_priority_changed(). Never make such calls for entries that have - * already been removed from the queue. The same @data can be inserted into - * a #GPQueue more than once, but remember that in this case, - * g_pqueue_priority_changed() needs to be called for - * every handle for that object if its priority changes. - * - * Returns: a handle for the freshly inserted entry. - * - * Since: 2.x - **/ -GPQueueHandle -g_pqueue_push (GPQueue *pqueue, - gpointer data) -{ - GPQueueNode *e; - - e = g_slice_new (GPQueueNode); - e->next = e; - e->prev = e; - e->parent = NULL; - e->child = NULL; - e->data = data; - e->degree = 0; - e->marked = FALSE; - - if (pqueue->root != NULL) { - g_pqueue_node_insert_before (pqueue->root, e); - if (cmp (pqueue, e, pqueue->root) < 0) - pqueue->root = e; - } else { - pqueue->root = e; - } - - return e; -} - -/** - * g_pqueue_peek: - * @pqueue: a #GPQueue. - * - * Returns the topmost entry's data pointer, or %NULL if the queue is empty. - * - * If you need to tell the difference between an empty queue and a queue - * that happens to have a %NULL pointer at the top, check if the queue is - * empty first. - * - * Returns: the topmost entry's data pointer, or %NULL if the queue is empty. - * - * Since: 2.x - **/ -gpointer -g_pqueue_peek (GPQueue *pqueue) -{ - return (pqueue->root != NULL) ? pqueue->root->data : NULL; -} - -static inline GPQueueNode* -g_pqueue_make_child (GPQueueNode *a, - GPQueueNode *b) -{ - g_pqueue_node_cut(b); - if (a->child != NULL) { - g_pqueue_node_insert_before (a->child, b); - a->degree += 1; - } else { - a->child = b; - a->degree = 1; - } - b->parent = a; - return a; -} - -static inline GPQueueNode* -g_pqueue_join_trees (GPQueue *pqueue, - GPQueueNode *a, - GPQueueNode *b) -{ - if (cmp (pqueue, a, b) < 0) - return g_pqueue_make_child (a, b); - return g_pqueue_make_child (b, a); -} - -static void -g_pqueue_fix_rootlist (GPQueue* pqueue) -{ - gsize degnode_size; - GPQueueNode **degnode; - GPQueueNode sentinel; - GPQueueNode *current; - GPQueueNode *minimum; - - /* We need to iterate over the circular list we are given and do - * several things: - * - Make sure all the elements are unmarked - * - Make sure to return the element in the list with smallest - * priority value - * - Find elements of identical degree and join them into trees - * The last point is irrelevant for correctness, but essential - * for performance. If we did not do this, our data structure would - * degrade into an unsorted linked list. - */ - - degnode_size = (8 * sizeof(gpointer) + 1) * sizeof(gpointer); - degnode = g_slice_alloc0 (degnode_size); - - sentinel.next = &sentinel; - sentinel.prev = &sentinel; - g_pqueue_node_insert_before (pqueue->root, &sentinel); - - current = pqueue->root; - while (current != &sentinel) { - current->marked = FALSE; - current->parent = NULL; - gint d = current->degree; - if (degnode[d] == NULL) { - degnode[d] = current; - current = current->next; - } else { - if (degnode[d] != current) { - current = g_pqueue_join_trees (pqueue, degnode[d], current); - degnode[d] = NULL; - } else { - current = current->next; - } - } - } - - current = sentinel.next; - minimum = current; - while (current != &sentinel) { - if (cmp (pqueue, current, minimum) < 0) - minimum = current; - current = current->next; - } - pqueue->root = minimum; - - g_pqueue_node_cut (&sentinel); - - g_slice_free1 (degnode_size, degnode); -} - -static void -g_pqueue_remove_root (GPQueue *pqueue, - GPQueueNode *root) -{ - /* This removes a node at the root _level_ of the structure, which can be, - * but does not have to be, the actual pqueue->root node. That is why - * we require an explicit pointer to the node to be removed instead of just - * removing pqueue->root implictly. - */ - - /* Step one: - * If root has any children, pull them up to root level. - * At this time, we only deal with their next/prev pointers, - * further changes are made later in g_pqueue_fix_rootlist(). - */ - if (root->child) { - g_pqueue_node_insert_after (root, root->child); - root->child = NULL; - root->degree = 0; - } - - /* Step two: - * Cut root out of the list. - */ - if (root->next != root) { - pqueue->root = root->next; - g_pqueue_node_cut (root); - /* Step three: - * Clean up the remaining list. - */ - g_pqueue_fix_rootlist (pqueue); - } else { - pqueue->root = NULL; - } - - g_slice_free (GPQueueNode, root); -} - -/** - * g_pqueue_pop: - * @pqueue: a #GPQueue. - * - * Removes the topmost entry from a #GPQueue and returns its data pointer. - * Calling this on an empty #GPQueue is not an error, but removes nothing - * and returns %NULL. - * - * If you need to tell the difference between an empty queue and a queue - * that happens to have a %NULL pointer at the top, check if the queue is - * empty first. - * - * Returns: the topmost entry's data pointer, or %NULL if the queue was empty. - * - * Since: 2.x - **/ -gpointer -g_pqueue_pop (GPQueue *pqueue) -{ - gpointer data; - - if (pqueue->root == NULL) return NULL; - data = pqueue->root->data; - g_pqueue_remove_root (pqueue, pqueue->root); - return data; -} - -static inline void -g_pqueue_make_root (GPQueue *pqueue, - GPQueueNode *entry) -{ - /* This moves a node up to the root _level_ of the structure. - * It does not always become the actual root element (pqueue->root). - */ - - GPQueueNode *parent; - - parent = entry->parent; - entry->parent = NULL; - entry->marked = FALSE; - if (parent != NULL) { - if (entry->next != entry) { - if (parent->child == entry) parent->child = entry->next; - g_pqueue_node_cut (entry); - parent->degree -= 1; - } else { - parent->child = NULL; - parent->degree = 0; - } - g_pqueue_node_insert_before (pqueue->root, entry); - } - - if (cmp (pqueue, entry, pqueue->root) < 0) - pqueue->root = entry; -} - -static void -g_pqueue_cut_tree (GPQueue *pqueue, - GPQueueNode *entry) -{ - /* This function moves an entry up to the root level of the structure. - * It extends g_pqueue_make_root() in that the entry's parent, grandparent - * etc. may also be moved to the root level if they are "marked". This is - * not essential for correctness, it just maintains the so-called "potential" - * of the structure, which is necessary for the amortized runtime analysis. - */ - - GPQueueNode *current; - GPQueueNode *parent; - - current = entry; - while ((current != NULL) && (current->parent != NULL)) { - parent = current->parent; - g_pqueue_make_root (pqueue, entry); - if (parent->marked) { - current = parent; - } else { - parent->marked = TRUE; - current = NULL; - } - } - if (cmp (pqueue, entry, pqueue->root) < 0) - pqueue->root = entry; -} - -/** - * g_pqueue_remove: - * @pqueue: a #GPQueue. - * @entry: a #GPQueueHandle for an entry in @pqueue. - * - * Removes one entry from a #GPQueue. - * - * Make sure that @entry refers to an entry that is actually part of - * @pqueue at the time, otherwise the behavior of this function is - * undefined (expect crashes). - * - * Since: 2.x - **/ -void -g_pqueue_remove (GPQueue* pqueue, - GPQueueHandle entry) -{ - g_pqueue_cut_tree (pqueue, entry); - g_pqueue_remove_root (pqueue, entry); -} - -/** - * g_pqueue_priority_changed: - * @pqueue: a #GPQueue. - * @entry: a #GPQueueHandle for an entry in @pqueue. - * - * Notifies the #GPQueue that the priority of one entry has changed. - * The internal representation is updated accordingly. - * - * Make sure that @entry refers to an entry that is actually part of - * @pqueue at the time, otherwise the behavior of this function is - * undefined (expect crashes). - * - * Do not attempt to change the priorities of several entries at once. - * Every time a single object is changed, the #GPQueue needs to be updated - * by calling g_pqueue_priority_changed() for that object. - * - * Since: 2.x - **/ -void -g_pqueue_priority_changed (GPQueue* pqueue, - GPQueueHandle entry) -{ - g_pqueue_cut_tree (pqueue, entry); - - if (entry->child) { - g_pqueue_node_insert_after (entry, entry->child); - entry->child = NULL; - entry->degree = 0; - } - - g_pqueue_fix_rootlist (pqueue); -} - -/** - * g_pqueue_priority_decreased: - * @pqueue: a #GPQueue. - * @entry: a #GPQueueHandle for an entry in @pqueue. - * - * Notifies the #GPQueue that the priority of one entry has - * decreased. - * - * This is a special case of g_pqueue_priority_changed(). If you are absolutely - * sure that the new priority of @entry is lower than it was before, you - * may call this function instead of g_pqueue_priority_changed(). - * - * - * - * In the current implementation, an expensive step in - * g_pqueue_priority_changed() can be skipped if the new priority is known - * to be lower, leading to an amortized running time of O(1) instead of - * O(log n). Of course, if the priority is not actually lower, behavior - * is undefined. - * - * - * - * Since: 2.x - **/ -void -g_pqueue_priority_decreased (GPQueue* pqueue, - GPQueueHandle entry) -{ - g_pqueue_cut_tree (pqueue, entry); -} - -static void -g_pqueue_node_free_all (GPQueueNode *node) -{ - if (node == NULL) return; - g_pqueue_node_free_all (node->child); - node->prev->next = NULL; - g_pqueue_node_free_all (node->next); - g_slice_free (GPQueueNode, node); -} - -/** - * g_pqueue_clear: - * @pqueue: a #GPQueue. - * - * Removes all entries from a @pqueue. - * - * Since: 2.x - **/ -void -g_pqueue_clear (GPQueue* pqueue) -{ - g_pqueue_node_free_all (pqueue->root); - pqueue->root = NULL; -} - -/** - * g_pqueue_free: - * @pqueue: a #GPQueue. - * - * Deallocates the memory used by @pqueue itself, but not any memory pointed - * to by the data pointers of its entries. - * - * Since: 2.x - **/ -void -g_pqueue_free (GPQueue* pqueue) -{ - g_pqueue_clear (pqueue); - g_slice_free (GPQueue, pqueue); -} diff --git a/src/gis/gpqueue.h b/src/gis/gpqueue.h deleted file mode 100644 index 3cadf18..0000000 --- a/src/gis/gpqueue.h +++ /dev/null @@ -1,63 +0,0 @@ -#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) -#error "Only can be included directly." -#endif - -#ifndef __G_PQUEUE_H__ -#define __G_PQUEUE_H__ - -G_BEGIN_DECLS - -typedef struct _GPQueueNode GPQueueNode; - -/** - * GPQueue: - * - * An opaque structure representing a priority queue. - * - * Since: 2.x - **/ -typedef struct _GPQueue GPQueue; - -/** - * GPQueueHandle: - * - * An opaque value representing one entry in a #GPQueue. - * - * Since: 2.x - **/ -typedef GPQueueNode* GPQueueHandle; - -GPQueue* g_pqueue_new (GCompareDataFunc compare_func, - gpointer *compare_userdata); - -void g_pqueue_free (GPQueue* pqueue); - -gboolean g_pqueue_is_empty (GPQueue *pqueue); - -void g_pqueue_foreach (GPQueue *pqueue, - GFunc func, - gpointer user_data); - -GPtrArray* g_pqueue_get_array (GPQueue *pqueue); - -GPQueueHandle g_pqueue_push (GPQueue *pqueue, - gpointer data); - -gpointer g_pqueue_peek (GPQueue *pqueue); - -gpointer g_pqueue_pop (GPQueue *pqueue); - -void g_pqueue_remove (GPQueue* pqueue, - GPQueueHandle entry); - -void g_pqueue_priority_changed (GPQueue* pqueue, - GPQueueHandle entry); - -void g_pqueue_priority_decreased (GPQueue* pqueue, - GPQueueHandle entry); - -void g_pqueue_clear (GPQueue* pqueue); - -G_END_DECLS - -#endif /* __G_PQUEUE_H__ */ diff --git a/src/gis/libgis.pc.in b/src/gis/libgis.pc.in deleted file mode 100644 index 859289e..0000000 --- a/src/gis/libgis.pc.in +++ /dev/null @@ -1,11 +0,0 @@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -libdir=@libdir@ -includedir=@includedir@ - -Name: libgis -Description: GIS Library for Gtk+ applications -Version: @VERSION@ -Requires: gmodule-2.0 gtk+-2.0 gtkglext-1.0 libsoup-2.4 -Libs: -L${libdir} -lgis -Cflags: -I${includedir}/gis diff --git a/src/gis/roam.c b/src/gis/roam.c deleted file mode 100644 index a95c697..0000000 --- a/src/gis/roam.c +++ /dev/null @@ -1,564 +0,0 @@ -/* - * Copyright (C) 2009 Andy Spencer - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include "gpqueue.h" -#include -#include - -#include "roam.h" - -/** - * TODO: - * - Optimize for memory consumption - * - Profile for computation speed - * - Target polygon count/detail - */ - -/* Misc */ -RoamView *roam_view_get() -{ - RoamView *view = g_new0(RoamView, 1); - glGetDoublev (GL_MODELVIEW_MATRIX, view->model); - glGetDoublev (GL_PROJECTION_MATRIX, view->proj); - glGetIntegerv(GL_VIEWPORT, view->view); - return view; -} - -/* For GPQueue comparators */ -static gint tri_cmp(RoamTriangle *a, RoamTriangle *b, gpointer data) -{ - if (a->error < b->error) return 1; - else if (a->error > b->error) return -1; - else return 0; -} -static gint dia_cmp(RoamDiamond *a, RoamDiamond *b, gpointer data) -{ - if (a->error < b->error) return -1; - else if (a->error > b->error) return 1; - else return 0; -} - -/************* - * RoamPoint * - *************/ -RoamPoint *roam_point_new(double x, double y, double z) -{ - RoamPoint *self = g_new0(RoamPoint, 1); - self->x = x; - self->y = y; - self->z = z; - return self; -} -RoamPoint *roam_point_dup(RoamPoint *self) -{ - RoamPoint *new = g_memdup(self, sizeof(RoamPoint)); - new->tris = 0; - return new; -} -void roam_point_add_triangle(RoamPoint *self, RoamTriangle *triangle) -{ - for (int i = 0; i < 3; i++) { - self->norm[i] *= self->tris; - self->norm[i] += triangle->norm[i]; - } - self->tris++; - for (int i = 0; i < 3; i++) - self->norm[i] /= self->tris; -} -void roam_point_remove_triangle(RoamPoint *self, RoamTriangle *triangle) -{ - for (int i = 0; i < 3; i++) { - self->norm[i] *= self->tris; - self->norm[i] -= triangle->norm[i]; - } - self->tris--; - for (int i = 0; i < 3; i++) - self->norm[i] /= self->tris; -} -void roam_point_update(RoamPoint *self, RoamSphere *sphere, gboolean do_height) -{ - if (!self->cached) { - /* Cache height */ - if (do_height) - sphere->height_func(self, sphere->user_data); - - /* Cache projection */ - gluProject(self->x, self->y, self->z, - sphere->view->model, sphere->view->proj, sphere->view->view, - &self->px, &self->py, &self->pz); - - self->cached = TRUE; - } -} -void roam_point_clear(RoamPoint *self) -{ - self->cached = FALSE; -} - -/**************** - * RoamTriangle * - ****************/ -RoamTriangle *roam_triangle_new(RoamPoint *l, RoamPoint *m, RoamPoint *r) -{ - RoamTriangle *self = g_new0(RoamTriangle, 1); - - self->p.l = l; - self->p.m = m; - self->p.r = r; - - self->error = 0; - - /* Update normal */ - double pa[3]; - double pb[3]; - pa[0] = self->p.l->x - self->p.m->x; - pa[1] = self->p.l->y - self->p.m->y; - pa[2] = self->p.l->z - self->p.m->z; - - pb[0] = self->p.r->x - self->p.m->x; - pb[1] = self->p.r->y - self->p.m->y; - pb[2] = self->p.r->z - self->p.m->z; - - self->norm[0] = pa[1] * pb[2] - pa[2] * pb[1]; - self->norm[1] = pa[2] * pb[0] - pa[0] * pb[2]; - self->norm[2] = pa[0] * pb[1] - pa[1] * pb[0]; - - double total = sqrt(self->norm[0] * self->norm[0] + - self->norm[1] * self->norm[1] + - self->norm[2] * self->norm[2]); - - self->norm[0] /= total; - self->norm[1] /= total; - self->norm[2] /= total; - - //g_message("roam_triangle_new: %p", self); - return self; -} - -void roam_triangle_add(RoamTriangle *self, - RoamTriangle *left, RoamTriangle *base, RoamTriangle *right, - RoamSphere *sphere) -{ - self->t.l = left; - self->t.b = base; - self->t.r = right; - - roam_point_add_triangle(self->p.l, self); - roam_point_add_triangle(self->p.m, self); - roam_point_add_triangle(self->p.r, self); - - if (sphere->view) - roam_triangle_update(self, sphere); - - self->handle = g_pqueue_push(sphere->triangles, self); -} - -void roam_triangle_remove(RoamTriangle *self, RoamSphere *sphere) -{ - /* Update vertex normals */ - roam_point_remove_triangle(self->p.l, self); - roam_point_remove_triangle(self->p.m, self); - roam_point_remove_triangle(self->p.r, self); - - g_pqueue_remove(sphere->triangles, self->handle); -} - -void roam_triangle_sync_neighbors(RoamTriangle *new, RoamTriangle *old, RoamTriangle *neigh) -{ - if (neigh->t.l == old) neigh->t.l = new; - else if (neigh->t.b == old) neigh->t.b = new; - else if (neigh->t.r == old) neigh->t.r = new; - else g_assert_not_reached(); -} - -gboolean roam_point_visible(RoamPoint *self, RoamSphere *sphere) -{ - gint *view = sphere->view->view; - return self->px > view[0] && self->px < view[2] && - self->py > view[1] && self->py < view[3] && - self->pz > 0 && self->pz < 1; - //double x, y, z; - //int view[4] = {0,0,1,1}; - //gluProject(self->x, self->y, self->z, - // sphere->view->model, sphere->view->proj, view, - // &x, &y, &z); - //return !(x < 0 || x > 1 || - // y < 0 || y > 1 || - // z < 0 || z > 1); -} -gboolean roam_triangle_visible(RoamTriangle *self, RoamSphere *sphere) -{ - /* Do this with a bounding box */ - return roam_point_visible(self->p.l, sphere) || - roam_point_visible(self->p.m, sphere) || - roam_point_visible(self->p.r, sphere); -} - -void roam_triangle_update(RoamTriangle *self, RoamSphere *sphere) -{ - /* Update points */ - roam_point_update(self->p.l, sphere, TRUE); - roam_point_update(self->p.m, sphere, TRUE); - roam_point_update(self->p.r, sphere, TRUE); - - /* Not exactly correct, could be out on both sides (middle in) */ - if (!roam_triangle_visible(self, sphere)) { - self->error = -1; - } else { - RoamPoint *l = self->p.l; - RoamPoint *m = self->p.m; - RoamPoint *r = self->p.r; - - /* TODO: share this with the base */ - RoamPoint base = { (l->x + r->x)/2, - (l->y + r->y)/2, - (l->z + r->z)/2 }; - RoamPoint good = base; - roam_point_update(&base, sphere, FALSE); - roam_point_update(&good, sphere, TRUE); - - self->error = sqrt((base.px - good.px) * (base.px - good.px) + - (base.py - good.py) * (base.py - good.py)); - - /* Multiply by size of triangle */ - double size = -( l->px * (m->py - r->py) + - m->px * (r->py - l->py) + - r->px * (l->py - m->py) ) / 2.0; - - /* Size < 0 == backface */ - self->error *= size; - } -} - -void roam_triangle_clear(RoamTriangle *self) -{ - /* Clear points */ - roam_point_clear(self->p.l); - roam_point_clear(self->p.m); - roam_point_clear(self->p.r); -} - -void roam_triangle_split(RoamTriangle *self, RoamSphere *sphere) -{ - //g_message("roam_triangle_split: %p, e=%f\n", self, self->error); - - sphere->polys += 2; - - if (self != self->t.b->t.b) - roam_triangle_split(self->t.b, sphere); - - RoamTriangle *base = self->t.b; - - /* Duplicate midpoint */ - RoamPoint *mid = roam_point_new( - (self->p.l->x + self->p.r->x)/2, - (self->p.l->y + self->p.r->y)/2, - (self->p.l->z + self->p.r->z)/2); - roam_point_update(mid, sphere, TRUE); - - /* Add new triangles */ - RoamTriangle *sl = roam_triangle_new(self->p.m, mid, self->p.l); // Self Left - RoamTriangle *sr = roam_triangle_new(self->p.r, mid, self->p.m); // Self Right - RoamTriangle *bl = roam_triangle_new(base->p.m, mid, base->p.l); // Base Left - RoamTriangle *br = roam_triangle_new(base->p.r, mid, base->p.m); // Base Right - - /* tri,l, base, r, sphere */ - roam_triangle_add(sl, sr, self->t.l, br, sphere); - roam_triangle_add(sr, bl, self->t.r, sl, sphere); - roam_triangle_add(bl, br, base->t.l, sr, sphere); - roam_triangle_add(br, sl, base->t.r, bl, sphere); - - roam_triangle_sync_neighbors(sl, self, self->t.l); - roam_triangle_sync_neighbors(sr, self, self->t.r); - roam_triangle_sync_neighbors(bl, base, base->t.l); - roam_triangle_sync_neighbors(br, base, base->t.r); - - /* Remove old triangles */ - roam_triangle_remove(self, sphere); - roam_triangle_remove(base, sphere); - - /* Add/Remove diamonds */ - RoamDiamond *diamond = roam_diamond_new(self, base, sl, sr, bl, br); - roam_diamond_update(diamond, sphere); - roam_diamond_add(diamond, sphere); - roam_diamond_remove(self->parent, sphere); - roam_diamond_remove(base->parent, sphere); -} - -void roam_triangle_draw_normal(RoamTriangle *self) -{ - double center[] = { - (self->p.l->x + self->p.m->x + self->p.r->x)/3.0, - (self->p.l->y + self->p.m->y + self->p.r->y)/3.0, - (self->p.l->z + self->p.m->z + self->p.r->z)/3.0, - }; - double end[] = { - center[0]+self->norm[0]/2, - center[1]+self->norm[1]/2, - center[2]+self->norm[2]/2, - }; - glBegin(GL_LINES); - glVertex3dv(center); - glVertex3dv(end); - glEnd(); -} - -/*************** - * RoamDiamond * - ***************/ -RoamDiamond *roam_diamond_new( - RoamTriangle *parent0, RoamTriangle *parent1, - RoamTriangle *kid0, RoamTriangle *kid1, - RoamTriangle *kid2, RoamTriangle *kid3) -{ - RoamDiamond *self = g_new0(RoamDiamond, 1); - - self->kids[0] = kid0; - self->kids[1] = kid1; - self->kids[2] = kid2; - self->kids[3] = kid3; - - kid0->parent = self; - kid1->parent = self; - kid2->parent = self; - kid3->parent = self; - - self->parents[0] = parent0; - self->parents[1] = parent1; - - return self; -} -void roam_diamond_add(RoamDiamond *self, RoamSphere *sphere) -{ - self->active = TRUE; - self->error = MAX(self->parents[0]->error, self->parents[1]->error); - self->handle = g_pqueue_push(sphere->diamonds, self); -} -void roam_diamond_remove(RoamDiamond *self, RoamSphere *sphere) -{ - if (self && self->active) { - self->active = FALSE; - g_pqueue_remove(sphere->diamonds, self->handle); - } -} -void roam_diamond_merge(RoamDiamond *self, RoamSphere *sphere) -{ - //g_message("roam_diamond_merge: %p, e=%f\n", self, self->error); - - sphere->polys -= 2; - - /* TODO: pick the best split */ - RoamTriangle **kids = self->kids; - - /* Create triangles */ - RoamTriangle *tri = self->parents[0]; - RoamTriangle *base = self->parents[1]; - - roam_triangle_add(tri, kids[0]->t.b, base, kids[1]->t.b, sphere); - roam_triangle_add(base, kids[2]->t.b, tri, kids[3]->t.b, sphere); - - roam_triangle_sync_neighbors(tri, kids[0], kids[0]->t.b); - roam_triangle_sync_neighbors(tri, kids[1], kids[1]->t.b); - roam_triangle_sync_neighbors(base, kids[2], kids[2]->t.b); - roam_triangle_sync_neighbors(base, kids[3], kids[3]->t.b); - - /* Remove triangles */ - roam_triangle_remove(kids[0], sphere); - roam_triangle_remove(kids[1], sphere); - roam_triangle_remove(kids[2], sphere); - roam_triangle_remove(kids[3], sphere); - - /* Add/Remove triangles */ - if (tri->t.l->t.l == tri->t.r->t.r && - tri->t.l->t.l != tri && tri->parent) { - roam_diamond_update(tri->parent, sphere); - roam_diamond_add(tri->parent, sphere); - } - - if (base->t.l->t.l == base->t.r->t.r && - base->t.l->t.l != base && base->parent) { - roam_diamond_update(base->parent, sphere); - roam_diamond_add(base->parent, sphere); - } - - /* Remove and free diamond and child triangles */ - roam_diamond_remove(self, sphere); - g_assert(self->kids[0]->p.m == self->kids[1]->p.m && - self->kids[1]->p.m == self->kids[2]->p.m && - self->kids[2]->p.m == self->kids[3]->p.m); - g_assert(self->kids[0]->p.m->tris == 0); - g_free(self->kids[0]->p.m); - g_free(self->kids[0]); - g_free(self->kids[1]); - g_free(self->kids[2]); - g_free(self->kids[3]); - g_free(self); -} -void roam_diamond_update(RoamDiamond *self, RoamSphere *sphere) -{ - roam_triangle_update(self->parents[0], sphere); - roam_triangle_update(self->parents[1], sphere); - self->error = MAX(self->parents[0]->error, self->parents[1]->error); -} - -/************** - * RoamSphere * - **************/ -RoamSphere *roam_sphere_new(RoamTriFunc tri_func, RoamHeightFunc height_func, gpointer user_data) -{ - RoamSphere *self = g_new0(RoamSphere, 1); - self->tri_func = tri_func; - self->height_func = height_func; - self->user_data = user_data; - self->polys = 12; - self->triangles = g_pqueue_new((GCompareDataFunc)tri_cmp, NULL); - self->diamonds = g_pqueue_new((GCompareDataFunc)dia_cmp, NULL); - - RoamPoint *vertexes[] = { - roam_point_new( 1, 1, 1), // 0 - roam_point_new( 1, 1,-1), // 1 - roam_point_new( 1,-1, 1), // 2 - roam_point_new( 1,-1,-1), // 3 - roam_point_new(-1, 1, 1), // 4 - roam_point_new(-1, 1,-1), // 5 - roam_point_new(-1,-1, 1), // 6 - roam_point_new(-1,-1,-1), // 7 - }; - int _triangles[][2][3] = { - /*lv mv rv ln, bn, rn */ - {{3,2,0}, {10, 1, 7}}, // 0 - {{0,1,3}, { 9, 0, 2}}, // 1 - {{7,3,1}, {11, 3, 1}}, // 2 - {{1,5,7}, { 8, 2, 4}}, // 3 - {{6,7,5}, {11, 5, 3}}, // 4 - {{5,4,6}, { 8, 4, 6}}, // 5 - {{2,6,4}, {10, 7, 5}}, // 6 - {{4,0,2}, { 9, 6, 0}}, // 7 - {{4,5,1}, { 5, 9, 3}}, // 8 - {{1,0,4}, { 1, 8, 7}}, // 9 - {{6,2,3}, { 6,11, 0}}, // 10 - {{3,7,6}, { 2,10, 4}}, // 11 - }; - RoamTriangle *triangles[12]; - - for (int i = 0; i < 12; i++) - triangles[i] = roam_triangle_new( - vertexes[_triangles[i][0][0]], - vertexes[_triangles[i][0][1]], - vertexes[_triangles[i][0][2]]); - for (int i = 0; i < 12; i++) - roam_triangle_add(triangles[i], - triangles[_triangles[i][1][0]], - triangles[_triangles[i][1][1]], - triangles[_triangles[i][1][2]], - self); - - return self; -} -void roam_sphere_update(RoamSphere *self) -{ - g_debug("RoamSphere: update - polys=%d", self->polys); - if (self->view) g_free(self->view); - self->view = roam_view_get(); - - GPtrArray *tris = g_pqueue_get_array(self->triangles); - GPtrArray *dias = g_pqueue_get_array(self->diamonds); - - for (int i = 0; i < tris->len; i++) { - /* Note: this also updates points */ - RoamTriangle *tri = tris->pdata[i]; - roam_triangle_clear(tri); - roam_triangle_update(tri, self); - g_pqueue_priority_changed(self->triangles, tri->handle); - } - - for (int i = 0; i < dias->len; i++) { - RoamDiamond *dia = dias->pdata[i]; - roam_diamond_update(dia, self); - g_pqueue_priority_changed(self->diamonds, dia->handle); - } - - g_ptr_array_free(tris, TRUE); - g_ptr_array_free(dias, TRUE); -} - -void roam_sphere_split_one(RoamSphere *self) -{ - RoamTriangle *to_split = g_pqueue_peek(self->triangles); - if (!to_split) return; - roam_triangle_split(to_split, self); -} -void roam_sphere_merge_one(RoamSphere *self) -{ - RoamDiamond *to_merge = g_pqueue_peek(self->diamonds); - if (!to_merge) return; - roam_diamond_merge(to_merge, self); -} -gint roam_sphere_split_merge(RoamSphere *self) -{ - gint iters = 0, max_iters = 500; - gint target = 2000; - - if (!self->view) - return 0; - - if (target - self->polys > 100) - while (self->polys < target && iters++ < max_iters) - roam_sphere_split_one(self); - - if (self->polys - target > 100) - while (self->polys > target && iters++ < max_iters) - roam_sphere_merge_one(self); - - while (((RoamTriangle*)g_pqueue_peek(self->triangles))->error > - ((RoamDiamond *)g_pqueue_peek(self->diamonds ))->error && - iters++ < max_iters) { - roam_sphere_merge_one(self); - roam_sphere_split_one(self); - } - - return iters; -} -void roam_sphere_draw(RoamSphere *self) -{ - g_pqueue_foreach(self->triangles, (GFunc)self->tri_func, self->user_data); -} -void roam_sphere_draw_normals(RoamSphere *self) -{ - g_pqueue_foreach(self->triangles, (GFunc)roam_triangle_draw_normal, NULL); -} -static void roam_sphere_free_tri(RoamTriangle *tri) -{ - if (--tri->p.l->tris == 0) g_free(tri->p.l); - if (--tri->p.m->tris == 0) g_free(tri->p.m); - if (--tri->p.r->tris == 0) g_free(tri->p.r); - g_free(tri); -} -void roam_sphere_free(RoamSphere *self) -{ - /* Slow method, but it should work */ - while (self->polys > 12) - roam_sphere_merge_one(self); - /* TODO: free points */ - g_pqueue_foreach(self->triangles, (GFunc)roam_sphere_free_tri, NULL); - g_pqueue_free(self->triangles); - g_pqueue_free(self->diamonds); - g_free(self); -} diff --git a/src/gis/roam.h b/src/gis/roam.h deleted file mode 100644 index 3d2fced..0000000 --- a/src/gis/roam.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (C) 2009 Andy Spencer - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef __ROAM_H__ -#define __ROAM_H__ - -#include "gpqueue.h" -#include "wms.h" - -/* Roam */ -typedef struct _RoamView RoamView; -typedef struct _RoamPoint RoamPoint; -typedef struct _RoamTriangle RoamTriangle; -typedef struct _RoamDiamond RoamDiamond; -typedef struct _RoamSphere RoamSphere; -typedef void (*RoamTriFunc)(RoamTriangle *triangle, gpointer user_data); -typedef void (*RoamHeightFunc)(RoamPoint *point, gpointer user_data); - -/* Misc */ -struct _RoamView { - gdouble model[16]; - gdouble proj[16]; - gint view[4]; -}; - -/************* - * RoamPoint * - *************/ -struct _RoamPoint { - gdouble x,y,z; // Model coordinates - gdouble px,py,pz; // Projected coordinates - - gboolean cached; // Height/projection cached - - gint tris; // Associated triangles - gdouble norm[3]; // Vertex normal - - WmsCacheNode *node; // TODO: don't depend on wms -}; -RoamPoint *roam_point_new(double x, double y, double z); -void roam_point_add_triangle(RoamPoint *point, RoamTriangle *triangle); -void roam_point_remove_triangle(RoamPoint *point, RoamTriangle *triangle); -void roam_point_update(RoamPoint *point, RoamSphere *sphere, gboolean do_height); -void roam_point_clear(RoamPoint *self); - -/**************** - * RoamTriangle * - ****************/ -struct _RoamTriangle { - struct { RoamPoint *l,*m,*r; } p; - struct { RoamTriangle *l,*b,*r; } t; - RoamDiamond *parent; - double norm[3]; - double error; - GPQueueHandle handle; - - WmsCacheNode *nodes[5]; // TODO: don't depend on wms -}; -RoamTriangle *roam_triangle_new(RoamPoint *l, RoamPoint *m, RoamPoint *r); -void roam_triangle_add(RoamTriangle *triangle, - RoamTriangle *left, RoamTriangle *base, RoamTriangle *right, - RoamSphere *sphere); -void roam_triangle_remove(RoamTriangle *triangle, RoamSphere *sphere); -void roam_triangle_update(RoamTriangle *triangle, RoamSphere *sphere); -void roam_triangle_split(RoamTriangle *triangle, RoamSphere *sphere); -void roam_triangle_draw_normal(RoamTriangle *triangle); - -/*************** - * RoamDiamond * - ***************/ -struct _RoamDiamond { - RoamTriangle *kids[4]; - RoamTriangle *parents[2]; - double error; - gboolean active; - GPQueueHandle handle; -}; -RoamDiamond *roam_diamond_new( - RoamTriangle *parent0, RoamTriangle *parent1, - RoamTriangle *kid0, RoamTriangle *kid1, - RoamTriangle *kid2, RoamTriangle *kid3); -void roam_diamond_add(RoamDiamond *diamond, RoamSphere *sphere); -void roam_diamond_remove(RoamDiamond *diamond, RoamSphere *sphere); -void roam_diamond_merge(RoamDiamond *diamond, RoamSphere *sphere); -void roam_diamond_update(RoamDiamond *self, RoamSphere *sphere); - -/************** - * RoamSphere * - **************/ -struct _RoamSphere { - GPQueue *triangles; - GPQueue *diamonds; - RoamView *view; - RoamTriFunc tri_func; - RoamHeightFunc height_func; - gpointer user_data; - gint polys; -}; -RoamSphere *roam_sphere_new(RoamTriFunc tri_func, RoamHeightFunc height_func, gpointer user_data); -void roam_sphere_update(RoamSphere *sphere); -void roam_sphere_split_one(RoamSphere *sphere); -void roam_sphere_merge_one(RoamSphere *sphere); -gint roam_sphere_split_merge(RoamSphere *sphere); -void roam_sphere_draw(RoamSphere *sphere); -void roam_sphere_draw_normals(RoamSphere *sphere); -void roam_sphere_free(RoamSphere *sphere); - -#endif diff --git a/src/gis/wms.c b/src/gis/wms.c deleted file mode 100644 index 92a3476..0000000 --- a/src/gis/wms.c +++ /dev/null @@ -1,541 +0,0 @@ -/* - * Copyright (C) 2009 Andy Spencer - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * http://www.nasa.network.com/elev? - * SERVICE=WMS& - * VERSION=1.1.0& - * REQUEST=GetMap& - * LAYERS=bmng200406& - * STYLES=& - * SRS=EPSG:4326& - * BBOX=-180,-90,180,90& - * FORMAT=image/jpeg& - * WIDTH=600& - * HEIGHT=300 - * - * http://www.nasa.network.com/elev? - * SERVICE=WMS& - * VERSION=1.1.0& - * REQUEST=GetMap& - * LAYERS=srtm30& - * STYLES=& - * SRS=EPSG:4326& - * BBOX=-180,-90,180,90& - * FORMAT=application/bil32& - * WIDTH=600& - * HEIGHT=300 - */ - -#include -#include -#include -#include -#include -#include - -#include "wms.h" - -/* TODO: try to remove these */ -#include "gis-world.h" -#include - -gchar *wms_make_uri(WmsInfo *info, gdouble xmin, gdouble ymin, gdouble xmax, gdouble ymax) -{ - return g_strdup_printf( - "%s?" - "SERVICE=WMS&" - "VERSION=1.1.0&" - "REQUEST=GetMap&" - "LAYERS=%s&" - "STYLES=&" - "SRS=EPSG:4326&" - "BBOX=%f,%f,%f,%f&" - "FORMAT=%s&" - "WIDTH=%d&" - "HEIGHT=%d", - info->uri_prefix, - info->uri_layer, - xmin, ymin, xmax, ymax, - info->uri_format, - info->width, - info->height); -} - -/**************** - * WmsCacheNode * - ****************/ -WmsCacheNode *wms_cache_node_new(WmsCacheNode *parent, - gdouble xmin, gdouble ymin, gdouble xmax, gdouble ymax, gint width) -{ - WmsCacheNode *self = g_new0(WmsCacheNode, 1); - //g_debug("WmsCacheNode: new - %p %+7.3f,%+7.3f,%+7.3f,%+7.3f", - // self, xmin, ymin, xmax, ymax); - self->latlon[0] = xmin; - self->latlon[1] = ymin; - self->latlon[2] = xmax; - self->latlon[3] = ymax; - self->parent = parent; - if (ymin <= 0 && ymax >= 0) - self->res = ll2m(xmax-xmin, 0)/width; - else - self->res = ll2m(xmax-xmin, MIN(ABS(ymin),ABS(ymax)))/width; - return self; -} - -void wms_cache_node_free(WmsCacheNode *node, WmsFreeer freeer) -{ - //g_debug("WmsCacheNode: free - %p", node); - if (node->data) { - freeer(node); - node->data = NULL; - } - for (int x = 0; x < 4; x++) - for (int y = 0; y < 4; y++) - if (node->children[x][y]) - wms_cache_node_free(node->children[x][y], freeer); - g_free(node); -} - -/*********** - * WmsInfo * - ***********/ -WmsInfo *wms_info_new(WmsLoader loader, WmsFreeer freeer, - gchar *uri_prefix, gchar *uri_layer, gchar *uri_format, - gchar *cache_prefix, gchar *cache_ext, - gint resolution, gint width, gint height -) { - WmsInfo *self = g_new0(WmsInfo, 1); - self->loader = loader; - self->freeer = freeer; - self->uri_prefix = uri_prefix; - self->uri_layer = uri_layer; - self->uri_format = uri_format; - self->cache_prefix = cache_prefix; - self->cache_ext = cache_ext; - self->resolution = resolution; - self->width = width; - self->height = height; - - self->max_age = 60; - self->atime = time(NULL); - self->gc_source = g_timeout_add_seconds(1, (GSourceFunc)wms_info_gc, self); - self->cache_root = wms_cache_node_new(NULL, -180, -90, 180, 90, width); - self->soup = soup_session_async_new(); - return self; -} - -struct _CacheImageState { - WmsInfo *info; - gchar *path; - FILE *output; - WmsCacheNode *node; - WmsChunkCallback user_chunk_cb; - WmsDoneCallback user_done_cb; - gpointer user_data; -}; -void wms_info_soup_chunk_cb(SoupMessage *message, SoupBuffer *chunk, gpointer _state) -{ - struct _CacheImageState *state = _state; - if (!SOUP_STATUS_IS_SUCCESSFUL(message->status_code)) - return; - - goffset total = soup_message_headers_get_content_length(message->response_headers); - if (fwrite(chunk->data, chunk->length, 1, state->output) != 1) - g_warning("WmsInfo: soup_chunk_cb - eror writing data"); - - gdouble cur = (gdouble)ftell(state->output); - if (state->user_chunk_cb) - state->user_chunk_cb(cur, total, state->user_data); -} -void wms_info_soup_done_cb(SoupSession *session, SoupMessage *message, gpointer _state) -{ - struct _CacheImageState *state = _state; - if (!SOUP_STATUS_IS_SUCCESSFUL(message->status_code)) - return; - gchar *dest = g_strndup(state->path, strlen(state->path)-5); - g_rename(state->path, dest); - state->node->atime = time(NULL); - state->info->loader(state->node, dest, state->info->width, state->info->height); - if (state->user_done_cb) - state->user_done_cb(state->node, state->user_data); - state->node->caching = FALSE; - fclose(state->output); - g_free(state->path); - g_free(dest); - g_free(state); -} -gboolean wms_info_cache_loader_cb(gpointer _state) -{ - struct _CacheImageState *state = _state; - state->node->atime = time(NULL); - state->info->loader(state->node, state->path, state->info->width, state->info->height); - if (state->user_done_cb) - state->user_done_cb(state->node, state->user_data); - state->node->caching = FALSE; - g_free(state->path); - g_free(state); - return FALSE; -} -/** - * Cache required tiles - * 1. Load closest tile that's stored on disk - * 2. Fetch the correct tile from the remote server - */ -void wms_info_cache(WmsInfo *info, gdouble resolution, gdouble lat, gdouble lon, - WmsChunkCallback chunk_callback, WmsDoneCallback done_callback, - gpointer user_data) -{ - /* Base cache path */ - gdouble x=lon, y=lat; - gdouble xmin=-180, ymin=-90, xmax=180, ymax=90; - gdouble xdist = xmax - xmin; - gdouble ydist = ymax - ymin; - int xpos=0, ypos=0; - gdouble cur_lat = 0; - - WmsCacheNode *target_node = info->cache_root; - WmsCacheNode *approx_node = NULL; - - GString *target_path = g_string_new(g_get_user_cache_dir()); - g_string_append(target_path, G_DIR_SEPARATOR_S); - g_string_append(target_path, "wms"); - g_string_append(target_path, G_DIR_SEPARATOR_S); - g_string_append(target_path, info->cache_prefix); - gchar *approx_path = NULL; - - /* Create nodes to tiles, determine paths and lat-lon coords */ - while (TRUE) { - /* Update the best approximation if it exists on disk */ - gchar *tmp = g_strconcat(target_path->str, info->cache_ext, NULL); - if (g_file_test(tmp, G_FILE_TEST_EXISTS)) { - g_free(approx_path); - approx_node = target_node; - approx_path = tmp; - } else { - g_free(tmp); - } - - /* Break if current resolution (m/px) is good enough */ - if (ll2m(xdist, cur_lat)/info->width <= resolution || - ll2m(xdist, cur_lat)/info->width <= info->resolution) - break; - - /* Get locations for the correct sub-tile */ - xpos = (int)(((x - xmin) / xdist) * 4); - ypos = (int)(((y - ymin) / ydist) * 4); - if (xpos == 4) xpos--; - if (ypos == 4) ypos--; - xdist /= 4; - ydist /= 4; - xmin = xmin + xdist*(xpos+0); - ymin = ymin + ydist*(ypos+0); - xmax = xmin + xdist; - ymax = ymin + ydist; - cur_lat = MIN(ABS(ymin), ABS(ymax)); - - /* Update target for correct sub-tile */ - g_string_append_printf(target_path, "/%d%d", xpos, ypos); - if (target_node->children[xpos][ypos] == NULL) - target_node->children[xpos][ypos] = - wms_cache_node_new(target_node, - xmin, ymin, xmax, ymax, info->width); - target_node = target_node->children[xpos][ypos]; - } - - /* Load disk on-disk approximation, TODO: async */ - if (approx_node && !approx_node->data && !approx_node->caching) { - approx_node->caching = TRUE; - struct _CacheImageState *state = g_new0(struct _CacheImageState, 1); - state->info = info; - state->path = approx_path; - state->node = approx_node; - state->user_done_cb = done_callback; - state->user_data = user_data; - g_idle_add(wms_info_cache_loader_cb, state); - } else { - g_free(approx_path); - } - - /* If target image is not on-disk, download it now */ - if (target_node != approx_node && !target_node->caching) { - target_node->caching = TRUE; - g_string_append(target_path, info->cache_ext); - g_string_append(target_path, ".part"); - - gchar *dirname = g_path_get_dirname(target_path->str); - g_mkdir_with_parents(dirname, 0755); - g_free(dirname); - - struct _CacheImageState *state = g_new0(struct _CacheImageState, 1); - state->info = info; - state->path = target_path->str; - state->output = fopen(target_path->str, "a"); - state->node = target_node; - state->user_chunk_cb = chunk_callback; - state->user_done_cb = done_callback; - state->user_data = user_data; - - gchar *uri = wms_make_uri(info, xmin, ymin, xmax, ymax); - SoupMessage *message = soup_message_new("GET", uri); - g_signal_connect(message, "got-chunk", G_CALLBACK(wms_info_soup_chunk_cb), state); - soup_message_headers_set_range(message->request_headers, ftell(state->output), -1); - - soup_session_queue_message(info->soup, message, wms_info_soup_done_cb, state); - - g_debug("Caching file: %s -> %s", uri, state->path); - g_free(uri); - g_string_free(target_path, FALSE); - } else { - g_string_free(target_path, TRUE); - } -} -/* TODO: - * - Store WmsCacheNode in point and then use parent pointers to go up/down - * - If resolution doesn't change, tell caller to skip remaining calculations - */ -WmsCacheNode *wms_info_fetch(WmsInfo *info, WmsCacheNode *root, - gdouble resolution, gdouble lat, gdouble lon, - gboolean *correct) -{ - if (root && root->data && !root->caching && - root->latlon[0] <= lon && lon <= root->latlon[2] && - root->latlon[1] <= lat && lat <= root->latlon[3] && - root->res <= resolution && - (!root->parent || root->parent->res > resolution)) { - *correct = TRUE; - info->atime = time(NULL); - root->atime = info->atime; - return root; - } - - if (info->cache_root == NULL) { - *correct = FALSE; - return NULL; - } - WmsCacheNode *node = info->cache_root; - WmsCacheNode *best = (node && node->data ? node : NULL); - gdouble xmin=-180, ymin=-90, xmax=180, ymax=90, xdist=360, ydist=180; - gdouble cur_lat = 0; - int xpos=0, ypos=0; - gdouble cur_res = ll2m(xdist, cur_lat)/info->width; - while (cur_res > resolution && - cur_res > info->resolution) { - - xpos = ((lon - xmin) / xdist) * 4; - ypos = ((lat - ymin) / ydist) * 4; - if (xpos == 4) xpos--; - if (ypos == 4) ypos--; - xdist /= 4; - ydist /= 4; - xmin = xmin + xdist*(xpos+0); - ymin = ymin + ydist*(ypos+0); - cur_lat = MIN(ABS(ymin), ABS(ymax)); - - node = node->children[xpos][ypos]; - if (node == NULL) - break; - if (node->data) - best = node; - - cur_res = ll2m(xdist, cur_lat)/info->width; - } - if (correct) - *correct = (node && node == best); - info->atime = time(NULL); - if (best) - best->atime = info->atime; - return best; -} - -WmsCacheNode *wms_info_fetch_cache(WmsInfo *info, WmsCacheNode *root, - gdouble res, gdouble lat, gdouble lon, - WmsChunkCallback chunk_callback, WmsDoneCallback done_callback, gpointer user_data) -{ - /* Fetch a node, if it isn't cached, cache it, also keep it's parent cached */ - gboolean correct; - WmsCacheNode *node = wms_info_fetch(info, root, res, lat, lon, &correct); - if (!node || !correct) - wms_info_cache(info, res, lat, lon, chunk_callback, done_callback, user_data); - //else if (node->parent && node->parent->data == NULL) - // wms_info_cache(info, node->parent->res, lat, lon, chunk_callback, done_callback, user_data); - //else if (node->parent) - // node->parent->atime = node->atime; - return node; -} - -/* Delete unused nodes and prune empty branches */ -static WmsCacheNode *wms_info_gc_cb(WmsInfo *self, WmsCacheNode *node) -{ - gboolean empty = FALSE; - if (self->atime - node->atime > self->max_age && - node->data && node != self->cache_root && !node->caching) { - g_debug("WmsInfo: gc - expired node %p", node); - self->freeer(node); - node->data = NULL; - empty = TRUE; - } - for (int x = 0; x < 4; x++) - for (int y = 0; y < 4; y++) - if (node->children[x][y]) { - node->children[x][y] = - wms_info_gc_cb(self, node->children[x][y]); - empty = FALSE; - } - if (empty) { - g_debug("WmsInfo: gc - empty branch %p", node); - /* - * TODO: Don't prune nodes while we're caching WmsCacheNodes in the Roam triangles - * and points - g_free(node); - return NULL; - */ - return node; - } else { - return node; - } -} - -gboolean wms_info_gc(WmsInfo *self) -{ - if (!wms_info_gc_cb(self, self->cache_root)) - g_warning("WmsInfo: gc - root not should not be empty"); - return TRUE; -} - -void wms_info_free(WmsInfo *self) -{ - wms_cache_node_free(self->cache_root, self->freeer); - g_object_unref(self->soup); - g_free(self); -} - - -/************************ - * Blue Marble Next Gen * - ************************/ -void bmng_opengl_loader(WmsCacheNode *node, const gchar *path, gint width, gint height) -{ - GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(path, NULL); - node->data = g_new0(guint, 1); - - /* Load image */ - guchar *pixels = gdk_pixbuf_get_pixels(pixbuf); - int alpha = gdk_pixbuf_get_has_alpha(pixbuf); - int nchan = 4; // gdk_pixbuf_get_n_channels(pixbuf); - - /* Create Texture */ - glGenTextures(1, node->data); - glBindTexture(GL_TEXTURE_2D, *(guint*)node->data); - - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glPixelStorei(GL_PACK_ALIGNMENT, 1); - glTexImage2D(GL_TEXTURE_2D, 0, nchan, width, height, 0, - (alpha ? GL_RGBA : GL_RGB), GL_UNSIGNED_BYTE, pixels); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); - - g_object_unref(pixbuf); - g_debug("WmsCacheNode: bmng_opengl_loader: %s -> %p", path, node->data); -} -void bmng_opengl_freeer(WmsCacheNode *node) -{ - g_debug("WmsCacheNode: bmng_opengl_freeer: %p", node->data); - glDeleteTextures(1, node->data); - g_free(node->data); -} - -void bmng_pixbuf_loader(WmsCacheNode *node, const gchar *path, gint width, gint height) -{ - node->data = gdk_pixbuf_new_from_file(path, NULL); - g_debug("WmsCacheNode: bmng_opengl_loader: %s -> %p", path, node->data); -} -void bmng_pixbuf_freeer(WmsCacheNode *node) -{ - g_debug("WmsCacheNode: bmng_opengl_freeer: %p", node->data); - g_object_unref(node->data); -} - -WmsInfo *wms_info_new_for_bmng(WmsLoader loader, WmsFreeer freeer) -{ - loader = loader ?: bmng_opengl_loader; - freeer = freeer ?: bmng_opengl_freeer; - return wms_info_new(loader, freeer, - "http://www.nasa.network.com/wms", "bmng200406", "image/jpeg", - "bmng", ".jpg", 500, 512, 256); -} - -/******************************************** - * Shuttle Radar Topography Mission 30 Plus * - ********************************************/ -void srtm_bil_loader(WmsCacheNode *node, const gchar *path, gint width, gint height) -{ - WmsBil *bil = g_new0(WmsBil, 1); - gchar **char_data = (gchar**)&bil->data; - g_file_get_contents(path, char_data, NULL, NULL); - bil->width = width; - bil->height = height; - node->data = bil; - g_debug("WmsCacheNode: srtm_opengl_loader: %s -> %p", path, node->data); -} -void srtm_bil_freeer(WmsCacheNode *node) -{ - g_debug("WmsCacheNode: srtm_opengl_freeer: %p", node); - g_free(((WmsBil*)node->data)->data); - g_free(node->data); -} - -void srtm_pixbuf_loader(WmsCacheNode *node, const gchar *path, gint width, gint height) -{ - GdkPixbuf *pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8, width, height); - guchar *pixels = gdk_pixbuf_get_pixels(pixbuf); - gint stride = gdk_pixbuf_get_rowstride(pixbuf); - - gint16 *data; - gchar **char_data = (gchar**)&data; - g_file_get_contents(path, char_data, NULL, NULL); - for (int r = 0; r < height; r++) { - for (int c = 0; c < width; c++) { - gint16 value = data[r*width + c]; - //guchar color = (float)(MAX(value,0))/8848 * 255; - guchar color = (float)value/8848 * 255; - pixels[r*stride + c*3 + 0] = color; - pixels[r*stride + c*3 + 1] = color; - pixels[r*stride + c*3 + 2] = color; - } - } - g_free(data); - - node->data = pixbuf; - g_debug("WmsCacheNode: srtm_opengl_loader: %s -> %p", path, node->data); -} -void srtm_pixbuf_freeer(WmsCacheNode *node) -{ - g_debug("WmsCacheNode: srtm_opengl_freeer: %p", node); - g_object_unref(node->data); -} - -WmsInfo *wms_info_new_for_srtm(WmsLoader loader, WmsFreeer freeer) -{ - loader = loader ?: srtm_bil_loader; - freeer = freeer ?: srtm_bil_freeer; - return wms_info_new(loader, freeer, - "http://www.nasa.network.com/elev", "srtm30", "application/bil", - "srtm", ".bil", 500, 512, 256); -} diff --git a/src/gis/wms.h b/src/gis/wms.h deleted file mode 100644 index a419e74..0000000 --- a/src/gis/wms.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (C) 2009 Andy Spencer - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef __WMS_H__ -#define __WMS_H__ - -#include -#include -#include - -typedef struct _WmsCacheNode WmsCacheNode; -typedef struct _WmsInfo WmsInfo; - -typedef void (*WmsChunkCallback)(gsize cur, gsize total, gpointer user_data); -typedef void (*WmsDoneCallback)(WmsCacheNode *node, gpointer user_data); -typedef void (*WmsLoader)(WmsCacheNode *node, const gchar *path, gint width, gint height); -typedef void (*WmsFreeer)(WmsCacheNode *node); - -/**************** - * WmsCacheNode * - ****************/ -struct _WmsCacheNode { - gpointer data; - gdouble latlon[4]; // xmin,ymin,xmax,ymax - gdouble res; // xmin,ymin,xmax,ymax - gboolean caching; - time_t atime; - WmsCacheNode *parent; - WmsCacheNode *children[4][4]; -}; - -WmsCacheNode *wms_cache_node_new(WmsCacheNode *parent, gdouble xmin, gdouble ymin, gdouble xmax, gdouble ymax, gint width); - -void wms_cache_node_free(WmsCacheNode *node, WmsFreeer freeer); - -/*********** - * WmsInfo * - ***********/ -struct _WmsInfo { - gchar *uri_prefix; - gchar *uri_layer; - gchar *uri_format; - gchar *cache_prefix; - gchar *cache_ext; - gint resolution; // m/px - gint width; - gint height; - - guint max_age; - guint gc_source; - time_t atime; - WmsLoader loader; - WmsFreeer freeer; - WmsCacheNode *cache_root; - SoupSession *soup; -}; - -WmsInfo *wms_info_new(WmsLoader loader, WmsFreeer freeer, - gchar *uri_prefix, gchar *uri_layer, gchar *uri_format, - gchar *cache_prefix, gchar *cache_ext, - gint resolution, gint width, gint height); - -void wms_info_cache(WmsInfo *info, gdouble resolution, gdouble lat, gdouble lon, - WmsChunkCallback chunk_callback, WmsDoneCallback done_callback, - gpointer user_data); - -WmsCacheNode *wms_info_fetch(WmsInfo *info, WmsCacheNode *root, - gdouble resolution, gdouble lat, gdouble lon, - gboolean *correct); - -WmsCacheNode *wms_info_fetch_cache(WmsInfo *info, WmsCacheNode *root, - gdouble resolution, gdouble lat, gdouble lon, - WmsChunkCallback chunk_callback, WmsDoneCallback done_callback, - gpointer user_data); - -gboolean wms_info_gc(WmsInfo *self); - -void wms_info_free(WmsInfo *info); - - -/******************************** - * Specific things (bmng, srtm) * - ********************************/ -typedef struct _WmsBil WmsBil; -struct _WmsBil { - gint16 *data; - gint width; - gint height; -}; - -void bmng_opengl_loader(WmsCacheNode *node, const gchar *path, gint width, gint height); -void bmng_opengl_freeer(WmsCacheNode *node); - -void bmng_pixbuf_loader(WmsCacheNode *node, const gchar *path, gint width, gint height); -void bmng_pixbuf_freeer(WmsCacheNode *node); - -WmsInfo *wms_info_new_for_bmng(WmsLoader loader, WmsFreeer freeer); - -void srtm_bil_loader(WmsCacheNode *node, const gchar *path, gint width, gint height); -void srtm_bil_freeer(WmsCacheNode *node); - -void srtm_pixbuf_loader(WmsCacheNode *node, const gchar *path, gint width, gint height); -void srtm_pixbuf_freeer(WmsCacheNode *node); - -WmsInfo *wms_info_new_for_srtm(WmsLoader loader, WmsFreeer freeer); - -#endif diff --git a/src/gis/wms_test.c b/src/gis/wms_test.c deleted file mode 100644 index 2eb4500..0000000 --- a/src/gis/wms_test.c +++ /dev/null @@ -1,84 +0,0 @@ -#include -#include - -#include "wms.h" - -struct CacheState { - GtkWidget *image; - GtkWidget *status; - GtkWidget *progress; -}; - -void done_callback(WmsCacheNode *node, gpointer _state) -{ - struct CacheState *state = _state; - g_message("done_callback: %p->%p", node, node->data); - gtk_image_set_from_pixbuf(GTK_IMAGE(state->image), node->data); -} - -void chunk_callback(gsize cur, gsize total, gpointer _state) -{ - struct CacheState *state = _state; - g_message("chunk_callback: %d/%d", cur, total); - - if (state->progress == NULL) { - state->progress = gtk_progress_bar_new(); - gtk_box_pack_end(GTK_BOX(state->status), state->progress, FALSE, FALSE, 0); - gtk_widget_show(state->progress); - } - - if (cur == total) - gtk_widget_destroy(state->progress); - else - gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(state->progress), (gdouble)cur/total); -} - -gboolean key_press_cb(GtkWidget *widget, GdkEventKey *event, gpointer user_data) -{ - if (event->keyval == GDK_q) - gtk_main_quit(); - return TRUE; -} - -int main(int argc, char **argv) -{ - gtk_init(&argc, &argv); - g_thread_init(NULL); - - GtkWidget *win = gtk_window_new(GTK_WINDOW_TOPLEVEL); - GtkWidget *vbox1 = gtk_vbox_new(FALSE, 0); - GtkWidget *vbox2 = gtk_vbox_new(FALSE, 0); - GtkWidget *status = gtk_statusbar_new(); - GtkWidget *scroll = gtk_scrolled_window_new(NULL, NULL); - GtkWidget *bmng_image = gtk_image_new(); - GtkWidget *srtm_image = gtk_image_new(); - gtk_container_add(GTK_CONTAINER(win), vbox1); - gtk_box_pack_start(GTK_BOX(vbox1), scroll, TRUE, TRUE, 0); - gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroll), vbox2); - gtk_box_pack_start(GTK_BOX(vbox2), bmng_image, TRUE, TRUE, 0); - gtk_box_pack_start(GTK_BOX(vbox2), srtm_image, TRUE, TRUE, 0); - gtk_box_pack_start(GTK_BOX(vbox1), status, FALSE, FALSE, 0); - g_signal_connect(win, "key-press-event", G_CALLBACK(key_press_cb), NULL); - g_signal_connect(win, "destroy", gtk_main_quit, NULL); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), - GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - - struct CacheState bmng_state = {bmng_image, status, NULL}; - struct CacheState srtm_state = {srtm_image, status, NULL}; - - gdouble res = 200, lon = -101.76, lat = 46.85; - - WmsInfo *bmng_info = wms_info_new_for_bmng(bmng_pixbuf_loader, bmng_pixbuf_freeer); - wms_info_fetch_cache(bmng_info, NULL, res, lat, lon, chunk_callback, done_callback, &bmng_state); - - WmsInfo *srtm_info = wms_info_new_for_srtm(srtm_pixbuf_loader, srtm_pixbuf_freeer); - wms_info_fetch_cache(srtm_info, NULL, res, lat, lon, chunk_callback, done_callback, &srtm_state); - - gtk_widget_show_all(win); - gtk_main(); - - wms_info_free(bmng_info); - wms_info_free(srtm_info); - - return 0; -} diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am index 87b74f1..c3718af 100644 --- a/src/plugins/Makefile.am +++ b/src/plugins/Makefile.am @@ -1,7 +1,7 @@ AM_CFLAGS = -Wall --std=gnu99 -I../ -AM_CPPFLAGS = $(GLIB_CFLAGS) $(GTK_CFLAGS) $(SOUP_CFLAGS) +AM_CPPFLAGS = $(GIS_CFLAGS) AM_LDFLAGS = -module -avoid-version -LIBS = $(top_srcdir)/src/gis/libgis.la +LIBS = $(GIS_LIBS) plugindir = $(libdir)/gis diff --git a/src/plugins/gis b/src/plugins/gis deleted file mode 120000 index 9e696c6..0000000 --- a/src/plugins/gis +++ /dev/null @@ -1 +0,0 @@ -.libs \ No newline at end of file -- 2.43.2