1 /*
2  * Copyright (C) 2010-2013 Jiri Techet <techet@gmail.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17  */
18 
19 /**
20  * SECTION:champlain-tile-cache
21  * @short_description: A base class of tile caches
22  *
23  * This class defines properties and methods commons to all caches (that is, map
24  * sources that permit storage and retrieval of tiles). Tiles are typically
25  * stored by #ChamplainTileSource objects.
26  */
27 
28 #include "champlain-tile-cache.h"
29 
30 G_DEFINE_ABSTRACT_TYPE (ChamplainTileCache, champlain_tile_cache, CHAMPLAIN_TYPE_MAP_SOURCE)
31 
32 
33 static const gchar *get_id (ChamplainMapSource * map_source);
34 static const gchar *get_name (ChamplainMapSource *map_source);
35 static const gchar *get_license (ChamplainMapSource *map_source);
36 static const gchar *get_license_uri (ChamplainMapSource *map_source);
37 static guint get_min_zoom_level (ChamplainMapSource *map_source);
38 static guint get_max_zoom_level (ChamplainMapSource *map_source);
39 static guint get_tile_size (ChamplainMapSource *map_source);
40 static ChamplainMapProjection get_projection (ChamplainMapSource *map_source);
41 
42 
43 static void
champlain_tile_cache_dispose(GObject * object)44 champlain_tile_cache_dispose (GObject *object)
45 {
46   G_OBJECT_CLASS (champlain_tile_cache_parent_class)->dispose (object);
47 }
48 
49 
50 static void
champlain_tile_cache_finalize(GObject * object)51 champlain_tile_cache_finalize (GObject *object)
52 {
53   G_OBJECT_CLASS (champlain_tile_cache_parent_class)->finalize (object);
54 }
55 
56 
57 static void
champlain_tile_cache_constructed(GObject * object)58 champlain_tile_cache_constructed (GObject *object)
59 {
60   G_OBJECT_CLASS (champlain_tile_cache_parent_class)->constructed (object);
61 }
62 
63 
64 static void
champlain_tile_cache_class_init(ChamplainTileCacheClass * klass)65 champlain_tile_cache_class_init (ChamplainTileCacheClass *klass)
66 {
67   GObjectClass *object_class = G_OBJECT_CLASS (klass);
68   ChamplainMapSourceClass *map_source_class = CHAMPLAIN_MAP_SOURCE_CLASS (klass);
69   ChamplainTileCacheClass *tile_cache_class = CHAMPLAIN_TILE_CACHE_CLASS (klass);
70 
71   object_class->finalize = champlain_tile_cache_finalize;
72   object_class->dispose = champlain_tile_cache_dispose;
73   object_class->constructed = champlain_tile_cache_constructed;
74 
75   map_source_class->get_id = get_id;
76   map_source_class->get_name = get_name;
77   map_source_class->get_license = get_license;
78   map_source_class->get_license_uri = get_license_uri;
79   map_source_class->get_min_zoom_level = get_min_zoom_level;
80   map_source_class->get_max_zoom_level = get_max_zoom_level;
81   map_source_class->get_tile_size = get_tile_size;
82   map_source_class->get_projection = get_projection;
83 
84   map_source_class->fill_tile = NULL;
85 
86   tile_cache_class->refresh_tile_time = NULL;
87   tile_cache_class->on_tile_filled = NULL;
88   tile_cache_class->store_tile = NULL;
89 }
90 
91 
92 static void
champlain_tile_cache_init(ChamplainTileCache * tile_cache)93 champlain_tile_cache_init (ChamplainTileCache *tile_cache)
94 {
95 }
96 
97 
98 /**
99  * champlain_tile_cache_store_tile:
100  * @tile_cache: a #ChamplainTileCache
101  * @tile: a #ChamplainTile
102  * @contents: the tile contents that should be stored
103  * @size: size of the contents in bytes
104  *
105  * Stores the tile including the metadata into the cache.
106  *
107  * Since: 0.6
108  */
109 void
champlain_tile_cache_store_tile(ChamplainTileCache * tile_cache,ChamplainTile * tile,const gchar * contents,gsize size)110 champlain_tile_cache_store_tile (ChamplainTileCache *tile_cache,
111     ChamplainTile *tile,
112     const gchar *contents,
113     gsize size)
114 {
115   g_return_if_fail (CHAMPLAIN_IS_TILE_CACHE (tile_cache));
116 
117   CHAMPLAIN_TILE_CACHE_GET_CLASS (tile_cache)->store_tile (tile_cache, tile, contents, size);
118 }
119 
120 
121 /**
122  * champlain_tile_cache_refresh_tile_time:
123  * @tile_cache: a #ChamplainTileCache
124  * @tile: a #ChamplainTile
125  *
126  * Refreshes the tile access time in the cache.
127  *
128  * Since: 0.6
129  */
130 void
champlain_tile_cache_refresh_tile_time(ChamplainTileCache * tile_cache,ChamplainTile * tile)131 champlain_tile_cache_refresh_tile_time (ChamplainTileCache *tile_cache,
132     ChamplainTile *tile)
133 {
134   g_return_if_fail (CHAMPLAIN_IS_TILE_CACHE (tile_cache));
135 
136   CHAMPLAIN_TILE_CACHE_GET_CLASS (tile_cache)->refresh_tile_time (tile_cache, tile);
137 }
138 
139 
140 /**
141  * champlain_tile_cache_on_tile_filled:
142  * @tile_cache: a #ChamplainTileCache
143  * @tile: a #ChamplainTile
144  *
145  * When a cache fills a tile and the next source in the chain is a tile cache,
146  * it should call this function on the next source. This way all the caches
147  * preceding a tile source in the chain get informed that the tile was used and
148  * can modify their metadata accordingly in the implementation of this function.
149  * In addition, the call of this function should be chained so within the
150  * implementation of this function it should be called on the next source
151  * in the chain when next source is a tile cache.
152  *
153  * Since: 0.6
154  */
155 void
champlain_tile_cache_on_tile_filled(ChamplainTileCache * tile_cache,ChamplainTile * tile)156 champlain_tile_cache_on_tile_filled (ChamplainTileCache *tile_cache,
157     ChamplainTile *tile)
158 {
159   g_return_if_fail (CHAMPLAIN_IS_TILE_CACHE (tile_cache));
160 
161   CHAMPLAIN_TILE_CACHE_GET_CLASS (tile_cache)->on_tile_filled (tile_cache, tile);
162 }
163 
164 
165 static const gchar *
get_id(ChamplainMapSource * map_source)166 get_id (ChamplainMapSource *map_source)
167 {
168   g_return_val_if_fail (CHAMPLAIN_IS_TILE_CACHE (map_source), NULL);
169 
170   ChamplainMapSource *next_source = champlain_map_source_get_next_source (map_source);
171 
172   g_return_val_if_fail (CHAMPLAIN_IS_MAP_SOURCE (next_source), NULL);
173 
174   return champlain_map_source_get_id (next_source);
175 }
176 
177 
178 static const gchar *
get_name(ChamplainMapSource * map_source)179 get_name (ChamplainMapSource *map_source)
180 {
181   g_return_val_if_fail (CHAMPLAIN_IS_TILE_CACHE (map_source), NULL);
182 
183   ChamplainMapSource *next_source = champlain_map_source_get_next_source (map_source);
184 
185   g_return_val_if_fail (CHAMPLAIN_IS_MAP_SOURCE (next_source), NULL);
186 
187   return champlain_map_source_get_name (next_source);
188 }
189 
190 
191 static const gchar *
get_license(ChamplainMapSource * map_source)192 get_license (ChamplainMapSource *map_source)
193 {
194   g_return_val_if_fail (CHAMPLAIN_IS_TILE_CACHE (map_source), NULL);
195 
196   ChamplainMapSource *next_source = champlain_map_source_get_next_source (map_source);
197 
198   g_return_val_if_fail (CHAMPLAIN_IS_MAP_SOURCE (next_source), NULL);
199 
200   return champlain_map_source_get_license (next_source);
201 }
202 
203 
204 static const gchar *
get_license_uri(ChamplainMapSource * map_source)205 get_license_uri (ChamplainMapSource *map_source)
206 {
207   g_return_val_if_fail (CHAMPLAIN_IS_TILE_CACHE (map_source), NULL);
208 
209   ChamplainMapSource *next_source = champlain_map_source_get_next_source (map_source);
210 
211   g_return_val_if_fail (CHAMPLAIN_IS_MAP_SOURCE (next_source), NULL);
212 
213   return champlain_map_source_get_license_uri (next_source);
214 }
215 
216 
217 static guint
get_min_zoom_level(ChamplainMapSource * map_source)218 get_min_zoom_level (ChamplainMapSource *map_source)
219 {
220   g_return_val_if_fail (CHAMPLAIN_IS_TILE_CACHE (map_source), 0);
221 
222   ChamplainMapSource *next_source = champlain_map_source_get_next_source (map_source);
223 
224   g_return_val_if_fail (CHAMPLAIN_IS_MAP_SOURCE (next_source), 0);
225 
226   return champlain_map_source_get_min_zoom_level (next_source);
227 }
228 
229 
230 static guint
get_max_zoom_level(ChamplainMapSource * map_source)231 get_max_zoom_level (ChamplainMapSource *map_source)
232 {
233   g_return_val_if_fail (CHAMPLAIN_IS_TILE_CACHE (map_source), 0);
234 
235   ChamplainMapSource *next_source = champlain_map_source_get_next_source (map_source);
236 
237   g_return_val_if_fail (CHAMPLAIN_IS_MAP_SOURCE (next_source), 0);
238 
239   return champlain_map_source_get_max_zoom_level (next_source);
240 }
241 
242 
243 static guint
get_tile_size(ChamplainMapSource * map_source)244 get_tile_size (ChamplainMapSource *map_source)
245 {
246   g_return_val_if_fail (CHAMPLAIN_IS_TILE_CACHE (map_source), 0);
247 
248   ChamplainMapSource *next_source = champlain_map_source_get_next_source (map_source);
249 
250   g_return_val_if_fail (CHAMPLAIN_IS_MAP_SOURCE (next_source), 0);
251 
252   return champlain_map_source_get_tile_size (next_source);
253 }
254 
255 
256 static ChamplainMapProjection
get_projection(ChamplainMapSource * map_source)257 get_projection (ChamplainMapSource *map_source)
258 {
259   g_return_val_if_fail (CHAMPLAIN_IS_TILE_CACHE (map_source), CHAMPLAIN_MAP_PROJECTION_MERCATOR);
260 
261   ChamplainMapSource *next_source = champlain_map_source_get_next_source (map_source);
262 
263   g_return_val_if_fail (CHAMPLAIN_IS_MAP_SOURCE (next_source), CHAMPLAIN_MAP_PROJECTION_MERCATOR);
264 
265   return champlain_map_source_get_projection (next_source);
266 }
267