#endif
#include "tilerepo.h"
-
-#include "image-cache.h"
#include "latlon.h"
#include "gtkmap.h"
#define MARKER_FONT_SIZE_BIG (10)
#define MARKER_FONT_SIZE_SMALL (8)
-/* Filename buffer */
-#define BUFFER_SIZE (2048)
-
#define SCALE_WIDTH (256)
#define MAP_CACHE_DEFAULT (64)
guint center_mark_size;
GdkRectangle center_rect;
- RepoData *curr_repo;
+ TileRepo *curr_repo;
GTimer *timer;
- ImageCache *icache;
GSList *markers;
GtkListStore *marker_store;
priv->center_mark_size=8;
-priv->icache=image_cache_new(64);
-
priv->show_scale=TRUE;
priv->show_velvec=TRUE;
priv->show_markers=TRUE;
while ((dest_dim >>= ratio_p2) > 1);
}
-static GdkPixbuf *
-gtk_map_tile_load(GtkWidget *widget, guint tilex, guint tiley, gint zoff, gboolean fast_fail)
+
+/**
+ * gtk_map_set_tile_repository:
+ *
+ * Set the map bitmap tile repository object to use. The map does not in itself
+ * handle downloading of loading of bitmaps. The repository object does that.
+ *
+ */
+void
+gtk_map_set_tile_repository(GtkWidget *widget, TileRepo *rd)
{
GtkMap *map;
GtkMapPriv *priv;
-GdkPixbuf *pixbuf;
-GError *error = NULL;
-gchar buffer[BUFFER_SIZE];
-gchar key[BUFFER_SIZE];
-struct stat tstat;
-gint se;
-g_return_val_if_fail(GTK_IS_MAP(widget), FALSE);
+g_return_if_fail(GTK_IS_MAP(widget));
map=GTK_MAP(widget);
priv=GTK_MAP_GET_PRIVATE(map);
-g_snprintf(buffer, sizeof(buffer), "%s/%u/%u/%u.jpg", priv->curr_repo->cache_dir, priv->zoom + zoff, (tilex >> zoff), (tiley >> zoff));
-g_snprintf(key, sizeof(key), "%s/%u/%u/%u", priv->curr_repo->cache_dir, priv->zoom + zoff, (tilex >> zoff), (tiley >> zoff));
-
-g_debug("LOAD: %u, %u @ (%d+%d): %s", tilex, tiley, priv->zoom, zoff, buffer);
-
-pixbuf=image_cache_get(priv->icache, key, buffer);
-if (!pixbuf) {
- g_unlink(buffer);
-#if 0
- if (_auto_download && _curr_repo->type != REPOTYPE_NONE && !((_zoom + zoff - (_curr_repo->double_size ? 1 : 0)) % _curr_repo->dl_zoom_steps)) {
- if (download)
- map_initiate_download(tilex >> zoff, tiley >> zoff, _zoom + zoff, -INITIAL_DOWNLOAD_RETRIES);
- }
-#endif
- return NULL;
-}
-
-g_object_ref(pixbuf);
-
-#if 0
-/* Check if we need to trim. */
-if (gdk_pixbuf_get_width(pixbuf) != TILE_SIZE_PIXELS || gdk_pixbuf_get_height(pixbuf) != TILE_SIZE_PIXELS)
- pixbuf=pixbuf_trim(pixbuf);
-#endif
+g_return_if_fail(rd);
-#if 0
-/* Check tile age, if file date is ower a week old, redownload if autodownload enabled */
-se=stat(buffer, &tstat);
-if (se==0) {
- time_t t;
- t=time(NULL);
- if (t-tstat.st_mtime>TILE_MAX_AGE) {
- if (_auto_download && _curr_repo->type != REPOTYPE_NONE && !((_zoom + zoff - (_curr_repo->double_size ? 1 : 0)) % _curr_repo->dl_zoom_steps)) {
- if (download) {
- g_debug("Tile: %s is old, re-downloading\n", buffer);
- map_initiate_download(tilex >> zoff, tiley >> zoff, _zoom + zoff, -INITIAL_DOWNLOAD_RETRIES);
- image_cache_invalidate(map_ic, key);
- }
- }
- }
-}
-#endif
+priv->curr_repo=rd;
-return pixbuf;
+gtk_map_refresh(widget);
}
/**
- * gtk_map_set_tile_repository:
- *
- * Set the map bitmap tile repository object to use. The map does not in itself
- * handle downloading of loading of bitmaps. The repository object does that.
+ * gtk_map_get_tile_reposotory:
*
+ * Get the active map tile repository object.
*/
-void
-gtk_map_set_tile_repository(GtkWidget *widget, RepoData *rd)
+TileRepo *
+gtk_map_get_tile_repository(GtkWidget *widget)
{
GtkMap *map;
GtkMapPriv *priv;
map=GTK_MAP(widget);
priv=GTK_MAP_GET_PRIVATE(map);
-g_return_if_fail(rd);
+return priv->curr_repo;
+}
-priv->curr_repo=rd;
+static void
+gtk_map_render_empty_tile(GtkWidget *widget, guint destx, guint desty)
+{
+GtkMap *map;
+GtkMapPriv *priv;
-gtk_map_refresh(widget);
-}
+g_return_val_if_fail(GTK_IS_MAP(widget), FALSE);
+map=GTK_MAP(widget);
+priv=GTK_MAP_GET_PRIVATE(map);
+gdk_draw_rectangle(priv->buffer, widget->style->black_gc, TRUE, destx, desty, GTK_MAP_TILE_SIZE_PIXELS, GTK_MAP_TILE_SIZE_PIXELS);
+}
/**
* gtk_map_render_tile:
priv->world_size_tiles, destx, desty, priv->buf_width_tiles, priv->buf_height_tiles);
g_return_val_if_fail(priv->buffer, FALSE);
-g_return_val_if_fail(priv->curr_repo, FALSE);
+
+if (priv->curr_repo==NULL) {
+ gtk_map_render_empty_tile(widget, destx, desty);
+ return FALSE;
+}
if (destx > priv->buf_width_pixels || desty > priv->buf_height_pixels)
return FALSE;
return FALSE;
for (zoff = (priv->curr_repo->double_size ? 1 : 0); !pixbuf && (priv->zoom + zoff) <= priv->max_zoom && zoff <= GTK_MAP_TILE_SIZE_P2; zoff += 1) {
- pixbuf=gtk_map_tile_load(GTK_WIDGET(map), tilex, tiley, zoff, !fast_fail);
+ pixbuf=tile_repo_load(priv->curr_repo, tilex, tiley, priv->zoom, zoff, !fast_fail);
if (!pixbuf) {
if (!fast_fail)
fast_fail=TRUE;
gtk_map_pixbuf_scale_inplace(pixbuf, zoff,
(tilex - ((tilex >> zoff) << zoff)) << (GTK_MAP_TILE_SIZE_P2 - zoff),
(tiley - ((tiley >> zoff) << zoff)) << (GTK_MAP_TILE_SIZE_P2 - zoff));
- image_cache_invalidate_by_image(priv->icache, pixbuf);
}
}
}
return TRUE;
}
-gdk_draw_rectangle(priv->buffer, widget->style->black_gc, TRUE, destx, desty, GTK_MAP_TILE_SIZE_PIXELS, GTK_MAP_TILE_SIZE_PIXELS);
+gtk_map_render_empty_tile(widget, destx, desty);
return FALSE;
}
priv=GTK_MAP_GET_PRIVATE(map);
if (cache_size>512)
cache_size=512;
-image_cache_set_size(priv->icache, cache_size);
+/* XXX Set repo cache size */
}
/******************************************************************************/
void gtk_map_refresh(GtkWidget *map);
/* Map repository handling */
-void gtk_map_set_tile_repository(GtkWidget *map, RepoData *rd);
+void gtk_map_set_tile_repository(GtkWidget *map, TileRepo *rd);
+TileRepo *gtk_map_get_tile_repository(GtkWidget *map);
/* Markers */
gboolean gtk_map_markers_add(GtkWidget *map, GtkMapMarkerType type, GtkListStore *store);
GtkWidget *window, *wvbox;
GtkWidget *hbox, *zoomer, *btn_left, *btn_right, *btn_up, *btn_down, *vbox;
GtkWidget *rotate;
-RepoData *rd;
+TileRepo *rd;
gint t;
gdouble slat, slon;
wvbox=gtk_vbox_new(FALSE, 3);
gtk_container_add(GTK_CONTAINER(window), wvbox);
-rd=map_tile_repo_new();
+rd=tile_repo_new();
rd->view_zoom_steps=1;
rd->cache_dir=TESTREPO;
/*
* This file is part of mapper
*
- * Copyright (C) 2007 Kaj-Michael Lang
+ * Copyright (C) 2007-2008 Kaj-Michael Lang
* Copyright (C) 2006-2007 John Costigan.
*
* This program is free software; you can redistribute it and/or modify
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
+#include <glib/gstdio.h>
+
#include <glib.h>
+#include <glib-object.h>
#include "tilerepo.h"
+#include "image-cache.h"
+
+G_DEFINE_TYPE(TileRepo, tile_repo, G_TYPE_OBJECT);
+
+/* Filename buffer */
+#define BUFFER_SIZE (2048)
+
+#if 0
+#define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), TILE_REPO_TYPE, TileRepoPrivate))
+#endif
+
+static void
+tile_repo_dispose(GObject *object)
+{
+G_OBJECT_CLASS(tile_repo_parent_class)->dispose(object);
+}
+
+static void
+tile_repo_finalize(GObject *object)
+{
+TileRepo *tr=TILE_REPO(object);
+}
+
+static void
+tile_repo_class_init(TileRepoClass *klass)
+{
+GObjectClass *object_class=G_OBJECT_CLASS(klass);
+
+object_class->dispose=tile_repo_dispose;
+object_class->finalize=tile_repo_finalize;
+}
/**
- * map_tile_repo_new:
+ * tile_repo_new:
*
- * Create a new empty Map image tile repository structure.
+ * Create a new empty Map image tile repository.
*
*/
-RepoData *
-map_tile_repo_new(void)
+TileRepo *
+tile_repo_new(void)
{
-RepoData *rd;
-rd=g_new0(RepoData, 1);
-rd->min_zoom=0;
-rd->max_zoom=17;
-return rd;
+return g_object_new(TILE_REPO_TYPE, NULL);
+}
+
+static void
+tile_repo_init(TileRepo *tr)
+{
+tr->min_zoom=0;
+tr->max_zoom=17;
+tr->view_zoom_steps=1;
+tr->icache=image_cache_new(64);
}
/**
- * map_tile_repo_new_from_string:
+ * tile_repo_new_from_string:
* @str
*
* Create a new Map image tile repository structure by filling in values from given configuration string.
*
*/
-RepoData *
-map_tile_repo_new_from_string(gchar *str)
+TileRepo *
+tile_repo_new_from_string(gchar *str)
{
gchar *token, *error_check;
-RepoData *rd;
+TileRepo *tr;
/* Parse each part of a repo, delimited by newline characters:
* 1. name
* 5. view_zoom_steps
*/
-rd=map_tile_repo_new();
+tr=tile_repo_new();
+g_return_val_if_fail(tr, NULL);
/* Parse name. */
-token = strsep(&str, "\n\t");
+token=strsep(&str, "\n\t");
if (token)
- rd->name = g_strdup(token);
+ tr->name = g_strdup(token);
/* Parse URL format. */
-token = strsep(&str, "\n\t");
+token=strsep(&str, "\n\t");
if (token)
- rd->url = g_strdup(token);
+ tr->url = g_strdup(token);
/* Parse cache dir. */
-token = strsep(&str, "\n\t");
+token=strsep(&str, "\n\t");
if (token)
- rd->cache_dir = gnome_vfs_expand_initial_tilde(token);
+ tr->cache_dir=gnome_vfs_expand_initial_tilde(token);
/* Parse download zoom steps. */
-token = strsep(&str, "\n\t");
-if (!token || !*token || !(rd->dl_zoom_steps = atoi(token)))
- rd->dl_zoom_steps = 1;
+token=strsep(&str, "\n\t");
+if (!token || !*token || !(tr->dl_zoom_steps=atoi(token)))
+ tr->dl_zoom_steps=1;
/* Parse view zoom steps. */
-token = strsep(&str, "\n\t");
-if (!token || !*token || !(rd->view_zoom_steps = atoi(token)))
- rd->view_zoom_steps = 1;
+token=strsep(&str, "\n\t");
+if (!token || !*token || !(tr->view_zoom_steps=atoi(token)))
+ tr->view_zoom_steps=1;
/* Parse double-size. */
-token = strsep(&str, "\n\t");
+token=strsep(&str, "\n\t");
if (token)
- rd->double_size = atoi(token); /* Default is zero (FALSE) */
+ tr->double_size=atoi(token); /* Default is zero (FALSE) */
/* Parse next-able. */
token = strsep(&str, "\n\t");
-if (!token || !*token || (rd->nextable = strtol(token, &error_check, 10), token == str))
- rd->nextable = TRUE;
+if (!token || !*token || (tr->nextable=strtol(token, &error_check, 10), token == str))
+ tr->nextable = TRUE;
-map_tile_repo_set_type(rd);
-return rd;
+tile_repo_set_type(tr);
+return tr;
}
/**
- * map_tile_repo_free:
- * @rd
+ * tile_repo_free:
+ * @tr
*
* Free a map image tile repository
*/
void
-map_tile_repo_free(RepoData *rd)
+tile_repo_free(TileRepo *tr)
{
-if (rd->name)
- g_free(rd->name);
-if (rd->url)
- g_free(rd->url);
-if (rd->cache_dir)
- g_free(rd->cache_dir);
-
-g_free(rd);
+g_return_if_fail(tr);
+if (tr->name)
+ g_free(tr->name);
+if (tr->url)
+ g_free(tr->url);
+if (tr->cache_dir)
+ g_free(tr->cache_dir);
+if (tr->icache)
+ image_cache_free(tr->icache);
+
+g_object_unref(tr);
}
void
-map_tile_repo_set_type(RepoData *rd)
+tile_repo_set_type(TileRepo *tr)
{
-if (rd->url && *rd->url) {
- gchar *url = g_utf8_strdown(rd->url, -1);
+g_return_if_fail(tr);
+
+if (tr->url && *tr->url) {
+ gchar *url = g_utf8_strdown(tr->url, -1);
/* Determine type of repository. */
if (strstr(url, "service=wms"))
- rd->type = REPOTYPE_WMS;
+ tr->type = REPOTYPE_WMS;
else if (strstr(url, "%s"))
- rd->type = REPOTYPE_QUAD_QRST;
+ tr->type = REPOTYPE_QUAD_QRST;
else if (strstr(url, "%0d"))
- rd->type = REPOTYPE_XYZ_INV;
+ tr->type = REPOTYPE_XYZ_INV;
else if (strstr(url, "%0s"))
- rd->type = REPOTYPE_QUAD_ZERO;
+ tr->type = REPOTYPE_QUAD_ZERO;
else
- rd->type = REPOTYPE_XYZ;
+ tr->type = REPOTYPE_XYZ;
g_free(url);
} else
- rd->type = REPOTYPE_NONE;
+ tr->type = REPOTYPE_NONE;
}
gboolean
-map_tile_repo_make_cache_dir(RepoData *rd)
+tile_repo_make_cache_dir(TileRepo *tr)
{
-if (g_mkdir_with_parents(rd->cache_dir, 0755))
+if (g_mkdir_with_parents(tr->cache_dir, 0755))
return FALSE;
-return g_file_test(rd->cache_dir, G_FILE_TEST_EXISTS);
+return g_file_test(tr->cache_dir, G_FILE_TEST_EXISTS);
}
+
+GdkPixbuf *
+tile_repo_load(TileRepo *tr, guint tilex, guint tiley, gint zoom, gint zoff, gboolean fast_fail)
+{
+GdkPixbuf *pixbuf;
+GError *error = NULL;
+gchar buffer[BUFFER_SIZE];
+gchar key[BUFFER_SIZE];
+struct stat tstat;
+gint se;
+
+g_snprintf(buffer, sizeof(buffer), "%s/%u/%u/%u.jpg", tr->cache_dir, zoom + zoff, (tilex >> zoff), (tiley >> zoff));
+g_snprintf(key, sizeof(key), "%s/%u/%u/%u", tr->cache_dir, zoom + zoff, (tilex >> zoff), (tiley >> zoff));
+
+g_debug("LOAD: %u, %u @ (%d+%d): %s", tilex, tiley, zoom, zoff, buffer);
+
+pixbuf=image_cache_get(tr->icache, key, buffer);
+if (!pixbuf) {
+ g_unlink(buffer);
+#if 0
+ if (tr->auto_download && tr->type!=REPOTYPE_NONE && !((zoom + zoff - (tr->double_size ? 1 : 0)) % tr->dl_zoom_steps)) {
+ if (download)
+ tile_repo_initiate_download(tilex >> zoff, tiley >> zoff, zoom + zoff, -INITIAL_DOWNLOAD_RETRIES);
+ }
+#endif
+ return NULL;
+}
+
+g_object_ref(pixbuf);
+
+#if 0
+/* Check if we need to trim. */
+if (gdk_pixbuf_get_width(pixbuf) != TILE_SIZE_PIXELS || gdk_pixbuf_get_height(pixbuf) != TILE_SIZE_PIXELS)
+ pixbuf=pixbuf_trim(pixbuf);
+#endif
+
+#if 0
+/* Check tile age, if file date is ower a week old, redownload if autodownload enabled */
+se=stat(buffer, &tstat);
+if (se==0 && tr->auto_update) {
+ time_t t;
+ t=time(NULL);
+ if (t-tstat.st_mtime>tr->tile_max_age) {
+ if (tr->auto_download && tr->type!=REPOTYPE_NONE && !((zoom + zoff - (tr->double_size ? 1 : 0)) % tr->dl_zoom_steps)) {
+ if (download) {
+ g_debug("Tile: %s is old, re-downloading\n", buffer);
+ tile_repo_initiate_download(tilex >> zoff, tiley >> zoff, _zoom + zoff, -INITIAL_DOWNLOAD_RETRIES);
+ image_cache_invalidate(map_ic, key);
+ }
+ }
+ }
+}
+#endif
+
+return pixbuf;
+}
+
+/*
+ * This file is part of mapper
+ *
+ * Copyright (C) 2007-2008 Kaj-Michael Lang
+ * Copyright (C) 2006-2007 John Costigan.
+ *
+ * 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 2 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, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
#ifndef _MAP_TILE_REPO_H
#define _MAP_TILE_REPO_H
#include <glib.h>
#include <gtk/gtk.h>
+#include "image-cache.h"
+
+G_BEGIN_DECLS
+
+#define TILE_REPO_TYPE (tile_repo_get_type ())
+#define TILE_REPO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TILE_REPO_TYPE, TileRepo))
+#define TILE_REPO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TILE_REPO_TYPE, TileRepoClass))
+#define IS_TILE_REPO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TILE_REPO_TYPE))
+#define IS_TILE_REPO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TILE_REPO_TYPE))
+#define TILE_REPO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), TILE_REPO_TYPE, TileRepoClass))
+
/** This enumerated type defines the supported types of repositories. */
typedef enum {
REPOTYPE_NONE, /* No URL set. */
REPOTYPE_WMS /* "service=wms" */
} RepoType;
-/** Data regarding a map repository. */
-typedef struct _RepoData RepoData;
-struct _RepoData {
+typedef struct _TileRepo TileRepo;
+struct _TileRepo {
+ GObject parent;
+ /* */
gchar *name;
gchar *url;
gchar *cache_dir;
guint max_zoom;
gboolean double_size;
gboolean nextable;
+ ImageCache *icache;
RepoType type;
GtkWidget *menu_item;
};
-RepoData *map_tile_repo_new(void);
-RepoData *map_tile_repo_new_from_string(gchar *str);
-void map_tile_repo_free(RepoData *rd);
-void map_tile_repo_set_type(RepoData *rd);
+/** Data regarding a map repository. */
+typedef struct _TileRepoClass TileRepoClass;
+struct _TileRepoClass {
+ GObjectClass parent;
+};
+
+TileRepo *tile_repo_new(void);
+TileRepo *tile_repo_new_from_string(gchar *str);
+void tile_repo_free(TileRepo *tr);
+void tile_repo_set_type(TileRepo *tr);
+GdkPixbuf *tile_repo_load(TileRepo *tr, guint tilex, guint tiley, gint zoom, gint zoff, gboolean fast_fail);
+
+G_END_DECLS
#endif