]> git.street.me.uk Git - andy/viking.git/blob - src/vikslippymapsource.c
Some spelling fixes in a comment
[andy/viking.git] / src / vikslippymapsource.c
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3  * viking
4  * Copyright (C) 2009, Guilhem Bonnefille <guilhem.bonnefille@gmail.com>
5  * 
6  * viking is free software: you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the
8  * Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  * 
11  * viking is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14  * See the GNU General Public License for more details.
15  * 
16  * You should have received a copy of the GNU General Public License along
17  * with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19  
20  /**
21   * SECTION:vikslippymapsource
22   * @short_description: the class for SlippyMap oriented map sources
23   * 
24   * The #VikSlippyMapSource class handles slippy map oriented map sources.
25   * The related service is tile oriented, à la Google.
26   * 
27   * The tiles are in 'google spherical mercator', which is
28   * basically a mercator projection that assumes a spherical earth.
29   * http://docs.openlayers.org/library/spherical_mercator.html
30   * 
31   * Such service is also a type of TMS (Tile Map Service) as defined in
32   * OSGeo's wiki.
33   * http://wiki.osgeo.org/wiki/Tile_Map_Service_Specification
34   * But take care that the Y axis is inverted, ie the origin is at top-left
35   * corner.
36   * Following this specification, the protocol handled by this class
37   * follows the global-mercator profile.
38   * 
39   * You can also find many interesting information on the OSM's wiki.
40   * http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames
41   * http://wiki.openstreetmap.org/wiki/Setting_up_TMS
42   */
43   
44 #ifdef HAVE_CONFIG_H
45 #include "config.h"
46 #endif
47
48 #include "vikslippymapsource.h"
49 #include "maputils.h"
50
51 static gboolean _coord_to_mapcoord ( VikMapSource *self, const VikCoord *src, gdouble xzoom, gdouble yzoom, MapCoord *dest );
52 static void _mapcoord_to_center_coord ( VikMapSource *self, MapCoord *src, VikCoord *dest );
53
54 static gboolean _is_direct_file_access (VikMapSource *self );
55 static gboolean _is_mbtiles (VikMapSource *self );
56 static gboolean _is_osm_meta_tiles (VikMapSource *self );
57 static gboolean _supports_download_only_new (VikMapSource *self );
58 static guint8 _get_zoom_min(VikMapSource *self );
59 static guint8 _get_zoom_max(VikMapSource *self );
60 static gdouble _get_lat_min(VikMapSource *self );
61 static gdouble _get_lat_max(VikMapSource *self );
62 static gdouble _get_lon_min(VikMapSource *self );
63 static gdouble _get_lon_max(VikMapSource *self );
64
65 static gchar *_get_uri( VikMapSourceDefault *self, MapCoord *src );
66 static gchar *_get_hostname( VikMapSourceDefault *self );
67 static DownloadFileOptions *_get_download_options( VikMapSourceDefault *self );
68
69 typedef struct _VikSlippyMapSourcePrivate VikSlippyMapSourcePrivate;
70 struct _VikSlippyMapSourcePrivate
71 {
72   gchar *hostname;
73   gchar *url;
74   DownloadFileOptions options;
75   // NB Probably best to keep the above fields in same order to be common across Slippy, TMS & WMS map definitions
76   guint zoom_min; // TMS Zoom level: 0 = Whole World // http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames
77   guint zoom_max; // TMS Zoom level: Often 18 for zoomed in.
78   gdouble lat_min; // Degrees
79   gdouble lat_max; // Degrees
80   gdouble lon_min; // Degrees
81   gdouble lon_max; // Degrees
82   gboolean is_direct_file_access;
83   gboolean is_mbtiles;
84   gboolean is_osm_meta_tiles; // http://wiki.openstreetmap.org/wiki/Meta_tiles as used by tirex or renderd
85   // Mainly for ARCGIS Tile Server URL Layout // http://help.arcgis.com/EN/arcgisserver/10.0/apis/rest/tile.html
86   gboolean switch_xy;
87 };
88
89 #define VIK_SLIPPY_MAP_SOURCE_PRIVATE(o)  (G_TYPE_INSTANCE_GET_PRIVATE ((o), VIK_TYPE_SLIPPY_MAP_SOURCE, VikSlippyMapSourcePrivate))
90
91 /* properties */
92 enum
93 {
94   PROP_0,
95
96   PROP_HOSTNAME,
97   PROP_URL,
98   PROP_ZOOM_MIN,
99   PROP_ZOOM_MAX,
100   PROP_LAT_MIN,
101   PROP_LAT_MAX,
102   PROP_LON_MIN,
103   PROP_LON_MAX,
104   PROP_REFERER,
105   PROP_FOLLOW_LOCATION,
106   PROP_CHECK_FILE_SERVER_TIME,
107   PROP_USE_ETAG,
108   PROP_IS_DIRECT_FILE_ACCESS,
109   PROP_IS_MBTILES,
110   PROP_IS_OSM_META_TILES,
111   PROP_SWITCH_XY,
112 };
113
114 G_DEFINE_TYPE (VikSlippyMapSource, vik_slippy_map_source, VIK_TYPE_MAP_SOURCE_DEFAULT);
115
116 static void
117 vik_slippy_map_source_init (VikSlippyMapSource *self)
118 {
119   /* initialize the object here */
120   VikSlippyMapSourcePrivate *priv = VIK_SLIPPY_MAP_SOURCE_PRIVATE (self);
121
122   priv->hostname = NULL;
123   priv->url = NULL;
124   priv->zoom_min = 0;
125   priv->zoom_max = 18;
126   priv->lat_min = -90.0;
127   priv->lat_max = 90.0;
128   priv->lon_min = -180.0;
129   priv->lon_max = 180.0;
130   priv->options.referer = NULL;
131   priv->options.follow_location = 0;
132   priv->options.check_file = a_check_map_file;
133   priv->options.check_file_server_time = FALSE;
134   priv->options.use_etag = FALSE;
135   priv->is_direct_file_access = FALSE;
136   priv->is_mbtiles = FALSE;
137   priv->is_osm_meta_tiles = FALSE;
138   priv->switch_xy = FALSE;
139
140   g_object_set (G_OBJECT (self),
141                 "tilesize-x", 256,
142                 "tilesize-y", 256,
143                 "drawmode", VIK_VIEWPORT_DRAWMODE_MERCATOR,
144                 NULL);
145 }
146
147 static void
148 vik_slippy_map_source_finalize (GObject *object)
149 {
150   VikSlippyMapSource *self = VIK_SLIPPY_MAP_SOURCE (object);
151   VikSlippyMapSourcePrivate *priv = VIK_SLIPPY_MAP_SOURCE_PRIVATE (self);
152
153   g_free (priv->hostname);
154   priv->hostname = NULL;
155   g_free (priv->url);
156   priv->url = NULL;
157   g_free (priv->options.referer);
158   priv->options.referer = NULL;
159
160   G_OBJECT_CLASS (vik_slippy_map_source_parent_class)->finalize (object);
161 }
162
163 static void
164 vik_slippy_map_source_set_property (GObject      *object,
165                                     guint         property_id,
166                                     const GValue *value,
167                                     GParamSpec   *pspec)
168 {
169   VikSlippyMapSource *self = VIK_SLIPPY_MAP_SOURCE (object);
170   VikSlippyMapSourcePrivate *priv = VIK_SLIPPY_MAP_SOURCE_PRIVATE (self);
171
172   switch (property_id)
173     {
174     case PROP_HOSTNAME:
175       g_free (priv->hostname);
176       priv->hostname = g_value_dup_string (value);
177       break;
178
179     case PROP_URL:
180       g_free (priv->url);
181       priv->url = g_value_dup_string (value);
182       break;
183
184     case PROP_ZOOM_MIN:
185       priv->zoom_min = g_value_get_uint (value);
186       break;
187
188     case PROP_ZOOM_MAX:
189       priv->zoom_max = g_value_get_uint (value);
190       break;
191
192     case PROP_LAT_MIN:
193       priv->lat_min = g_value_get_double (value);
194       break;
195
196     case PROP_LAT_MAX:
197       priv->lat_max = g_value_get_double (value);
198       break;
199
200     case PROP_LON_MIN:
201       priv->lon_min = g_value_get_double (value);
202       break;
203
204     case PROP_LON_MAX:
205       priv->lon_max = g_value_get_double (value);
206       break;
207
208     case PROP_REFERER:
209       g_free (priv->options.referer);
210       priv->options.referer = g_value_dup_string (value);
211       break;
212
213     case PROP_FOLLOW_LOCATION:
214       priv->options.follow_location = g_value_get_long (value);
215       break;
216
217     case PROP_CHECK_FILE_SERVER_TIME:
218       priv->options.check_file_server_time = g_value_get_boolean (value);
219       break;
220
221     case PROP_USE_ETAG:
222       priv->options.use_etag = g_value_get_boolean (value);
223       break;
224
225     case PROP_IS_DIRECT_FILE_ACCESS:
226       priv->is_direct_file_access = g_value_get_boolean (value);
227       break;
228
229     case PROP_IS_MBTILES:
230       priv->is_mbtiles = g_value_get_boolean (value);
231       break;
232
233     case PROP_IS_OSM_META_TILES:
234       priv->is_osm_meta_tiles = g_value_get_boolean (value);
235       break;
236
237     case PROP_SWITCH_XY:
238       priv->switch_xy = g_value_get_boolean (value);
239       break;
240
241     default:
242       /* We don't have any other property... */
243       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
244       break;
245     }
246 }
247
248 static void
249 vik_slippy_map_source_get_property (GObject    *object,
250                                     guint       property_id,
251                                     GValue     *value,
252                                     GParamSpec *pspec)
253 {
254   VikSlippyMapSource *self = VIK_SLIPPY_MAP_SOURCE (object);
255   VikSlippyMapSourcePrivate *priv = VIK_SLIPPY_MAP_SOURCE_PRIVATE (self);
256
257   switch (property_id)
258     {
259     case PROP_HOSTNAME:
260       g_value_set_string (value, priv->hostname);
261       break;
262
263     case PROP_URL:
264       g_value_set_string (value, priv->url);
265       break;
266
267     case PROP_ZOOM_MIN:
268       g_value_set_uint (value, priv->zoom_min);
269       break;
270
271     case PROP_ZOOM_MAX:
272       g_value_set_uint (value, priv->zoom_max);
273       break;
274
275     case PROP_LON_MIN:
276       g_value_set_double (value, priv->lon_min);
277       break;
278
279     case PROP_LON_MAX:
280       g_value_set_double (value, priv->lon_max);
281       break;
282
283     case PROP_LAT_MIN:
284       g_value_set_double (value, priv->lat_min);
285       break;
286
287     case PROP_LAT_MAX:
288       g_value_set_double (value, priv->lat_max);
289       break;
290
291     case PROP_REFERER:
292       g_value_set_string (value, priv->options.referer);
293       break;
294
295     case PROP_FOLLOW_LOCATION:
296       g_value_set_long (value, priv->options.follow_location);
297       break;
298
299     case PROP_CHECK_FILE_SERVER_TIME:
300       g_value_set_boolean (value, priv->options.check_file_server_time);
301       break;
302           
303     case PROP_USE_ETAG:
304       g_value_set_boolean (value, priv->options.use_etag);
305       break;
306
307     case PROP_IS_DIRECT_FILE_ACCESS:
308       g_value_set_boolean (value, priv->is_direct_file_access);
309       break;
310
311     case PROP_IS_MBTILES:
312       g_value_set_boolean (value, priv->is_mbtiles);
313       break;
314
315     case PROP_IS_OSM_META_TILES:
316       g_value_set_boolean (value, priv->is_osm_meta_tiles);
317       break;
318
319     case PROP_SWITCH_XY:
320       g_value_set_boolean (value, priv->switch_xy);
321       break;
322
323     default:
324       /* We don't have any other property... */
325       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
326       break;
327     }
328 }
329
330 static void
331 vik_slippy_map_source_class_init (VikSlippyMapSourceClass *klass)
332 {
333         GObjectClass* object_class = G_OBJECT_CLASS (klass);
334         VikMapSourceClass* grandparent_class = VIK_MAP_SOURCE_CLASS (klass);
335         VikMapSourceDefaultClass* parent_class = VIK_MAP_SOURCE_DEFAULT_CLASS (klass);
336         GParamSpec *pspec = NULL;
337                 
338         object_class->set_property = vik_slippy_map_source_set_property;
339     object_class->get_property = vik_slippy_map_source_get_property;
340
341         /* Overiding methods */
342         grandparent_class->coord_to_mapcoord =        _coord_to_mapcoord;
343         grandparent_class->mapcoord_to_center_coord = _mapcoord_to_center_coord;
344         grandparent_class->is_direct_file_access = _is_direct_file_access;
345         grandparent_class->is_mbtiles = _is_mbtiles;
346         grandparent_class->is_osm_meta_tiles = _is_osm_meta_tiles;
347         grandparent_class->supports_download_only_new = _supports_download_only_new;
348         grandparent_class->get_zoom_min = _get_zoom_min;
349         grandparent_class->get_zoom_max = _get_zoom_max;
350         grandparent_class->get_lat_min = _get_lat_min;
351         grandparent_class->get_lat_max = _get_lat_max;
352         grandparent_class->get_lon_min = _get_lon_min;
353         grandparent_class->get_lon_max = _get_lon_max;
354
355         parent_class->get_uri = _get_uri;
356         parent_class->get_hostname = _get_hostname;
357         parent_class->get_download_options = _get_download_options;
358
359         pspec = g_param_spec_string ("hostname",
360                                      "Hostname",
361                                      "The hostname of the map server",
362                                      "<no-set>" /* default value */,
363                                      G_PARAM_READWRITE);
364         g_object_class_install_property (object_class, PROP_HOSTNAME, pspec);
365
366         pspec = g_param_spec_string ("url",
367                                      "URL",
368                                      "The template of the tiles' URL",
369                                      "<no-set>" /* default value */,
370                                      G_PARAM_READWRITE);
371         g_object_class_install_property (object_class, PROP_URL, pspec);
372
373         pspec = g_param_spec_uint ("zoom-min",
374                                    "Minimum zoom",
375                                    "Minimum Zoom level supported by the map provider",
376                                    0,  // minimum value,
377                                    22, // maximum value
378                                    0, // default value
379                                    G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
380         g_object_class_install_property (object_class, PROP_ZOOM_MIN, pspec);
381
382         pspec = g_param_spec_uint ("zoom-max",
383                                    "Maximum zoom",
384                                    "Maximum Zoom level supported by the map provider",
385                                    0,  // minimum value,
386                                    22, // maximum value
387                                    18, // default value
388                                    G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
389         g_object_class_install_property (object_class, PROP_ZOOM_MAX, pspec);
390
391         pspec = g_param_spec_double ("lat-min",
392                                      "Minimum latitude",
393                                      "Minimum latitude in degrees supported by the map provider",
394                                      -90.0,  // minimum value
395                                      90.0, // maximum value
396                                      -90.0, // default value
397                                      G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
398         g_object_class_install_property (object_class, PROP_LAT_MIN, pspec);
399
400         pspec = g_param_spec_double ("lat-max",
401                                      "Maximum latitude",
402                                      "Maximum latitude in degrees supported by the map provider",
403                                      -90.0,  // minimum value
404                                      90.0, // maximum value
405                                      90.0, // default value
406                                      G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
407         g_object_class_install_property (object_class, PROP_LAT_MAX, pspec);
408
409         pspec = g_param_spec_double ("lon-min",
410                                      "Minimum longitude",
411                                      "Minimum longitude in degrees supported by the map provider",
412                                      -180.0,  // minimum value
413                                      180.0, // maximum value
414                                      -180.0, // default value
415                                      G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
416         g_object_class_install_property (object_class, PROP_LON_MIN, pspec);
417
418         pspec = g_param_spec_double ("lon-max",
419                                      "Maximum longitude",
420                                      "Maximum longitude in degrees supported by the map provider",
421                                      -180.0,  // minimum value
422                                      180.0, // maximum value
423                                      180.0, // default value
424                                      G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
425         g_object_class_install_property (object_class, PROP_LON_MAX, pspec);
426
427         pspec = g_param_spec_string ("referer",
428                                      "Referer",
429                                      "The REFERER string to use in HTTP request",
430                                      NULL /* default value */,
431                                      G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
432         g_object_class_install_property (object_class, PROP_REFERER, pspec);
433         
434         pspec = g_param_spec_long ("follow-location",
435                                    "Follow location",
436                                "Specifies the number of retries to follow a redirect while downloading a page",
437                                0  /* minimum value */,
438                                G_MAXLONG /* maximum value */,
439                                0  /* default value */,
440                                G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
441         g_object_class_install_property (object_class, PROP_FOLLOW_LOCATION, pspec);
442         
443         pspec = g_param_spec_boolean ("check-file-server-time",
444                                       "Check file server time",
445                                   "Age of current cache before redownloading tile",
446                                   FALSE  /* default value */,
447                                   G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
448         g_object_class_install_property (object_class, PROP_CHECK_FILE_SERVER_TIME, pspec);
449
450         pspec = g_param_spec_boolean ("use-etag",
451                                       "Use etag values with server",
452                                   "Store etag in a file, and send it to server to check if we have the latest file",
453                                   FALSE  /* default value */,
454                                   G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
455         g_object_class_install_property (object_class, PROP_USE_ETAG, pspec);
456
457         pspec = g_param_spec_boolean ("use-direct-file-access",
458                                       "Use direct file access",
459                                       "Use direct file access to OSM like tile images - no need for a webservice",
460                                   FALSE  /* default value */,
461                                   G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
462         g_object_class_install_property (object_class, PROP_IS_DIRECT_FILE_ACCESS, pspec);
463
464         pspec = g_param_spec_boolean ("is-mbtiles",
465                                       "Is an SQL MBTiles File",
466                                       "Use an SQL MBTiles File for the tileset - no need for a webservice",
467                                       FALSE  /* default value */,
468                                       G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
469         g_object_class_install_property (object_class, PROP_IS_MBTILES, pspec);
470
471         pspec = g_param_spec_boolean ("is-osm-meta-tiles",
472                                       "Is in OSM Meta Tile format",
473                                       "Read from OSM Meta Tiles - Should be 'use-direct-file-access' as well",
474                                       FALSE  /* default value */,
475                                       G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
476         g_object_class_install_property (object_class, PROP_IS_OSM_META_TILES, pspec);
477
478         pspec = g_param_spec_boolean ("switch-xy",
479                                       "Switch the order of x,y components in the URL",
480                                       "Switch the order of x,y components in the URL (such as used by ARCGIS Tile Server",
481                                       FALSE  /* default value */,
482                                       G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE);
483         g_object_class_install_property (object_class, PROP_SWITCH_XY, pspec);
484
485         g_type_class_add_private (klass, sizeof (VikSlippyMapSourcePrivate));
486         
487         object_class->finalize = vik_slippy_map_source_finalize;
488 }
489
490 static gboolean
491 _is_direct_file_access (VikMapSource *self)
492 {
493   g_return_val_if_fail (VIK_IS_SLIPPY_MAP_SOURCE(self), FALSE);
494
495   VikSlippyMapSourcePrivate *priv = VIK_SLIPPY_MAP_SOURCE_PRIVATE(self);
496
497   return priv->is_direct_file_access;
498 }
499
500 static gboolean
501 _is_mbtiles (VikMapSource *self)
502 {
503   g_return_val_if_fail (VIK_IS_SLIPPY_MAP_SOURCE(self), FALSE);
504
505   VikSlippyMapSourcePrivate *priv = VIK_SLIPPY_MAP_SOURCE_PRIVATE(self);
506
507   return priv->is_mbtiles;
508 }
509
510 /**
511  *
512  */
513 static gboolean
514 _is_osm_meta_tiles (VikMapSource *self)
515 {
516   g_return_val_if_fail (VIK_IS_SLIPPY_MAP_SOURCE(self), FALSE);
517   VikSlippyMapSourcePrivate *priv = VIK_SLIPPY_MAP_SOURCE_PRIVATE(self);
518   return priv->is_osm_meta_tiles;
519 }
520
521 static gboolean
522 _supports_download_only_new (VikMapSource *self)
523 {
524   g_return_val_if_fail (VIK_IS_SLIPPY_MAP_SOURCE(self), FALSE);
525         
526   VikSlippyMapSourcePrivate *priv = VIK_SLIPPY_MAP_SOURCE_PRIVATE(self);
527         
528   return priv->options.check_file_server_time || priv->options.use_etag;
529 }
530
531 /**
532  *
533  */
534 static guint8
535 _get_zoom_min (VikMapSource *self)
536 {
537   g_return_val_if_fail (VIK_IS_SLIPPY_MAP_SOURCE(self), FALSE);
538   VikSlippyMapSourcePrivate *priv = VIK_SLIPPY_MAP_SOURCE_PRIVATE(self);
539   return priv->zoom_min;
540 }
541
542 /**
543  *
544  */
545 static guint8
546 _get_zoom_max (VikMapSource *self)
547 {
548   g_return_val_if_fail (VIK_IS_SLIPPY_MAP_SOURCE(self), FALSE);
549   VikSlippyMapSourcePrivate *priv = VIK_SLIPPY_MAP_SOURCE_PRIVATE(self);
550   return priv->zoom_max;
551 }
552
553 /**
554  *
555  */
556 static gdouble
557 _get_lat_min (VikMapSource *self)
558 {
559   g_return_val_if_fail (VIK_IS_SLIPPY_MAP_SOURCE(self), FALSE);
560   VikSlippyMapSourcePrivate *priv = VIK_SLIPPY_MAP_SOURCE_PRIVATE(self);
561   return priv->lat_min;
562 }
563
564 /**
565  *
566  */
567 static gdouble
568 _get_lat_max (VikMapSource *self)
569 {
570   g_return_val_if_fail (VIK_IS_SLIPPY_MAP_SOURCE(self), FALSE);
571   VikSlippyMapSourcePrivate *priv = VIK_SLIPPY_MAP_SOURCE_PRIVATE(self);
572   return priv->lat_max;
573 }
574
575 /**
576  *
577  */
578 static gdouble
579 _get_lon_min (VikMapSource *self)
580 {
581   g_return_val_if_fail (VIK_IS_SLIPPY_MAP_SOURCE(self), FALSE);
582   VikSlippyMapSourcePrivate *priv = VIK_SLIPPY_MAP_SOURCE_PRIVATE(self);
583   return priv->lon_min;
584 }
585
586 /**
587  *
588  */
589 static gdouble
590 _get_lon_max (VikMapSource *self)
591 {
592   g_return_val_if_fail (VIK_IS_SLIPPY_MAP_SOURCE(self), FALSE);
593   VikSlippyMapSourcePrivate *priv = VIK_SLIPPY_MAP_SOURCE_PRIVATE(self);
594   return priv->lon_max;
595 }
596
597 static gboolean
598 _coord_to_mapcoord ( VikMapSource *self, const VikCoord *src, gdouble xzoom, gdouble yzoom, MapCoord *dest )
599 {
600         return map_utils_vikcoord_to_iTMS ( src, xzoom, yzoom, dest );
601 }
602
603 static void
604 _mapcoord_to_center_coord ( VikMapSource *self, MapCoord *src, VikCoord *dest )
605 {
606         map_utils_iTMS_to_center_vikcoord ( src, dest );
607 }
608
609 static gchar *
610 _get_uri( VikMapSourceDefault *self, MapCoord *src )
611 {
612         g_return_val_if_fail (VIK_IS_SLIPPY_MAP_SOURCE(self), NULL);
613         
614         VikSlippyMapSourcePrivate *priv = VIK_SLIPPY_MAP_SOURCE_PRIVATE(self);
615
616         gchar *uri = NULL;
617         if ( priv->switch_xy )
618                 // 'ARC GIS' Tile Server layout ordering
619                 uri = g_strdup_printf (priv->url, 17 - src->scale, src->y, src->x);
620         else
621                 // (Default) Standard OSM Tile Server layout ordering
622                 uri = g_strdup_printf (priv->url, 17 - src->scale, src->x, src->y);
623
624         return uri;
625
626
627 static gchar *
628 _get_hostname( VikMapSourceDefault *self )
629 {
630         g_return_val_if_fail (VIK_IS_SLIPPY_MAP_SOURCE(self), NULL);
631         
632     VikSlippyMapSourcePrivate *priv = VIK_SLIPPY_MAP_SOURCE_PRIVATE(self);
633         return g_strdup( priv->hostname );
634 }
635
636 static DownloadFileOptions *
637 _get_download_options( VikMapSourceDefault *self )
638 {
639         g_return_val_if_fail (VIK_IS_SLIPPY_MAP_SOURCE(self), NULL);
640         
641         VikSlippyMapSourcePrivate *priv = VIK_SLIPPY_MAP_SOURCE_PRIVATE(self);
642         return &(priv->options);
643 }
644
645 VikSlippyMapSource *
646 vik_slippy_map_source_new_with_id (guint16 id, const gchar *label, const gchar *hostname, const gchar *url)
647 {
648         return g_object_new(VIK_TYPE_SLIPPY_MAP_SOURCE,
649                             "id", id, "label", label, "hostname", hostname, "url", url, NULL);
650 }