From: Pierre-Luc Beaudoin Date: Mon, 4 May 2009 01:13:47 +0000 (-0400) Subject: Introduce ChamplainMapSourceDesc to list available map sources X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=04e154d9fa3f9faa7158fdaaff6d87ae65d4ab0d;p=libchamplain Introduce ChamplainMapSourceDesc to list available map sources --- diff --git a/champlain/Makefile.am b/champlain/Makefile.am index 51d091c..9898dde 100644 --- a/champlain/Makefile.am +++ b/champlain/Makefile.am @@ -27,6 +27,7 @@ libchamplain_headers = \ champlain-map-source.h \ champlain-network-map-source.h \ champlain-map-source-factory.h \ + champlain-map-source-desc.h \ champlain-version.h @@ -59,6 +60,7 @@ noinst_HEADERS = \ champlain-map-source.h \ champlain-network-map-source.h \ champlain-map-source-factory.h \ + champlain-map-source-desc.h \ champlain-version.h \ champlain-cache.h @@ -71,6 +73,7 @@ libchamplain_include_HEADERS = \ champlain-map-source.h \ champlain-network-map-source.h \ champlain-map-source-factory.h \ + champlain-map-source-desc.h \ champlain-tile.h \ champlain-zoom-level.h \ champlain-base-marker.h \ diff --git a/champlain/champlain-map-source-desc.h b/champlain/champlain-map-source-desc.h new file mode 100644 index 0000000..e7e9f40 --- /dev/null +++ b/champlain/champlain-map-source-desc.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2009 Pierre-Luc Beaudoin + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#if !defined (__CHAMPLAIN_CHAMPLAIN_H_INSIDE__) && !defined (CHAMPLAIN_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef CHAMPLAIN_MAP_SOURCE_DESC_H +#define CHAMPLAIN_MAP_SOURCE_DESC_H + +#include + +G_BEGIN_DECLS + +/** + * ChamplainMapSourceConstructor: + * + * A #ChamplainMapSource constructor. It should return a ready to use + * #ChamplainMapSource. + * + * Since: 0.4 + */ +typedef ChamplainMapSource * (*ChamplainMapSourceConstructor) (); +#define CHAMPLAIN_MAP_SOURCE_CONSTRUCTOR (f) ((ChamplainMapSourceConstructor) (f)) + +/** + * ChamplainMapSourceDesc: + * + * Describes a #ChamplainMapSource. This is returned by #champlain_map_source_factory_get_list. + * + * Since: 0.4 + */ +typedef struct { + gchar *id; + gchar *name; + gchar *license; + gchar *license_uri; + gint min_zoom_level; + gint max_zoom_level; + ChamplainMapProjection projection; + ChamplainMapSourceConstructor constructor; +} ChamplainMapSourceDesc; + +G_END_DECLS + +#endif diff --git a/champlain/champlain-map-source-factory.c b/champlain/champlain-map-source-factory.c index 67c379f..c3dcdf7 100644 --- a/champlain/champlain-map-source-factory.c +++ b/champlain/champlain-map-source-factory.c @@ -132,10 +132,70 @@ champlain_map_source_factory_class_init (ChamplainMapSourceFactoryClass *klass) object_class->set_property = champlain_map_source_factory_set_property; } -typedef struct { - gchar *name; - ChamplainMapSourceConstructor constructor; -} MapSourceConstructor; +static +ChamplainMapSourceDesc OSM_MAPNIK_DESC = + { + CHAMPLAIN_MAP_SOURCE_OSM_MAPNIK, + "OpenStreetMap Mapnik", + "(CC) BY 2.0 OpenStreetMap contributor", + "http://creativecommons.org/licenses/by/2.0/", + 0, + 18, + CHAMPLAIN_MAP_PROJECTION_MERCATOR, + champlain_map_source_new_osm_mapnik + }; + +static +ChamplainMapSourceDesc OSM_OSMARENDER_DESC = + { + CHAMPLAIN_MAP_SOURCE_OSM_OSMARENDER, + "OpenStreetMap Osmarender", + "(CC) BY 2.0 OpenStreetMap contributor", + "http://creativecommons.org/licenses/by/2.0/", + 0, + 18, + CHAMPLAIN_MAP_PROJECTION_MERCATOR, + champlain_map_source_new_osm_osmarender + }; + +static +ChamplainMapSourceDesc OSM_CYCLEMAP_DESC = + { + CHAMPLAIN_MAP_SOURCE_OSM_CYCLE_MAP, + "OpenStreetMap Cycle Map", + "(CC) BY 2.0 OpenStreetMap contributor", + "http://creativecommons.org/licenses/by/2.0/", + 0, + 18, + CHAMPLAIN_MAP_PROJECTION_MERCATOR, + champlain_map_source_new_osm_cyclemap + }; + +static +ChamplainMapSourceDesc OAM_DESC = + { + CHAMPLAIN_MAP_SOURCE_OAM, + "OpenAerialMap", + "(CC) BY 3.0 OpenAerialMap contributor", + "http://creativecommons.org/licenses/by/3.0/", + 0, + 17, + CHAMPLAIN_MAP_PROJECTION_MERCATOR, + champlain_map_source_new_oam + }; + +static +ChamplainMapSourceDesc MFF_RELIEF_DESC = + { + CHAMPLAIN_MAP_SOURCE_MFF_RELIEF, + "Maps For Free Relief", + "GNU Free Documentation Licence, version 1.2 or later", + "http://www.gnu.org/copyleft/fdl.html", + 0, + 11, + CHAMPLAIN_MAP_PROJECTION_MERCATOR, + champlain_map_source_new_mff_relief + }; static void champlain_map_source_factory_init (ChamplainMapSourceFactory *factory) @@ -146,16 +206,11 @@ champlain_map_source_factory_init (ChamplainMapSourceFactory *factory) priv->registered_sources = NULL; - champlain_map_source_factory_register (factory, CHAMPLAIN_MAP_SOURCE_OSM_MAPNIK, - champlain_map_source_new_osm_mapnik); - champlain_map_source_factory_register (factory, CHAMPLAIN_MAP_SOURCE_OSM_CYCLEMAP, - champlain_map_source_new_osm_cyclemap); - champlain_map_source_factory_register (factory, CHAMPLAIN_MAP_SOURCE_OSM_OSMARENDER, - champlain_map_source_new_osm_osmarender); - champlain_map_source_factory_register (factory, CHAMPLAIN_MAP_SOURCE_OAM, - champlain_map_source_new_oam); - champlain_map_source_factory_register (factory, CHAMPLAIN_MAP_SOURCE_MFF_RELIEF, - champlain_map_source_new_mff_relief); + champlain_map_source_factory_register (factory, &OSM_MAPNIK_DESC); + champlain_map_source_factory_register (factory, &OSM_CYCLEMAP_DESC); + champlain_map_source_factory_register (factory, &OSM_OSMARENDER_DESC); + champlain_map_source_factory_register (factory, &OAM_DESC); + champlain_map_source_factory_register (factory, &MFF_RELIEF_DESC); } /** @@ -182,40 +237,21 @@ champlain_map_source_factory_get_default (void) /** * champlain_map_source_factory_get_list: * - * Returns the list of registered map sources, the list should be freed with - * #g_strfreev. + * Returns the list of registered map sources, the items should not be freed, + * the list should be freed with #g_slist_free. * * Since: 0.4 */ -gchar ** +GSList * champlain_map_source_factory_get_list (ChamplainMapSourceFactory *factory) { - - gint count; - gchar **ret; - GSList *item; - - count = g_slist_length (factory->priv->registered_sources); - ret = g_new0(char*, count + 1); - item = factory->priv->registered_sources; - - count = 0; - while (item != NULL) - { - MapSourceConstructor *cons = (MapSourceConstructor*) item->data; - ret[count] = g_strdup (cons->name); - item = g_slist_next (item); - count++; - } - ret[count] = NULL; - - return ret; + return g_slist_copy (factory->priv->registered_sources); } /** * champlain_map_source_factory_create: * @factory: the Factory - * @name: the wanted map source name + * @id: the wanted map source id * * Returns a ready to use #ChamplainMapSource matching the given name, returns * NULL is none match. @@ -224,7 +260,7 @@ champlain_map_source_factory_get_list (ChamplainMapSourceFactory *factory) */ ChamplainMapSource * champlain_map_source_factory_create (ChamplainMapSourceFactory *factory, - const gchar *name) + const gchar *id) { GSList *item; @@ -232,9 +268,9 @@ champlain_map_source_factory_create (ChamplainMapSourceFactory *factory, while (item != NULL) { - MapSourceConstructor *cons = (MapSourceConstructor*) item->data; - if (strcmp (cons->name, name) == 0) - return cons->constructor (); + ChamplainMapSourceDesc *desc = (ChamplainMapSourceDesc*) item->data; + if (strcmp (desc->id, id) == 0) + return desc->constructor (); item = g_slist_next (item); } return NULL; @@ -246,9 +282,11 @@ champlain_map_source_factory_create (ChamplainMapSourceFactory *factory, * @name: the new map source name * @constructor: the new map source constructor function * - * Register the new map source with the given constructor. When this map - * source is requested, the given constructor will be given to build the - * map source. + * Registers the new map source with the given constructor. When this map + * source is requested, the given constructor will be used to build the + * map source. #ChamplainMapSourceFactory will take ownership of the passed + * ChamplainMapSourceDesc, so don't free it. They will not be freed either so + * you can use static structs here. * * Returns TRUE if the registration suceeded. * @@ -256,23 +294,18 @@ champlain_map_source_factory_create (ChamplainMapSourceFactory *factory, */ gboolean champlain_map_source_factory_register (ChamplainMapSourceFactory *factory, - const gchar *name, - ChamplainMapSourceConstructor callback) + ChamplainMapSourceDesc *desc) { - MapSourceConstructor *cons; /* FIXME: check for existing factory with that name? */ - cons = g_slice_new0(MapSourceConstructor); - cons->name = g_strdup (name); - cons->constructor = callback; - factory->priv->registered_sources = g_slist_append (factory->priv->registered_sources, cons); + factory->priv->registered_sources = g_slist_append (factory->priv->registered_sources, desc); return TRUE; } static ChamplainMapSource * champlain_map_source_new_osm_cyclemap (void) { - return CHAMPLAIN_MAP_SOURCE (champlain_network_map_source_new_full (CHAMPLAIN_MAP_SOURCE_OSM_CYCLEMAP, + return CHAMPLAIN_MAP_SOURCE (champlain_network_map_source_new_full (CHAMPLAIN_MAP_SOURCE_OSM_CYCLE_MAP, "(CC) BY 2.0 OpenStreetMap contributors", "http://creativecommons.org/licenses/by/2.0/", 0, 18, 256, CHAMPLAIN_MAP_PROJECTION_MERCATOR, @@ -292,7 +325,7 @@ champlain_map_source_new_osm_osmarender (void) static ChamplainMapSource * champlain_map_source_new_osm_mapnik (void) { - return CHAMPLAIN_MAP_SOURCE (champlain_network_map_source_new_full (CHAMPLAIN_MAP_SOURCE_OSM_MAPNIK, + return CHAMPLAIN_MAP_SOURCE (champlain_network_map_source_new_full ("OpenStreetMap Mapnik", "(CC) BY 2.0 OpenStreetMap contributors", "http://creativecommons.org/licenses/by/2.0/", 0, 18, 256, CHAMPLAIN_MAP_PROJECTION_MERCATOR, @@ -303,7 +336,7 @@ static ChamplainMapSource * champlain_map_source_new_oam (void) { return CHAMPLAIN_MAP_SOURCE (champlain_network_map_source_new_full (CHAMPLAIN_MAP_SOURCE_OAM, - "(CC) BY 3.0 OpenArialMap contributors", + "(CC) BY 3.0 OpenAerialMap contributors", "http://creativecommons.org/licenses/by/3.0/", 0, 17, 256, CHAMPLAIN_MAP_PROJECTION_MERCATOR, "http://tile.openaerialmap.org/tiles/1.0.0/openaerialmap-900913/#Z#/#X#/#Y#.jpg")); @@ -317,4 +350,4 @@ champlain_map_source_new_mff_relief (void) "http://www.gnu.org/copyleft/fdl.html", 0, 11, 256, CHAMPLAIN_MAP_PROJECTION_MERCATOR, "http://maps-for-free.com/layer/relief/z#Z#/row#Y#/#Z#_#X#-#Y#.jpg")); -} +} diff --git a/champlain/champlain-map-source-factory.h b/champlain/champlain-map-source-factory.h index 5b94935..191d141 100644 --- a/champlain/champlain-map-source-factory.h +++ b/champlain/champlain-map-source-factory.h @@ -25,6 +25,7 @@ #include #include +#include #include @@ -56,31 +57,19 @@ GType champlain_map_source_factory_get_type (void); ChamplainMapSourceFactory * champlain_map_source_factory_get_default (void); -gchar ** champlain_map_source_factory_get_list (ChamplainMapSourceFactory *factory); +GSList * champlain_map_source_factory_get_list (ChamplainMapSourceFactory *factory); ChamplainMapSource * champlain_map_source_factory_create (ChamplainMapSourceFactory *factory, const gchar *id); -/** - * ChamplainMapSourceConstructor: - * - * A #ChamplainMapSource constructor. It should return a ready to use - * #ChamplainMapSource. - * - * Since: 0.4 - */ -typedef ChamplainMapSource * (*ChamplainMapSourceConstructor) (); -#define CHAMPLAIN_MAP_SOURCE_CONSTRUCTOR (f) ((ChamplainMapSourceConstructor) (f)) - gboolean champlain_map_source_factory_register (ChamplainMapSourceFactory *factory, - const gchar *id, - ChamplainMapSourceConstructor callback); - -#define CHAMPLAIN_MAP_SOURCE_OSM_MAPNIK "OpenStreetMap Mapnik" -#define CHAMPLAIN_MAP_SOURCE_OSM_OSMARENDER "OpenStreetMap Osmarender" -#define CHAMPLAIN_MAP_SOURCE_OSM_CYCLEMAP "OpenStreetMap CycleMap" -#define CHAMPLAIN_MAP_SOURCE_OAM "OpenAerialMap" -#define CHAMPLAIN_MAP_SOURCE_MFF_RELIEF "MapsForFree Relief" + ChamplainMapSourceDesc *desc); + +#define CHAMPLAIN_MAP_SOURCE_OSM_MAPNIK "osm::mapnik" +#define CHAMPLAIN_MAP_SOURCE_OSM_OSMARENDER "osm::osmarender" +#define CHAMPLAIN_MAP_SOURCE_OSM_CYCLE_MAP "osm::cyclemap" +#define CHAMPLAIN_MAP_SOURCE_OAM "oam" +#define CHAMPLAIN_MAP_SOURCE_MFF_RELIEF "mff::relief" G_END_DECLS diff --git a/demos/launcher-gtk.c b/demos/launcher-gtk.c index b0fdaa6..3cceeac 100644 --- a/demos/launcher-gtk.c +++ b/demos/launcher-gtk.c @@ -24,6 +24,10 @@ #include +#define N_COLS 2 +#define COL_ID 0 +#define COL_NAME 1 + /* * Terminate the main loop. */ @@ -47,16 +51,27 @@ static void map_source_changed (GtkWidget *widget, ChamplainView *view) { - gchar* selection; + gchar* id; ChamplainMapSource *source; + GtkTreeIter iter; + GtkTreeModel *model; + + if (!gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter)) + return; + + model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget)); + + gtk_tree_model_get (model, &iter, COL_ID, &id, -1); - selection = gtk_combo_box_get_active_text(GTK_COMBO_BOX(widget)); ChamplainMapSourceFactory *factory = champlain_map_source_factory_get_default (); - source = champlain_map_source_factory_create (factory, selection); + source = champlain_map_source_factory_create (factory, id); - g_object_set (G_OBJECT (view), "map-source", source, NULL); + if (source != NULL) + { + g_object_set (G_OBJECT (view), "map-source", source, NULL); + g_object_unref (factory); + } - g_object_unref (factory); g_object_unref (source); } @@ -116,22 +131,41 @@ static void build_combo_box (GtkComboBox *box) { ChamplainMapSourceFactory *factory; - gchar **sources; - gchar *name; + GSList *sources; gint i = 0; + GtkTreeStore *store; + GtkTreeIter parent; + GtkCellRenderer *cell; + + store = gtk_tree_store_new (N_COLS, G_TYPE_STRING, /* id */ + G_TYPE_STRING, /* name */ + -1); factory = champlain_map_source_factory_get_default (); sources = champlain_map_source_factory_get_list (factory); - name = sources[i]; - while (name != NULL) + while (sources != NULL) { - gtk_combo_box_append_text(GTK_COMBO_BOX(box), g_strdup (name)); - name = sources[++i]; + ChamplainMapSourceDesc *desc; + + desc = (ChamplainMapSourceDesc*) sources->data; + + gtk_tree_store_append( store, &parent, NULL ); + gtk_tree_store_set( store, &parent, COL_ID, g_strdup (desc->id), + COL_NAME, g_strdup (desc->name), -1); + + sources = g_slist_next (sources); } - g_strfreev (sources); + g_slist_free (sources); g_object_unref (factory); + + gtk_combo_box_set_model (box, store); + + cell = gtk_cell_renderer_text_new (); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (box), cell, FALSE); + gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (box), cell, + "text", COL_NAME, NULL ); } int @@ -187,7 +221,7 @@ main (int argc, g_signal_connect (button, "toggled", G_CALLBACK (toggle_layer), layer); gtk_container_add (GTK_CONTAINER (bbox), button); - button = gtk_combo_box_new_text(); + button = gtk_combo_box_new (); build_combo_box (button); gtk_combo_box_set_active(GTK_COMBO_BOX(button), 0); g_signal_connect (button, "changed", G_CALLBACK (map_source_changed), view); diff --git a/docs/reference/libchamplain-sections.txt b/docs/reference/libchamplain-sections.txt index 7c50ab1..627eb79 100644 --- a/docs/reference/libchamplain-sections.txt +++ b/docs/reference/libchamplain-sections.txt @@ -325,6 +325,7 @@ CHAMPLAIN_CACHE_GET_CLASS champlain-map-source-factory ChamplainMapSourceFactory ChamplainMapSourceFactory +ChamplainMapSourceDesc ChamplainMapSourceConstructor champlain_map_source_factory_get_default champlain_map_source_factory_get_list