Branch data Line data Source code
1 : : /*
2 : : * Copyright 2021 Collabora Ltd. (https://collabora.com)
3 : : * Copyright 2021 Corentin Noël <corentin.noel@collabora.com>
4 : : * Copyright 2009 Pierre-Luc Beaudoin <pierre-luc@pierlux.com>
5 : : * Copyright 2010-2013 Jiri Techet <techet@gmail.com>
6 : : * Copyright 2019 Marcus Lundblad <ml@update.uu.se>
7 : : *
8 : : * This library is free software; you can redistribute it and/or
9 : : * modify it under the terms of the GNU Lesser General Public
10 : : * License as published by the Free Software Foundation; either
11 : : * version 2.1 of the License, or (at your option) any later version.
12 : : *
13 : : * This library is distributed in the hope that it will be useful,
14 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 : : * Lesser General Public License for more details.
17 : : *
18 : : * You should have received a copy of the GNU Lesser General Public
19 : : * License along with this library; if not, write to the Free Software
20 : : * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 : : */
22 : :
23 : : /**
24 : : * ShumateMapSourceRegistry:
25 : : *
26 : : * This object allows you to hold [class@MapSource] instances, you can access a
27 : : * default set of sources with [method@MapSourceRegistry.populate_defaults].
28 : : *
29 : : * It conveniently implements [iface@Gio.ListModel] to easily integrate with it.
30 : : */
31 : :
32 : : #include "shumate-map-source-registry.h"
33 : :
34 : : #include <gio/gio.h>
35 : :
36 : : #include "shumate-raster-renderer.h"
37 : : #include "shumate-tile-downloader.h"
38 : :
39 : : struct _ShumateMapSourceRegistry
40 : : {
41 : : GObject parent_instance;
42 : :
43 : : GPtrArray *map_sources;
44 : : };
45 : :
46 : : static void shumate_map_source_registry_list_model_init (GListModelInterface *iface);
47 : :
48 [ + + + - ]: 45 : G_DEFINE_TYPE_WITH_CODE (ShumateMapSourceRegistry, shumate_map_source_registry, G_TYPE_OBJECT,
49 : : G_IMPLEMENT_INTERFACE(G_TYPE_LIST_MODEL, shumate_map_source_registry_list_model_init))
50 : :
51 : : static gboolean
52 : 111 : shumate_map_source_registry_find_by_id (ShumateMapSource *map_source,
53 : : const gchar *id)
54 : : {
55 : 111 : return g_strcmp0 (shumate_map_source_get_id (map_source), id) == 0;
56 : : }
57 : :
58 : : static void
59 : 3 : shumate_map_source_registry_dispose (GObject *object)
60 : : {
61 : 3 : ShumateMapSourceRegistry *self = (ShumateMapSourceRegistry *)object;
62 : :
63 [ + - ]: 3 : g_clear_pointer (&self->map_sources, g_ptr_array_unref);
64 : :
65 : 3 : G_OBJECT_CLASS (shumate_map_source_registry_parent_class)->dispose (object);
66 : 3 : }
67 : :
68 : : static void
69 : 4 : shumate_map_source_registry_class_init (ShumateMapSourceRegistryClass *klass)
70 : : {
71 : 4 : GObjectClass *object_class = G_OBJECT_CLASS (klass);
72 : :
73 : 4 : object_class->dispose = shumate_map_source_registry_dispose;
74 : : }
75 : :
76 : : static void
77 : 3 : shumate_map_source_registry_init (ShumateMapSourceRegistry *self)
78 : : {
79 : 3 : self->map_sources = g_ptr_array_new_with_free_func (g_object_unref);
80 : 3 : }
81 : :
82 : : static GType
83 : 0 : shumate_map_source_registry_get_item_type (GListModel *list)
84 : : {
85 : 0 : return SHUMATE_TYPE_MAP_SOURCE;
86 : : }
87 : :
88 : : static guint
89 : 0 : shumate_map_source_registry_get_n_items (GListModel *list)
90 : : {
91 : 0 : ShumateMapSourceRegistry *self = SHUMATE_MAP_SOURCE_REGISTRY (list);
92 : :
93 : 0 : return self->map_sources->len;
94 : : }
95 : :
96 : : static gpointer
97 : 0 : shumate_map_source_registry_get_item (GListModel *list,
98 : : guint position)
99 : : {
100 : 0 : ShumateMapSourceRegistry *self = SHUMATE_MAP_SOURCE_REGISTRY (list);
101 : :
102 [ # # ]: 0 : if (position >= self->map_sources->len)
103 : : return NULL;
104 : : else
105 : 0 : return g_object_ref (g_ptr_array_index (self->map_sources, position));
106 : : }
107 : :
108 : : static void
109 : 4 : shumate_map_source_registry_list_model_init (GListModelInterface *iface)
110 : : {
111 : 4 : iface->get_item_type = shumate_map_source_registry_get_item_type;
112 : 4 : iface->get_n_items = shumate_map_source_registry_get_n_items;
113 : 4 : iface->get_item = shumate_map_source_registry_get_item;
114 : 4 : }
115 : :
116 : : /**
117 : : * shumate_map_source_registry_new:
118 : : *
119 : : * Create a new #ShumateMapSourceRegistry.
120 : : *
121 : : * Returns: (transfer full): a newly created #ShumateMapSourceRegistry
122 : : */
123 : : ShumateMapSourceRegistry *
124 : 3 : shumate_map_source_registry_new (void)
125 : : {
126 : 3 : return g_object_new (SHUMATE_TYPE_MAP_SOURCE_REGISTRY, NULL);
127 : : }
128 : :
129 : : /**
130 : : * shumate_map_source_registry_new_with_defaults:
131 : : *
132 : : * Create a new #ShumateMapSourceRegistry with defaults map sources.
133 : : * This is identical to calling [method@MapSourceRegistry.populate_defaults]
134 : : * after shumate_map_source_registry_new().
135 : : *
136 : : * Returns: (transfer full): a newly created #ShumateMapSourceRegistry
137 : : */
138 : : ShumateMapSourceRegistry *
139 : 3 : shumate_map_source_registry_new_with_defaults (void)
140 : : {
141 : 3 : ShumateMapSourceRegistry *registry = shumate_map_source_registry_new ();
142 : :
143 : 3 : shumate_map_source_registry_populate_defaults (registry);
144 : :
145 : 3 : return registry;
146 : : }
147 : :
148 : : /**
149 : : * shumate_map_source_registry_populate_defaults:
150 : : * @self: a #ShumateMapSourceRegistry
151 : : *
152 : : * Populates the #ShumateMapSourceRegistry with a default set of sources.
153 : : */
154 : : void
155 : 3 : shumate_map_source_registry_populate_defaults (ShumateMapSourceRegistry *self)
156 : : {
157 : 3 : guint n_items;
158 : :
159 [ + - ]: 3 : g_return_if_fail (SHUMATE_IS_MAP_SOURCE_REGISTRY (self));
160 : :
161 : 3 : n_items = self->map_sources->len;
162 : :
163 [ + - ]: 3 : if (!shumate_map_source_registry_get_by_id (self, SHUMATE_MAP_SOURCE_OSM_MAPNIK))
164 : : {
165 : 3 : g_ptr_array_add (self->map_sources,
166 : 3 : shumate_raster_renderer_new_full_from_url (
167 : : SHUMATE_MAP_SOURCE_OSM_MAPNIK,
168 : : "OpenStreetMap Mapnik",
169 : : "Map Data ODBL OpenStreetMap Contributors, Map Imagery CC-BY-SA 2.0 OpenStreetMap",
170 : : "http://creativecommons.org/licenses/by-sa/2.0/",
171 : : 0,
172 : : 18,
173 : : 256,
174 : : SHUMATE_MAP_PROJECTION_MERCATOR,
175 : : "https://tile.openstreetmap.org/{z}/{x}/{y}.png"
176 : : )
177 : : );
178 : : }
179 : :
180 [ + - ]: 3 : if (!shumate_map_source_registry_get_by_id (self, SHUMATE_MAP_SOURCE_OSM_CYCLE_MAP))
181 : : {
182 : 3 : g_ptr_array_add (self->map_sources,
183 : 3 : shumate_raster_renderer_new_full_from_url (
184 : : SHUMATE_MAP_SOURCE_OSM_CYCLE_MAP,
185 : : "OpenStreetMap Cycle Map",
186 : : "Map data is CC-BY-SA 2.0 OpenStreetMap contributors",
187 : : "http://creativecommons.org/licenses/by-sa/2.0/",
188 : : 0,
189 : : 18,
190 : : 256,
191 : : SHUMATE_MAP_PROJECTION_MERCATOR,
192 : : "http://tile.opencyclemap.org/cycle/{z}/{x}/{y}.png"
193 : : )
194 : : );
195 : : }
196 : :
197 [ + - ]: 3 : if (!shumate_map_source_registry_get_by_id (self, SHUMATE_MAP_SOURCE_OSM_TRANSPORT_MAP))
198 : : {
199 : 3 : g_ptr_array_add (self->map_sources,
200 : 3 : shumate_raster_renderer_new_full_from_url (
201 : : SHUMATE_MAP_SOURCE_OSM_TRANSPORT_MAP,
202 : : "OpenStreetMap Transport Map",
203 : : "Map data is CC-BY-SA 2.0 OpenStreetMap contributors",
204 : : "http://creativecommons.org/licenses/by-sa/2.0/",
205 : : 0,
206 : : 18,
207 : : 256,
208 : : SHUMATE_MAP_PROJECTION_MERCATOR,
209 : : "http://tile.xn--pnvkarte-m4a.de/tilegen/{z}/{x}/{y}.png"
210 : : )
211 : : );
212 : : }
213 : :
214 [ + - ]: 3 : if (!shumate_map_source_registry_get_by_id (self, SHUMATE_MAP_SOURCE_MFF_RELIEF))
215 : : {
216 : 3 : g_ptr_array_add (self->map_sources,
217 : 3 : shumate_raster_renderer_new_full_from_url (
218 : : SHUMATE_MAP_SOURCE_MFF_RELIEF,
219 : : "Maps for Free Relief",
220 : : "Map data available under GNU Free Documentation license, Version 1.2 or later",
221 : : "http://www.gnu.org/copyleft/fdl.html",
222 : : 0,
223 : : 11,
224 : : 256,
225 : : SHUMATE_MAP_PROJECTION_MERCATOR,
226 : : "http://maps-for-free.com/layer/relief/z{z}/row{y}/{z}_{x}-{y}.jpg"
227 : : )
228 : : );
229 : : }
230 : :
231 [ + - ]: 3 : if (!shumate_map_source_registry_get_by_id (self, SHUMATE_MAP_SOURCE_OWM_CLOUDS))
232 : : {
233 : 3 : g_ptr_array_add (self->map_sources,
234 : 3 : shumate_raster_renderer_new_full_from_url (
235 : : SHUMATE_MAP_SOURCE_OWM_CLOUDS,
236 : : "OpenWeatherMap cloud layer",
237 : : "Map data is CC-BY-SA 2.0 OpenWeatherMap contributors",
238 : : "http://creativecommons.org/licenses/by-sa/2.0/",
239 : : 0,
240 : : 18,
241 : : 256,
242 : : SHUMATE_MAP_PROJECTION_MERCATOR,
243 : : "http://tile.openweathermap.org/map/clouds/{z}/{x}/{y}.png"
244 : : )
245 : : );
246 : : }
247 : :
248 [ + - ]: 3 : if (!shumate_map_source_registry_get_by_id (self, SHUMATE_MAP_SOURCE_OWM_WIND))
249 : : {
250 : 3 : g_ptr_array_add (self->map_sources,
251 : 3 : shumate_raster_renderer_new_full_from_url (
252 : : SHUMATE_MAP_SOURCE_OWM_WIND,
253 : : "OpenWeatherMap wind layer",
254 : : "Map data is CC-BY-SA 2.0 OpenWeatherMap contributors",
255 : : "http://creativecommons.org/licenses/by-sa/2.0/",
256 : : 0,
257 : : 18,
258 : : 256,
259 : : SHUMATE_MAP_PROJECTION_MERCATOR,
260 : : "http://tile.openweathermap.org/map/wind/{z}/{x}/{y}.png"
261 : : )
262 : : );
263 : : }
264 : :
265 [ + - ]: 3 : if (!shumate_map_source_registry_get_by_id (self, SHUMATE_MAP_SOURCE_OWM_TEMPERATURE))
266 : : {
267 : 3 : g_ptr_array_add (self->map_sources,
268 : 3 : shumate_raster_renderer_new_full_from_url (
269 : : SHUMATE_MAP_SOURCE_OWM_TEMPERATURE,
270 : : "OpenWeatherMap temperature layer",
271 : : "Map data is CC-BY-SA 2.0 OpenWeatherMap contributors",
272 : : "http://creativecommons.org/licenses/by-sa/2.0/",
273 : : 0,
274 : : 18,
275 : : 256,
276 : : SHUMATE_MAP_PROJECTION_MERCATOR,
277 : : "http://tile.openweathermap.org/map/temp/{z}/{x}/{y}.png"
278 : : )
279 : : );
280 : : }
281 : :
282 [ + - ]: 3 : if (!shumate_map_source_registry_get_by_id (self, SHUMATE_MAP_SOURCE_OWM_PRECIPITATION))
283 : : {
284 : 3 : g_ptr_array_add (self->map_sources,
285 : 3 : shumate_raster_renderer_new_full_from_url (
286 : : SHUMATE_MAP_SOURCE_OWM_PRECIPITATION,
287 : : "OpenWeatherMap precipitation layer",
288 : : "Map data is CC-BY-SA 2.0 OpenWeatherMap contributors",
289 : : "http://creativecommons.org/licenses/by-sa/2.0/",
290 : : 0,
291 : : 18,
292 : : 256,
293 : : SHUMATE_MAP_PROJECTION_MERCATOR,
294 : : "http://tile.openweathermap.org/map/precipitation/{z}/{x}/{y}.png"
295 : : )
296 : : );
297 : : }
298 : :
299 [ + - ]: 3 : if (!shumate_map_source_registry_get_by_id (self, SHUMATE_MAP_SOURCE_OWM_PRESSURE))
300 : : {
301 : 3 : g_ptr_array_add (self->map_sources,
302 : 3 : shumate_raster_renderer_new_full_from_url (
303 : : SHUMATE_MAP_SOURCE_OWM_PRESSURE,
304 : : "OpenWeatherMap sea level pressure layer",
305 : : "Map data is CC-BY-SA 2.0 OpenWeatherMap contributors",
306 : : "http://creativecommons.org/licenses/by-sa/2.0/",
307 : : 0,
308 : : 18,
309 : : 256,
310 : : SHUMATE_MAP_PROJECTION_MERCATOR,
311 : : "http://tile.openweathermap.org/map/pressure/{z}/{x}/{y}.png"
312 : : )
313 : : );
314 : : }
315 : :
316 [ + - ]: 3 : if (self->map_sources->len - n_items > 0) {
317 : 3 : g_list_model_items_changed (G_LIST_MODEL (self), n_items, self->map_sources->len - n_items, 0);
318 : : }
319 : : }
320 : :
321 : : /**
322 : : * shumate_map_source_registry_get_by_id:
323 : : * @self: a #ShumateMapSourceRegistry
324 : : * @id: the id of the #ShumateMapSource
325 : : *
326 : : * Find the #ShumateMapSource with the corresponding id
327 : : *
328 : : * Returns: (transfer none) (nullable): the #ShumateMapSource or %NULL if no
329 : : * map source has been found
330 : : */
331 : : ShumateMapSource *
332 : 30 : shumate_map_source_registry_get_by_id (ShumateMapSourceRegistry *self,
333 : : const gchar *id)
334 : : {
335 : 30 : guint index;
336 : :
337 [ + - ]: 30 : g_return_val_if_fail (SHUMATE_IS_MAP_SOURCE_REGISTRY (self), NULL);
338 [ - + ]: 30 : g_return_val_if_fail (id != NULL, NULL);
339 : :
340 [ + + ]: 30 : if (g_ptr_array_find_with_equal_func (self->map_sources, id,
341 : : (GEqualFunc) shumate_map_source_registry_find_by_id,
342 : : &index))
343 : : {
344 : 3 : return g_ptr_array_index (self->map_sources, index);
345 : : }
346 : :
347 : : return NULL;
348 : : }
349 : :
350 : : /**
351 : : * shumate_map_source_registry_add:
352 : : * @self: a #ShumateMapSourceRegistry
353 : : * @map_source: (transfer full): a #ShumateMapSource
354 : : *
355 : : * Adds the #ShumateMapSource to the #ShumateMapSourceRegistry
356 : : */
357 : 0 : void shumate_map_source_registry_add (ShumateMapSourceRegistry *self,
358 : : ShumateMapSource *map_source)
359 : : {
360 : 0 : guint n_items;
361 : :
362 [ # # ]: 0 : g_return_if_fail (SHUMATE_IS_MAP_SOURCE_REGISTRY (self));
363 [ # # ]: 0 : g_return_if_fail (SHUMATE_IS_MAP_SOURCE (map_source));
364 : :
365 [ # # ]: 0 : if (!g_ptr_array_find_with_equal_func (self->map_sources, shumate_map_source_get_id (map_source),
366 : : (GEqualFunc) shumate_map_source_registry_find_by_id,
367 : : NULL))
368 : : {
369 : 0 : n_items = self->map_sources->len;
370 : 0 : g_ptr_array_add (self->map_sources, map_source);
371 : :
372 : 0 : g_list_model_items_changed (G_LIST_MODEL (self), n_items, 0, 1);
373 : : }
374 : : }
375 : :
376 : : /**
377 : : * shumate_map_source_registry_remove:
378 : : * @self: a #ShumateMapSourceRegistry
379 : : * @id: a #ShumateMapSource id
380 : : *
381 : : * Removes the corresponding #ShumateMapSource from the registry.
382 : : * If the source doesn't exist in the registry, this function does nothing.
383 : : */
384 : 0 : void shumate_map_source_registry_remove (ShumateMapSourceRegistry *self,
385 : : const gchar *id)
386 : : {
387 : 0 : guint index;
388 : :
389 [ # # ]: 0 : g_return_if_fail (SHUMATE_IS_MAP_SOURCE_REGISTRY (self));
390 [ # # ]: 0 : g_return_if_fail (id != NULL);
391 : :
392 [ # # ]: 0 : if (g_ptr_array_find_with_equal_func (self->map_sources, id,
393 : : (GEqualFunc) shumate_map_source_registry_find_by_id,
394 : : &index))
395 : : {
396 : 0 : g_ptr_array_remove_index (self->map_sources, index);
397 : 0 : g_list_model_items_changed (G_LIST_MODEL (self), index, 1, 0);
398 : : }
399 : : }
|