X-Git-Url: https://git.street.me.uk/andy/viking.git/blobdiff_plain/50a14534a51f892500ee82f867e8ab2f85b936ae..6d0927b1b61b1f2f9ec5d048d85d8a4cad24f649:/src/vikviewport.c diff --git a/src/vikviewport.c b/src/vikviewport.c index 78f9a7cc..65028819 100644 --- a/src/vikviewport.c +++ b/src/vikviewport.c @@ -23,22 +23,26 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif #define DEFAULT_BACKGROUND_COLOR "#CCCCCC" #include +#ifdef HAVE_MATH_H #include +#endif #include "coords.h" #include "vikcoord.h" +#include "vikwindow.h" #include "vikviewport.h" #include "mapcoord.h" /* for ALTI_TO_MPP */ #include "globals.h" -#include "googlemaps.h" -#include "khmaps.h" static gdouble EASTING_OFFSET = 500000.0; @@ -56,8 +60,6 @@ static void viewport_init_ra(); static GObjectClass *parent_class; -static void viewport_google_rezoom ( VikViewport *vvp ); - struct _VikViewport { GtkDrawingArea drawing_area; @@ -76,6 +78,9 @@ struct _VikViewport { GdkGC *background_gc; GdkColor background_color; + GdkGC *scale_bg_gc; + gboolean draw_scale; + gboolean draw_centermark; /* subset of coord types. lat lon can be plotted in 2 ways, google or exp. */ VikViewportDrawMode drawmode; @@ -85,6 +90,11 @@ struct _VikViewport { gdouble google_calcy_fact; gdouble google_calcx_rev_fact; gdouble google_calcy_rev_fact; + + /* trigger stuff */ + gpointer trigger; + GdkPixmap *snapshot_buffer; + gboolean half_drawn; }; static gdouble @@ -144,7 +154,8 @@ static void viewport_class_init ( VikViewportClass *klass ) VikViewport *vik_viewport_new () { - return VIK_VIEWPORT ( g_object_new ( VIK_VIEWPORT_TYPE, NULL ) ); + VikViewport *vv = VIK_VIEWPORT ( g_object_new ( VIK_VIEWPORT_TYPE, NULL ) ); + return vv; } static void viewport_init ( VikViewport *vvp ) @@ -154,10 +165,11 @@ static void viewport_init ( VikViewport *vvp ) /* TODO: not static */ vvp->xmpp = 4.0; vvp->ympp = 4.0; - vvp->coord_mode = VIK_COORD_UTM; - vvp->drawmode = VIK_VIEWPORT_DRAWMODE_UTM; - vvp->center.north_south = 0; - vvp->center.east_west = -166021; + vvp->coord_mode = VIK_COORD_LATLON; + vvp->drawmode = VIK_VIEWPORT_DRAWMODE_MERCATOR; + vvp->center.mode = VIK_COORD_LATLON; + vvp->center.north_south = 40.714490; + vvp->center.east_west = -74.007130; vvp->center.utm_zone = 31; vvp->center.utm_letter = 'N'; vvp->scr_buffer = NULL; @@ -165,7 +177,17 @@ static void viewport_init ( VikViewport *vvp ) vvp->alpha_pixbuf_width = vvp->alpha_pixbuf_height = 0; vvp->utm_zone_width = 0.0; vvp->background_gc = NULL; + vvp->scale_bg_gc = NULL; + vvp->draw_scale = TRUE; + vvp->draw_centermark = TRUE; + + vvp->trigger = NULL; + vvp->snapshot_buffer = NULL; + vvp->half_drawn = FALSE; + g_signal_connect (G_OBJECT(vvp), "configure_event", G_CALLBACK(vik_viewport_configure), NULL); + + GTK_WIDGET_SET_FLAGS(vvp, GTK_CAN_FOCUS); /* allow VVP to have focus -- enabling key events, etc */ } GdkColor *vik_viewport_get_background_gdkcolor ( VikViewport *vvp ) @@ -227,6 +249,11 @@ void vik_viewport_configure_manually ( VikViewport *vvp, gint width, guint heigh if ( vvp->scr_buffer ) g_object_unref ( G_OBJECT ( vvp->scr_buffer ) ); vvp->scr_buffer = gdk_pixmap_new ( GTK_WIDGET(vvp)->window, vvp->width, vvp->height, -1 ); + + /* TODO trigger: only if this is enabled !!! */ + if ( vvp->snapshot_buffer ) + g_object_unref ( G_OBJECT ( vvp->snapshot_buffer ) ); + vvp->snapshot_buffer = gdk_pixmap_new ( GTK_WIDGET(vvp)->window, vvp->width, vvp->height, -1 ); } @@ -247,12 +274,22 @@ gboolean vik_viewport_configure ( VikViewport *vvp ) vvp->scr_buffer = gdk_pixmap_new ( GTK_WIDGET(vvp)->window, vvp->width, vvp->height, -1 ); + /* TODO trigger: only if enabled! */ + if ( vvp->snapshot_buffer ) + g_object_unref ( G_OBJECT ( vvp->snapshot_buffer ) ); + + vvp->snapshot_buffer = gdk_pixmap_new ( GTK_WIDGET(vvp)->window, vvp->width, vvp->height, -1 ); + /* TODO trigger */ + /* this is down here so it can get a GC (necessary?) */ if ( ! vvp->background_gc ) { vvp->background_gc = vik_viewport_new_gc ( vvp, "", 1 ); vik_viewport_set_background_color ( vvp, DEFAULT_BACKGROUND_COLOR ); /* set to "backup" color in vvp->background_color */ } + if ( !vvp->scale_bg_gc) { + vvp->scale_bg_gc = vik_viewport_new_gc(vvp, "grey", 3); + } return FALSE; } @@ -266,12 +303,20 @@ static void viewport_finalize ( GObject *gob ) if ( vvp->scr_buffer ) g_object_unref ( G_OBJECT ( vvp->scr_buffer ) ); + if ( vvp->snapshot_buffer ) + g_object_unref ( G_OBJECT ( vvp->snapshot_buffer ) ); + if ( vvp->alpha_pixbuf ) g_object_unref ( G_OBJECT ( vvp->alpha_pixbuf ) ); if ( vvp->background_gc ) g_object_unref ( G_OBJECT ( vvp->background_gc ) ); + if ( vvp->scale_bg_gc ) { + g_object_unref ( G_OBJECT ( vvp->scale_bg_gc ) ); + vvp->scale_bg_gc = NULL; + } + G_OBJECT_CLASS(parent_class)->finalize(gob); } @@ -281,6 +326,132 @@ void vik_viewport_clear ( VikViewport *vvp ) gdk_draw_rectangle(GDK_DRAWABLE(vvp->scr_buffer), vvp->background_gc, TRUE, 0, 0, vvp->width, vvp->height); } +void vik_viewport_set_draw_scale ( VikViewport *vvp, gboolean draw_scale ) +{ + vvp->draw_scale = draw_scale; +} + +gboolean vik_viewport_get_draw_scale ( VikViewport *vvp ) +{ + return vvp->draw_scale; +} + +void vik_viewport_draw_scale ( VikViewport *vvp ) +{ + if ( vvp->draw_scale ) { + VikCoord left, right; + gdouble unit, base, diff, old_unit, old_diff, ratio; + gint odd, len, PAD = 10, SCSIZE = 5, HEIGHT=10; + PangoFontDescription *pfd; + PangoLayout *pl; + gchar s[128]; + + g_return_if_fail ( vvp != NULL ); + + vik_viewport_screen_to_coord ( vvp, 0, vvp->height, &left ); + vik_viewport_screen_to_coord ( vvp, vvp->width/SCSIZE, vvp->height, &right ); + + base = vik_coord_diff ( &left, &right ); // in meters + ratio = (vvp->width/SCSIZE)/base; + + unit = 1; + diff = fabs(base-unit); + old_unit = unit; + old_diff = diff; + odd = 1; + while (diff <= old_diff) { + old_unit = unit; + old_diff = diff; + unit = unit * (odd%2 ? 5 : 2); + diff = fabs(base-unit); + odd++; + } + unit = old_unit; + len = unit * ratio; + + /* white background */ + vik_viewport_draw_line(vvp, vvp->scale_bg_gc, + PAD, vvp->height-PAD, PAD + len, vvp->height-PAD); + vik_viewport_draw_line(vvp, vvp->scale_bg_gc, + PAD, vvp->height-PAD, PAD, vvp->height-PAD-HEIGHT); + vik_viewport_draw_line(vvp, vvp->scale_bg_gc, + PAD + len, vvp->height-PAD, PAD + len, vvp->height-PAD-HEIGHT); + /* black scale */ + vik_viewport_draw_line(vvp, GTK_WIDGET(&vvp->drawing_area)->style->black_gc, + PAD, vvp->height-PAD, PAD + len, vvp->height-PAD); + vik_viewport_draw_line(vvp, GTK_WIDGET(&vvp->drawing_area)->style->black_gc, + PAD, vvp->height-PAD, PAD, vvp->height-PAD-HEIGHT); + vik_viewport_draw_line(vvp, GTK_WIDGET(&vvp->drawing_area)->style->black_gc, + PAD + len, vvp->height-PAD, PAD + len, vvp->height-PAD-HEIGHT); + if (odd%2) { + int i; + for (i=1; i<5; i++) { + vik_viewport_draw_line(vvp, vvp->scale_bg_gc, + PAD+i*len/5, vvp->height-PAD, PAD+i*len/5, vvp->height-PAD-((i==5)?(2*HEIGHT/3):(HEIGHT/2))); + vik_viewport_draw_line(vvp, GTK_WIDGET(&vvp->drawing_area)->style->black_gc, + PAD+i*len/5, vvp->height-PAD, PAD+i*len/5, vvp->height-PAD-((i==5)?(2*HEIGHT/3):(HEIGHT/2))); + } + } else { + int i; + for (i=1; i<10; i++) { + vik_viewport_draw_line(vvp, vvp->scale_bg_gc, + PAD+i*len/10, vvp->height-PAD, PAD+i*len/10, vvp->height-PAD-((i==5)?(2*HEIGHT/3):(HEIGHT/2))); + vik_viewport_draw_line(vvp, GTK_WIDGET(&vvp->drawing_area)->style->black_gc, + PAD+i*len/10, vvp->height-PAD, PAD+i*len/10, vvp->height-PAD-((i==5)?(2*HEIGHT/3):(HEIGHT/2))); + } + } + pl = gtk_widget_create_pango_layout (GTK_WIDGET(&vvp->drawing_area), NULL); + pfd = pango_font_description_from_string ("Sans 8"); // FIXME: settable option? global variable? + pango_layout_set_font_description (pl, pfd); + pango_font_description_free (pfd); + + if (unit >= 1000) { + sprintf(s, "%d km", (int)unit/1000); + } else { + sprintf(s, "%d m", (int)unit); + } + pango_layout_set_text(pl, s, -1); + vik_viewport_draw_layout(vvp, GTK_WIDGET(&vvp->drawing_area)->style->black_gc, + PAD + len + PAD, vvp->height - PAD - 10, pl); + g_object_unref(pl); + pl = NULL; + } +} + +void vik_viewport_set_draw_centermark ( VikViewport *vvp, gboolean draw_centermark ) +{ + vvp->draw_centermark = draw_centermark; +} + +gboolean vik_viewport_get_draw_centermark ( VikViewport *vvp ) +{ + return vvp->draw_centermark; +} + +void vik_viewport_draw_centermark ( VikViewport *vvp ) +{ + if ( !vvp->draw_centermark ) + return; + + const int len = 30; + const int gap = 4; + int center_x = vvp->width/2; + int center_y = vvp->height/2; + GdkGC * black_gc = GTK_WIDGET(&vvp->drawing_area)->style->black_gc; + + /* white back ground */ + vik_viewport_draw_line(vvp, vvp->scale_bg_gc, center_x - len, center_y, center_x - gap, center_y); + vik_viewport_draw_line(vvp, vvp->scale_bg_gc, center_x + gap, center_y, center_x + len, center_y); + vik_viewport_draw_line(vvp, vvp->scale_bg_gc, center_x, center_y - len, center_x, center_y - gap); + vik_viewport_draw_line(vvp, vvp->scale_bg_gc, center_x, center_y + gap, center_x, center_y + len); + /* black fore ground */ + vik_viewport_draw_line(vvp, black_gc, center_x - len, center_y, center_x - gap, center_y); + vik_viewport_draw_line(vvp, black_gc, center_x + gap, center_y, center_x + len, center_y); + vik_viewport_draw_line(vvp, black_gc, center_x, center_y - len, center_x, center_y - gap); + vik_viewport_draw_line(vvp, black_gc, center_x, center_y + gap, center_x, center_y + len); + +} + void vik_viewport_sync ( VikViewport *vvp ) { g_return_if_fail ( vvp != NULL ); @@ -289,8 +460,27 @@ void vik_viewport_sync ( VikViewport *vvp ) void vik_viewport_pan_sync ( VikViewport *vvp, gint x_off, gint y_off ) { + gint x, y, wid, hei; + g_return_if_fail ( vvp != NULL ); gdk_draw_drawable(GTK_WIDGET(vvp)->window, GTK_WIDGET(vvp)->style->bg_gc[0], GDK_DRAWABLE(vvp->scr_buffer), 0, 0, x_off, y_off, vvp->width, vvp->height); + + if (x_off >= 0) { + x = 0; + wid = x_off; + } else { + x = vvp->width+x_off; + wid = -x_off; + } + if (y_off >= 0) { + y = 0; + hei = y_off; + } else { + y = vvp->height+y_off; + hei = -y_off; + } + gtk_widget_queue_draw_area(GTK_WIDGET(vvp), x, 0, wid, vvp->height); + gtk_widget_queue_draw_area(GTK_WIDGET(vvp), 0, y, vvp->width, hei); } void vik_viewport_set_zoom ( VikViewport *vvp, gdouble xympp ) @@ -301,8 +491,6 @@ void vik_viewport_set_zoom ( VikViewport *vvp, gdouble xympp ) if ( vvp->drawmode == VIK_VIEWPORT_DRAWMODE_UTM ) viewport_utm_zone_check(vvp); - else if ( vvp->drawmode == VIK_VIEWPORT_DRAWMODE_GOOGLE ) - viewport_google_rezoom ( vvp ); } /* or could do factor */ @@ -314,9 +502,6 @@ void vik_viewport_zoom_in ( VikViewport *vvp ) vvp->xmpp /= 2; vvp->ympp /= 2; - if ( vvp->drawmode == VIK_VIEWPORT_DRAWMODE_GOOGLE ) - viewport_google_rezoom ( vvp ); - viewport_utm_zone_check(vvp); } } @@ -329,9 +514,6 @@ void vik_viewport_zoom_out ( VikViewport *vvp ) vvp->xmpp *= 2; vvp->ympp *= 2; - if ( vvp->drawmode == VIK_VIEWPORT_DRAWMODE_GOOGLE ) - viewport_google_rezoom ( vvp ); - viewport_utm_zone_check(vvp); } } @@ -359,8 +541,6 @@ void vik_viewport_set_xmpp ( VikViewport *vvp, gdouble xmpp ) vvp->xmpp = xmpp; if ( vvp->drawmode == VIK_VIEWPORT_DRAWMODE_UTM ) viewport_utm_zone_check(vvp); - if ( vvp->drawmode == VIK_VIEWPORT_DRAWMODE_GOOGLE ) - viewport_google_rezoom ( vvp ); } } @@ -370,8 +550,6 @@ void vik_viewport_set_ympp ( VikViewport *vvp, gdouble ympp ) vvp->ympp = ympp; if ( vvp->drawmode == VIK_VIEWPORT_DRAWMODE_UTM ) viewport_utm_zone_check(vvp); - if ( vvp->drawmode == VIK_VIEWPORT_DRAWMODE_GOOGLE ) - viewport_google_rezoom ( vvp ); } } @@ -515,14 +693,7 @@ void vik_viewport_screen_to_coord ( VikViewport *vvp, int x, int y, VikCoord *co coord->mode = VIK_COORD_LATLON; if ( vvp->drawmode == VIK_VIEWPORT_DRAWMODE_EXPEDIA ) calcxy_rev(&(coord->east_west), &(coord->north_south), x, y, vvp->center.east_west, vvp->center.north_south, vvp->xmpp * ALTI_TO_MPP, vvp->ympp * ALTI_TO_MPP, vvp->width/2, vvp->height/2); - else if ( vvp->drawmode == VIK_VIEWPORT_DRAWMODE_GOOGLE ) { - /* google */ - coord->east_west = (x - (vvp->width/2)) * vvp->google_calcx_rev_fact + vvp->center.east_west; - coord->north_south = ((vvp->height/2) - y) * vvp->google_calcy_rev_fact + vvp->center.north_south; - } else if ( vvp->drawmode == VIK_VIEWPORT_DRAWMODE_KH ) { - coord->east_west = vvp->center.east_west + (180.0 * vvp->xmpp / 65536 / 256 * (x - vvp->width/2)); - coord->north_south = vvp->center.north_south + (180.0 * vvp->ympp / 65536 / 256 * (vvp->height/2 - y)); - } else if ( vvp->drawmode == VIK_VIEWPORT_DRAWMODE_MERCATOR ) { + else if ( vvp->drawmode == VIK_VIEWPORT_DRAWMODE_MERCATOR ) { /* FIXMERCATOR */ coord->east_west = vvp->center.east_west + (180.0 * vvp->xmpp / 65536 / 256 * (x - vvp->width/2)); coord->north_south = DEMERCLAT ( MERCLAT(vvp->center.north_south) + (180.0 * vvp->ympp / 65536 / 256 * (vvp->height/2 - y)) ); @@ -569,14 +740,6 @@ void vik_viewport_coord_to_screen ( VikViewport *vvp, const VikCoord *coord, int if ( vvp->drawmode == VIK_VIEWPORT_DRAWMODE_EXPEDIA ) { calcxy ( &xx, &yy, center->lon, center->lat, ll->lon, ll->lat, vvp->xmpp * ALTI_TO_MPP, vvp->ympp * ALTI_TO_MPP, vvp->width / 2, vvp->height / 2 ); *x = xx; *y = yy; - } else if ( vvp->drawmode == VIK_VIEWPORT_DRAWMODE_GOOGLE ) { - /* google */ - *x = vvp->google_calcx_fact * (ll->lon - center->lon) + (vvp->width/2); - *y = vvp->google_calcy_fact * (center->lat - ll->lat) + (vvp->height/2); - } else if ( vvp->drawmode == VIK_VIEWPORT_DRAWMODE_KH ) { - /* subtract, convert to KH coords; blow it up by 256 */ - *x = vvp->width/2 + (65536.0 / 180 / vvp->xmpp * (ll->lon - center->lon))*256.0; - *y = vvp->height/2 + (65536.0 / 180 / vvp->ympp * (center->lat - ll->lat))*256.0; } else if ( vvp->drawmode == VIK_VIEWPORT_DRAWMODE_MERCATOR ) { /* FIXMERCATOR: Optimize */ *x = vvp->width/2 + (65536.0 / 180 / vvp->xmpp * (ll->lon - center->lon))*256.0; @@ -585,11 +748,36 @@ void vik_viewport_coord_to_screen ( VikViewport *vvp, const VikCoord *coord, int } } +void a_viewport_clip_line ( gint *x1, gint *y1, gint *x2, gint *y2 ) +{ + if ( *x1 > 20000 || *x1 < -20000 ) { + gdouble shrinkfactor = ABS(20000.0 / *x1); + *x1 = *x2 + (shrinkfactor * (*x1-*x2)); + *y1 = *y2 + (shrinkfactor * (*y1-*y2)); + } else if ( *y1 > 20000 || *y1 < -20000 ) { + gdouble shrinkfactor = ABS(20000.0 / *x1); + *x1 = *x2 + (shrinkfactor * (*x1-*x2)); + *y1 = *y2 + (shrinkfactor * (*y1-*y2)); + } else if ( *x2 > 20000 || *x2 < -20000 ) { + gdouble shrinkfactor = ABS(20000.0 / (gdouble)*x2); + *x2 = *x1 + (shrinkfactor * (*x2-*x1)); + *y2 = *y1 + (shrinkfactor * (*y2-*y1)); + g_print("%f, %d, %d\n", shrinkfactor, *x2, *y2); + } else if ( *y2 > 20000 || *y2 < -20000 ) { + gdouble shrinkfactor = ABS(20000.0 / (gdouble)*x2); + *x2 = *x1 + (shrinkfactor * (*x2-*x1)); + *y2 = *y1 + (shrinkfactor * (*y2-*y1)); + } +} + void vik_viewport_draw_line ( VikViewport *vvp, GdkGC *gc, gint x1, gint y1, gint x2, gint y2 ) { if ( ! ( ( x1 < 0 && x2 < 0 ) || ( y1 < 0 && y2 < 0 ) || - ( x1 > vvp->width && x2 > vvp->width ) || ( y1 > vvp->height && y2 > vvp->height ) ) ) - gdk_draw_line ( vvp->scr_buffer, gc, x1, y1, x2, y2); + ( x1 > vvp->width && x2 > vvp->width ) || ( y1 > vvp->height && y2 > vvp->height ) ) ) { + /*** clipping, yeah! ***/ + a_viewport_clip_line ( &x1, &y1, &x2, &y2 ); + gdk_draw_line ( vvp->scr_buffer, gc, x1, y1, x2, y2); + } } void vik_viewport_draw_rectangle ( VikViewport *vvp, GdkGC *gc, gboolean filled, gint x1, gint y1, gint x2, gint y2 ) @@ -805,8 +993,6 @@ void vik_viewport_set_drawmode ( VikViewport *vvp, VikViewportDrawMode drawmode viewport_set_coord_mode ( vvp, VIK_COORD_UTM ); else { viewport_set_coord_mode ( vvp, VIK_COORD_LATLON ); - if ( drawmode == VIK_VIEWPORT_DRAWMODE_GOOGLE ) - viewport_google_rezoom ( vvp ); } } @@ -815,10 +1001,71 @@ VikViewportDrawMode vik_viewport_get_drawmode ( VikViewport *vvp ) return vvp->drawmode; } -static void viewport_google_rezoom ( VikViewport *vvp ) +/******** triggering *******/ +void vik_viewport_set_trigger ( VikViewport *vp, gpointer trigger ) +{ + vp->trigger = trigger; +} + +gpointer vik_viewport_get_trigger ( VikViewport *vp ) +{ + return vp->trigger; +} + +void vik_viewport_snapshot_save ( VikViewport *vp ) +{ + gdk_draw_drawable ( vp->snapshot_buffer, vp->background_gc, vp->scr_buffer, 0, 0, 0, 0, -1, -1 ); +} + +void vik_viewport_snapshot_load ( VikViewport *vp ) +{ + gdk_draw_drawable ( vp->scr_buffer, vp->background_gc, vp->snapshot_buffer, 0, 0, 0, 0, -1, -1 ); +} + +void vik_viewport_set_half_drawn(VikViewport *vp, gboolean half_drawn) +{ + vp->half_drawn = half_drawn; +} + +gboolean vik_viewport_get_half_drawn( VikViewport *vp ) +{ + return vp->half_drawn; +} + + +const gchar *vik_viewport_get_drawmode_name(VikViewport *vv, VikViewportDrawMode mode) + { + const gchar *name = NULL; + VikWindow *vw = NULL; + GtkWidget *mode_button; + GtkWidget *label; + + vw = VIK_WINDOW_FROM_WIDGET(vv); + mode_button = vik_window_get_drawmode_button(vw, mode); + label = gtk_bin_get_child(GTK_BIN(mode_button)); + + name = gtk_label_get_text ( GTK_LABEL(label) ); + + return name; + +} + +void vik_viewport_get_min_max_lat_lon ( VikViewport *vp, gdouble *min_lat, gdouble *max_lat, gdouble *min_lon, gdouble *max_lon ) { - vvp->google_calcx_fact = (GOOGLEMAPS_ZOOM_ONE_MPP * 65536.0 * 0.7716245833877 / vvp->xmpp); - vvp->google_calcy_fact = (GOOGLEMAPS_ZOOM_ONE_MPP * 65536.0 / vvp->ympp); - vvp->google_calcx_rev_fact = 1 / vvp->google_calcx_fact; - vvp->google_calcy_rev_fact = 1 / vvp->google_calcy_fact; + VikCoord tleft, tright, bleft, bright; + + vik_viewport_screen_to_coord ( vp, 0, 0, &tleft ); + vik_viewport_screen_to_coord ( vp, vik_viewport_get_width(vp), 0, &tright ); + vik_viewport_screen_to_coord ( vp, 0, vik_viewport_get_height(vp), &bleft ); + vik_viewport_screen_to_coord ( vp, vp->width, vp->height, &bright ); + + vik_coord_convert(&tleft, VIK_COORD_LATLON); + vik_coord_convert(&tright, VIK_COORD_LATLON); + vik_coord_convert(&bleft, VIK_COORD_LATLON); + vik_coord_convert(&bright, VIK_COORD_LATLON); + + *max_lat = MAX(tleft.north_south, tright.north_south); + *min_lat = MIN(bleft.north_south, bright.north_south); + *max_lon = MAX(tright.east_west, bright.east_west); + *min_lon = MIN(tleft.east_west, bleft.east_west); }