*
* viking 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
+ * Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* viking is distributed in the hope that it will be useful, but
#include <glib/gi18n.h>
#include <gdk-pixbuf/gdk-pixdata.h>
#include "globals.h"
-#include "curl_download.h"
#include "bingmapsource.h"
+#include "maputils.h"
#include "bbox.h"
#include "background.h"
#include "icons/icons.h"
/* Format for URL */
#define URL_ATTR_FMT "http://dev.virtualearth.net/REST/v1/Imagery/Metadata/Aerial/0,0?zl=1&mapVersion=v1&key=%s&include=ImageryProviders&output=xml"
-static gchar *_get_uri ( VikMapSourceDefault *self, MapCoord *src );
-static void _get_copyright (VikMapSource * self, LatLonBBox bbox, gdouble zoom, void (*fct)(void*,const gchar*), void *data);
+static gchar *bget_uri ( VikMapSourceDefault *self, MapCoord *src );
+static gchar *bget_hostname ( VikMapSourceDefault *self );
+static void _get_copyright (VikMapSource * self, LatLonBBox bbox, gdouble zoom, void (*fct)(VikViewport*,const gchar*), void *data);
static const GdkPixbuf *_get_logo ( VikMapSource *self );
static int _load_attributions ( BingMapSource *self );
static void _async_load_attributions ( BingMapSource *self );
typedef struct _BingMapSourcePrivate BingMapSourcePrivate;
struct _BingMapSourcePrivate
{
+ gchar *hostname;
+ gchar *url;
gchar *api_key;
GList *attributions;
/* Current attribution, when parsing */
gchar *attribution;
+ gboolean loading_attributions;
};
/* The pixbuf to store the logo */
{
PROP_0,
+ PROP_HOSTNAME,
+ PROP_URL,
PROP_API_KEY,
};
/* initialize the object here */
BingMapSourcePrivate *priv = BING_MAP_SOURCE_GET_PRIVATE (self);
+ priv->hostname = NULL;
+ priv->url = NULL;
priv->api_key = NULL;
priv->attributions = NULL;
priv->attribution = NULL;
+ priv->loading_attributions = FALSE;
}
static void
BingMapSource *self = BING_MAP_SOURCE (object);
BingMapSourcePrivate *priv = BING_MAP_SOURCE_GET_PRIVATE (self);
+ g_free (priv->hostname);
+ priv->hostname = NULL;
+ g_free (priv->url);
+ priv->url = NULL;
g_free (priv->api_key);
priv->api_key = NULL;
switch (property_id)
{
+ case PROP_HOSTNAME:
+ g_free (priv->hostname);
+ priv->hostname = g_value_dup_string (value);
+ break;
+
+ case PROP_URL:
+ g_free (priv->url);
+ priv->url = g_value_dup_string (value);
+ break;
+
case PROP_API_KEY:
priv->api_key = g_strdup (g_value_get_string (value));
break;
switch (property_id)
{
+ case PROP_HOSTNAME:
+ g_value_set_string (value, priv->hostname);
+ break;
+
+ case PROP_URL:
+ g_value_set_string (value, priv->url);
+ break;
+
case PROP_API_KEY:
g_value_set_string (value, priv->api_key);
break;
VikMapSourceDefaultClass* grandparent_class = VIK_MAP_SOURCE_DEFAULT_CLASS (klass);
VikMapSourceClass* base_class = VIK_MAP_SOURCE_CLASS (klass);
GParamSpec *pspec = NULL;
-
+
/* Overiding methods */
object_class->set_property = _set_property;
object_class->get_property = _get_property;
- grandparent_class->get_uri = _get_uri;
+ grandparent_class->get_uri = bget_uri;
+ grandparent_class->get_hostname = bget_hostname;
base_class->get_logo = _get_logo;
base_class->get_copyright = _get_copyright;
+ pspec = g_param_spec_string ("hostname",
+ "Hostname",
+ "The hostname of the map server",
+ "<no-set>" /* default value */,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
+ g_object_class_install_property (object_class, PROP_HOSTNAME, pspec);
+
+ pspec = g_param_spec_string ("url",
+ "URL",
+ "The template of the tiles' URL",
+ "<no-set>" /* default value */,
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
+ g_object_class_install_property (object_class, PROP_URL, pspec);
+
pspec = g_param_spec_string ("api-key",
"API key",
"The API key to access Bing",
}
static gchar *
-_get_uri( VikMapSourceDefault *self, MapCoord *src )
+bget_uri( VikMapSourceDefault *self, MapCoord *src )
{
g_return_val_if_fail (BING_IS_MAP_SOURCE(self), NULL);
- /* BingMapSourcePrivate *priv = BING_MAP_SOURCE_GET_PRIVATE(self); */
+ BingMapSourcePrivate *priv = BING_MAP_SOURCE_GET_PRIVATE(self);
gchar *quadtree = compute_quad_tree (17 - src->scale, src->x, src->y);
- gchar *uri = g_strdup_printf ( "/tiles/a%s.%s?g=587", quadtree, "jpeg");
+ gchar *uri = g_strdup_printf ( priv->url, quadtree );
g_free (quadtree);
return uri;
}
+static gchar *
+bget_hostname( VikMapSourceDefault *self )
+{
+ g_return_val_if_fail (BING_IS_MAP_SOURCE(self), NULL);
+
+ BingMapSourcePrivate *priv = BING_MAP_SOURCE_GET_PRIVATE(self);
+ return g_strdup( priv->hostname );
+}
+
static const GdkPixbuf *
_get_logo( VikMapSource *self )
{
}
static void
-_get_copyright(VikMapSource * self, LatLonBBox bbox, gdouble zoom, void (*fct)(void*,const gchar*), void *data)
+_get_copyright(VikMapSource * self, LatLonBBox bbox, gdouble zoom, void (*fct)(VikViewport*,const gchar*), void *data)
{
g_return_if_fail (BING_IS_MAP_SOURCE(self));
g_debug("%s: looking for %g %g %g %g at %g", __FUNCTION__, bbox.south, bbox.north, bbox.east, bbox.west, zoom);
BingMapSourcePrivate *priv = BING_MAP_SOURCE_GET_PRIVATE(self);
- int level = vik_slippy_map_source_zoom_to_scale (zoom);
+ int level = map_utils_mpp_to_scale (zoom);
/* Loop over all known attributions */
GList *attribution = priv->attributions;
- if (attribution == NULL) {
- _async_load_attributions (BING_MAP_SOURCE (self));
+ if (attribution == NULL && g_strcmp0 ("<no-set>", priv->api_key)) {
+ if ( ! priv->loading_attributions )
+ _async_load_attributions (BING_MAP_SOURCE (self));
+ else
+ // Wait until attributions loaded before processing them
+ return;
}
while (attribution != NULL) {
struct _Attribution *current = (struct _Attribution*)attribution->data;
/* Called for open tags <foo bar="baz"> */
static void
-_start_element (GMarkupParseContext *context,
+bstart_element (GMarkupParseContext *context,
const gchar *element_name,
const gchar **attribute_names,
const gchar **attribute_values,
const gchar *element = g_markup_parse_context_get_element (context);
if (strcmp (element, "CoverageArea") == 0) {
/* New Attribution */
- struct _Attribution *attribution = g_malloc (sizeof(struct _Attribution));
+ struct _Attribution *attribution = g_malloc0 (sizeof(struct _Attribution));
priv->attributions = g_list_append (priv->attributions, attribution);
attribution->attribution = g_strdup (priv->attribution);
}
/* Called for character data */
/* text is not nul-terminated */
static void
-_text (GMarkupParseContext *context,
+btext (GMarkupParseContext *context,
const gchar *text,
gsize text_len,
gpointer user_data,
int len = g_slist_length ((GSList *)stack);
const gchar *parent = len > 1 ? g_slist_nth_data ((GSList *)stack, 1) : NULL;
-
if (strcmp (element, "Attribution") == 0) {
g_free (priv->attribution);
priv->attribution = g_strdup (textl);
- } else if (parent != NULL && strcmp (parent, "CoverageArea") == 0) {
- if (strcmp (element, "ZoomMin") == 0) {
- attribution->minZoom = atoi (textl);
- } else if (strcmp (element, "ZoomMax") == 0) {
- attribution->maxZoom = atoi (textl);
- }
- } else if (parent != NULL && strcmp (parent, "BoundingBox") == 0) {
- if (strcmp (element, "SouthLatitude") == 0) {
- attribution->bounds.south = g_ascii_strtod (textl, NULL);
- } else if (strcmp (element, "WestLongitude") == 0) {
- attribution->bounds.west = g_ascii_strtod (textl, NULL);
- } else if (strcmp (element, "NorthLatitude") == 0) {
- attribution->bounds.north = g_ascii_strtod (textl, NULL);
- } else if (strcmp (element, "EastLongitude") == 0) {
- attribution->bounds.east = g_ascii_strtod (textl, NULL);
+ }
+ else {
+ if ( attribution ) {
+ if (parent != NULL && strcmp (parent, "CoverageArea") == 0) {
+ if (strcmp (element, "ZoomMin") == 0) {
+ attribution->minZoom = atoi (textl);
+ } else if (strcmp (element, "ZoomMax") == 0) {
+ attribution->maxZoom = atoi (textl);
+ }
+ } else if (parent != NULL && strcmp (parent, "BoundingBox") == 0) {
+ if (strcmp (element, "SouthLatitude") == 0) {
+ attribution->bounds.south = g_ascii_strtod (textl, NULL);
+ } else if (strcmp (element, "WestLongitude") == 0) {
+ attribution->bounds.west = g_ascii_strtod (textl, NULL);
+ } else if (strcmp (element, "NorthLatitude") == 0) {
+ attribution->bounds.north = g_ascii_strtod (textl, NULL);
+ } else if (strcmp (element, "EastLongitude") == 0) {
+ attribution->bounds.east = g_ascii_strtod (textl, NULL);
+ }
+ }
}
}
- if (attribution)
- g_debug("Current attribution %s from %d to %d %g %g %g %g",
- attribution->attribution,
- attribution->minZoom, attribution->maxZoom,
- attribution->bounds.south, attribution->bounds.north, attribution->bounds.west, attribution->bounds.east);
-
g_free(textl);
}
return FALSE;
/* setup context parse (ie callbacks) */
- xml_parser.start_element = &_start_element;
+ xml_parser.start_element = &bstart_element;
xml_parser.end_element = NULL;
- xml_parser.text = &_text;
+ xml_parser.text = &btext;
xml_parser.passthrough = NULL;
xml_parser.error = NULL;
xml_context = NULL;
fclose (file);
+ if (vik_debug) {
+ GList *attribution = priv->attributions;
+ while (attribution != NULL) {
+ struct _Attribution *aa = (struct _Attribution*)attribution->data;
+ g_debug ("Bing Attribution: %s from %d to %d %g %g %g %g", aa->attribution, aa->minZoom, aa->maxZoom, aa->bounds.south, aa->bounds.north, aa->bounds.east, aa->bounds.west);
+ attribution = attribution->next;
+ }
+ }
+
return TRUE;
}
static int
_load_attributions ( BingMapSource *self )
{
- FILE *tmp_file;
- int tmp_fd;
- gchar *tmpname;
- gchar *uri;
int ret = 0; /* OK */
BingMapSourcePrivate *priv = BING_MAP_SOURCE_GET_PRIVATE (self);
+ priv->loading_attributions = TRUE;
+ gchar *uri = g_strdup_printf(URL_ATTR_FMT, priv->api_key);
- if ((tmp_fd = g_file_open_tmp ("vik-bing.XXXXXX", &tmpname, NULL)) == -1) {
- g_critical(_("couldn't open temp file"));
- return -1;
- }
-
- tmp_file = fdopen(tmp_fd, "r+");
- uri = g_strdup_printf(URL_ATTR_FMT, priv->api_key);
-
- /* TODO: curl may not be available */
- if (curl_download_uri(uri, tmp_file, vik_map_source_default_get_download_options(VIK_MAP_SOURCE_DEFAULT(self)), 0, NULL)) { /* error */
- fclose(tmp_file);
- tmp_file = NULL;
+ gchar *tmpname = a_download_uri_to_tmp_file ( uri, vik_map_source_default_get_download_options(VIK_MAP_SOURCE_DEFAULT(self)) );
+ if ( !tmpname ) {
ret = -1;
goto done;
}
- fclose(tmp_file);
- tmp_file = NULL;
-
g_debug("%s: %s", __FUNCTION__, tmpname);
if (!_parse_file_for_attributions(self, tmpname)) {
ret = -1;
- goto done;
}
+ (void)g_remove(tmpname);
+ g_free(tmpname);
done:
+ priv->loading_attributions = FALSE;
g_free(uri);
- g_remove(tmpname);
- g_free(tmpname);
return ret;
}
vik_layers_panel_emit_update ( VIK_LAYERS_PANEL (data) );
*/
gdk_threads_leave();
+ return 0;
}
static int
static void
_async_load_attributions ( BingMapSource *self )
{
- a_background_thread ( /*VIK_GTK_WINDOW_FROM_WIDGET(vp)*/NULL,
- _("Bing attribution Loading"),
- (vik_thr_func) _load_attributions_thread,
- self,
- NULL,
- NULL,
- 1 );
+ a_background_thread ( BACKGROUND_POOL_REMOTE,
+ /*VIK_GTK_WINDOW_FROM_WIDGET(vp)*/NULL,
+ _("Bing attribution Loading"),
+ (vik_thr_func) _load_attributions_thread,
+ self,
+ NULL,
+ NULL,
+ 1 );
}
* Returns: a newly allocated BingMapSource GObject.
*/
BingMapSource *
-bing_map_source_new_with_id (guint8 id, const gchar *label, const gchar *key)
+bing_map_source_new_with_id (guint16 id, const gchar *label, const gchar *key)
{
/* initialize settings here */
return g_object_new(BING_TYPE_MAP_SOURCE,
"id", id,
"label", label,
+ "name", "Bing-Aerial",
"hostname", "ecn.t2.tiles.virtualearth.net",
+ "url", "/tiles/a%s.jpeg?g=587",
"api-key", key,
"check-file-server-time", TRUE,
+ "zoom-min", 0,
+ "zoom-max", 19, // NB: Might be regionally different rather than the same across the world
"copyright", "© 2011 Microsoft Corporation and/or its suppliers",
"license", "Microsoft Bing Maps Specific",
"license-url", "http://www.microsoft.com/maps/assets/docs/terms.aspx",