From 14d71d96fdc48df1834cfd6cc1805b4482f00c17 Mon Sep 17 00:00:00 2001 From: Kaj-Michael Lang Date: Wed, 11 Jun 2008 17:10:32 +0300 Subject: [PATCH] Remove old map sources --- src/map.c | 1682 ----------------------------------------------------- src/map.h | 218 ------- 2 files changed, 1900 deletions(-) delete mode 100644 src/map.c delete mode 100644 src/map.h diff --git a/src/map.c b/src/map.c deleted file mode 100644 index 6377753..0000000 --- a/src/map.c +++ /dev/null @@ -1,1682 +0,0 @@ -/* - * This file is part of mapper - * - * Copyright (C) 2007 Kaj-Michael Lang - * Copyright (C) 2006-2007 John Costigan. - * - * POI and GPS-Info code originally written by Cezary Jackiewicz. - * - * Default map data provided by http://www.openstreetmap.org/ - * - * This program 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 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "hildon-mapper.h" - -#include "utils.h" -#include "map.h" -#include "osm.h" -#include "db.h" -#include "osm-db.h" -#include "poi.h" -#include "route.h" -#include "track.h" -#include "gps.h" -#include "mapper-types.h" -#include "ui-common.h" -#include "settings.h" -#include "latlon.h" -#include "gpx.h" -#include "speak.h" -#include "map-poi.h" -#include "map-download.h" -#include "announcements.h" -#include "gtkcompass.h" -#include "dialogs.h" -#include "image-cache.h" - -#define DEBUG_MAP_TIME 1 - -#define MAP_THUMB_MARGIN_X (100) -#define MAP_THUMB_MARGIN_Y (75) - -/* Initial size */ -#define BUF_WIDTH_TILES (4) -#define BUF_HEIGHT_TILES (3) -#define BUF_WIDTH_PIXELS (1024) -#define BUF_HEIGHT_PIXELS (768) - -static guint buf_width_tiles=BUF_WIDTH_TILES; -static guint buf_height_tiles=BUF_HEIGHT_TILES; -static guint buf_width_pixels=BUF_WIDTH_PIXELS; -static guint buf_height_pixels=BUF_HEIGHT_PIXELS; - -#ifdef WITH_GL -#include -#include -GdkGLConfig* map_gl_config=NULL; -#endif -gboolean map_gl=FALSE; - -#ifdef WITH_CAIRO -cairo_t *ct_pixmap; -#endif - -/** The backing pixmap of map_widget. */ -static GdkPixmap *map_pixmap; - -/* Tile cache, this might need some adjustment */ -#define MAP_CACHE_DEFAULT (64) -static ImageCache *map_ic; - -/** The "base tile" is the upper-left tile in the pixmap. */ -guint _base_tilex = -5; -guint _base_tiley = -5; - -static guint map_max_zoom=MAX_ZOOM; -guint _zoom = 3; /* zoom level, from 0 to MAX_ZOOM. */ - -Point _min_center = { -1, -1 }; -Point _max_center = { -1, -1 }; -Point _focus = { -1, -1 }; -/* current center location, X. */ -Point _center = { -1, -1 }; - -CenterMode _center_mode = CENTER_LEAD; - -/* Drag */ -static guint press[2] = { 0, 0 }; -static guint release[2] = { 0, 0 }; -static guint before[2] = { 0, 0 }; -static guint map_drag_id = 0; -static gboolean map_dragged; - -/** VARIABLES FOR ACCESSING THE LOCATION/BOUNDS OF THE CURRENT MARK. */ -static gint mark_x1; -static gint mark_x2; -static gint mark_y1; -static gint mark_y2; -static gint mark_minx; -static gint mark_miny; -static gint mark_width; -static gint mark_height; - -static GdkRectangle scale_rect; -static PangoContext *scale_context; -static PangoFontDescription *scale_font; -static PangoLayout *scale_layout; - -static GdkGC *speed_gc1; -static GdkGC *speed_gc2; -static PangoContext *speed_context; -static PangoLayout *speed_layout; -static PangoFontDescription *speed_fontdesc; - -static gint zoom_timeout_sid=0; -static gint map_mode=0; -static gboolean map_data_needs_refresh=FALSE; - -osm_location map_loc = {NULL, NULL, NULL, FALSE, FALSE, 0, 0, 0.0, 0.0, 0 }; - -static GTimer *map_timer; - -/* Tile max age, 1 week */ -#define TILE_MAX_AGE (604800) - -#define KM10KNOTS (5.39956803) - -static void map_update_location(gdouble lat, gdouble lon, gboolean force); -static void map_speed_draw(void); -static void map_draw_position_icon(Position *pos, const gchar *icon); - -static gboolean map_cb_after_realize(GtkWidget *map_widget, gpointer data); -static gboolean map_cb_configure(GtkWidget *widget, GdkEventConfigure *event); -static gboolean map_cb_expose(GtkWidget * widget, GdkEventExpose * event); -static gboolean map_cb_button_press(GtkWidget * widget, GdkEventButton * event); -static gboolean map_cb_button_release(GtkWidget * widget, GdkEventButton * event); -static gboolean map_cb_scroll_event(GtkWidget * widget, GdkEventScroll * event); - -/******************************************************************************/ - -GtkWidget * -map_new(void) -{ -GtkWidget *map_widget; - -map_widget=gtk_drawing_area_new(); -map_timer=g_timer_new(); - -map_ic=image_cache_new(MAP_CACHE_DEFAULT); - -gtk_widget_set_extension_events(GTK_WIDGET(map_widget), GDK_EXTENSION_EVENTS_ALL); - -#ifdef WITH_GL -map_gl_config=gdk_gl_config_new_by_mode(GDK_GL_MODE_RGB | GDK_GL_MODE_DEPTH); -if (map_gl_config) { - g_print("OpenGL version: %s\n", glGetString (GL_VERSION)); - g_print("OpenGL vendor: %s\n", glGetString (GL_VENDOR)); - g_print("OpenGL renderer: %s\n", glGetString (GL_RENDERER)); - gtk_widget_set_gl_capability(map_widget, map_gl_config, NULL, TRUE, GDK_GL_RGBA_TYPE); - map_gl=TRUE; -} -#endif - -g_signal_connect_after(G_OBJECT(map_widget), "realize", G_CALLBACK(map_cb_after_realize), NULL); -g_signal_connect(G_OBJECT(map_widget), "configure_event", G_CALLBACK(map_cb_configure), NULL); - -return map_widget; -} - -void -map_set_cache_size(guint cache_size) -{ -image_cache_set_size(map_ic, cache_size); -} - -static gboolean -map_cb_after_realize(GtkWidget *map_widget, gpointer data) -{ -GdkColor color; - -g_debug("MAP: after_realize"); - -scale_context=gtk_widget_get_pango_context(map_widget); -scale_layout=pango_layout_new(scale_context); -scale_font=pango_font_description_new(); -pango_font_description_set_size(scale_font, 12 * PANGO_SCALE); -pango_layout_set_font_description(scale_layout, scale_font); - -/* Speed limit, over limit color */ -speed_gc1=gdk_gc_new(map_widget->window); -color.red=0xffff; -color.green=0; -color.blue=0; -gdk_gc_set_rgb_fg_color(speed_gc1, &color); - -/* Speed limit, under limit color */ -speed_gc2=gdk_gc_new(map_widget->window); -color.red=0; -color.green=0x1000; -color.blue=0; -gdk_gc_set_rgb_fg_color(speed_gc2, &color); - -speed_context=gtk_widget_get_pango_context(map_widget); -speed_layout=pango_layout_new(speed_context); -speed_fontdesc=pango_font_description_new(); -pango_font_description_set_size(speed_fontdesc, 48 * PANGO_SCALE); -pango_layout_set_font_description(speed_layout, speed_fontdesc); -pango_layout_set_alignment(speed_layout, PANGO_ALIGN_CENTER); - -/* Signals */ -g_signal_connect(G_OBJECT(map_widget), "expose_event", G_CALLBACK(map_cb_expose), NULL); -g_signal_connect(G_OBJECT(map_widget), "button_press_event", G_CALLBACK(map_cb_button_press), NULL); -g_signal_connect(G_OBJECT(map_widget), "button_release_event",G_CALLBACK(map_cb_button_release), NULL); -g_signal_connect(G_OBJECT(map_widget), "scroll_event", G_CALLBACK(map_cb_scroll_event), NULL); - -gtk_widget_add_events(map_widget, GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - | GDK_LEAVE_NOTIFY_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK); - -map_poi_init(map_widget); - -return TRUE; -} - -static gboolean -map_cb_configure(GtkWidget *widget, GdkEventConfigure *event) -{ -guint tw, th; - -tw=TILE_SIZE_PIXELS*((widget->allocation.width/TILE_SIZE_PIXELS)+2); -th=TILE_SIZE_PIXELS*((widget->allocation.height/TILE_SIZE_PIXELS)+2); - -if (map_pixmap==NULL) { - map_pixmap=gdk_pixmap_new(widget->window, tw, th, -1); -} else { - if (tw>buf_width_pixels || th>buf_height_pixels) { - g_object_unref(map_pixmap); - map_pixmap=gdk_pixmap_new(widget->window, tw, th, -1); - } else if (twwindow, tw, th, -1); - } -} -g_assert(map_pixmap); - -buf_width_pixels=tw; -buf_height_pixels=th; -buf_width_tiles=buf_width_pixels/TILE_SIZE_PIXELS; -buf_height_tiles=buf_height_pixels/TILE_SIZE_PIXELS; - -_screen_width_pixels = widget->allocation.width; -_screen_height_pixels = widget->allocation.height; -_screen_grids_halfwidth = pixel2grid(_screen_width_pixels) / 2; -_screen_grids_halfheight = pixel2grid(_screen_height_pixels) / 2; - -/* Set scale_rect. */ -scale_rect.x = (_screen_width_pixels - SCALE_WIDTH) / 2; -scale_rect.width = SCALE_WIDTH; - -MACRO_RECALC_FOCUS_BASE(_center_ratio); -MACRO_RECALC_FOCUS_SIZE(_center_ratio); - -_min_center.unitx = pixel2unit(grid2pixel(_screen_grids_halfwidth)); -_min_center.unity = pixel2unit(grid2pixel(_screen_grids_halfheight)); -_max_center.unitx = WORLD_SIZE_UNITS - grid2unit(_screen_grids_halfwidth) - 1; -_max_center.unity = WORLD_SIZE_UNITS - grid2unit(_screen_grids_halfheight) - 1; - -map_force_redraw(); -return TRUE; -} - -/** - * Draw the current mark (representing the current GPS location) onto - * _map_widget. This method does not queue the draw area. - */ -static void -map_draw_mark(Gps *gps) -{ -gdk_draw_arc(_map_widget->window, gps->io.conn == RCVR_FIXED ? _gc[COLORABLE_MARK] : _gc[COLORABLE_MARK_OLD], FALSE, - mark_x1 - _draw_width, mark_y1 - _draw_width, 2 * _draw_width, 2 * _draw_width, 0, 360 * 64); -gdk_draw_line(_map_widget->window, gps->io.conn == RCVR_FIXED ? (_show_velvec ? _gc[COLORABLE_MARK_VELOCITY] : _gc[COLORABLE_MARK]) : _gc[COLORABLE_MARK_OLD], - mark_x1, mark_y1, mark_x2, mark_y2); -} - -/** - * "Set" the mark, which translates the current GPS position into on-screen - * units in preparation for drawing the mark with map_draw_mark(). - */ -void -map_set_mark(GpsData *gps) -{ -mark_x1 = unit2x(gps->unitx); -mark_y1 = unit2y(gps->unity); -mark_x2 = mark_x1 + (_show_velvec ? gps->vel_offsetx : 0); -mark_y2 = mark_y1 + (_show_velvec ? gps->vel_offsety : 0); -mark_minx = MIN(mark_x1, mark_x2) - (2 * _draw_width); -mark_miny = MIN(mark_y1, mark_y2) - (2 * _draw_width); -mark_width = abs(mark_x1 - mark_x2) + (4 * _draw_width); -mark_height = abs(mark_y1 - mark_y2) + (4 * _draw_width); -} - -/** - * Do an in-place scaling of a pixbuf's pixels at the given ratio from the - * given source location. It would have been nice if gdk_pixbuf provided - * this method, but I guess it's not general-purpose enough. - */ -static void -map_pixbuf_scale_inplace(GdkPixbuf *pixbuf, guint ratio_p2, guint src_x, guint src_y) -{ -guint dest_x = 0, dest_y = 0, dest_dim = TILE_SIZE_PIXELS; -guint rowstride = gdk_pixbuf_get_rowstride(pixbuf); -guint n_channels = gdk_pixbuf_get_n_channels(pixbuf); -guchar *pixels = gdk_pixbuf_get_pixels(pixbuf); - -/* Sweep through the entire dest area, copying as necessary, but - * DO NOT OVERWRITE THE SOURCE AREA. We'll copy it afterward. */ -do { - guint src_dim = dest_dim >> ratio_p2; - guint src_endx = src_x - dest_x + src_dim; - gint x, y; - - for (y = dest_dim - 1; y >= 0; y--) { - guint src_offset_y, dest_offset_y; - - src_offset_y = (src_y + (y >> ratio_p2)) * rowstride; - dest_offset_y = (dest_y + y) * rowstride; - x = dest_dim - 1; - - if ((unsigned)(dest_y + y - src_y) < src_dim && (unsigned)(dest_x + x - src_x) < src_dim) - x -= src_dim; - - for (; x >= 0; x--) { - guint src_offset, dest_offset, i; - - src_offset = src_offset_y + (src_x + (x >> ratio_p2)) * n_channels; - dest_offset = dest_offset_y + (dest_x + x) * n_channels; - - pixels[dest_offset] = pixels[src_offset]; - for (i = n_channels - 1; i; i--) - pixels[dest_offset + i] = pixels[src_offset + i]; - - if ((unsigned)(dest_y + y - src_y) < src_dim && x == src_endx) - x -= src_dim; - } - } - - /* Reuse src_dim and src_endx to store new src_x and src_y. */ - src_dim = src_x + ((src_x - dest_x) >> ratio_p2); - src_endx = src_y + ((src_y - dest_y) >> ratio_p2); - dest_x = src_x; - dest_y = src_y; - src_x = src_dim; - src_y = src_endx; -} -while ((dest_dim >>= ratio_p2) > 1); -} - -/** - * Trim pixbufs that are bigger than tiles. (Those pixbufs result, when - * captions should be cut off.) - */ -static GdkPixbuf * -pixbuf_trim(GdkPixbuf * pixbuf) -{ -GdkPixbuf *mpixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, gdk_pixbuf_get_has_alpha(pixbuf), - 8, TILE_SIZE_PIXELS, TILE_SIZE_PIXELS); - -g_debug("TRIM!!"); -gdk_pixbuf_copy_area(pixbuf, - (gdk_pixbuf_get_width(pixbuf) - TILE_SIZE_PIXELS) / 2, - (gdk_pixbuf_get_height(pixbuf) - TILE_SIZE_PIXELS) / 2, - TILE_SIZE_PIXELS, - TILE_SIZE_PIXELS, mpixbuf, 0, 0); - -g_object_unref(pixbuf); -return mpixbuf; -} - -GdkPixmap * -map_pixmap_get(void) -{ -return map_pixmap; -} - -static GdkPixbuf * -map_tile_load(guint tilex, guint tiley, gint zoff, gboolean download) -{ -GdkPixbuf *pixbuf; -GError *error = NULL; -gchar buffer[BUFFER_SIZE]; -gchar key[BUFFER_SIZE]; -struct stat tstat; -gint se; - -g_snprintf(buffer, sizeof(buffer), "%s/%u/%u/%u.jpg", _curr_repo->cache_dir, _zoom + zoff, (tilex >> zoff), (tiley >> zoff)); -g_snprintf(key, sizeof(key), "%s/%u/%u/%u", _curr_repo->cache_dir, _zoom + zoff, (tilex >> zoff), (tiley >> zoff)); - -pixbuf=image_cache_get(map_ic, key, buffer); -if (!pixbuf) { - g_unlink(buffer); - - if (_auto_download && _curr_repo->type != REPOTYPE_NONE && !((_zoom + zoff - (_curr_repo->double_size ? 1 : 0)) % _curr_repo->dl_zoom_steps)) { - if (download) - map_initiate_download(tilex >> zoff, tiley >> zoff, _zoom + zoff, -INITIAL_DOWNLOAD_RETRIES); - } - return NULL; -} - -g_object_ref(pixbuf); - -#if 0 -/* Check if we need to trim. */ -if (gdk_pixbuf_get_width(pixbuf) != TILE_SIZE_PIXELS || gdk_pixbuf_get_height(pixbuf) != TILE_SIZE_PIXELS) - pixbuf=pixbuf_trim(pixbuf); -#endif - -/* Check tile age, if file date is ower a week old, redownload if autodownload enabled */ -se=stat(buffer, &tstat); -if (se==0) { - time_t t; - t=time(NULL); - if (t-tstat.st_mtime>TILE_MAX_AGE) { - if (_auto_download && _curr_repo->type != REPOTYPE_NONE && !((_zoom + zoff - (_curr_repo->double_size ? 1 : 0)) % _curr_repo->dl_zoom_steps)) { - if (download) { - g_debug("Tile: %s is old, re-downloading\n", buffer); - map_initiate_download(tilex >> zoff, tiley >> zoff, _zoom + zoff, -INITIAL_DOWNLOAD_RETRIES); - image_cache_invalidate(map_ic, key); - } - } - } -} - -return pixbuf; -} - -gboolean -map_render_tile(guint tilex, guint tiley, guint destx, guint desty, gboolean fast_fail) -{ -GdkPixbuf *pixbuf=NULL; -gint zoff; - -if (destx > buf_width_pixels || desty > buf_height_pixels) - return FALSE; - -if (tilex > _world_size_tiles || tiley > _world_size_tiles) - return FALSE; - -g_debug("MAP RT: %u %u (%u) %u %u (%u, %u)", tilex, tiley, _world_size_tiles, destx, desty, buf_width_tiles, buf_height_tiles); - -/* The tile is possible. */ -for (zoff = (_curr_repo->double_size ? 1 : 0); !pixbuf && (_zoom + zoff) <= map_max_zoom && zoff <= TILE_SIZE_P2; zoff += 1) { - pixbuf=map_tile_load(tilex, tiley, zoff, !fast_fail); - if (!pixbuf) { - if (!fast_fail) - fast_fail=TRUE; - } else { - /* Check if we need to blit. */ - if (zoff) { - map_pixbuf_scale_inplace(pixbuf, zoff, - (tilex - ((tilex >> zoff) << zoff)) << (TILE_SIZE_P2 - zoff), - (tiley - ((tiley >> zoff) << zoff)) << (TILE_SIZE_P2 - zoff)); - image_cache_invalidate_by_image(map_ic, pixbuf); - } - } -} - -if (pixbuf) { - gdk_draw_pixbuf(map_pixmap, _gc[COLORABLE_MARK], - pixbuf, 0, 0, destx, desty, - TILE_SIZE_PIXELS, TILE_SIZE_PIXELS, GDK_RGB_DITHER_NONE, 0, 0); - - g_object_unref(pixbuf); - return TRUE; -} -gdk_draw_rectangle(map_pixmap, _map_widget->style->black_gc, TRUE, destx, desty, TILE_SIZE_PIXELS, TILE_SIZE_PIXELS); -return TRUE; -} - -void -map_render_data(void) -{ -/* Don't update if dragging, too much lag */ -if (map_drag_id>0) - return; - -if(_show_poi) - map_render_all_pois(buf_width_pixels, buf_height_pixels); - -if (_home->valid) - map_draw_position_icon(_home, "home"); - -if (_dest->valid) - map_draw_position_icon(_dest, "destination"); - -if(_show_tracks>0) - map_render_paths(); -} - -/** - * Force a redraw of the entire map_pixmap, including fetching the - * background maps from disk and redrawing the tracks on top of them. - */ -void -map_force_redraw(void) -{ -guint new_x, new_y; -#ifdef DEBUG -gulong tms; - -g_timer_start(map_timer); -#endif -for (new_y = 0; new_y < buf_height_tiles; ++new_y) - for (new_x = 0; new_x < buf_width_tiles; ++new_x) { - map_render_tile(_base_tilex + new_x, _base_tiley + new_y, - new_x * TILE_SIZE_PIXELS, new_y * TILE_SIZE_PIXELS, FALSE); - } -#ifdef DEBUG -g_timer_stop(map_timer); -g_debug("Full redraw: %f sec\n", g_timer_elapsed(map_timer, &tms)); -#endif - -map_render_data(); -MACRO_QUEUE_DRAW_AREA(); -} - -guint -map_get_zoom(void) -{ -return _zoom; -} - -/** - * Set the current zoom level. If the given zoom level is the same as the - * current zoom level, or if the new zoom is invalid - * (not MIN_ZOOM <= new_zoom < MAX_ZOOM), then this method does nothing. - */ -gboolean -map_set_zoom(guint new_zoom) -{ -/* Note that, since new_zoom is a guint and MIN_ZOOM is 0, this if - * condition also checks for new_zoom >= MIN_ZOOM. */ -if (new_zoom > (map_max_zoom - 1)) - return FALSE; -if (new_zoom == _zoom) - return FALSE; - -_zoom = new_zoom / _curr_repo->view_zoom_steps * _curr_repo->view_zoom_steps; -_world_size_tiles = unit2tile(WORLD_SIZE_UNITS); - -/* If we're leading, update the center to reflect new zoom level. */ -MACRO_RECALC_CENTER(_gps->data, _center.unitx, _center.unity); - -/* Update center bounds to reflect new zoom level. */ -_min_center.unitx = pixel2unit(grid2pixel(_screen_grids_halfwidth)); -_min_center.unity = pixel2unit(grid2pixel(_screen_grids_halfheight)); -_max_center.unitx = WORLD_SIZE_UNITS - grid2unit(_screen_grids_halfwidth) - 1; -_max_center.unity = WORLD_SIZE_UNITS - grid2unit(_screen_grids_halfheight) - 1; - -BOUND(_center.unitx, _min_center.unitx, _max_center.unitx); -BOUND(_center.unity, _min_center.unity, _max_center.unity); - -_base_tilex = grid2tile((gint) pixel2grid((gint) unit2pixel((gint) _center.unitx)) - (gint) _screen_grids_halfwidth); -_base_tiley = grid2tile(pixel2grid(unit2pixel(_center.unity)) - _screen_grids_halfheight); - -/* New zoom level, so we can't reuse the old buffer's pixels. */ -/* Update state variables. */ -MACRO_RECALC_OFFSET(); -MACRO_RECALC_FOCUS_BASE(_center_ratio); -MACRO_RECALC_FOCUS_SIZE(_center_ratio); - -map_set_mark(&_gps->data); -map_force_redraw(); -return TRUE; -} - -/** - * Center the view on the given unitx/unity. - */ -void -map_center_unit(guint new_center_unitx, guint new_center_unity) -{ -gint new_base_tilex, new_base_tiley; -guint new_x, new_y; -guint j, k, base_new_x, base_old_x, old_x, old_y, iox, ioy; - -/* Assure that _center.unitx/y are bounded. */ -BOUND(new_center_unitx, _min_center.unitx, _max_center.unitx); -BOUND(new_center_unity, _min_center.unity, _max_center.unity); - -_center.unitx = new_center_unitx; -_center.unity = new_center_unity; - -new_base_tilex = grid2tile((gint) pixel2grid((gint)unit2pixel((gint) _center.unitx)) - (gint)_screen_grids_halfwidth); -new_base_tiley = grid2tile(pixel2grid(unit2pixel(_center.unity)) - _screen_grids_halfheight); - -/* Same zoom level, so it's likely that we can reuse some of the old - * buffer's pixels. */ - -if (new_base_tilex != _base_tilex || new_base_tiley != _base_tiley) { - /* If copying from old parts to new parts, we need to make sure we - * don't overwrite the old parts when copying, so set up new_x, - * new_y, old_x, old_y, iox, and ioy with that in mind. */ - if (new_base_tiley < _base_tiley) { - /* New is lower than old - start at bottom and go up. */ - new_y = buf_height_tiles - 1; - ioy = -1; - } else { - /* New is higher than old - start at top and go down. */ - new_y = 0; - ioy = 1; - } - if (new_base_tilex < _base_tilex) { - /* New is righter than old - start at right and go left. */ - base_new_x = buf_width_tiles - 1; - iox = -1; - } else { - /* New is lefter than old - start at left and go right. */ - base_new_x = 0; - iox = 1; - } - - /* Iterate over the y tile values. */ - old_y = new_y + new_base_tiley - _base_tiley; - base_old_x = base_new_x + new_base_tilex - _base_tilex; - _base_tilex = new_base_tilex; - _base_tiley = new_base_tiley; - - for (j = 0; j < buf_height_tiles; ++j, new_y += ioy, old_y += ioy) { - new_x = base_new_x; - old_x = base_old_x; - /* Iterate over the x tile values. */ - for (k = 0; k < buf_width_tiles; ++k, new_x += iox, old_x += iox) { - /* Can we get this grid block from the old buffer?. */ - if (old_x >= 0 && old_x < buf_width_tiles && old_y >= 0 && old_y < buf_height_tiles) { - /* Copy from old buffer to new buffer. */ - gdk_draw_drawable(map_pixmap, - _gc[COLORABLE_MARK], - map_pixmap, - old_x * TILE_SIZE_PIXELS, - old_y * TILE_SIZE_PIXELS, - new_x * TILE_SIZE_PIXELS, - new_y * TILE_SIZE_PIXELS, - TILE_SIZE_PIXELS, - TILE_SIZE_PIXELS); - } else { - map_render_tile(new_base_tilex + new_x, - new_base_tiley + new_y, - new_x * TILE_SIZE_PIXELS, - new_y * TILE_SIZE_PIXELS, - map_drag_id!=0 ? TRUE : FALSE); - } - } - } - map_render_data(); -} - -MACRO_RECALC_OFFSET(); -MACRO_RECALC_FOCUS_BASE(_center_ratio); - -map_set_mark(&_gps->data); -MACRO_QUEUE_DRAW_AREA(); -} - -/** - * Pan the view by the given number of units in the X and Y directions. - */ -void -map_pan(gint delta_unitx, gint delta_unity) -{ -if (_center_mode > 0) - set_action_activate("autocenter_none", TRUE); - -map_center_unit(_center.unitx + delta_unitx, _center.unity + delta_unity); -} - -/** - * Helper to center map on given lat/lon - */ -void -map_center_latlon(gdouble lat, gdouble lon) -{ -guint unitx, unity; - -latlon2unit(lat, lon, unitx, unity); -map_center_unit(unitx, unity); -} - -/** - * Helper to goto given point and update location - * - */ -gboolean -map_goto_position(Position *pos) -{ -if (pos->valid==FALSE) - return FALSE; - -_center_mode=CENTER_MANUAL; -map_center_latlon(pos->lat, pos->lon); -map_set_autozoom(FALSE, 0); -g_idle_add_full(G_PRIORITY_HIGH_IDLE,(GSourceFunc)map_update_location_from_center, NULL, NULL); -return TRUE; -} - -/** - * Initiate a move of the mark from the old location to the current - * location. This function queues the draw area of the old mark (to force - * drawing of the background map), then updates the mark, then queus the - * draw area of the new mark. - */ -void -map_move_mark(void) -{ -/* Just queue the old and new draw areas. */ -gtk_widget_queue_draw_area(_map_widget, - mark_minx<0 ? 0 : mark_minx, - mark_miny<0 ? 0 : mark_miny, - mark_width, mark_height); -map_set_mark(&_gps->data); -gtk_widget_queue_draw_area(_map_widget, - mark_minx<0 ? 0 : mark_minx, - mark_miny<0 ? 0 : mark_miny, - mark_width, mark_height); -} - -gboolean -map_update_location_from_gps(Gps *gps) -{ -g_assert(gps); -map_update_location(gps->data.lat, gps->data.lon, FALSE); -return FALSE; -} - -gboolean -map_update_location_from_center(void) -{ -gdouble lat, lon; -/* Force re-validation of place if user is clicking around */ -map_loc.valid=FALSE; -/* XXX: hmm, not the right place for this */ -#if 0 -if (_gps->fix==FIX_NOFIX) { - _gps->data.unitx=_center.unitx; - _gps->data.unity=_center.unity; - unit2latlon(_gps->data.unitx, _gps->data.unity, _gps->data.lat, _gps->data.lon); -} -#endif -unit2latlon(_center.unitx, _center.unity, lat, lon); -map_update_location(lat, lon, TRUE); -return FALSE; -} - -void -map_draw_pixbuf_on_buffer(gint x, gint y, GdkPixbuf *p) -{ -if ((x < 0) || (y < 0)) - return; - -if ((x > buf_width_pixels) || (y > buf_height_pixels)) - return; - -gdk_draw_pixbuf(map_pixmap, _gc[COLORABLE_POI], - p, 0, 0, - x - gdk_pixbuf_get_width(p) / 2, - y - gdk_pixbuf_get_height(p) / 2, - -1, -1, GDK_RGB_DITHER_NONE, 0, 0); -} - -/** - * Draw given pixbuf on map, centered on x,y - */ -void -map_draw_pixbuf(guint unitx, guint unity, GdkPixbuf *p) -{ -gint x,y; -x=unit2bufx(unitx); -y=unit2bufy(unity); - -map_draw_pixbuf_on_buffer(x, y, p); -} - -/** - * Draw an icon at given Position. - * - */ -static void -map_draw_position_icon(Position *pos, const gchar *icon) -{ -gint x, y; -guint ux, uy; -gchar buffer[128]; -GdkPixbuf *p; - -latlon2unit(pos->lat, pos->lon, ux, uy); -x=unit2bufx(ux); -y=unit2bufy(uy); - -if ((x < 0) || (y < 0)) - return; - -if ((x > buf_width_pixels) || (y > buf_height_pixels)) - return; - -g_snprintf(buffer, sizeof(buffer), "%s/pixmaps/mapper/%s.png", DATADIR, icon); -p=gdk_pixbuf_new_from_file(buffer, NULL); -if (!p) - return; - -map_draw_pixbuf_on_buffer(x, y, p); -g_object_unref(p); -} - -/** - * Make sure the mark is up-to-date. This function triggers a panning of - * the view if the mark is appropriately close to the edge of the view. - */ -void -map_refresh_mark(void) -{ -guint new_center_unitx; -guint new_center_unity; - -MACRO_RECALC_CENTER(_gps->data, new_center_unitx, new_center_unity); - -if ((new_center_unitx - _focus.unitx) < _focus_unitwidth && (new_center_unity - _focus.unity) < _focus_unitheight) - /* We're not changing the view - just move the mark. */ - map_move_mark(); -else - map_center_unit(new_center_unitx, new_center_unity); - -/* Draw speed info */ -if (_speed_on) - map_speed_draw(); - -if (_center_mode>0) - g_idle_add_full(G_PRIORITY_HIGH_IDLE,(GSourceFunc)map_update_location_from_gps, _gps, NULL); -} - -/** - * Render a single track line to map_pixmap. If either point on the line - * is a break (defined as unity == 0), a circle is drawn at the other point. - * IT IS AN ERROR FOR BOTH POINTS TO INDICATE A BREAK. - */ -void -map_render_segment(GdkGC *gc_norm, GdkGC *gc_alt, guint unitx1, guint unity1, guint unitx2, guint unity2) -{ -if (!unity1) { - guint x2, y2; - - x2 = unit2bufx(unitx2); - y2 = unit2bufy(unity2); - /* Make sure this circle will be visible. */ - if ((x2 < buf_width_pixels) && (y2 < buf_height_pixels)) - gdk_draw_arc(map_pixmap, gc_alt, FALSE, /* FALSE: not filled. */ - x2 - _draw_width, y2 - _draw_width, 2 * _draw_width, 2 * _draw_width, 0, /* start at 0 degrees. */ - 360 * 64); -} else if (!unity2) { - guint x1, y1; - - x1 = unit2bufx(unitx1); - y1 = unit2bufy(unity1); - /* Make sure this circle will be visible. */ - if ((x1 < buf_width_pixels) && ((unsigned)y1 < buf_height_pixels)) - gdk_draw_arc(map_pixmap, gc_alt, FALSE, /* FALSE: not filled. */ - x1 - _draw_width, y1 - _draw_width, 2 * _draw_width, 2 * _draw_width, 0, /* start at 0 degrees. */ - 360 * 64); -} else { - gint x1, y1, x2, y2; - - x1 = unit2bufx(unitx1); - y1 = unit2bufy(unity1); - x2 = unit2bufx(unitx2); - y2 = unit2bufy(unity2); - /* Make sure this line could possibly be visible. */ - if (!((x1 > buf_width_pixels && x2 > buf_width_pixels) - || (x1 < 0 && x2 < 0) - || (y1 > buf_height_pixels && y2 > buf_height_pixels) - || (y1 < 0 && y2 < 0))) - gdk_draw_line(map_pixmap, gc_norm, x1, y1, x2, y2); - } -} - -void -map_render_waypoint(guint x1, guint y1, GdkGC *gc) -{ -if ((x1 > buf_width_pixels) || (y1 > buf_height_pixels)) - return; -gdk_draw_arc(map_pixmap, gc, FALSE, x1 - _draw_width, y1 - _draw_width, 2 * _draw_width, 2 * _draw_width, 0, 360 * 64); -} - -/** - * Render all track data onto the map_pixmap. Note that this does not - * clear the pixmap of previous track data (use map_force_redraw() for - * that), and also note that this method does not queue any redraws, so it - * is up to the caller to decide which part of the track really needs to be - * redrawn. - */ -void -map_render_path(Path *path, GdkGC **gc) -{ -Point *curr; -WayPoint *wcurr; - -g_return_if_fail(path); -if (path->head==path->tail) - return; - -/* gc is a pointer to the first GC to use (for plain points). (gc + 1) - * is a pointer to the GC to use for waypoints, and (gc + 2) is a pointer - * to the GC to use for breaks. */ - -/* else there is a route to draw. */ -for (curr = path->head, wcurr = path->whead; curr++ != path->tail;) { - /* Draw the line from (curr - 1) to (curr). */ - map_render_segment(gc[0], gc[2], curr[-1].unitx, curr[-1].unity, curr->unitx, curr->unity); - - /* Now, check if curr is a waypoint. */ - if (wcurr && wcurr <= path->wtail && wcurr->point == curr) { - guint x1 = unit2bufx(wcurr->point->unitx); - guint y1 = unit2bufy(wcurr->point->unity); - - map_render_waypoint(x1, y1, _gc[COLORABLE_TRACK_BREAK]); - wcurr++; - } -} -} - -void -map_render_next_waypoint(Path *path) -{ -guint x1, y1; - -g_return_if_fail(path); -if (!path->next_way) - return; - -g_return_if_fail(path->next_way->point); - -x1=unit2bufx(path->next_way->point->unitx); -y1=unit2bufy(path->next_way->point->unity); - -if ((x1 < buf_width_pixels) && (y1 < buf_height_pixels)) { - /* Draw the next waypoint as a break. */ - gdk_draw_arc(map_pixmap, _gc[COLORABLE_ROUTE_BREAK], FALSE, - x1 - _draw_width, y1 - _draw_width, - 4 * _draw_width, 4 * _draw_width, 0, 360 * 64); -} -} - -void -map_render_paths(void) -{ -if (_show_tracks & ROUTES_MASK) { - map_render_path(_route, _gc + COLORABLE_ROUTE); - - /* Now, draw the next waypoint on top of all other waypoints. */ - map_render_next_waypoint(_route); -} -if (_show_tracks & TRACKS_MASK) - map_render_path(_track, _gc + COLORABLE_TRACK); -} - -/** - * - * - */ -static gboolean -map_follow_move_cb(GtkWidget *widget, GdkEventMotion *event, gpointer data) -{ -GdkModifierType state; -gint xx, yy; -guint unitx, unity, nunitx, nunity; -guint cx, cy; -gboolean lat,lon; - -if (!(event->state & GDK_BUTTON1_MASK)) { - map_drag_id=0; - return TRUE; -} - -if (event->is_hint) { - gdk_window_get_pointer(event->window, &xx, &yy, &state); - state = event->state; -} else { - xx = event->x; - yy = event->y; - state = event->state; -} - -unitx = x2unit((gint) (xx - before[0])); -unity = y2unit((gint) (yy - before[1])); - -unit2latlon(x2unit(xx), y2unit(yy), lat, lon); -g_printf("MOUSE: %u,%u (%f,%f)\n", unitx, unity, lat, lon); - -cx = unit2x(_center.unitx); -cy = unit2y(_center.unity); - -nunitx=x2unit((gint) (cx - (xx - before[0]))); -nunity=y2unit((gint) (cy - (yy - before[1]))); - - -map_center_unit(nunitx, nunity); - -g_debug("PAN: %d %d %d %d (%d, %d)==(%d, %d)", cx, cy, xx, yy, nunitx, nunity, unitx, unity); - -map_dragged=TRUE; -before[0] = xx; -before[1] = yy; - -return FALSE; -} - -gboolean -map_key_zoom_timeout(void) -{ -if (_key_zoom_new < _zoom) { - /* We're currently zooming in (_zoom is decreasing). */ - guint test = _key_zoom_new - _curr_repo->view_zoom_steps; - if (test < map_max_zoom) - _key_zoom_new = test; - else - return FALSE; -} else { - /* We're currently zooming out (_zoom is increasing). */ - guint test = _key_zoom_new + _curr_repo->view_zoom_steps; - if (test < map_max_zoom) - _key_zoom_new = test; - else - return FALSE; -} - -return TRUE; -} - -static void -map_information_text(guint x, guint y, GdkGC *gc, gchar *msg) -{ -guint width, height; - -pango_layout_set_text(speed_layout, msg, -1); -pango_layout_get_pixel_size(speed_layout, &width, &height); -gtk_widget_queue_draw_area(_map_widget, x - 5, y - 5, width * 3 + 15, height + 5); -gdk_window_process_all_updates(); -gdk_draw_layout(_map_widget->window, gc, x, y, speed_layout); -} - -static void -map_speed_draw(void) -{ -GdkGC *gc; -gfloat cur_speed; -gchar *buffer; - -cur_speed = _gps->data.speed * UNITS_CONVERT[_units]; -gc=(cur_speed > _speed_limit) ? speed_gc1 : speed_gc2; -buffer = g_strdup_printf("%0.0f", cur_speed); -map_information_text(10, 10, gc, buffer); -g_free(buffer); -} - -static void -map_scale_draw(GdkEventExpose *event) -{ -gchar buffer[16]; -gdouble distance; -gdouble lat1, lon1, lat2, lon2; -gint width; - -pango_layout_set_text(scale_layout, "0", -1); -pango_layout_get_pixel_size(scale_layout, NULL, &scale_rect.height); -scale_rect.y = _screen_height_pixels - scale_rect.height - 1; - -gdk_rectangle_intersect(&event->area, &scale_rect, &event->area); - -if (event->area.width && event->area.height) { - gdk_draw_rectangle(_map_widget->window, - _map_widget->style->bg_gc[GTK_WIDGET_STATE(_map_widget)], - TRUE, scale_rect.x, scale_rect.y, - scale_rect.width, - scale_rect.height); - gdk_draw_rectangle(_map_widget->window, - _map_widget->style->fg_gc[GTK_WIDGET_STATE(_map_widget)], - FALSE, scale_rect.x, scale_rect.y, - scale_rect.width, - scale_rect.height); - - /* Now calculate and draw the distance. */ - unit2latlon(_center.unitx - pixel2unit(SCALE_WIDTH / 2 - 4), _center.unity, lat1, lon1); - unit2latlon(_center.unitx + pixel2unit(SCALE_WIDTH / 2 - 4), _center.unity, lat2, lon2); - distance=calculate_distance(lat1, lon1, lat2, lon2) * UNITS_CONVERT[_units]; - - if (distance < 1.f) - g_snprintf(buffer, sizeof(buffer), "%0.2f %s", distance, UNITS_TEXT[_units]); - else if (distance < 10.f) - g_snprintf(buffer, sizeof(buffer), "%0.1f %s", distance, UNITS_TEXT[_units]); - else - g_snprintf(buffer, sizeof(buffer), "%0.f %s", distance, UNITS_TEXT[_units]); - - pango_layout_set_text(scale_layout, buffer, -1); - pango_layout_get_pixel_size(scale_layout, &width, NULL); - - /* Draw the layout itself. */ - gdk_draw_layout(_map_widget->window, - _map_widget->style->fg_gc[GTK_WIDGET_STATE(_map_widget)], - scale_rect.x + (scale_rect.width - width) / 2, - scale_rect.y, scale_layout); - - /* Draw little hashes on the ends. */ - gdk_draw_line(_map_widget->window, - _map_widget->style->fg_gc[GTK_WIDGET_STATE(_map_widget)], - scale_rect.x + 4, - scale_rect.y + scale_rect.height / 2 - 4, - scale_rect.x + 4, - scale_rect.y + scale_rect.height / 2 + 4); - gdk_draw_line(_map_widget->window, - _map_widget->style->fg_gc[GTK_WIDGET_STATE(_map_widget)], - scale_rect.x + 4, - scale_rect.y + scale_rect.height / 2, - scale_rect.x + (scale_rect.width - width) / 2 - 4, - scale_rect.y + scale_rect.height / 2); - gdk_draw_line(_map_widget->window, - _map_widget->style->fg_gc[GTK_WIDGET_STATE(_map_widget)], - scale_rect.x + scale_rect.width - 4, - scale_rect.y + scale_rect.height / 2 - 4, - scale_rect.x + scale_rect.width - 4, - scale_rect.y + scale_rect.height / 2 + 4); - gdk_draw_line(_map_widget->window, - _map_widget->style->fg_gc[GTK_WIDGET_STATE(_map_widget)], - scale_rect.x + scale_rect.width - 4, - scale_rect.y + scale_rect.height / 2, - scale_rect.x + (scale_rect.width + width) / 2 + 4, - scale_rect.y + scale_rect.height / 2); - } -} - -static gboolean -map_cb_expose(GtkWidget *widget, GdkEventExpose *event) -{ -gdk_draw_drawable(GDK_DRAWABLE(_map_widget->window), - _gc[COLORABLE_MARK], - map_pixmap, - event->area.x + _offsetx, event->area.y + _offsety, - event->area.x, event->area.y, - event->area.width, event->area.height); -map_draw_mark(_gps); - -/* Draw scale, if necessary. */ -if (_show_scale) - map_scale_draw(event); - -#if 0 -if (_speed_on) - map_speed_draw(); -#endif - -return TRUE; -} - -int -map_zoom(gint zdir) -{ -gint nzoom; - -nzoom=_zoom+zdir; -if ((nzoom >= 0) && (nzoom < map_max_zoom - 1)) { - map_set_zoom(nzoom); -} -return nzoom; -} - -gboolean -map_zoom_in(void) -{ -map_zoom(-1); -return FALSE; -} - -gboolean -map_zoom_out(void) -{ -map_zoom(1); -return FALSE; -} - -static gboolean -map_autozoomer(void) -{ -static gfloat z=5.0; -static gint last=5; -gint b=0; -gint iz; - -if (zoom_timeout_sid==0) - return FALSE; - -/* If location is known, use road type and speed for zoom setting */ -if (map_loc.valid && map_loc.street) { - switch (map_loc.street->type) { - case WAY_MOTORWAY: - case WAY_TRUNK: - b=2; - break; - case WAY_PRIMARY: - case WAY_SECONDARY: - b=1; - break; - default: - b=0; - break; - } -} - -z=(z+_gps->data.speed+1)/5; -z+=b; -if (z>5) z=5.0; else if (z<1) z=1.0; -iz=(gint)roundf(z); -g_debug("Setting autozoom to: %f %d S:%f\n", z, iz, _gps->data.speed); -if (iz>last) - iz=last+1; -else if (izdata.unitx=x2unit((gint) (x + 0.5)); -_gps->data.unity=y2unit((gint) (y + 0.5)); -unit2latlon(_gps->data.unitx, _gps->data.unity, _gps->data.lat, _gps->data.lon); -_gps->data.speed=20.f; -gps_data_integerize(&_gps->data); -_gps->data.time=time(NULL); -track_add(_track, &_gps->data); -map_refresh_mark(); -} - -static void -map_set_place_information(osm_way *s, osm_place *mp, osm_place *sp) -{ -gchar buffer[256]; - -if (!s && !mp && !sp) { - g_snprintf(buffer, sizeof(buffer), _("Unknown location")); -} else { - /* oh, fun */ - g_snprintf(buffer, sizeof(buffer), "%s%s%s%s%s%s%s%s%s%s", - s ? s->name ? s->name : "" : "", - s ? s->ref ? ", " : "" : "", - s ? s->ref ? s->ref : "" : "", - s ? s->int_ref ? " (" : "" : "", - s ? s->int_ref ? s->int_ref : "" : "", - s ? s->int_ref ? ") " : "" : "", - (sp && sp->name) ? " in " : "", - (sp && sp->name) ? sp->name : "", - (mp && mp->name) ? " in " : "", - (mp && mp->name) ? mp->name : ""); -} -gtk_label_set_label(GTK_LABEL(info_banner.location), buffer); -} - -static void -map_update_destination(gdouble lat, gdouble lon) -{ -gdouble dh=0.0; -gdouble dt, cdist; -static gdouble prev_dt=99999.0; -static gboolean dest_reached=FALSE; -gchar buffer[64]; - -if (_dest->valid) { - dt=calculate_distance(lat, lon, _dest->lat, _dest->lon); - dh=calculate_course(lat, lon, _dest->lat, _dest->lon); - cdist=dt*UNITS_CONVERT[_units]; - - g_snprintf(buffer, sizeof(buffer), "%.02f %s (%0.02f)", cdist, UNITS_TEXT[_units], dh<0 ? 360+dh : dh); - gtk_label_set_label(GTK_LABEL(info_banner.distance), buffer); - - if (dt<0.005 && dest_reached==FALSE) { - if (_center_mode>0) - announce_destination_reached(); - dest_reached=TRUE; - } else if (dt0 && _announce_destination==TRUE) - announce_distance_to_destination(cdist, UNITS_TEXT[_units], KM10KNOTS); - prev_dt=dt; - } else if (dt>prev_dt+KM10KNOTS/4) { - prev_dt=dt; - } - if (dt>0.05) { - dest_reached=FALSE; - } - g_debug("%f (Prev:%f)\n", prev_dt, dt); -} else { - dest_reached=FALSE; - prev_dt=99999.0; - gtk_label_set_label(GTK_LABEL(info_banner.distance), ""); -} - -gtk_compass_set_dest_heading(_gps_compass, _dest->valid, (gfloat)dh); -gtk_compass_set_dest_heading(_tab_compass, _dest->valid, (gfloat)dh); - -if (_route->next_way && _route->next_way->point) { - gdouble wp_lat, wp_lon; - gfloat wc; - - unit2latlon(_route->next_way->point->unitx, _route->next_way->point->unity, wp_lat, wp_lon); - wc=calculate_course(lat, lon, wp_lat, wp_lon); - gtk_compass_set_way_heading(_gps_compass, TRUE, wc); - gtk_compass_set_way_heading(_tab_compass, TRUE, wc); -} else { - gtk_compass_set_way_heading(_gps_compass, FALSE, 0); - gtk_compass_set_way_heading(_tab_compass, FALSE, 0); -} - -} - -/** - * Query the OSM database for where we are. - * - * XXX: This is the wrong place for this function. - */ -static void -map_update_location(gdouble lat, gdouble lon, gboolean force) -{ -gint ilat, ilon; -static gboolean inp=FALSE; - -/* We run the gtk mainloop in progress callback so we can be called again, we don't like that */ -if (inp==TRUE) { - g_debug("LOC: Query in progress"); - return; -} -inp=TRUE; - -ilat=lat2mp_int(lat); -ilon=lon2mp_int(lon); - -if (_gps->data.fix>1 && !force) - osm_set_way_range_from_speed(_gps->data.speed); -else - osm_set_way_range(2800); - -map_update_destination(lat, lon); - -if (osm_check_location(&map_loc, ilat, ilon)==FALSE) { - osm_progress_set_widget(_db, _progress_item); - osm_get_location_data(ilat, ilon, _gps->data.heading, &map_loc); - if (map_loc.valid) - map_set_place_information(map_loc.street, map_loc.primary, map_loc.secondary); - else - map_set_place_information(NULL, NULL, NULL); - osm_progress_set_widget(_db, NULL); -} else g_debug("IN PLACE"); - -inp=FALSE; -} - -/** - * Mouse scroller zoom in/out callback - */ -static gboolean -map_cb_scroll_event(GtkWidget * widget, GdkEventScroll * event) -{ -if (event->direction == GDK_SCROLL_UP) { - map_center_unit(x2unit((gint) (event->x + 0.5)), y2unit((gint) (event->y + 0.5))); - map_set_zoom(_zoom - 1); -} else if (event->direction == GDK_SCROLL_DOWN) { - map_center_unit(x2unit((gint) (event->x + 0.5)), y2unit((gint) (event->y + 0.5))); - map_set_zoom(_zoom + 1); -} -return FALSE; -} - -/** - * Start map drag operation - */ -static void -map_drag_start(gint x,gint y) -{ -press[0] = x; -press[1] = y; -before[0] = press[0]; -before[1] = press[1]; -_center_mode=CENTER_MANUAL; -if (map_drag_id!=0) - g_signal_handler_disconnect(G_OBJECT(_map_widget), map_drag_id); -map_dragged=FALSE; -map_drag_id=g_signal_connect(G_OBJECT(_map_widget), "motion_notify_event", G_CALLBACK(map_follow_move_cb), NULL); -} - -/** - * Stop map drag operation - */ -static void -map_drag_stop(gint x, gint y) -{ -if (map_drag_id==0) - return; - -g_signal_handler_disconnect(G_OBJECT(_map_widget), map_drag_id); - -release[0]=x; -release[1]=y; -press[0]=0; -press[1]=0; -release[0]=0; -release[1]=0; -before[0]=0; -before[1]=0; -map_drag_id=0; -if (map_dragged==TRUE) - map_force_redraw(); -} - -/* Workaround hildon content menu problem */ -static gboolean -map_cb_show_poi_info_dialog(gpointer data) -{ -guint poi_id=GPOINTER_TO_INT(data); -if (poi_info_dialog(_window, poi_id)==FALSE) - g_printerr("Huh? Failed to display info dialog\n"); -return FALSE; -} - -static gboolean -map_cb_button_press(GtkWidget *widget, GdkEventButton *event) -{ -_cmenu_position_x = event->x + 0.5; -_cmenu_position_y = event->y + 0.5; - -switch (event->button) { -case 1: - if (event->type==GDK_2BUTTON_PRESS) { - map_center_unit(x2unit((gint) (event->x + 0.5)), y2unit((gint) (event->y + 0.5))); -#ifdef MAP_ZOOM_ON_DOUBLE_CLICK - map_set_zoom(_zoom-1); -#endif - map_data_needs_refresh=TRUE; - map_drag_stop(event->x, event->y); - return FALSE; - } - if (event->type==GDK_3BUTTON_PRESS) { - map_drag_stop(event->x, event->y); - return FALSE; - } - - map_drag_start(event->x, event->y); - return FALSE; -break; -case 2: - /* */ -break; -case 3: -#ifndef WITH_HILDON - gtk_menu_popup(GTK_MENU(_menu_map), NULL, NULL, NULL, NULL, event->button, gtk_get_current_event_time()); -#endif -break; -} -/* Return FALSE to allow context menu to work. */ -return FALSE; -} - -static gboolean -map_pan_click_check(gint x, gint y) -{ -gint pns=0, pew=0; - -if (x(_screen_width_pixels-MAP_THUMB_MARGIN_X)) - pns=PAN_UNITS; - -if (y(_screen_height_pixels-MAP_THUMB_MARGIN_Y)) - pew=PAN_UNITS; - -if (pns!=0 || pew!=0) { - map_pan(pns, pew); - g_debug("MPAN: %d, %d", pns, pew); - return TRUE; -} -return FALSE; -} - -static gboolean -map_cb_button_release(GtkWidget *widget, GdkEventButton *event) -{ -gdouble lat, lon; -guint poi_id; -gint ux, uy; - -switch (event->button) { -case 1: - -#if defined(WITH_HILDON_NEW) - if (hildon_helper_event_button_is_finger(event)) { - g_debug("Thumb down"); - if (map_pan_click_check(event->x, event->y)) - return FALSE; - } -#endif - - switch (map_mode) { - case MAP_MODE_DRAW_TRACK: - map_draw_track(event->x, event->y); - break; - case MAP_MODE_DRAW_ROUTE: - map_draw_route(event->x, event->y); - break; - case MAP_MODE_SET_ROUTE_FROM: - case MAP_MODE_SET_ROUTE_POINT: - case MAP_MODE_SET_ROUTE_TO: - break; - default: - ux=x2unit(_cmenu_position_x); - uy=y2unit(_cmenu_position_y); - - unit2latlon(ux, uy, lat, lon); - if (map_poi_find_at_latlon(lat, lon, &poi_id)==TRUE) { - g_idle_add_full(G_PRIORITY_HIGH_IDLE,(GSourceFunc)map_cb_show_poi_info_dialog, GINT_TO_POINTER(poi_id), NULL); - } - if (map_data_needs_refresh==TRUE) { - map_data_needs_refresh=FALSE; - map_render_data(); - g_idle_add_full(G_PRIORITY_HIGH_IDLE,(GSourceFunc)map_update_location_from_center, NULL, NULL); - } - if (_center_mode>0) - set_action_activate("autocenter_none", TRUE); - map_drag_stop(event->x, event->y); - break; - } -break; -case 2: - if (map_pan_click_check(event->x, event->y)==FALSE) - map_set_zoom(_zoom-1); - return FALSE; -break; -case 3: - /* */ -break; -} - -/* Return FALSE to avoid context menu (if it hasn't popped up already). */ -return FALSE; -} - -gboolean -map_dialog_goto_latlon(void) -{ -GtkWidget *dialog; -GtkWidget *table; -GtkWidget *label; -GtkWidget *txt_lat; -GtkWidget *txt_lon; - -dialog = gtk_dialog_new_with_buttons(_("Go to Lat/Lon"), - GTK_WINDOW(_window), - GTK_DIALOG_MODAL, GTK_STOCK_OK, - GTK_RESPONSE_ACCEPT, - GTK_STOCK_CANCEL, - GTK_RESPONSE_REJECT, NULL); - -gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), table = gtk_table_new(2, 3, FALSE), TRUE, TRUE, 0); - -gtk_table_attach(GTK_TABLE(table), label = gtk_label_new(_("Latitude")),0, 1, 0, 1, GTK_FILL, 0, 2, 4); -gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f); - -gtk_table_attach(GTK_TABLE(table), txt_lat = gtk_entry_new(), 1, 2, 0, 1, GTK_FILL, 0, 2, 4); -gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f); - -gtk_table_attach(GTK_TABLE(table), label = gtk_label_new(_("Longitude")), 0, 1, 1, 2, GTK_FILL, 0, 2, 4); -gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f); - -gtk_table_attach(GTK_TABLE(table), txt_lon = gtk_entry_new(), 1, 2, 1, 2, GTK_FILL, 0, 2, 4); -gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f); - -#if defined (WITH_DEVICE_770) && !defined(WITH_HILDON_NEW) -g_object_set(G_OBJECT(txt_lat), HILDON_INPUT_MODE_HINT, HILDON_INPUT_MODE_HINT_NUMERICSPECIAL, NULL); -g_object_set(G_OBJECT(txt_lon), HILDON_INPUT_MODE_HINT, HILDON_INPUT_MODE_HINT_NUMERICSPECIAL, NULL); -#endif - -/* Initialize with the current center position. */ -{ - gchar buffer[32]; - gdouble lat, lon; - unit2latlon(_center.unitx, _center.unity, lat, lon); - g_snprintf(buffer, sizeof(buffer), "%.06f", lat); - gtk_label_set_text(GTK_LABEL(txt_lat), buffer); - g_snprintf(buffer, sizeof(buffer), "%.06f", lon); - gtk_label_set_text(GTK_LABEL(txt_lon), buffer); -} - -gtk_widget_show_all(dialog); - -while (GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog))) { - const gchar *text; - gchar *error_check; - gdouble lat, lon; - guint unitx, unity; - - text = gtk_entry_get_text(GTK_ENTRY(txt_lat)); - lat = strtof(text, &error_check); - if (text == error_check || lat < -90.f || lat > 90.f) { - popup_error(dialog, _("Invalid Latitude")); - continue; - } - - text = gtk_entry_get_text(GTK_ENTRY(txt_lon)); - lon = strtof(text, &error_check); - if (text == error_check || lon < -180.f || lon > 180.f) { - popup_error(dialog, _("Invalid Longitude")); - continue; - } - - latlon2unit(lat, lon, unitx, unity); - if (_center_mode > 0) - set_action_activate("autocenter_none", TRUE); - - map_center_unit(unitx, unity); - break; -} -gtk_widget_destroy(dialog); -return TRUE; -} - diff --git a/src/map.h b/src/map.h deleted file mode 100644 index d5e635a..0000000 --- a/src/map.h +++ /dev/null @@ -1,218 +0,0 @@ -#include - -#ifndef _MAPPER_MAP_H -#define _MAPPER_MAP_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "utils.h" -#include "mapper-types.h" -#include "position.h" -#include "osm.h" - -/** MAX_ZOOM defines the largest map zoom level we will download. - * (MAX_ZOOM - 1) is the largest map zoom level that the user can zoom to. - */ -#define MAX_ZOOM 16 - -#define TILE_SIZE_PIXELS (256) -#define TILE_SIZE_P2 (8) - -#define WORLD_SIZE_UNITS (2 << (MAX_ZOOM + TILE_SIZE_P2)) - -#define tile2grid(tile) ((tile) << 3) -#define grid2tile(grid) ((grid) >> 3) -#define tile2pixel(tile) ((tile) << 8) -#define pixel2tile(pixel) ((pixel) >> 8) -#define tile2unit(tile) ((tile) << (8 + _zoom)) -#define unit2tile(unit) ((unit) >> (8 + _zoom)) -#define tile2zunit(tile, zoom) ((tile) << (8 + zoom)) -#define unit2ztile(unit, zoom) ((unit) >> (8 + zoom)) - -#define grid2pixel(grid) ((grid) << 5) -#define pixel2grid(pixel) ((pixel) >> 5) -#define grid2unit(grid) ((grid) << (5 + _zoom)) -#define unit2grid(unit) ((unit) >> (5 + _zoom)) - -#define pixel2unit(pixel) ((pixel) << _zoom) -#define unit2pixel(pixel) ((pixel) >> _zoom) -#define pixel2zunit(pixel, zoom) ((pixel) << (zoom)) - -#define unit2bufx(unit) (unit2pixel(unit) - tile2pixel(_base_tilex)) -#define bufx2unit(x) (pixel2unit(x) + tile2unit(_base_tilex)) -#define unit2bufy(unit) (unit2pixel(unit) - tile2pixel(_base_tiley)) -#define bufy2unit(y) (pixel2unit(y) + tile2unit(_base_tiley)) - -#define unit2x(unit) (unit2pixel(unit) - tile2pixel(_base_tilex) - _offsetx) -#define x2unit(x) (pixel2unit(x + _offsetx) + tile2unit(_base_tilex)) -#define unit2y(unit) (unit2pixel(unit) - tile2pixel(_base_tiley) - _offsety) -#define y2unit(y) (pixel2unit(y + _offsety) + tile2unit(_base_tiley)) - -#define leadx2unit(mgps) (mgps.unitx + (_lead_ratio) * pixel2unit(mgps.vel_offsetx)) -#define leady2unit(mgps) (mgps.unity + (0.6f*_lead_ratio)*pixel2unit(mgps.vel_offsety)) - -/* Pans are done two "grids" at a time, or 64 pixels. */ -#define PAN_UNITS (grid2unit(2)) - -#define MACRO_RECALC_CENTER(mgps, center_unitx, center_unity) { \ - switch(_center_mode) \ - { \ - case CENTER_LEAD: \ - center_unitx = leadx2unit(mgps); \ - center_unity = leady2unit(mgps); \ - break; \ - case CENTER_LATLON: \ - center_unitx = mgps.unitx; \ - center_unity = mgps.unity; \ - break; \ - default: \ - center_unitx = _center.unitx; \ - center_unity = _center.unity; \ - ; \ - } \ -}; - -#define MACRO_RECALC_OFFSET() { \ - _offsetx = grid2pixel(unit2grid(_center.unitx) - _screen_grids_halfwidth - tile2grid(_base_tilex)); \ - _offsety = grid2pixel(unit2grid(_center.unity) - _screen_grids_halfheight - tile2grid(_base_tiley)); \ -} - -#define MACRO_RECALC_FOCUS_BASE(sens) { \ - _focus.unitx = x2unit(_screen_width_pixels * sens / 20); \ - _focus.unity = y2unit(_screen_height_pixels * sens / 20); \ -} - -#define MACRO_QUEUE_DRAW_AREA() \ - gtk_widget_queue_draw(_map_widget) - -/* Render all on-map metadata an annotations, including POI and paths. */ -#define MACRO_MAP_RENDER_DATA() { \ - if(_show_poi) \ - map_render_poi(); \ - if(_show_tracks > 0) \ - map_render_paths(); \ -} - -#define MACRO_RECALC_FOCUS_SIZE(sens) { \ - _focus_unitwidth = pixel2unit((10 - sens) * _screen_width_pixels / 10); \ - _focus_unitheight = pixel2unit((10 - sens) * _screen_height_pixels / 10); \ -} - -#define MACRO_RECALC_CENTER_BOUNDS() { \ - _min_center.unitx = pixel2unit(grid2pixel(_screen_grids_halfwidth)); \ - _min_center.unity = pixel2unit(grid2pixel(_screen_grids_halfheight)); \ - _max_center.unitx = WORLD_SIZE_UNITS-grid2unit(_screen_grids_halfwidth) - 1; \ - _max_center.unity = WORLD_SIZE_UNITS-grid2unit(_screen_grids_halfheight) - 1; \ -} - -typedef enum { - MAP_MODE_NORMAL=0, - MAP_MODE_DRAW_TRACK, - MAP_MODE_DRAW_ROUTE, - MAP_MODE_SET_ROUTE_FROM, - MAP_MODE_SET_ROUTE_POINT, - MAP_MODE_SET_ROUTE_TO, - MAP_MODES -} MapMode; - -/** Possible center modes. The "WAS" modes imply no current center mode; - * they only hint at what the last center mode was, so that it can be - * recalled. */ -typedef enum { - CENTER_WAS_LATLON = -2, - CENTER_WAS_LEAD = -1, - CENTER_MANUAL =0, - CENTER_LEAD = 1, - CENTER_LATLON = 2 -} CenterMode; - -/** VARIABLES FOR MAINTAINING STATE OF THE CURRENT VIEW. */ - -/** The "zoom" level defines the resolution of a pixel, from 0 to MAX_ZOOM. - * Each pixel in the current view is exactly (1 << _zoom) "units" wide. */ - -Point _min_center; -Point _max_center; -Point _focus; - -/** The "base tile" is the upper-left tile in the pixmap. */ -guint _base_tilex; -guint _base_tiley; - -guint _zoom; /* zoom level, from 0 to MAX_ZOOM. */ -Point _center; /* current center location, X. */ - -/** The "offset" defines the upper-left corner of the visible portion of the - * 1024x768 pixmap. */ -guint _offsetx; -guint _offsety; - -/** CACHED SCREEN INFORMATION THAT IS DEPENDENT ON THE CURRENT VIEW. */ -guint _screen_grids_halfwidth; -guint _screen_grids_halfheight; -guint _screen_width_pixels; -guint _screen_height_pixels; - -guint _focus_unitwidth; -guint _focus_unitheight; -guint _world_size_tiles; - -gint _show_tracks; -gboolean _show_scale; -gboolean _show_velvec; -gboolean _show_poi; - -guint _lead_ratio; -guint _center_ratio; -guint _draw_width; - -guint _key_zoom_new; -guint _key_zoom_timeout_sid; - -osm_location map_loc; - -CenterMode _center_mode; - -/** The widget that provides the visual display of the map. */ -GtkWidget *_map_widget; -GtkWidget *map_new(void); - -gboolean map_key_zoom_timeout(); - -int map_zoom(gint zdir); -guint map_get_zoom(void); -gboolean map_set_zoom(guint zoom); - -gboolean map_zoom_in(void); -gboolean map_zoom_out(void); -void map_set_autozoom(gboolean az, gfloat speed); -void map_render_path(Path * path, GdkGC ** gc); -void map_pan(gint delta_unitx, gint delta_unity); -void map_move_mark(void); -void map_set_mark(GpsData *gps); -void map_render_data(void); -gboolean map_render_tile(guint tilex, guint tiley, guint destx, guint desty, gboolean fast_fail); - -void map_render_waypoint(guint x1, guint y1, GdkGC *gc); -void map_render_paths(void); -void map_force_redraw(void); -GdkPixmap *map_pixmap_get(void); - -void map_center_unit(guint new_center_unitx, guint new_center_unity); -void map_center_latlon(gdouble lat, gdouble lon); - -gboolean map_goto_position(Position *pos); -gboolean map_update_location_from_center(void); - -#endif -- 2.39.5