]> git.street.me.uk Git - andy/viking.git/blame - src/expedia.c
SF Features#116: Add an Acquire From URL option.
[andy/viking.git] / src / expedia.c
CommitLineData
50a14534
EB
1/*
2 * viking -- GPS Data and Topo Analyzer, Explorer, and Manager
3 *
4 * Copyright (C) 2005, Evan Battaglia <viking@greentorch.org>
5 *
6 * Some formulas or perhaps even code derived from GPSDrive
7 * GPSDrive Copyright (C) 2001-2004 Fritz Ganter <ganter@ganter.at>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
23 */
4c77d5e0
GB
24#ifdef HAVE_CONFIG_H
25#include "config.h"
26#endif
50a14534 27
4c77d5e0 28#include <glib/gi18n.h>
50a14534 29#include <gtk/gtk.h>
8c00358d 30#ifdef HAVE_MATH_H
50a14534 31#include <math.h>
8c00358d
GB
32#endif
33
50a14534
EB
34#include "globals.h"
35#include "coords.h"
36#include "vikcoord.h"
37#include "mapcoord.h"
85611cd9 38#include "download.h"
cdcaf41c 39#include "vikmapslayer.h"
50a14534 40
cdcaf41c
QT
41#include "expedia.h"
42
96bcc8cb
QT
43static gboolean expedia_coord_to_mapcoord ( const VikCoord *src, gdouble xzoom, gdouble yzoom, MapCoord *dest );
44static void expedia_mapcoord_to_center_coord ( MapCoord *src, VikCoord *dest );
c21cf491
RN
45static int expedia_download ( MapCoord *src, const gchar *dest_fn, void *handle );
46static void * expedia_handle_init ( );
47static void expedia_handle_cleanup ( void *handle );
96bcc8cb 48
a3697549 49static DownloadMapOptions expedia_options = { FALSE, FALSE, NULL, 2, a_check_map_file, NULL };
80214df2 50
cdcaf41c 51void expedia_init() {
c21cf491 52 VikMapsLayer_MapType map_type = { 5, 0, 0, VIK_VIEWPORT_DRAWMODE_EXPEDIA, expedia_coord_to_mapcoord, expedia_mapcoord_to_center_coord, expedia_download, expedia_handle_init, expedia_handle_cleanup };
4c77d5e0 53 maps_layer_register_type(_("Expedia Street Maps"), 5, &map_type);
cdcaf41c 54}
50a14534
EB
55
56#define EXPEDIA_SITE "expedia.com"
57#define MPP_MARGIN_OF_ERROR 0.01
58#define DEGREES_TO_RADS 0.0174532925
59#define HEIGHT_OF_LAT_DEGREE (111318.84502/ALTI_TO_MPP)
60#define HEIGHT_OF_LAT_MINUTE (1855.3140837/ALTI_TO_MPP)
61#define WIDTH_BUFFER 0
62#define HEIGHT_BUFFER 25
63#define REAL_WIDTH_BUFFER 1
64#define REAL_HEIGHT_BUFFER 26
65
66/* first buffer is to cut off the expedia/microsoft logo. Annoying little buggers ;) */
67/* second is to allow for a 1-pixel overlap on each side. this is a good thing (tm) */
68
69static const guint expedia_altis[] = { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512 };
70/* square this number to find out how many per square degree. */
71static const gdouble expedia_altis_degree_freq[] = { 120, 60, 30, 15, 8, 4, 2, 1, 1, 1 };
72static const guint expedia_altis_count = sizeof(expedia_altis) / sizeof(expedia_altis[0]);
73
74gdouble expedia_altis_freq ( gint alti )
75{
76 static gint i;
77 for ( i = 0; i < expedia_altis_count; i++ )
78 if ( expedia_altis[i] == alti )
79 return expedia_altis_degree_freq [ i ];
80
4c77d5e0 81 g_error ( _("Invalid expedia altitude") );
50a14534
EB
82 return 0;
83}
84
85/* returns -1 if none of the above. */
86gint expedia_zoom_to_alti ( gdouble zoom )
87{
88 guint i;
89 for ( i = 0; i < expedia_altis_count; i++ )
90 if ( fabs(expedia_altis[i] - zoom) / zoom < MPP_MARGIN_OF_ERROR )
91 return expedia_altis[i];
92 return -1;
93}
94
95/*
96gint expedia_pseudo_zone ( gint alti, gint x, gint y )
97{
98 return (int) (x/expedia_altis_freq(alti)*180) + (int) (y/expedia_altis_freq(alti)*90);
99}
100*/
101
102void expedia_snip ( const gchar *file )
103{
104 /* Load the pixbuf */
105 GError *gx = NULL;
106 GdkPixbuf *old, *cropped;
107 gint width, height;
108
109 old = gdk_pixbuf_new_from_file ( file, &gx );
110 if (gx)
111 {
4c77d5e0 112 g_warning ( _("Couldn't open EXPEDIA image file (right after successful download! Please report and delete image file!): %s"), gx->message );
50a14534
EB
113 g_error_free ( gx );
114 return;
115 }
116
117 width = gdk_pixbuf_get_width ( old );
118 height = gdk_pixbuf_get_height ( old );
119
120 cropped = gdk_pixbuf_new_subpixbuf ( old, WIDTH_BUFFER, HEIGHT_BUFFER,
121 width - 2*WIDTH_BUFFER, height - 2*HEIGHT_BUFFER );
122
3adc68b0 123 gdk_pixbuf_save ( cropped, file, "png", &gx, NULL );
50a14534 124 if ( gx ) {
4c77d5e0 125 g_warning ( _("Couldn't save EXPEDIA image file (right after successful download! Please report and delete image file!): %s"), gx->message );
50a14534
EB
126 g_error_free ( gx );
127 }
128
129 g_object_unref ( cropped );
130 g_object_unref ( old );
131}
132
133/* if degree_freeq = 60 -> nearest minute (in middle) */
134/* everything starts at -90,-180 -> 0,0. then increments by (1/degree_freq) */
96bcc8cb 135static gboolean expedia_coord_to_mapcoord ( const VikCoord *src, gdouble xzoom, gdouble yzoom, MapCoord *dest )
50a14534
EB
136{
137 gint alti;
138
139 g_assert ( src->mode == VIK_COORD_LATLON );
140
141 if ( xzoom != yzoom )
142 return FALSE;
143
144 alti = expedia_zoom_to_alti ( xzoom );
145 if ( alti != -1 )
146 {
147 dest->scale = alti;
148 dest->x = (int) (((src->east_west+180) * expedia_altis_freq(alti))+0.5);
149 dest->y = (int) (((src->north_south+90) * expedia_altis_freq(alti))+0.5);
150 /* + 0.5 to round off and not floor */
151
152 /* just to space out tiles on the filesystem */
153 dest->z = 0;
154 return TRUE;
155 }
156 return FALSE;
157}
158
159void expedia_xy_to_latlon_middle ( gint alti, gint x, gint y, struct LatLon *ll )
160{
161 ll->lon = (((gdouble)x) / expedia_altis_freq(alti)) - 180;
162 ll->lat = (((gdouble)y) / expedia_altis_freq(alti)) - 90;
163}
164
96bcc8cb 165static void expedia_mapcoord_to_center_coord ( MapCoord *src, VikCoord *dest )
50a14534
EB
166{
167 dest->mode = VIK_COORD_LATLON;
168 dest->east_west = (((gdouble)src->x) / expedia_altis_freq(src->scale)) - 180;
169 dest->north_south = (((gdouble)src->y) / expedia_altis_freq(src->scale)) - 90;
170}
171
c21cf491 172static int expedia_download ( MapCoord *src, const gchar *dest_fn, void *handle )
50a14534
EB
173{
174 gint height, width;
175 struct LatLon ll;
176 gchar *uri;
96bcc8cb 177 int res = -1;
50a14534
EB
178
179 expedia_xy_to_latlon_middle ( src->scale, src->x, src->y, &ll );
180
181 height = HEIGHT_OF_LAT_DEGREE / expedia_altis_freq(src->scale) / (src->scale);
182 width = height * cos ( ll.lat * DEGREES_TO_RADS );
183
184 height += 2*REAL_HEIGHT_BUFFER;
185 width += 2*REAL_WIDTH_BUFFER;
186
187 uri = g_strdup_printf ( "/pub/agent.dll?qscr=mrdt&ID=3XNsF.&CenP=%lf,%lf&Lang=%s&Alti=%d&Size=%d,%d&Offs=0.000000,0.000000&BCheck&tpid=1",
188 ll.lat, ll.lon, (ll.lon > -30) ? "EUR0809" : "USA0409", src->scale, width, height );
189
fcdced54 190 if ((res = a_http_download_get_url ( EXPEDIA_SITE, uri, dest_fn, &expedia_options, NULL )) == 0) /* All OK */
96bcc8cb 191 expedia_snip ( dest_fn );
97634600 192 g_free(uri);
96bcc8cb 193 return(res);
50a14534
EB
194}
195
c21cf491
RN
196static void * expedia_handle_init ( )
197{
198 // Not much going on here
199 return 0;
200}
201
202static void expedia_handle_cleanup ( void *handle )
203{
204 // Even less here!
205}