gis-opengl.h \
gis-plugin.h \
gis-data.h \
+ gis-tile.h \
+ gis-wms.h \
gpqueue.h \
roam.h
libgis_la_SOURCES = \
gis-plugin.c gis-plugin.h \
gis-marshal.c gis-marshal.h \
gis-data.c gis-data.h \
+ gis-tile.c gis-tile.h \
+ gis-wms.c gis-wms.h \
roam.c roam.h \
gpqueue.c gpqueue.h
libgis_la_CPPFLAGS = $(AM_CPPFLAGS) \
pkgconfig_DATA = libgis.pc
# Test programs
-bin_PROGRAMS = gis_test # wms_test
+bin_PROGRAMS = gis_test wms_test
gis_test_SOURCES = gis_test.c gis.h
gis_test_LDFLAGS = -static
gis_test_LDADD = $(AM_LDADD) libgis.la
-# wms_test_SOURCES = wms_test.c gis-world.c gis-world.h
-# wms_test_LDADD = $(AM_LDADD)
+wms_test_SOURCES = wms_test.c gis-world.c gis-world.h gis-wms.c gis-wms.h gis-tile.c gis-tile.h
+wms_test_LDADD = $(AM_LDADD)
MAINTAINERCLEANFILES = Makefile.in
--- /dev/null
+/*
+ * Copyright (C) 2009 Andy Spencer <spenceal@rose-hulman.edu>
+ *
+ * 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.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <glib.h>
+
+#include "gis-world.h"
+#include "gis-tile.h"
+
+gchar *gis_tile_path_table[2][2] = {
+ {".00", ".01"},
+ {".10", ".11"},
+};
+
+GisTile *gis_tile_new(GisTile *parent,
+ gdouble n, gdouble s, gdouble e, gdouble w)
+{
+ GisTile *self = g_new0(GisTile, 1);
+ self->parent = parent;
+ self->edge.n = n;
+ self->edge.s = s;
+ self->edge.e = e;
+ self->edge.w = w;
+ return self;
+}
+
+gchar *gis_tile_get_path(GisTile *child)
+{
+ /* This could be easily cached if necessasairy */
+ int x, y;
+ GList *parts = NULL;
+ for (GisTile *parent = child->parent; parent; child = parent, parent = child->parent)
+ gis_tile_foreach_index(child, x, y)
+ if (parent->children[x][y] == child)
+ parts = g_list_prepend(parts, gis_tile_path_table[x][y]);
+ GString *path = g_string_new("");
+ for (; parts; parts = parts->next)
+ g_string_append(path, parts->data);
+ g_list_free(parts);
+ return g_string_free(path, FALSE);
+}
+
+
+void gis_tile_free(GisTile *self, GisTileFreeFunc free_func, gpointer user_data)
+{
+ if (!self)
+ return;
+ GisTile *child;
+ gis_tile_foreach(self, child)
+ gis_tile_free(child, free_func, user_data);
+ if (free_func)
+ free_func(self, user_data);
+ g_free(self);
+}
--- /dev/null
+/*
+ * Copyright (C) 2009 Andy Spencer <spenceal@rose-hulman.edu>
+ *
+ * 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.gnu.org/licenses/>.
+ */
+
+#ifndef __GIS_TILE_H__
+#define __GIS_TILE_H__
+
+#include <config.h>
+#include <glib.h>
+
+typedef struct _GisTile GisTile;
+
+#define gis_tile_foreach(tile, child) \
+ for (int _x = 0; _x < G_N_ELEMENTS(tile->children); _x++) \
+ for (int _y = 0; child = tile->children[_x][_y], \
+ _y < G_N_ELEMENTS(tile->children[_x]); _y++) \
+
+#define gis_tile_foreach_index(tile, x, y) \
+ for (x = 0; x < G_N_ELEMENTS(tile->children); x++) \
+ for (y = 0; y < G_N_ELEMENTS(tile->children[x]); y++)
+
+typedef void (*GisTileLoadFunc)(GisTile *tile, gpointer user_data);
+typedef void (*GisTileFreeFunc)(GisTile *tile, gpointer user_data);
+
+struct _GisTile {
+ /* Pointer to the tile data */
+ gpointer data;
+
+ /* North,South,East,West limits */
+ struct {
+ gdouble n,s,e,w;
+ } edge;
+
+ /* Pointers to parent/child nodes */
+ GisTile *parent;
+ GisTile *children[2][2];
+};
+
+/* Path to string table, keep in sync with tile->children */
+extern gchar *gis_tile_path_table[2][2];
+
+/* Allocate a new Tile */
+GisTile *gis_tile_new(GisTile *parent,
+ gdouble n, gdouble s, gdouble e, gdouble w);
+
+/* Return a string representation of the tile's path */
+gchar *gis_tile_get_path(GisTile *child);
+
+/* Free a tile and all it's children */
+void gis_tile_free(GisTile *root,
+ GisTileFreeFunc free_func, gpointer user_data);
+
+#endif
--- /dev/null
+/*
+ * Copyright (C) 2009 Andy Spencer <spenceal@rose-hulman.edu>
+ *
+ * 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.gnu.org/licenses/>.
+ */
+
+/**
+ * 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 <config.h>
+#include <stdio.h>
+#include <glib.h>
+
+#include "gis-wms.h"
+
+static gchar *_make_uri(GisWms *wms, GisTile *tile)
+{
+ return g_strdup_printf(
+ "%s?"
+ "SERVICE=WMS&"
+ "VERSION=1.1.0&"
+ "REQUEST=GetMap&"
+ "LAYERS=%s&"
+ "STYLES=&"
+ "SRS=EPSG:4326&"
+ "FORMAT=%s&"
+ "WIDTH=%d&"
+ "HEIGHT=%d&"
+ "BBOX=%f,%f,%f,%f",
+ wms->uri_prefix,
+ wms->uri_layer,
+ wms->uri_format,
+ wms->width,
+ wms->height,
+ tile->edge.w,
+ tile->edge.s,
+ tile->edge.e,
+ tile->edge.n);
+}
+
+void gis_wms_soup_chunk_cb(SoupMessage *message, SoupBuffer *chunk, gpointer _file)
+{
+ FILE *file = _file;
+ 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, file) != 1)
+ g_warning("GisWms: soup_chunk_cb - eror writing data");
+}
+
+char *gis_wms_make_local(GisWms *self, GisTile *tile)
+{
+ /* Get file path */
+ gchar *tile_path = gis_tile_get_path(tile);
+ gchar *path = g_strdup_printf("%s/wms/%s%s%s",
+ g_get_user_cache_dir(),
+ self->cache_prefix,
+ tile_path,
+ self->cache_ext);
+ g_free(tile_path);
+
+ /* Return if it already exists */
+ if (g_file_test(path, G_FILE_TEST_EXISTS))
+ return path;
+
+ /* Open temp file for writing */
+ gchar *tmp_path = g_strconcat(path, ".part", NULL);
+ gchar *dirname = g_path_get_dirname(tmp_path);
+ g_mkdir_with_parents(dirname, 0755);
+ g_free(dirname);
+ FILE *file = fopen(tmp_path, "a");
+
+ /* Download file */
+ gchar *uri = _make_uri(self, tile);
+ SoupMessage *message = soup_message_new("GET", uri);
+ g_signal_connect(message, "got-chunk", G_CALLBACK(gis_wms_soup_chunk_cb), file);
+ soup_message_headers_set_range(message->request_headers, ftell(file), -1);
+ int status = soup_session_send_message(self->soup, message);
+ g_free(uri);
+
+ /* Clean up */
+ fclose(file);
+ rename(tmp_path, path);
+ g_free(tmp_path);
+ return path;
+}
+
+GisWms *gis_wms_new(
+ gchar *uri_prefix, gchar *uri_layer, gchar *uri_format,
+ gchar *cache_prefix, gchar *cache_ext,
+ gint width, gint height)
+{
+ GisWms *self = g_new0(GisWms, 1);
+ 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->width = width;
+ self->height = height;
+ self->soup = soup_session_sync_new();
+ return self;
+}
+
+void gis_wms_free(GisWms *self)
+{
+ g_object_unref(self->soup);
+ g_free(self);
+}
--- /dev/null
+/*
+ * Copyright (C) 2009 Andy Spencer <spenceal@rose-hulman.edu>
+ *
+ * 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.gnu.org/licenses/>.
+ */
+
+#ifndef __GIS_WMS_H__
+#define __GIS_WMS_H__
+
+#include <config.h>
+#include <glib.h>
+#include <libsoup/soup.h>
+
+#include "gis-tile.h"
+
+typedef struct _GisWms GisWms;
+
+struct _GisWms {
+ gchar *uri_prefix;
+ gchar *uri_layer;
+ gchar *uri_format;
+ gchar *cache_prefix;
+ gchar *cache_ext;
+ gint width;
+ gint height;
+ SoupSession *soup;
+};
+
+char *gis_wms_make_local(GisWms *wms, GisTile *tile);
+
+GisWms *gis_wms_new(
+ gchar *uri_prefix, gchar *uri_layer, gchar *uri_format,
+ gchar *cache_prefix, gchar *cache_ext,
+ gint width, gint height);
+
+void gis_wms_free(GisWms *self);
+
+#endif
#define EARTH_R (6371000)
#define EARTH_C (2*M_PI*EARTH_R)
+#define NORTH 90
+#define SOUTH -90
+#define EAST 180
+#define WEST -180
/**
* Terms
/* GIS helprs */
#include "gis-data.h"
+#include "gis-tile.h"
+#include "gis-wms.h"
/* Plugins */
#include "gis-plugin.h"
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
-#include "wms.h"
+#include "gis-world.h"
+#include "gis-tile.h"
+#include "gis-wms.h"
struct CacheState {
GtkWidget *image;
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)
{
gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(state->progress), (gdouble)cur/total);
}
+gpointer do_cache(gpointer _image)
+{
+ GtkImage *image = _image;
+ g_message("Creating tile");
+ GisTile *tile = gis_tile_new(NULL, NORTH, SOUTH, EAST, WEST);
+ tile->children[0][1] = gis_tile_new(tile, NORTH, 0, 0, WEST);
+ tile = tile->children[0][1];
+
+ g_message("Fetching image");
+ GisWms *bmng_wms = gis_wms_new(
+ "http://www.nasa.network.com/wms", "bmng200406", "image/jpeg",
+ "bmng", ".jpg", 512, 256);
+ const char *path = gis_wms_make_local(bmng_wms, tile);
+
+ g_message("Loading image: [%s]", path);
+ GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(path, NULL);
+ gdk_threads_enter();
+ gtk_image_set_from_pixbuf(GTK_IMAGE(image), pixbuf);
+ gdk_threads_leave();
+
+ g_message("Cleaning up");
+ gis_wms_free(bmng_wms);
+ gis_tile_free(tile, NULL, NULL);
+ return NULL;
+}
+
gboolean key_press_cb(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
{
if (event->keyval == GDK_q)
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);
+ g_thread_create(do_cache, bmng_image, FALSE, NULL);
gtk_widget_show_all(win);
gtk_main();
- wms_info_free(bmng_info);
- wms_info_free(srtm_info);
-
return 0;
}