]> git.street.me.uk Git - andy/viking.git/blob - src/expedia.c
Elevation map click and bugfixes
[andy/viking.git] / src / expedia.c
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  */
24
25 #include <gtk/gtk.h>
26 #include <math.h>
27 #include "globals.h"
28 #include "coords.h"
29 #include "vikcoord.h"
30 #include "mapcoord.h"
31 #include "http.h"
32
33
34 #define EXPEDIA_SITE "expedia.com"
35 #define MPP_MARGIN_OF_ERROR 0.01
36 #define DEGREES_TO_RADS 0.0174532925
37 #define HEIGHT_OF_LAT_DEGREE (111318.84502/ALTI_TO_MPP)
38 #define HEIGHT_OF_LAT_MINUTE (1855.3140837/ALTI_TO_MPP)
39 #define WIDTH_BUFFER 0
40 #define HEIGHT_BUFFER 25
41 #define REAL_WIDTH_BUFFER 1
42 #define REAL_HEIGHT_BUFFER 26
43
44 /* first buffer is to cut off the expedia/microsoft logo. Annoying little buggers ;) */
45 /* second is to allow for a 1-pixel overlap on each side. this is a good thing (tm) */
46
47 static const guint expedia_altis[]              = { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512 };
48 /* square this number to find out how many per square degree. */
49 static const gdouble expedia_altis_degree_freq[]  = { 120, 60, 30, 15, 8, 4, 2, 1, 1, 1 };
50 static const guint expedia_altis_count = sizeof(expedia_altis) / sizeof(expedia_altis[0]);
51
52 gdouble expedia_altis_freq ( gint alti )
53 {
54   static gint i;
55   for ( i = 0; i < expedia_altis_count; i++ )
56     if ( expedia_altis[i] == alti )
57       return expedia_altis_degree_freq [ i ];
58
59   g_error ( "Invalid expedia altitude" );
60   return 0;
61 }
62
63 /* returns -1 if none of the above. */
64 gint expedia_zoom_to_alti ( gdouble zoom )
65 {
66   guint i;
67   for ( i = 0; i < expedia_altis_count; i++ )
68     if ( fabs(expedia_altis[i] - zoom) / zoom < MPP_MARGIN_OF_ERROR )
69       return expedia_altis[i];
70   return -1;
71 }
72
73 /*
74 gint expedia_pseudo_zone ( gint alti, gint x, gint y )
75 {
76   return (int) (x/expedia_altis_freq(alti)*180) + (int) (y/expedia_altis_freq(alti)*90);
77 }
78 */
79
80 void expedia_snip ( const gchar *file )
81 {
82   /* Load the pixbuf */
83   GError *gx = NULL;
84   GdkPixbuf *old, *cropped;
85   gint width, height;
86
87   old = gdk_pixbuf_new_from_file ( file, &gx );
88   if (gx)
89   {
90     g_warning ( "Couldn't open EXPEDIA image file (right after successful download! Please report and delete image file!): %s", gx->message );
91     g_error_free ( gx );
92     return;
93   }
94
95   width = gdk_pixbuf_get_width ( old );
96   height = gdk_pixbuf_get_height ( old );
97
98   cropped = gdk_pixbuf_new_subpixbuf ( old, WIDTH_BUFFER, HEIGHT_BUFFER,
99                               width - 2*WIDTH_BUFFER, height - 2*HEIGHT_BUFFER );
100
101   gdk_pixbuf_save ( cropped, file, "png", NULL, NULL, &gx );
102   if ( gx ) {
103     g_warning ( "Couldn't save EXPEDIA image file (right after successful download! Please report and delete image file!): %s", gx->message );
104     g_error_free ( gx );
105   }
106
107   g_object_unref ( cropped );
108   g_object_unref ( old );
109 }
110
111 /* if degree_freeq = 60 -> nearest minute (in middle) */
112 /* everything starts at -90,-180 -> 0,0. then increments by (1/degree_freq) */
113 gboolean expedia_coord_to_mapcoord ( const VikCoord *src, gdouble xzoom, gdouble yzoom, MapCoord *dest )
114 {
115   gint alti;
116
117   g_assert ( src->mode == VIK_COORD_LATLON );
118
119   if ( xzoom != yzoom )
120     return FALSE;
121
122   alti = expedia_zoom_to_alti ( xzoom );
123   if ( alti != -1 )
124   {
125     dest->scale = alti;
126     dest->x = (int) (((src->east_west+180) * expedia_altis_freq(alti))+0.5);
127     dest->y = (int) (((src->north_south+90) * expedia_altis_freq(alti))+0.5);
128     /* + 0.5 to round off and not floor */
129
130     /* just to space out tiles on the filesystem */
131     dest->z = 0;
132     return TRUE;
133   }
134   return FALSE;
135 }
136
137 void expedia_xy_to_latlon_middle ( gint alti, gint x, gint y, struct LatLon *ll )
138 {
139   ll->lon = (((gdouble)x) / expedia_altis_freq(alti)) - 180;
140   ll->lat = (((gdouble)y) / expedia_altis_freq(alti)) - 90;
141 }
142
143 void expedia_mapcoord_to_center_coord ( MapCoord *src, VikCoord *dest )
144 {
145   dest->mode = VIK_COORD_LATLON;
146   dest->east_west = (((gdouble)src->x) / expedia_altis_freq(src->scale)) - 180;
147   dest->north_south = (((gdouble)src->y) / expedia_altis_freq(src->scale)) - 90;
148 }
149
150 void expedia_download ( MapCoord *src, const gchar *dest_fn )
151 {
152   gint height, width;
153   struct LatLon ll;
154   gchar *uri;
155
156   expedia_xy_to_latlon_middle ( src->scale, src->x, src->y, &ll );
157
158   height = HEIGHT_OF_LAT_DEGREE / expedia_altis_freq(src->scale) / (src->scale);
159   width = height * cos ( ll.lat * DEGREES_TO_RADS );
160
161   height += 2*REAL_HEIGHT_BUFFER;
162   width  += 2*REAL_WIDTH_BUFFER;
163
164   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",
165                ll.lat, ll.lon, (ll.lon > -30) ? "EUR0809" : "USA0409", src->scale, width, height );
166
167   a_http_download_get_url_nohostname ( "expedia.com", uri, dest_fn );
168
169   expedia_snip ( dest_fn );
170 }
171
172