From 954596a73cc844a6d5388e1cb956225d89fac140 Mon Sep 17 00:00:00 2001 From: Kaj-Michael Lang Date: Mon, 19 May 2008 09:33:44 +0300 Subject: [PATCH] MapWidgetIntegration: - Start of modification to use the map widget - Minimize use of map units outside of map widget - POIs are not special anymore, start to create a generic map marker system --- do-configure.sh | 4 +- src/Makefile.am | 2 - src/cb.c | 495 ++++++++++++++++--------------------- src/filter-gui.c | 1 - src/gps-conn.c | 1 - src/gps.c | 12 +- src/gpsdata.h | 6 +- src/gpx.c | 7 +- src/gtkmap.c | 558 ++++++++++++++++++++++++++++++++++-------- src/gtkmap.h | 35 ++- src/latlon.h | 17 +- src/maemo-osso.c | 2 - src/map-download.c | 41 ++-- src/map-poi.c | 188 +------------- src/map-poi.h | 4 +- src/map-repo.c | 54 ++-- src/map-widget-test.c | 2 +- src/map.c | 10 +- src/mapper.c | 3 +- src/osm-db.c | 3 + src/osm-sql-tables.h | 9 + src/path.c | 54 +++- src/path.h | 28 ++- src/poi-gui.c | 2 +- src/track.c | 2 +- src/ui-common.c | 10 +- src/ui-common.h | 7 +- 27 files changed, 865 insertions(+), 692 deletions(-) diff --git a/do-configure.sh b/do-configure.sh index ab457c5..7a28416 100755 --- a/do-configure.sh +++ b/do-configure.sh @@ -4,12 +4,14 @@ case "$1" in desktop) ./configure --prefix=/usr --sysconfdir=/etc \ --enable-maintainer-mode --enable-debug \ - --enable-gpsd --enable-gst --enable-hal + --enable-gpsd --enable-gst --enable-hal \ + --enable-btdbus ;; desktop-gc) ./configure --prefix=/usr --sysconfdir=/etc \ --enable-maintainer-mode --enable-debug \ --enable-gpsd --enable-gst --enable-hal \ + --enable-btdbus \ --enable-cairo --enable-opengl ;; hildon) diff --git a/src/Makefile.am b/src/Makefile.am index 0d0b617..a76e0cb 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -81,8 +81,6 @@ mapper_SOURCES = \ map-tile-repo.h \ map-repo.c \ map-repo.h \ - map.c \ - map.h \ mapper.c \ mapper.h \ path.c \ diff --git a/src/cb.c b/src/cb.c index 95b2779..5b654f9 100644 --- a/src/cb.c +++ b/src/cb.c @@ -49,7 +49,6 @@ #include "track.h" #include "settings.h" #include "gps.h" -#include "map.h" #include "mapper-types.h" #include "ui-common.h" #include "db.h" @@ -64,6 +63,7 @@ #include "help.h" #include "map-repo.h" #include "config-gconf.h" +#include "gtkmap.h" static gboolean path_tree_view_update_store(GtkWidget *tree_view, Path *path) @@ -86,7 +86,7 @@ return TRUE; Route menu callbacks ***********************/ gboolean -menu_cb_route_download(GtkAction * action) +menu_cb_route_download(GtkAction *action) { route_download(_route, NULL); route_menu_set_sensitive(path_tree_view_update_store(route_tree_view, _route)); @@ -102,37 +102,37 @@ return TRUE; } gboolean -menu_cb_route_save(GtkAction * action) +menu_cb_route_save(GtkAction *action) { route_save(_route); return TRUE; } gboolean -menu_cb_route_distnext(GtkAction * action) +menu_cb_route_distnext(GtkAction *action) { route_show_distance_to_next(_route); return TRUE; } gboolean -menu_cb_route_distlast(GtkAction * action) +menu_cb_route_distlast(GtkAction *action) { route_show_distance_to_last(_route); return TRUE; } gboolean -menu_cb_route_reset(GtkAction * action) +menu_cb_route_reset(GtkAction *action) { route_find_nearest_point(_route); -map_render_data(); +gtk_map_refresh(_map); MACRO_QUEUE_DRAW_AREA(); return TRUE; } gboolean -menu_cb_route_clear(GtkAction * action) +menu_cb_route_clear(GtkAction *action) { if (route_clear(_route)) { gtk_tree_view_set_model(route_tree_view, NULL); @@ -145,7 +145,7 @@ return TRUE; Track menu callbacks ***********************/ gboolean -menu_cb_track_open(GtkAction * action) +menu_cb_track_open(GtkAction *action) { track_open(_track); path_tree_view_update_store(track_tree_view, _track); @@ -153,7 +153,7 @@ return TRUE; } gboolean -menu_cb_track_save(GtkAction * action) +menu_cb_track_save(GtkAction *action) { track_save(_track); path_tree_view_update_store(track_tree_view, _track); @@ -161,7 +161,7 @@ return TRUE; } gboolean -menu_cb_track_insert_break(GtkAction * action) +menu_cb_track_insert_break(GtkAction *action) { path_insert_break(_track); path_tree_view_update_store(track_tree_view, _track); @@ -169,32 +169,30 @@ return TRUE; } gboolean -menu_cb_track_insert_mark(GtkAction * action) +menu_cb_track_insert_mark(GtkAction *action) { if (track_insert_mark(_track)) { - map_render_paths(); - MACRO_QUEUE_DRAW_AREA(); path_tree_view_update_store(track_tree_view, _track); } return TRUE; } gboolean -menu_cb_track_distlast(GtkAction * action) +menu_cb_track_distlast(GtkAction *action) { track_show_distance_from_last(_track); return TRUE; } gboolean -menu_cb_track_distfirst(GtkAction * action) +menu_cb_track_distfirst(GtkAction *action) { track_show_distance_from_first(_track); return TRUE; } gboolean -menu_cb_track_clear(GtkAction * action) +menu_cb_track_clear(GtkAction *action) { track_clear(_track); path_tree_view_update_store(track_tree_view, _track); @@ -202,7 +200,7 @@ return TRUE; } gboolean -menu_cb_track_filter(GtkAction * action) +menu_cb_track_filter(GtkAction *action) { filter_dialog(_window); return TRUE; @@ -217,19 +215,18 @@ menu_cb_show_tracks(GtkAction *action) _show_tracks ^= TRACKS_MASK; if (gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action))) { _show_tracks |= TRACKS_MASK; - map_render_paths(); - MACRO_QUEUE_DRAW_AREA(); + gtk_map_set_path_display(_map, _show_tracks); MACRO_BANNER_SHOW_INFO(_window, _("Tracks are now shown")); } else { _show_tracks &= ~TRACKS_MASK; - map_force_redraw(); + gtk_map_set_path_display(_map, _show_tracks); MACRO_BANNER_SHOW_INFO(_window, _("Tracks are now hidden")); } return TRUE; } gboolean -menu_cb_show_scale(GtkAction * action) +menu_cb_show_scale(GtkAction *action) { _show_scale = gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action)); MACRO_QUEUE_DRAW_AREA(); @@ -237,39 +234,38 @@ return TRUE; } gboolean -menu_cb_show_routes(GtkAction * action) +menu_cb_show_routes(GtkAction *action) { if (gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action))) { _show_tracks |= ROUTES_MASK; - map_render_paths(); - MACRO_QUEUE_DRAW_AREA(); + gtk_map_set_path_display(_map, _show_tracks); MACRO_BANNER_SHOW_INFO(_window, _("Routes are now shown")); } else { _show_tracks &= ~ROUTES_MASK; - map_force_redraw(); + gtk_map_set_path_display(_map, _show_tracks); MACRO_BANNER_SHOW_INFO(_window, _("Routes are now hidden")); } return TRUE; } gboolean -menu_cb_show_velvec(GtkAction * action) +menu_cb_show_velvec(GtkAction *action) { _show_velvec = gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action)); -map_move_mark(); +gtk_map_set_show_velvec(_map, _show_velvec); return TRUE; } gboolean -menu_cb_show_poi(GtkAction * action) +menu_cb_show_poi(GtkAction *action) { _show_poi = gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action)); -map_force_redraw(); +gtk_map_set_show_poi(_map, _show_poi); return TRUE; } gboolean -menu_cb_gps_show_info(GtkAction * action) +menu_cb_gps_show_info(GtkAction *action) { _gps_info = gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action)); gps_show_info(_gps); @@ -279,46 +275,42 @@ return TRUE; gboolean menu_cb_autocenter(GtkAction *action, GtkRadioAction *current) { -guint new_center_unitx, new_center_unity; -gint value = gtk_radio_action_get_current_value (GTK_RADIO_ACTION (current)); +gint value=gtk_radio_action_get_current_value(GTK_RADIO_ACTION(current)); switch (value) { case CENTER_LEAD: - _center_mode = CENTER_LEAD; + gtk_map_set_center_mode(_map, CENTER_LEAD); MACRO_BANNER_SHOW_INFO(_window, _("Auto-Center Mode: Lead")); break; case CENTER_LATLON: - _center_mode = CENTER_LATLON; + gtk_map_set_center_mode(_map, CENTER_LATLON); MACRO_BANNER_SHOW_INFO(_window, _("Auto-Center Mode: Lat/Lon")); break; case CENTER_MANUAL: default: - _center_mode = -_center_mode; + gtk_map_set_center_mode(_map, CENTER_MANUAL); MACRO_BANNER_SHOW_INFO(_window, _("Auto-Center Off")); - return TRUE; break; } -MACRO_RECALC_CENTER(_gps->data, new_center_unitx, new_center_unity); -map_center_unit(new_center_unitx, new_center_unity); return TRUE; } gboolean -menu_cb_goto_latlon(GtkAction * action) +menu_cb_goto_latlon(GtkAction *action) { -map_dialog_goto_latlon(); +gtk_map_dialog_goto_latlon(); return TRUE; } gboolean menu_cb_goto_home(GtkAction *action) { -if (map_goto_position(_home)==FALSE) { +if (gtk_map_goto_position(_home)==FALSE) { MACRO_BANNER_SHOW_INFO(_window, _("Home not set.")); } else { - if (map_get_zoom()>3) - map_set_zoom(3); + if (gtk_map_get_zoom(_map)>3) + gtk_map_set_zoom(_map, 3); MACRO_BANNER_SHOW_INFO(_window, _("At home location")); } return TRUE; @@ -327,10 +319,10 @@ return TRUE; gboolean menu_cb_goto_destination(GtkAction *action) { -if (map_goto_position(_dest)==FALSE) { +if (gtk_map_goto_position(_dest)==FALSE) { MACRO_BANNER_SHOW_INFO(_window, _("Destination not set.")); } else { - map_set_zoom(3); + gtk_map_set_zoom(_map, 3); MACRO_BANNER_SHOW_INFO(_window, _("At destination")); } return TRUE; @@ -339,23 +331,22 @@ return TRUE; gboolean menu_cb_goto_gps(GtkAction *action) { -_center_mode = CENTER_LATLON; -map_center_unit(_gps->data.unitx, _gps->data.unity); -map_update_location_from_center(); +gtk_map_set_center_mode(_map, CENTER_LATLON); MACRO_BANNER_SHOW_INFO(_window, _("At GPS coordinates.")); +map_update_location_from_center(); return TRUE; } gboolean -menu_cb_goto_nextway(GtkAction * action) +menu_cb_goto_nextway(GtkAction *action) { g_return_val_if_fail(_route, TRUE); if (_route->next_way && _route->next_way->point->unity) { - if (_center_mode > 0) + if (gtk_map_get_center_mode(_map) > 0) set_action_activate("autocenter_none", TRUE); - map_center_unit(_route->next_way->point->unitx, _route->next_way->point->unity); + gtk_map_set_center_unit(_route->next_way->point->unitx, _route->next_way->point->unity); } else { MACRO_BANNER_SHOW_INFO(_window, _("There is no next waypoint.")); } @@ -364,37 +355,33 @@ return TRUE; } gboolean -menu_cb_goto_nearpoi(GtkAction * action) +menu_cb_goto_nearpoi(GtkAction *action) { gdouble lat, lon; poi_info *p; -if (_center_mode > 0) { +if (gtk_map_get_center_mode(_map)!=CENTER_MANUAL) { /* Auto-Center is enabled - use the GPS position. */ lat=_gps->data.lat; lon=_gps->data.lon; } else { - /* Auto-Center is disabled - use the view center. */ - unit2latlon(_center.unitx, _center.unity, lat, lon); + gtk_map_get_center_latlon(_map, &lat, &lon); } p=poi_find_nearest(lat, lon); if (p) { - guint unitx, unity; gchar *banner; - latlon2unit(p->lat, p->lon, unitx, unity); banner = g_strdup_printf("%s (%s)", p->label, p->cat_label); - g_printf("%s\n", banner); MACRO_BANNER_SHOW_INFO(_window, banner); g_free(banner); poi_free(p); - if (_center_mode > 0) + if (gtk_map_get_center_mode(_map)!=CENTER_MANUAL) set_action_activate("autocenter_none", TRUE); - map_center_unit(unitx, unity); + gtk_map_set_center_latlon(_map, p->lat, p->lon); map_update_location_from_center(); } else { MACRO_BANNER_SHOW_INFO(_window, _("No POIs found.")); @@ -404,53 +391,49 @@ return TRUE; } gboolean -menu_cb_maps_repoman(GtkAction * action) +menu_cb_maps_repoman(GtkAction *action) { repoman_dialog(); return TRUE; } gboolean -menu_cb_maps_select(GtkAction * action, gpointer new_repo) +menu_cb_maps_select(GtkAction *action, gpointer new_repo) { -repo_set_curr(new_repo); -map_force_redraw(); +gtk_map_set_repo(_map, new_repo); return TRUE; } gboolean -cb_zoom_auto(GtkAction * action) +cb_zoom_auto(GtkAction *action) { -map_set_autozoom(TRUE, _gps->data.speed); +gtk_map_set_autozoom(_map, TRUE); return TRUE; } gboolean -cb_zoom_base(GtkAction * action) +cb_zoom_base(GtkAction *action) { -map_set_autozoom(FALSE, 0); -map_set_zoom(3); +gtk_map_set_autozoom(_map, FALSE); return TRUE; } gboolean -cb_zoomin(GtkAction * action) +cb_zoomin(GtkAction *action) { -map_set_autozoom(FALSE, 0); -g_idle_add((GSourceFunc)map_zoom_in, NULL); +g_idle_add((GSourceFunc)gtk_map_zoom_in, NULL); return TRUE; } gboolean -cb_zoomout(GtkAction * action) +cb_zoomout(GtkAction *action) { -map_set_autozoom(FALSE, 0); -g_idle_add((GSourceFunc)map_zoom_out, NULL); +g_idle_add((GSourceFunc)gtk_map_zoom_out, NULL); return TRUE; } gboolean -cb_fullscreen(GtkAction * action) +cb_fullscreen(GtkAction *action) { if ((_fullscreen = gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action)))) { gtk_window_fullscreen(GTK_WINDOW(_window)); @@ -473,7 +456,7 @@ return TRUE; } gboolean -menu_cb_enable_gps(GtkAction * action) +menu_cb_enable_gps(GtkAction *action) { if ((_enable_gps = gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action)))) { if (_gps->io.address) { @@ -496,21 +479,18 @@ set_action_sensitive("goto_gps", _enable_gps); set_action_sensitive("autocenter_latlon", _enable_gps); set_action_sensitive("autocenter_lead", _enable_gps); -map_move_mark(); gps_show_info(&_gps->data); return TRUE; } gboolean -menu_cb_auto_download(GtkAction * action) +menu_cb_auto_download(GtkAction *action) { if ((_auto_download = gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(action)) )) { - if (_curr_repo->url == REPOTYPE_NONE) { + if (_curr_repo->url == REPOTYPE_NONE) popup_error(_window, _("NOTE: You must set a Map URI in the current repository in order to download maps.")); - /* set_action_activate("", FALSE); */ - } - map_force_redraw(); + gtk_map_refresh(_map); } else { map_download_stop(); } @@ -519,18 +499,16 @@ return TRUE; } gboolean -menu_cb_settings(GtkAction * action) +menu_cb_settings(GtkAction *action) { if (settings_dialog()) { - MACRO_RECALC_FOCUS_BASE(_center_ratio); - MACRO_RECALC_FOCUS_SIZE(_center_ratio); - map_force_redraw(); + gtk_map_refresh(_map); } return TRUE; } gboolean -menu_cb_settings_gps(GtkAction * action) +menu_cb_settings_gps(GtkAction *action) { if (settings_dialog_gps(_gps)) { /* Settings have changed - reconnect to receiver. */ @@ -545,43 +523,42 @@ return TRUE; } gboolean -menu_cb_settings_colors(GtkAction * action) +menu_cb_settings_colors(GtkAction *action) { settings_dialog_colors(); -map_force_redraw(); return TRUE; } gboolean -menu_cb_settings_osm(GtkAction * action) +menu_cb_settings_osm(GtkAction *action) { settings_dialog_osm(); return TRUE; } gboolean -menu_cb_settings_keys(GtkAction * action) +menu_cb_settings_keys(GtkAction *action) { settings_dialog_hardkeys(); return TRUE; } gboolean -menu_cb_import_osm(GtkAction * action) +menu_cb_import_osm(GtkAction *action) { osm_import_dialog(_window); return TRUE; } gboolean -menu_cb_help(GtkAction * action) +menu_cb_help(GtkAction *action) { help_topic_display(HELP_ID_INTRO, 0); return TRUE; } gboolean -menu_cb_about(GtkAction * action) +menu_cb_about(GtkAction *action) { gchar *authors[]={ "Kaj-Michael Lang", @@ -647,19 +624,19 @@ if (custom_key==CUSTOM_KEY_ENUM_COUNT) switch (_action[custom_key]) { case CUSTOM_ACTION_PAN_NORTH: - map_pan(0, -PAN_UNITS); + gtk_map_pan(_map, 0, -1); break; case CUSTOM_ACTION_PAN_WEST: - map_pan(-PAN_UNITS, 0); + gtk_map_pan(_map, -1, 0); break; case CUSTOM_ACTION_PAN_SOUTH: - map_pan(0, PAN_UNITS); + gtk_map_pan(_map, 0, 1); break; case CUSTOM_ACTION_PAN_EAST: - map_pan(PAN_UNITS, 0); + gtk_map_pan(_map, 1, 0); break; case CUSTOM_ACTION_TOGGLE_AUTOCENTER: - switch (_center_mode) { + switch (gtk_map_get_center_mode(_map)) { case CENTER_LATLON: case CENTER_WAS_LEAD: set_action_activate("autocenter_lead", TRUE); @@ -674,14 +651,10 @@ switch (_action[custom_key]) { } break; case CUSTOM_ACTION_ZOOM_IN: + gtk_map_zoomin(_map); + break; case CUSTOM_ACTION_ZOOM_OUT: - if (!_key_zoom_timeout_sid) { - _key_zoom_new = _zoom + (_action[custom_key] == CUSTOM_ACTION_ZOOM_IN ? -_curr_repo->view_zoom_steps : _curr_repo->view_zoom_steps); - /* Remember, _key_zoom_new is unsigned. */ - if (_key_zoom_new < MAX_ZOOM) { - _key_zoom_timeout_sid = g_timeout_add(400, map_key_zoom_timeout, NULL); - } - } + gtk_map_zoomout(_map); break; case CUSTOM_ACTION_TOGGLE_FULLSCREEN: set_action_activate("view_fullscreen", !_fullscreen); @@ -768,57 +741,46 @@ window_cb_key_release(GtkWidget * widget, GdkEventKey * event) { switch (event->keyval) { case HILDON_HARDKEY_INCREASE: + gtk_map_zoomin(_map); + break; case HILDON_HARDKEY_DECREASE: - if (_key_zoom_timeout_sid) { - g_source_remove(_key_zoom_timeout_sid); - _key_zoom_timeout_sid = 0; - map_set_zoom(_key_zoom_new); - } - return TRUE; + gtk_map_zoomout(_map); break; default: - return FALSE; + break; } +return FALSE; } void -cmenu_show_latlon(guint unitx, guint unity) +cmenu_show_latlon(gdouble lat, gdouble lon) { -gdouble lat, lon; gchar buffer[80], tmp1[16], tmp2[16]; -unit2latlon(unitx, unity, lat, lon); lat_format(_degformat, lat, tmp1); lon_format(_degformat, lon, tmp2); -g_snprintf(buffer, sizeof(buffer), - "%s: %s\n" - "%s: %s", _("Latitude"), tmp1, _("Longitude"), tmp2); - +g_snprintf(buffer, sizeof(buffer), "%s: %s\n%s: %s", _("Latitude"), tmp1, _("Longitude"), tmp2); +/* XXX: Use a dialog under plain Gtk */ MACRO_BANNER_SHOW_INFO(_window, buffer); } void -cmenu_clip_latlon(guint unitx, guint unity) +cmenu_clip_latlon(gdouble lat, gdouble lon) { gchar buffer[80]; -gdouble lat, lon; -unit2latlon(unitx, unity, lat, lon); g_snprintf(buffer, sizeof(buffer), "%.06f,%.06f", lat, lon); gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), buffer, -1); } void -cmenu_route_to(guint unitx, guint unity) +cmenu_route_to(gdouble lat, gdouble lon) { gchar buffer[80]; gchar strlat[32]; gchar strlon[32]; -gdouble lat, lon; - -unit2latlon(unitx, unity, lat, lon); g_ascii_formatd(strlat, 32, "%.06f", lat); g_ascii_formatd(strlon, 32, "%.06f", lon); @@ -828,31 +790,18 @@ route_download(_route, buffer); } void -cmenu_distance_to(guint unitx, guint unity) +cmenu_distance_to(gdouble lat, gdouble lon) { gchar buffer[80]; -gdouble lat, lon; - -unit2latlon(unitx, unity, lat, lon); g_snprintf(buffer, sizeof(buffer), "%s: %.02lf %s", _("Distance"), calculate_distance(_gps->data.lat, _gps->data.lon, lat, lon) * UNITS_CONVERT[_units], UNITS_TEXT[_units]); MACRO_BANNER_SHOW_INFO(_window, buffer); } -void -cmenu_add_route(guint unitx, guint unity) -{ -MACRO_PATH_INCREMENT_TAIL(*_route); -_route->tail->unitx = x2unit(_cmenu_position_x); -_route->tail->unity = y2unit(_cmenu_position_y); -route_find_nearest_point(_route); -map_force_redraw(); -} - -void cmenu_route_add_way(guint unitx, guint unity) +void +cmenu_route_add_way(gdouble lat, gdouble lon) { -gdouble lat, lon; gchar tmp1[16], tmp2[16], *p_latlon; GtkWidget *dialog; GtkWidget *table; @@ -872,7 +821,6 @@ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), table = gtk_table_new(2, 2 gtk_table_attach(GTK_TABLE(table), label = gtk_label_new(_("Lat, Lon")), 0, 1, 0, 1, GTK_FILL, 0, 2, 4); gtk_misc_set_alignment(GTK_MISC(label), 1.f, 0.5f); -unit2latlon(unitx, unity, lat, lon); lat_format(_degformat, lat, tmp1); lon_format(_degformat, lon, tmp2); p_latlon = g_strdup_printf("%s, %s", tmp1, tmp2); @@ -907,107 +855,79 @@ while (GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(dialog))) { gtk_text_buffer_get_end_iter(tbuf, &ti2); desc = gtk_text_buffer_get_text(tbuf, &ti1, &ti2, TRUE); - if (*desc) { - /* There's a description. Add a waypoint. */ - MACRO_PATH_INCREMENT_TAIL(*_route); - _route->tail->unitx = unitx; - _route->tail->unity = unity; - _route->tail->time = 0; - _route->tail->altitude = NAN; - - MACRO_PATH_INCREMENT_WTAIL(*_route); - _route->wtail->point = _route->tail; - _route->wtail->desc = gtk_text_buffer_get_text(tbuf, &ti1, &ti2, TRUE); - } else { - GtkWidget *confirm; - - g_free(desc); - - confirm = hildon_note_new_confirmation(GTK_WINDOW(dialog), - _("Creating a \"waypoint\" with no description actually " - "adds a break point. Is that what you want?")); - - if (GTK_RESPONSE_OK == gtk_dialog_run(GTK_DIALOG(confirm))) { - /* There's no description. Add a break by adding a (0, 0) - * point (if necessary), and then the ordinary route point. */ - if (_route->tail->unity) { - MACRO_PATH_INCREMENT_TAIL(*_route); - *_route->tail = _point_null; - } - - MACRO_PATH_INCREMENT_TAIL(*_route); - _route->tail->unitx = unitx; - _route->tail->unity = unity; - _route->tail->time = 0; - _route->tail->altitude = NAN; - - gtk_widget_destroy(confirm); - } else { - gtk_widget_destroy(confirm); - continue; - } - } - - route_find_nearest_point(_route); - map_render_paths(); - MACRO_QUEUE_DRAW_AREA(); + path_add_waypoint(_route, lat, lon, desc); break; } gtk_widget_destroy(dialog); } gboolean -cmenu_cb_loc_show_latlon(GtkAction * action) +cmenu_cb_loc_show_latlon(GtkAction *action) { -cmenu_show_latlon(x2unit(_cmenu_position_x), y2unit(_cmenu_position_y)); +gdouble lat, lon; + +gtk_map_get_menu_latlon(_map, &lat, &lon); +cmenu_show_latlon(lat, lon); return TRUE; } gboolean -cmenu_cb_loc_clip_latlon(GtkAction * action) +cmenu_cb_loc_clip_latlon(GtkAction *action) { -cmenu_clip_latlon(x2unit(_cmenu_position_x), y2unit(_cmenu_position_y)); +gdouble lat, lon; + +gtk_map_get_menu_latlon(_map, &lat, &lon); +cmenu_clip_latlon(lat, lon); return TRUE; } gboolean -cmenu_cb_loc_route_to(GtkAction * action) +cmenu_cb_loc_route_to(GtkAction *action) { -cmenu_route_to(x2unit(_cmenu_position_x), y2unit(_cmenu_position_y)); +gdouble lat, lon; + +gtk_map_get_menu_latlon(_map, &lat, &lon); +cmenu_route_to(lat, lon); return TRUE; } gboolean -cmenu_cb_loc_distance_to(GtkAction * action) +cmenu_cb_loc_distance_to(GtkAction *action) { -cmenu_distance_to(x2unit(_cmenu_position_x), y2unit(_cmenu_position_y)); +gdouble lat, lon; + +gtk_map_get_menu_latlon(_map, &lat, &lon); +cmenu_distance_to(lat, lon); return TRUE; } gboolean -cmenu_cb_loc_add_route(GtkAction * action) +cmenu_cb_loc_add_route(GtkAction *action) { -cmenu_add_route(x2unit(_cmenu_position_x), y2unit(_cmenu_position_y)); +gdouble lat, lon; + +gtk_map_get_menu_latlon(_map, &lat, &lon); +path_add_latlon(_route, lat, lon); return TRUE; } gboolean -cmenu_cb_loc_add_way(GtkAction * action) +cmenu_cb_loc_add_way(GtkAction *action) { -cmenu_route_add_way(x2unit(_cmenu_position_x), y2unit(_cmenu_position_y)); +gdouble lat, lon; + +gtk_map_get_menu_latlon(_map, &lat, &lon); +cmenu_route_add_way(lat, lon); return TRUE; } gboolean -cmenu_cb_loc_add_poi(GtkAction * action) +cmenu_cb_loc_add_poi(GtkAction *action) { -guint ux, uy; poi_info *poi; poi=poi_new(); -ux=x2unit(_cmenu_position_x); -uy=y2unit(_cmenu_position_y); -unit2latlon(ux, uy, poi->lat, poi->lon); +gtk_map_get_menu_latlon(_map, &poi->lat, &poi->lon); poi_edit_dialog(ACTION_ADD_POI, poi); return TRUE; @@ -1019,11 +939,11 @@ cb_poi_search(GtkAction *action) poi_info poi; gdouble lat, lon; -if (_center_mode>0) { +if (gtk_map_get_center_mode(_map)!=CENTER_MANUAL) { lat=_gps->data.lat; lon=_gps->data.lon; } else { - unit2latlon(_center.unitx, _center.unity, lat, lon); + gtk_map_get_center_latlon(_map, &lat, &lon); } mapper_search_dialog(SEARCH_TYPE_POI, lat, lon); @@ -1037,11 +957,11 @@ gdouble lat,lon; const gchar *name = gtk_action_get_name(action); poi_info *p; -if (_center_mode>0) { +if (gtk_map_get_center_mode(_map)!=CENTER_MANUAL) { lat=_gps->data.lat; lon=_gps->data.lon; } else { - unit2latlon(_center.unitx, _center.unity, lat, lon); + gtk_map_get_center_latlon(_map, &lat, &lon); } if (strcmp(name, "poi_add")==0) { @@ -1064,120 +984,122 @@ menu_cb_search_address(GtkAction *action) { gdouble lat, lon; -if (_center_mode>0) { +if (gtk_map_get_center_mode(_map)!=CENTER_MANUAL) { lat=_gps->data.lat; lon=_gps->data.lon; } else { - unit2latlon(_center.unitx, _center.unity, lat, lon); + gtk_map_get_center_latlon(_map, &lat, &lon); } mapper_search_dialog(SEARCH_TYPE_WAY, lat, lon); return TRUE; } gboolean -cmenu_cb_loc_set_home(GtkAction * action) +cmenu_cb_loc_set_home(GtkAction *action) { -guint unitx, unity; - -unitx = x2unit(_cmenu_position_x); -unity = y2unit(_cmenu_position_y); -unit2latlon(unitx, unity, _home->lat, _home->lon); +gtk_map_get_menu_latlon(_map, &_home->lat, &_home->lon); _home->valid=TRUE; if (!config_save_position(_home, GCONF_KEY_POSITION_HOME)) popup_error(_window, _("Failed to save home position.")); -map_render_data(); +gtk_map_refresh(_map); return TRUE; } gboolean cmenu_cb_loc_set_destination(GtkAction *action) { -guint unitx, unity; - -unitx = x2unit(_cmenu_position_x); -unity = y2unit(_cmenu_position_y); -unit2latlon(unitx, unity, _dest->lat, _dest->lon); +gtk_map_get_menu_latlon(_map, &_dest->lat, &_dest->lon); _dest->valid=TRUE; + if (!config_save_position(&_dest, GCONF_KEY_POSITION_DEST)) popup_error(_window, _("Failed to save destination.")); +gtk_map_refresh(_map); return TRUE; } gboolean -cmenu_cb_loc_set_gps(GtkAction * action) +cmenu_cb_loc_set_gps(GtkAction *action) { -_gps->data.unitx = x2unit(_cmenu_position_x); -_gps->data.unity = y2unit(_cmenu_position_y); -unit2latlon(_gps->data.unitx, _gps->data.unity, _gps->data.lat, _gps->data.lon); - -/* Move mark to new location. */ +gtk_map_get_menu_latlon(_map, &_gps->data.lat, &_gps->data.lon); _gps->data.time=time(NULL); -track_add(_track, &_gps->data); -map_refresh_mark(); +path_add(_track, &_gps->data); return TRUE; } gboolean -cmenu_cb_way_show_latlon(GtkAction * action) +cmenu_cb_way_show_latlon(GtkAction *action) { WayPoint *way; +gdouble lat, lon; -if ((way = route_find_nearest_waypoint(_route, x2unit(_cmenu_position_x), y2unit(_cmenu_position_y)))) - cmenu_show_latlon(way->point->unitx, way->point->unity); +gtk_map_get_menu_latlon(_map, &lat, &lon); + +if ((way = path_find_nearest_waypoint(_route, lat, lon))) + cmenu_show_latlon(lat, lon); return TRUE; } gboolean -cmenu_cb_way_show_desc(GtkAction * action) +cmenu_cb_way_show_desc(GtkAction *action) { WayPoint *way; +gdouble lat, lon; -if ((way = route_find_nearest_waypoint(_route, x2unit(_cmenu_position_x), y2unit(_cmenu_position_y)))) { +gtk_map_get_menu_latlon(_map, &lat, &lon); + +if ((way = path_find_nearest_waypoint(_route, lat, lon))) MACRO_BANNER_SHOW_INFO(_window, way->desc); -} return TRUE; } gboolean -cmenu_cb_way_clip_latlon(GtkAction * action) +cmenu_cb_way_clip_latlon(GtkAction *action) { WayPoint *way; +gdouble lat, lon; -if ((way = route_find_nearest_waypoint(_route, x2unit(_cmenu_position_x), y2unit(_cmenu_position_y)))) +gtk_map_get_menu_latlon(_map, &lat, &lon); +if ((way = path_find_nearest_waypoint(_route, lat, lon))) cmenu_clip_latlon(way->point->unitx, way->point->unity); + return TRUE; } gboolean -cmenu_cb_way_clip_desc(GtkAction * action) +cmenu_cb_way_clip_desc(GtkAction *action) { WayPoint *way; +gdouble lat, lon; -if ((way = route_find_nearest_waypoint(_route, x2unit(_cmenu_position_x), y2unit(_cmenu_position_y)))) +gtk_map_get_menu_latlon(_map, &lat, &lon); +if ((way = path_find_nearest_waypoint(_route, lat, lon))) gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), way->desc, -1); return TRUE; } gboolean -cmenu_cb_way_route_to(GtkAction * action) +cmenu_cb_way_route_to(GtkAction *action) { WayPoint *way; +gdouble lat, lon; -if ((way = route_find_nearest_waypoint(_route, x2unit(_cmenu_position_x), y2unit(_cmenu_position_y)))) +gtk_map_get_menu_latlon(_map, &lat, &lon); + +if ((way = path_find_nearest_waypoint(_route, lat, lon))) cmenu_route_to(way->point->unitx, way->point->unity); return TRUE; } gboolean -cmenu_cb_way_distance_to(GtkAction * action) +cmenu_cb_way_distance_to(GtkAction *action) { WayPoint *way; @@ -1188,7 +1110,7 @@ return TRUE; } gboolean -cmenu_cb_way_delete(GtkAction * action) +cmenu_cb_way_delete(GtkAction *action) { WayPoint *way; @@ -1214,17 +1136,13 @@ if ((way = route_find_nearest_waypoint(_route, x2unit(_cmenu_position_x), y2unit else pdel_max = way[1].point; - /* Find largest continuous segment around the waypoint, EXCLUDING - * pdel_min and pdel_max. */ - for (pdel_start = way->point - 1; pdel_start->unity - && pdel_start > pdel_min; pdel_start--) { + /* Find largest continuous segment around the waypoint, EXCLUDING pdel_min and pdel_max. */ + for (pdel_start = way->point - 1; pdel_start->unity && pdel_start > pdel_min; pdel_start--) { } - for (pdel_end = way->point + 1; pdel_end->unity - && pdel_end < pdel_max; pdel_end++) { + for (pdel_end = way->point + 1; pdel_end->unity && pdel_end < pdel_max; pdel_end++) { } - /* If pdel_end is set to _route->tail, and if _route->tail is a - * non-zero point, then delete _route->tail. */ + /* If pdel_end is set to _route->tail, and if _route->tail is a non-zero point, then delete _route->tail. */ if (pdel_end == _route->tail && pdel_end->unity) pdel_end++; /* delete _route->tail too */ /* else, if *both* endpoints are zero points, delete one. */ @@ -1245,8 +1163,7 @@ if ((way = route_find_nearest_waypoint(_route, x2unit(_cmenu_position_x), y2unit } _route->wtail--; - route_find_nearest_point(_route); - map_force_redraw(); + path_find_nearest_point(_route); } gtk_widget_destroy(confirm); } @@ -1255,82 +1172,82 @@ return TRUE; } gboolean -menu_cb_category(GtkAction * action) +menu_cb_category(GtkAction *action) { if (poi_category_list()) - map_force_redraw(); + gtk_map_refresh(_map); return TRUE; } gboolean -cmenu_cb_way_add_poi(GtkAction * action) +cmenu_cb_way_add_poi(GtkAction *action) { WayPoint *way; +gdouble lat, lon; -if ((way = route_find_nearest_waypoint(_route, x2unit(_cmenu_position_x), y2unit(_cmenu_position_y)))) { +gtk_map_get_menu_latlon(_map, &lat, &lon); + +if ((way = path_find_nearest_waypoint(_route, lat, lon))) { poi_info *p; p=poi_new(); - unit2latlon(way->point->unitx, way->point->unity, p->lat, p->lon); + path_get_waypoint_latlon(way, &p->lat, &p->lon); poi_edit_dialog(ACTION_ADD_POI, p); - /* XXX: free it ? */ } return TRUE; } gboolean -cmenu_cb_poi_route_to(GtkAction * action) +cmenu_cb_poi_route_to(GtkAction *action) { poi_info poi; +gdouble lat, lon; -if (poi_select(x2unit(_cmenu_position_x), y2unit(_cmenu_position_y), 4, &poi)) { - guint unitx, unity; - latlon2unit(poi.lat, poi.lon, unitx, unity); - cmenu_route_to(unitx, unity); -} +gtk_map_get_menu_latlon(_map, &lat, &lon); +if (poi_select(lat, lon, 4, &poi)) + cmenu_route_to(poi.lat, poi.lon); return TRUE; } gboolean -cmenu_cb_poi_distance_to(GtkAction * action) +cmenu_cb_poi_distance_to(GtkAction *action) { poi_info poi; +gdouble lat, lon; -if (poi_select(x2unit(_cmenu_position_x), y2unit(_cmenu_position_y), 4, &poi)) { - guint unitx, unity; - latlon2unit(poi.lat, poi.lon, unitx, unity); - cmenu_distance_to(unitx, unity); -} +gtk_map_get_menu_latlon(_map, &lat, &lon); + +if (poi_select(lat, lon, 4, &poi)) + cmenu_distance_to(poi.lat, poi.lon); return TRUE; } gboolean -cmenu_cb_poi_add_route(GtkAction * action) +cmenu_cb_poi_add_route(GtkAction *action) { poi_info poi; +gdouble lat, lon; -if (poi_select(x2unit(_cmenu_position_x), y2unit(_cmenu_position_y), 4, &poi)) { - guint unitx, unity; - latlon2unit(poi.lat, poi.lon, unitx, unity); - cmenu_add_route(unitx, unity); -} +gtk_map_get_menu_latlon(_map, &lat, &lon); +if (poi_select(lat, lon, 4, &poi)) + path_add_latlon(_route, lat, lon); return TRUE; } gboolean -cmenu_cb_poi_add_way(GtkAction * action) +cmenu_cb_poi_add_way(GtkAction *action) { poi_info poi; +gdouble lat, lon; -if (poi_select(x2unit(_cmenu_position_x), y2unit(_cmenu_position_y), 4, &poi)) { - guint unitx, unity; - latlon2unit(poi.lat, poi.lon, unitx, unity); - cmenu_route_add_way(unitx, unity); -} +gtk_map_get_menu_latlon(_map, &lat, &lon); + +if (poi_select(lat, lon, 4, &poi)) + cmenu_route_add_way(lat, lon); return TRUE; } @@ -1343,12 +1260,12 @@ return TRUE; } gboolean -cmenu_cb_poi_edit_poi(GtkAction * action) +cmenu_cb_poi_edit_poi(GtkAction *action) { poi_info *p; gdouble lat, lon; -unit2latlon(x2unit(_cmenu_position_x), y2unit(_cmenu_position_y), lat, lon); +gtk_map_get_menu_latlon(_map, &lat, &lon); p=poi_find_nearest(lat, lon); if (!p) { popup_error(_window, _("No POI found at location.")); diff --git a/src/filter-gui.c b/src/filter-gui.c index e1874e4..42b331b 100644 --- a/src/filter-gui.c +++ b/src/filter-gui.c @@ -36,7 +36,6 @@ #include "utils.h" #include "gps.h" -#include "map.h" #include "mapper-types.h" #include "ui-common.h" #include "settings.h" diff --git a/src/gps-conn.c b/src/gps-conn.c index a841f1c..26dc1dd 100644 --- a/src/gps-conn.c +++ b/src/gps-conn.c @@ -45,7 +45,6 @@ static GtkWidget *fix_banner = NULL; #include "utils.h" #include "settings.h" #include "gps.h" -#include "map.h" #include "ui-common.h" #include "gps-conn.h" diff --git a/src/gps.c b/src/gps.c index 1d27c44..feb461b 100644 --- a/src/gps.c +++ b/src/gps.c @@ -46,7 +46,6 @@ #include "gps.h" #include "latlon.h" -#include "map.h" #include "gps-conn.h" #include "gps-nmea-parse.h" #include "position.h" @@ -154,18 +153,15 @@ g_slice_free(Gps, gps); } /** - * Convert the float lat/lon/speed/heading data into integer units. - * Also calculate offsets. + * Calculate offsets. */ void gps_data_integerize(GpsData *gpsdata) { -gdouble tmp; +gdouble tmp=(gpsdata->heading*(1.f/180.f))*G_PI; -tmp=(gpsdata->heading*(1.f/180.f))*G_PI; -latlon2unit(gpsdata->lat, gpsdata->lon, gpsdata->unitx, gpsdata->unity); -gpsdata->vel_offsetx=(gint)(floor(gpsdata->speed*sin(tmp)+0.5f)); -gpsdata->vel_offsety=-(gint)(floor(gpsdata->speed*cos(tmp)+0.5f)); +gpsdata->vel_offset_lat=-(floor(gpsdata->speed*cos(tmp)+0.5f)); +gpsdata->vel_offset_lon=(floor(gpsdata->speed*sin(tmp)+0.5f)); } #ifdef WITH_HILDON_DBUS_BT diff --git a/src/gpsdata.h b/src/gpsdata.h index dc75484..ba63b99 100644 --- a/src/gpsdata.h +++ b/src/gpsdata.h @@ -30,8 +30,6 @@ typedef struct _GpsData GpsData; struct _GpsData { gdouble lat; gdouble lon; - guint unitx; - guint unity; time_t time; GpsFix fix; gboolean newly_fixed; @@ -45,8 +43,8 @@ struct _GpsData { gfloat hdop; gfloat vdop; gfloat pdop; - gint vel_offsetx; - gint vel_offsety; + gdouble vel_offset_lat; + gdouble vel_offset_lon; guint satinview; guint satinuse; GpsSatelliteData sat[GPS_SAT_MAX]; diff --git a/src/gpx.c b/src/gpx.c index 6a60b25..d42b2a9 100644 --- a/src/gpx.c +++ b/src/gpx.c @@ -49,12 +49,11 @@ #include "ui-common.h" #include "path.h" #include "utils.h" -#include "gps.h" #include "mapper-types.h" #include "latlon.h" -#include "map.h" #include "gpx.h" #include "dialogs.h" +#include "gtkmap.h" #define XML_DATE_FORMAT "%FT%T" @@ -158,7 +157,7 @@ for (curr--; curr++ != path->tail;) { WRITE_STRING("\n\n"); trkseg_break = FALSE; } - unit2latlon(curr->unitx, curr->unity, lat, lon); + unit2latlon(curr->unitx, curr->unity, &lat, &lon); WRITE_STRING("path); - latlon2unit(lat, lon, data->path.tail->unitx, data->path.tail->unity); + latlon2unit(lat, lon, &data->path.tail->unitx, &data->path.tail->unity); data->path.tail->time = 0; data->path.tail->altitude = NAN; data->state = INSIDE_PATH_POINT; diff --git a/src/gtkmap.c b/src/gtkmap.c index 67e576f..fe3605e 100644 --- a/src/gtkmap.c +++ b/src/gtkmap.c @@ -44,6 +44,9 @@ #define BUF_WIDTH_PIXELS (1024) #define BUF_HEIGHT_PIXELS (768) +#define MARKER_FONT_SIZE_BIG (10) +#define MARKER_FONT_SIZE_SMALL (8) + /* Filename buffer */ #define BUFFER_SIZE (2048) @@ -65,9 +68,10 @@ struct _GtkMapPriv guint buf_width_pixels; guint buf_height_pixels; - /* Cairo context for widget->window */ #ifdef WITH_CAIRO + /* Cairo context for widget->window */ cairo_t *ct; + cairo_matrix_t matrix_rotate; #endif GtkMenu *menu; @@ -84,6 +88,10 @@ struct _GtkMapPriv PangoLayout *scale_layout; PangoFontDescription *scale_font; + PangoContext *marker_context; + PangoLayout *marker_layout; + PangoFontDescription *marker_font; + GdkGC *gc_track; GdkGC *gc_route; GdkGC *gc_waypoint; @@ -110,6 +118,9 @@ struct _GtkMapPriv ImageCache *icache; GSList *markers; + GtkListStore *marker_store; + GdkGC *marker_gc; + gint marker_zoom; /* Cached Location dot x,y values */ gint mark_x1; @@ -160,34 +171,44 @@ struct _GtkMapPriv guint focus_unitheight; guint world_size_tiles; + /* Flags */ gint show_paths; gboolean show_scale; gboolean show_location; gboolean show_velvec; gboolean show_markers; + gboolean show_marker_labels; gboolean show_speed; gboolean click_to_center; gboolean zoom_in_on_2button; + + /* View rotation */ gboolean rotate_view; gfloat rotate_angle; + /* How wide paths are drawn */ guint draw_width; + /* Mouse related stuff */ gboolean button_down; gint mouse_x; gint mouse_y; gdouble mouse_lat; gdouble mouse_lon; + /* Lat/Lon where context menu has popped up */ + gdouble menu_lat; + gdouble menu_lon; + gboolean fast_render; guint key_zoom_new; guint key_zoom_timeout_sid; /* Paths */ - GSList *paths; /* A list with paths to draw (tracks, routes, friends) */ - Path *current_track; /* Pointer to main track */ - Path *current_route; /* Pointer to main route */ + GSList *paths; /* A list with paths to draw (tracks, routes, friends, etc) */ + Path *current_track; /* Pointer to main track, "We" */ + Path *current_route; /* Pointer to main route, "We are following" */ }; #define tile2grid(tile) ((tile) << 3) @@ -282,7 +303,14 @@ enum { /* Property IDs */ enum { - LAST_PROP + PROP_CENTER_MODE=1, + PROP_CENTER_LAT, + PROP_CENTER_LON, + PROP_MIN_LAT, + PROP_MAX_LAT, + PROP_MIN_LON, + PROP_MAX_LON, + PROP_LAST }; static guint gtk_map_signals[LAST_SIGNAL] = { 0 }; @@ -290,6 +318,8 @@ static guint gtk_map_signals[LAST_SIGNAL] = { 0 }; #define MERCATOR_SPAN (-6.28318377773622f) #define MERCATOR_TOP (3.14159188886811f) +/******************************************************************************/ + void latlon2unit(gdouble lat, gdouble lon, guint *unitx, guint *unity) { @@ -307,40 +337,7 @@ unit2latlon(guint unitx, guint unity, gdouble *lat, gdouble *lon) *lat=(360.f * (atan(exp(((unity) * (MERCATOR_SPAN / GTK_MAP_WORLD_SIZE_UNITS)) + MERCATOR_TOP)))) * (1.f / M_PIl) - 90.f; } - -static void -gtk_map_class_init(GtkMapClass *class) -{ -GObjectClass *object_class; -GtkWidgetClass *widget_class; - -object_class = (GObjectClass*) class; -widget_class = (GtkWidgetClass*) class; - -object_class->finalize = gtk_map_finalize; -object_class->set_property = gtk_map_set_property; -object_class->get_property = gtk_map_get_property; - -widget_class->size_request = gtk_map_size_request; -widget_class->expose_event = gtk_map_expose; -widget_class->realize = gtk_map_realize; -widget_class->size_allocate = gtk_map_size_allocate; - -g_type_class_add_private (object_class, sizeof(GtkMapPriv)); - -gtk_map_signals[MAP_ZOOM_CHANGED]=g_signal_new("zoom-changed", G_OBJECT_CLASS_TYPE(object_class), - G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET(GtkMapClass, zoom_changed), - NULL, NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT); - -gtk_map_signals[MAP_LOCATION_CHANGED]=g_signal_new("location-changed", G_OBJECT_CLASS_TYPE(object_class), - G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET(GtkMapClass, location_changed), - NULL, NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT); - -gtk_map_signals[MAP_LOCATION_CHANGED]=g_signal_new("center-mode-changed", G_OBJECT_CLASS_TYPE(object_class), - G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET(GtkMapClass, center_mode_changed), - NULL, NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT); - -} +/******************************************************************************/ static inline void gtk_map_recalc_center(GtkMapPriv *priv) @@ -367,11 +364,11 @@ gtk_map_recalc_offset(GtkMapPriv *priv) { g_return_if_fail(priv); #if 0 -priv->offsetx = grid2pixel(unit2grid(priv->center.unitx) - priv->screen_grids_halfwidth - tile2grid(priv->base_tilex)); -priv->offsety = grid2pixel(unit2grid(priv->center.unity) - priv->screen_grids_halfheight - tile2grid(priv->base_tiley)); +priv->offsetx=grid2pixel(unit2grid(priv->center.unitx) - priv->screen_grids_halfwidth - tile2grid(priv->base_tilex)); +priv->offsety=grid2pixel(unit2grid(priv->center.unity) - priv->screen_grids_halfheight - tile2grid(priv->base_tiley)); #else -priv->offsetx = unit2pixel(priv->center.unitx) - priv->screen_width_pixels/2 - tile2pixel(priv->base_tilex); -priv->offsety = unit2pixel(priv->center.unity) - priv->screen_height_pixels/2 - tile2pixel(priv->base_tiley); +priv->offsetx=unit2pixel(priv->center.unitx) - priv->screen_width_pixels/2 - tile2pixel(priv->base_tilex); +priv->offsety=unit2pixel(priv->center.unity) - priv->screen_height_pixels/2 - tile2pixel(priv->base_tiley); #endif } @@ -379,26 +376,87 @@ static void gtk_map_recalc_focus_base(GtkMapPriv *priv) { g_return_if_fail(priv); -priv->focus.unitx = x2unit(priv->screen_width_pixels * priv->center_ratio / 20); -priv->focus.unity = y2unit(priv->screen_height_pixels * priv->center_ratio / 20); +priv->focus.unitx=x2unit(priv->screen_width_pixels * priv->center_ratio / 20); +priv->focus.unity=y2unit(priv->screen_height_pixels * priv->center_ratio / 20); } static void gtk_map_recalc_focus_size(GtkMapPriv *priv) { g_return_if_fail(priv); -priv->focus_unitwidth = pixel2unit((10 - priv->center_ratio) * priv->screen_width_pixels / 10); -priv->focus_unitheight = pixel2unit((10 - priv->center_ratio) * priv->screen_height_pixels / 10); +priv->focus_unitwidth=pixel2unit((10 - priv->center_ratio) * priv->screen_width_pixels / 10); +priv->focus_unitheight=pixel2unit((10 - priv->center_ratio) * priv->screen_height_pixels / 10); } -static inline void +static void gtk_map_recalc_center_bounds(GtkMapPriv *priv) { g_return_if_fail(priv); -priv->min_center.unitx = pixel2unit(grid2pixel(priv->screen_grids_halfwidth)); -priv->min_center.unity = pixel2unit(grid2pixel(priv->screen_grids_halfheight)); -priv->max_center.unitx = GTK_MAP_WORLD_SIZE_UNITS-grid2unit(priv->screen_grids_halfwidth) - 1; -priv->max_center.unity = GTK_MAP_WORLD_SIZE_UNITS-grid2unit(priv->screen_grids_halfheight) - 1; +priv->min_center.unitx=pixel2unit(grid2pixel(priv->screen_grids_halfwidth)); +priv->min_center.unity=pixel2unit(grid2pixel(priv->screen_grids_halfheight)); +priv->max_center.unitx=GTK_MAP_WORLD_SIZE_UNITS-grid2unit(priv->screen_grids_halfwidth) - 1; +priv->max_center.unity=GTK_MAP_WORLD_SIZE_UNITS-grid2unit(priv->screen_grids_halfheight) - 1; +} + +/******************************************************************************/ + +static void +gtk_map_class_init(GtkMapClass *class) +{ +GObjectClass *object_class; +GtkWidgetClass *widget_class; +GParamSpec *pspec; + +object_class = (GObjectClass*) class; +widget_class = (GtkWidgetClass*) class; + +object_class->finalize = gtk_map_finalize; +object_class->set_property = gtk_map_set_property; +object_class->get_property = gtk_map_get_property; + +widget_class->size_request = gtk_map_size_request; +widget_class->expose_event = gtk_map_expose; +widget_class->realize = gtk_map_realize; +widget_class->size_allocate = gtk_map_size_allocate; + +g_type_class_add_private (object_class, sizeof(GtkMapPriv)); + +pspec=g_param_spec_uint("center-mode","Center Mode","Map centering mode on current track tail", 0, 2, 1, G_PARAM_READWRITE); +g_object_class_install_property (object_class, PROP_CENTER_MODE, pspec); + +/* Center lat/lon */ +pspec=g_param_spec_double("center-lat","Center Lat","Latitude", -90, 90, 0, G_PARAM_READABLE); +g_object_class_install_property (object_class, PROP_CENTER_LAT, pspec); + +pspec=g_param_spec_double("center-lon","Center Lon","Longitude", -180, 180, 0, G_PARAM_READABLE); +g_object_class_install_property (object_class, PROP_CENTER_LAT, pspec); + +/* Min/Max latitude */ +pspec=g_param_spec_double("max-lat","Max Lat","View max latitude", -90, 90, 0, G_PARAM_READABLE); +g_object_class_install_property (object_class, PROP_MAX_LAT, pspec); + +pspec=g_param_spec_double("min-lat","Min Lat","View min latitude", -90, 90, 0, G_PARAM_READABLE); +g_object_class_install_property (object_class, PROP_MIN_LAT, pspec); + +/* Min/Max longitude */ +pspec=g_param_spec_double("max-lon","Max Lon","View max longitude", -180, 180, 0, G_PARAM_READABLE); +g_object_class_install_property (object_class, PROP_MAX_LAT, pspec); + +pspec=g_param_spec_double("min-lon","Min Lon","View min longitude", -180, 180, 0, G_PARAM_READABLE); +g_object_class_install_property (object_class, PROP_MIN_LAT, pspec); + +gtk_map_signals[MAP_ZOOM_CHANGED]=g_signal_new("zoom-changed", G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET(GtkMapClass, zoom_changed), + NULL, NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT); + +gtk_map_signals[MAP_LOCATION_CHANGED]=g_signal_new("location-changed", G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET(GtkMapClass, location_changed), + NULL, NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT); + +gtk_map_signals[MAP_LOCATION_CHANGED]=g_signal_new("center-mode-changed", G_OBJECT_CLASS_TYPE(object_class), + G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET(GtkMapClass, center_mode_changed), + NULL, NULL, g_cclosure_marshal_VOID__INT, G_TYPE_NONE, 1, G_TYPE_INT); + } static void @@ -406,7 +464,6 @@ gtk_map_init(GtkMap *map) { GtkMapPriv *priv; -g_debug("GTKMAP: %s", __PRETTY_FUNCTION__); priv=GTK_MAP_GET_PRIVATE(map); priv->base_tilex=-5; @@ -446,13 +503,29 @@ priv->gl=FALSE; priv->buffer=NULL; } +GtkWidget* +gtk_map_new(void) +{ +return g_object_new(GTK_MAP_TYPE, NULL); +} + +/******************************************************************************/ + static void gtk_map_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { GtkMap *map; +GtkMapPriv *priv; + g_return_if_fail(GTK_IS_MAP(object)); + map=GTK_MAP(object); +priv=GTK_MAP_GET_PRIVATE(map); + switch (prop_id) { + case PROP_CENTER_MODE: + priv->center_mode=g_value_get_int(value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -463,22 +536,48 @@ static void gtk_map_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { GtkMap *map; +GtkMapPriv *priv; +gdouble lat,lon; g_return_if_fail(GTK_IS_MAP(object)); map=GTK_MAP(object); +priv=GTK_MAP_GET_PRIVATE(map); + switch (prop_id) { + case PROP_CENTER_MODE: + g_value_set_int(value, priv->center_mode); + break; + case PROP_CENTER_LAT: + unit2latlon(priv->center.unitx, priv->center.unity, &lat, &lon); + g_value_set_double(value, lat); + break; + case PROP_CENTER_LON: + unit2latlon(priv->center.unitx, priv->center.unity, &lat, &lon); + g_value_set_double(value, lon); + break; + case PROP_MAX_LAT: + unit2latlon(x2unit(priv->screen_width_pixels), y2unit(priv->screen_height_pixels), &lat, &lon); + g_value_set_double(value, lat); + break; + case PROP_MIN_LAT: + unit2latlon(x2unit(0), y2unit(0), &lat, &lon); + g_value_set_double(value, lat); + break; + case PROP_MAX_LON: + unit2latlon(x2unit(priv->screen_width_pixels), y2unit(priv->screen_height_pixels), &lat, &lon); + g_value_set_double(value, lon); + break; + case PROP_MIN_LON: + unit2latlon(x2unit(0), y2unit(0), &lat, &lon); + g_value_set_double(value, lon); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; } } -GtkWidget* -gtk_map_new(void) -{ -g_debug("GTKMAP: %s", __PRETTY_FUNCTION__); -return g_object_new(GTK_MAP_TYPE, NULL); -} +/******************************************************************************/ static void gtk_map_finalize(GObject *object) @@ -534,11 +633,7 @@ priv->scale_rect.width = SCALE_WIDTH; gtk_map_recalc_focus_base(priv); gtk_map_recalc_focus_size(priv); - -priv->min_center.unitx = pixel2unit(grid2pixel(priv->screen_grids_halfwidth)); -priv->min_center.unity = pixel2unit(grid2pixel(priv->screen_grids_halfheight)); -priv->max_center.unitx = GTK_MAP_WORLD_SIZE_UNITS - grid2unit(priv->screen_grids_halfwidth) - 1; -priv->max_center.unity = GTK_MAP_WORLD_SIZE_UNITS - grid2unit(priv->screen_grids_halfheight) - 1; +gtk_map_recalc_center_bounds(priv); } static void @@ -554,6 +649,9 @@ widget->allocation = *allocation; g_debug("GTKMAP: Size allocate (%d, %d)", widget->allocation.width, widget->allocation.height); +gtk_map_recalc_offset(priv); +gtk_map_recalc_focus_base(priv); + if (GTK_WIDGET_REALIZED(widget)) { gdk_window_move_resize(widget->window, allocation->x, allocation->y, allocation->width, allocation->height); gtk_map_update_size(widget, allocation->width, allocation->height); @@ -640,10 +738,9 @@ gdk_window_set_user_data(widget->window, widget); widget->style=gtk_style_attach(widget->style, widget->window); gtk_style_set_background(widget->style, widget->window, GTK_STATE_NORMAL); - gtk_widget_set_extension_events(widget, GDK_EXTENSION_EVENTS_ALL); -#ifdef WITH_GL +#ifdef WITH_GL_NOTYET priv->gl_config=gdk_gl_config_new_by_mode(GDK_GL_MODE_RGB | GDK_GL_MODE_DEPTH); if (priv->gl_config) { g_print("OpenGL version: %s\n", glGetString (GL_VERSION)); @@ -657,9 +754,26 @@ if (priv->gl_config) { priv->scale_context=gtk_widget_get_pango_context(widget); priv->scale_layout=pango_layout_new(priv->scale_context); priv->scale_font=pango_font_description_new(); -pango_font_description_set_size(priv->scale_font, 12 * PANGO_SCALE); +pango_font_description_set_family(priv->scale_font,"Sans Serif"); +pango_font_description_set_size(priv->scale_font, 14 * PANGO_SCALE); pango_layout_set_font_description(priv->scale_layout, priv->scale_font); +priv->marker_context=gtk_widget_get_pango_context(widget); +priv->marker_layout=pango_layout_new(priv->marker_context); +priv->marker_font=pango_font_description_new(); +pango_font_description_set_family(priv->marker_font,"Sans Serif"); +pango_font_description_set_size(priv->marker_font, MARKER_FONT_SIZE_SMALL*PANGO_SCALE); +pango_layout_set_font_description (priv->marker_layout, priv->marker_font); +pango_layout_set_alignment(priv->marker_layout, PANGO_ALIGN_CENTER); +pango_layout_set_width(priv->marker_layout, 80*PANGO_SCALE); + +priv->speed_context=gtk_widget_get_pango_context(widget); +priv->speed_layout=pango_layout_new(priv->speed_context); +priv->speed_font=pango_font_description_new(); +pango_font_description_set_size(priv->speed_font, 48 * PANGO_SCALE); +pango_layout_set_font_description(priv->speed_layout, priv->speed_font); +pango_layout_set_alignment(priv->speed_layout, PANGO_ALIGN_LEFT); + /* Speed limit, over limit color */ priv->speed_gc1=gdk_gc_new(widget->window); color.red=0xffff; @@ -698,18 +812,12 @@ color.green=0; color.blue=0xffff; gdk_gc_set_rgb_fg_color(priv->gc_break, &color); -priv->speed_context=gtk_widget_get_pango_context(widget); -priv->speed_layout=pango_layout_new(priv->speed_context); -priv->speed_font=pango_font_description_new(); -pango_font_description_set_size(priv->speed_font, 48 * PANGO_SCALE); -pango_layout_set_font_description(priv->speed_layout, priv->speed_font); -pango_layout_set_alignment(priv->speed_layout, PANGO_ALIGN_LEFT); - g_signal_connect(G_OBJECT(map), "button_press_event", G_CALLBACK(gtk_map_button_press_cb), NULL); g_signal_connect(G_OBJECT(map), "button_release_event",G_CALLBACK(gtk_map_button_release_cb), NULL); g_signal_connect(G_OBJECT(map), "scroll_event", G_CALLBACK(gtk_map_scroll_event_cb), NULL); g_signal_connect(G_OBJECT(map), "motion_notify_event", G_CALLBACK(gtk_map_motion_notify_cb), NULL); +gtk_widget_set_app_paintable(widget, TRUE); gtk_widget_queue_resize(widget); } @@ -728,37 +836,30 @@ priv=GTK_MAP_GET_PRIVATE(map); if (!priv->buffer) return -g_debug("GTKMAP: expose (%d, %d)-(%d, %d)", event->area.x, event->area.y, event->area.width, event->area.height); -g_debug("GTKMAP: offset (%d, %d)", event->area.x + priv->offsetx, event->area.y + priv->offsety); -g_debug("GTKMAP: x,y (%d, %d)", unit2x(priv->center.unitx), unit2y(priv->center.unity)); - #ifdef WITH_CAIRO cairo_save(priv->ct); cairo_rectangle(priv->ct, event->area.x, event->area.y, event->area.width, event->area.height); cairo_clip(priv->ct); if (priv->rotate_view) { - cairo_matrix_t r; + guint x,y; - g_debug("ROTATE: %f", priv->rotate_angle); + x=unit2bufx(priv->center.unitx); + y=unit2bufy(priv->center.unity); -#if 0 - cairo_matrix_init_translate(&r, -(unit2x(priv->center.unitx)+priv->offsetx), -(unit2y(priv->center.unity)+priv->offsety)); - cairo_matrix_rotate(&r, priv->rotate_angle); - cairo_matrix_translate(&r, (unit2x(priv->center.unitx)+priv->offsetx), (unit2y(priv->center.unity)+priv->offsety)); -#else - cairo_matrix_init_translate(&r, -(priv->offsetx), -(priv->offsety)); - cairo_matrix_rotate(&r, priv->rotate_angle); - cairo_matrix_translate(&r, priv->offsetx, priv->offsety); -#endif + cairo_matrix_init_translate(&priv->matrix_rotate, (gdouble)x, (gdouble)y); + cairo_matrix_rotate(&priv->matrix_rotate, (gdouble)priv->rotate_angle); + cairo_matrix_translate(&priv->matrix_rotate, (gdouble)-x, (gdouble)-y); + cairo_set_matrix(priv->ct, &priv->matrix_rotate); - cairo_set_matrix(priv->ct, &r); - gdk_cairo_set_source_pixmap(priv->ct, priv->buffer, 0, 0); + gdk_cairo_set_source_pixmap(priv->ct, priv->buffer, -priv->offsetx, -priv->offsety); cairo_set_operator (priv->ct, CAIRO_OPERATOR_SOURCE); cairo_paint(priv->ct); cairo_identity_matrix(priv->ct); } else { + cairo_set_source_rgb (priv->ct, 0, 0, 0); cairo_translate(priv->ct, -(event->area.x+priv->offsetx), -(event->area.y+priv->offsety)); gdk_cairo_set_source_pixmap(priv->ct, priv->buffer, event->area.x, event->area.y); + cairo_set_operator (priv->ct, CAIRO_OPERATOR_SOURCE); cairo_paint(priv->ct); } @@ -811,12 +912,6 @@ priv->ct=NULL; return TRUE; } -static void -gtk_map_render_markers(GtkWidget *widget, GdkEventExpose *event) -{ - -} - static void gtk_map_render_waypoint(GtkWidget *widget, guint x1, guint y1) { @@ -1150,6 +1245,8 @@ gdk_draw_layout(widget->window, gc, x, y, priv->speed_layout); gdk_window_process_all_updates(); } +/******************************************************************************/ + static void gtk_map_speed_draw(GtkWidget *widget, GdkEventExpose *event) { @@ -1182,6 +1279,199 @@ priv->speed_gc=(overspeed) ? priv->speed_gc1 : priv->speed_gc2; priv->speed=speed; } +/******************************************************************************/ + +static gboolean +gtk_map_marker_find_at_latlon(GtkWidget *widget, gdouble lat, gdouble lon, guint *id) +{ +GtkMap *map; +GtkMapPriv *priv; +GtkTreeIter iter; +gboolean found=FALSE; +gboolean valid; +gdouble pdist=99999.0; + +g_return_val_if_fail(GTK_IS_MAP(widget), FALSE); + +map=GTK_MAP(widget); +priv=GTK_MAP_GET_PRIVATE(map); + +g_return_val_if_fail(priv->marker_store, FALSE); + +if (!priv->show_markers) + return FALSE; + +if (priv->marker_zoom<=priv->zoom) + return FALSE; + +valid=gtk_tree_model_get_iter_first(GTK_TREE_MODEL(priv->marker_store), &iter); +g_return_val_if_fail(valid, FALSE); + +while (valid) { + gdouble dist, plat, plon; + guint tid; + GtkMapMarkerType type; + + gtk_tree_model_get(GTK_TREE_MODEL(priv->marker_store), + &iter, + MAP_MARKER_ID, &tid, + MAP_MARKER_TYPE, &type, + MAP_MARKER_LAT, &plat, + MAP_MARKER_LON, &plon, + -1); + + /* XXX: Use quicker and simple distance check, convert to x,y values, check against +-icon size */ + dist=calculate_distance(lat, lon, plat, plon); + if ((distmarker_store), &iter); +} + +return found; +} + +static inline GdkGC * +gtk_map_set_marker_fg_color_from_string(GtkMapPriv *priv, const gchar *hexcolor, GdkGC *def) +{ +GdkColor color; + +if (!hexcolor) + return def; + +if (!gdk_color_parse(hexcolor, &color)) + return def; + +gdk_gc_set_rgb_fg_color(priv->marker_gc, &color); +return priv->marker_gc; +} + +static void +gtk_map_poi_title(GtkWidget *widget, gint x, gint y, GdkGC *gc, const gchar *title) +{ +GtkMap *map; +GtkMapPriv *priv; +gint w,h; + +g_return_if_fail(GTK_IS_MAP(widget)); + +map=GTK_MAP(widget); +priv=GTK_MAP_GET_PRIVATE(map); + +/* XXX: Add cairo version */ +pango_layout_set_text(priv->layout, title, -1); +pango_layout_get_pixel_size(priv->layout, &w, &h); +gdk_draw_layout(widget->window, gc, x-(w>>1), y-h-priv->draw_width, priv->layout); +} + +/** + * Render all the POI data. + * This should be done before rendering track data. + */ +static void +gtk_map_render_markers(GtkWidget *widget, GdkEventExpose *event) +{ +GtkTreeIter iter; +GtkMap *map; +GtkMapPriv *priv; +guint unitx, unity; +gint poix, poiy; +gdouble lat1, lat2, lon1, lon2; +gboolean valid; + +g_return_if_fail(GTK_IS_MAP(widget)); + +map=GTK_MAP(widget); +priv=GTK_MAP_GET_PRIVATE(map); + +if (!priv->marker_store) + return; + +if (priv->marker_zoom<=priv->zoom) + return; + +unitx=x2unit(0); +unity=y2unit(priv->screen_height_pixels); +unit2latlon(unitx, unity, &lat1, &lon1); + +unitx=x2unit(priv->screen_width_pixels); +unity=y2unit(0); +unit2latlon(unitx, unity, &lat2, &lon2); + +valid=gtk_tree_model_get_iter_first(GTK_TREE_MODEL(priv->marker_store), &iter); +if (!valid) + return; + +if (priv->zoom<2 && priv->show_marker_labels==TRUE) { + pango_font_description_set_size(priv->fontdesc, MARKER_FONT_SIZE_SMALL*PANGO_SCALE); + pango_layout_set_font_description (priv->layout, priv->fontdesc); + pango_layout_set_ellipsize(priv->layout, PANGO_ELLIPSIZE_NONE); +} + +while (valid) { + GdkPixbuf *pixbuf; + GdkGC *gc; + GdkRectangle marker_rect; + gchar *label, *icon, *color; + + gtk_tree_model_get(GTK_TREE_MODEL(priv->marker_store), + &iter, + MAP_MARKER_LAT, &lat1, + MAP_MARKER_LON, &lon1, + MAP_MARKER_LABEL, &label, + MAP_MARKER_ICON, &icon, + MAP_MARKER_COLOR, &color, + -1); + + latlon2unit(lat1, lon1, &unitx, &unity); + poix=unit2x(unitx); + poiy=unit2y(unity); + + marker_rect.x=poix-16; + marker_rect.y=poiy-16; + marker_rect.width=poix+16; + marker_rect.height=poiy+16; + + /* Don't bother if it's outside our event area */ + if (!gdk_rectangle_intersect(&event->area, &marker_rect, NULL)) + continue; + +#if 0 + pixbuf=poi_get_icon(icon, priv->zoom<2 ? TRUE : FALSE); +#else + pixbuf=NULL; +#endif + gc=gtk_map_set_marker_fg_color_from_string(priv, color, widget->style->fg_gc[GTK_WIDGET_STATE(widget)]); + + if (!pixbuf) { + /* No icon for POI or for category - draw default. */ + gdk_draw_arc(widget->window, gc, FALSE, poix - priv->draw_width, poiy - priv->draw_width, + (MAX_ZOOM-priv->zoom)/6 * priv->draw_width, (MAX_ZOOM-priv->zoom)/6 * priv->draw_width, 0, 360 * 64); + } else { + guint w,h; + + w=gdk_pixbuf_get_width(pixbuf); + h=gdk_pixbuf_get_height(pixbuf); + gdk_draw_pixbuf(widget->window, gc, pixbuf, 0, 0, poix-w/2, poiy-h/2, -1, -1, GDK_RGB_DITHER_NONE, 0, 0); +#if 0 + /* Draw rectangle around icon. Not really need with the square icons */ + if (_zoom<2) + gdk_draw_rectangle(widget->window, gc, FALSE, poix-w/2-1, poiy-h/2-1, w+1, h+1); +#endif + } + + if (priv->zoom<2 && priv->show_marker_labels==TRUE && label) + gtk_map_poi_title(widget, poix, poiy, gc, label); + + valid=gtk_tree_model_iter_next(GTK_TREE_MODEL(priv->marker_store), &iter); +} +} + +/******************************************************************************/ + /** * Do an in-place scaling of a pixbuf's pixels at the given ratio from the given source location. */ @@ -1309,6 +1599,8 @@ g_return_if_fail(GTK_IS_MAP(widget)); map=GTK_MAP(widget); priv=GTK_MAP_GET_PRIVATE(map); +g_return_if_fail(rd); + priv->curr_repo=rd; } @@ -1370,6 +1662,8 @@ gdk_draw_rectangle(priv->buffer, return TRUE; } +/******************************************************************************/ + void gtk_map_set_center(GtkWidget *widget, guint unitx, guint unity) { @@ -1386,8 +1680,6 @@ map=GTK_MAP(widget); priv=GTK_MAP_GET_PRIVATE(map); style=widget->style; -priv->center_mode=CENTER_MANUAL; - /* Assure that _center.unitx/y are bounded. */ BOUND(unitx, priv->min_center.unitx, priv->max_center.unitx); BOUND(unity, priv->min_center.unity, priv->max_center.unity); @@ -1469,10 +1761,24 @@ gtk_map_set_center_latlon(GtkWidget *widget, gdouble lat, gdouble lon) { guint unitx, unity; -latlon2unit(lat, lon, unitx, unity); +g_return_if_fail(GTK_IS_MAP(widget)); +latlon2unit(lat, lon, &unitx, &unity); gtk_map_set_center(widget, unitx, unity); } +void +gtk_map_get_center_latlon(GtkWidget *widget, gdouble *lat, gdouble *lon) +{ +GtkMap *map; +GtkMapPriv *priv; + +g_return_if_fail(GTK_IS_MAP(widget)); +map=GTK_MAP(widget); +priv=GTK_MAP_GET_PRIVATE(map); + +unit2latlon(priv->center.unitx, priv->center.unity, lat, lon); +} + void gtk_map_pan(GtkWidget *widget, gint delta_x, gint delta_y) { @@ -1482,6 +1788,7 @@ GtkMapPriv *priv; g_return_if_fail(GTK_IS_MAP(widget)); map=GTK_MAP(widget); priv=GTK_MAP_GET_PRIVATE(map); +priv->center_mode=CENTER_MANUAL; gtk_map_set_center(widget, priv->center.unitx + delta_x*GTK_MAP_PAN_UNITS, priv->center.unity + delta_y*GTK_MAP_PAN_UNITS); } @@ -1529,6 +1836,8 @@ for (y = 0; y < priv->buf_height_tiles; ++y) gtk_widget_queue_draw(widget); } +/******************************************************************************/ + gint gtk_map_get_zoom(GtkWidget *widget) { @@ -1640,6 +1949,48 @@ gtk_map_zoom(widget, 1); return FALSE; } +/******************************************************************************/ + +void +gtk_map_set_context_menu(GtkWidget *widget, GtkMenu *menu) +{ +GtkMap *map; +GtkMapPriv *priv; + +g_return_if_fail(GTK_IS_MAP(widget)); +map=GTK_MAP(widget); +priv=GTK_MAP_GET_PRIVATE(map); + +#ifdef WITH_DEVICE_770 +gtk_widget_tap_and_hold_setup(widget, GTK_WIDGET(menu), NULL, 0); +#else +g_object_ref(menu); +priv->menu=menu; +#endif +} + +void +gtk_map_clear_context_menu(GtkWidget *widget) +{ +GtkMap *map; +GtkMapPriv *priv; + +g_return_if_fail(GTK_IS_MAP(widget)); +map=GTK_MAP(widget); +priv=GTK_MAP_GET_PRIVATE(map); + +g_return_if_fail(priv->menu); + +#ifdef WITH_DEVICE_770 +gtk_widget_tap_and_hold_setup(widget, NULL, NULL, 0); +#else +g_object_unref(priv->menu); +#endif +priv->menu=NULL; +} + +/******************************************************************************/ + void gtk_map_set_cache_size(GtkWidget *widget, guint cache_size) { @@ -1706,6 +2057,8 @@ g_return_val_if_fail(GTK_IS_MAP(widget), FALSE); map=GTK_MAP(widget); priv=GTK_MAP_GET_PRIVATE(map); +unit2latlon(x2unit((gint) (event->x+0.5)), y2unit((gint) (event->y+0.5)), &priv->menu_lat, &priv->menu_lon); + switch (event->button) { case 1: priv->button_down=TRUE; @@ -1713,6 +2066,7 @@ case 1: gtk_map_set_center(widget, x2unit((gint) (event->x+0.5)), y2unit((gint) (event->y+0.5))); return FALSE; } else if (event->type==GDK_2BUTTON_PRESS) { + priv->center_mode=CENTER_MANUAL; gtk_map_set_center(widget, x2unit((gint) (event->x+0.5)), y2unit((gint) (event->y+0.5))); if (priv->zoom_in_on_2button) gtk_map_zoom_in(widget); @@ -1743,6 +2097,10 @@ priv=GTK_MAP_GET_PRIVATE(map); switch (event->button) { case 1: priv->button_down=FALSE; + /* Check if a marker was clicked, if they are shown and if there is something to show */ + if (priv->show_markers && priv->marker_store) { + /* XXX */ + } break; case 2: diff --git a/src/gtkmap.h b/src/gtkmap.h index f4c0c07..2bfbe91 100644 --- a/src/gtkmap.h +++ b/src/gtkmap.h @@ -22,6 +22,7 @@ #include #include "path.h" +#include "position.h" #include "map-tile-repo.h" typedef enum { @@ -32,6 +33,26 @@ typedef enum { CENTER_LATLON = 2 } GtkMapCenterMode; +typedef enum { + MAP_MARKER_TYPE_POI=0, + MAP_MARKER_TYPE_POSITION, + MAP_MARKER_TYPE_BOOKMARK, + MAP_MARKER_TYPE_CACHE, +} GtkMapMarkerType; + +typedef enum { + MAP_MARKER_ID=0, + MAP_MARKER_TYPE, + MAP_MARKER_LAT, + MAP_MARKER_LON, + MAP_MARKER_LABEL, + MAP_MARKER_ICON, + MAP_MARKER_COLOR, + MAP_MARKER_CACHE_X, /* Private, screen x,y cache */ + MAP_MARKER_CACHE_Y, + MAP_MARKER_ENUM +} GtkMapMarkerStoreID; + #define TRACKS_MASK 0x00000001 #define ROUTES_MASK 0x00000002 #define FRIENDS_MASK 0x00000004 @@ -71,18 +92,17 @@ void gtk_map_refresh(GtkWidget *map); /* Map repository handling */ void gtk_map_set_tile_repository(GtkWidget *map, RepoData *rd); -/* */ -void gtk_map_set_mark(GtkWidget *map); -void gtk_map_move_mark(GtkWidget *map); +/* Markers */ +gboolean gtk_map_markers_add(GtkWidget *map, GtkMapMarkerType type, GtkListStore *store); +gboolean gtk_map_markers_remove(GtkWidget *map, GtkMapMarkerType type, GtkListStore *store); -/* Path functions */ +/* Paths */ gboolean gtk_map_add_path(GtkWidget *map, Path *path); gboolean gtk_map_remove_path(GtkWidget *map, Path *path); gboolean gtk_map_remove_path_by_id(GtkWidget *map, gint path_id); - void gtk_map_set_path_display(GtkWidget *widget, gint path_mask); -/* Get copy of map buffer */ +/* Get copy of map back buffer */ GdkPixmap *gtk_map_pixmap_get(GtkWidget *map); /* Tile cache config */ @@ -108,6 +128,9 @@ gboolean gtk_map_zoom_out(GtkWidget *map); gboolean gtk_map_zoom_in(GtkWidget *map); gboolean gtk_map_set_autozoom(GtkWidget *map, gboolean az); +/* Menu and mouse related */ +void gtk_map_set_context_menu(GtkWidget *widget, GtkMenu *menu); +void gtk_map_clear_context_menu(GtkWidget *widget); void gtk_map_get_menu_latlon(GtkWidget *map, gdouble *lat, gdouble *lon); G_END_DECLS diff --git a/src/latlon.h b/src/latlon.h index 683daa1..e9aeaa0 100644 --- a/src/latlon.h +++ b/src/latlon.h @@ -9,21 +9,6 @@ #define LATLON_MIN -2147483646 #define EARTH_RADIUS (3440.06479f) -#define MERCATOR_SPAN (-6.28318377773622f) -#define MERCATOR_TOP (3.14159188886811f) - -#define latlon2unit(lat, lon, unitx, unity) { \ - gdouble tmp; \ - unitx=lrint((lon + 180.f) * (WORLD_SIZE_UNITS / 360.f)); \ - tmp=sin(lat * (M_PIl / 180.f)); \ - unity=lrint((WORLD_SIZE_UNITS / MERCATOR_SPAN) * (log((1.f + tmp) / (1.f - tmp)) * 0.5f - MERCATOR_TOP)); \ -} - -#define unit2latlon(unitx, unity, lat, lon) { \ - (lon)=((unitx) * (360.f / WORLD_SIZE_UNITS)) - 180.f; \ - (lat)=(360.f * (atan(exp(((unity) * (MERCATOR_SPAN / WORLD_SIZE_UNITS)) + MERCATOR_TOP)))) * (1.f / M_PIl) - 90.f; \ -} - typedef enum { DDPDDDDD, DD_MMPMMM, @@ -45,7 +30,7 @@ typedef enum { gchar *UNITS_TEXT[UNITS_ENUM_COUNT]; /* UNITS_CONVERTS, when multiplied, converts from NM. */ -#define EARTH_RADIUS (3440.06479f) + gfloat UNITS_CONVERT[UNITS_ENUM_COUNT]; UnitType _units; diff --git a/src/maemo-osso.c b/src/maemo-osso.c index ead0471..c50f686 100644 --- a/src/maemo-osso.c +++ b/src/maemo-osso.c @@ -40,8 +40,6 @@ #include #endif -#include "map.h" -#include "map-download.h" #include "route.h" #include "track.h" #include "mapper-types.h" diff --git a/src/map-download.c b/src/map-download.c index bd36aa3..fd6b66e 100644 --- a/src/map-download.c +++ b/src/map-download.c @@ -43,7 +43,6 @@ #include "hildon-mapper.h" #include "utils.h" -#include "map.h" #include "osm.h" #include "db.h" #include "osm-db.h" @@ -58,6 +57,7 @@ #include "map-download.h" #include "iap.h" #include "map-repo.h" +#include "gtkmap.h" static guint _num_downloads=0; static guint _curr_download=0; @@ -241,11 +241,15 @@ if (!(num_transfers || g_tree_nnodes(pui_tree))) { return TRUE; } +#ifdef MAP_DOWNLOAD_WMS /** * Given a wms uri pattern, compute the coordinate transformation and * trimming. * 'proj' is used for the conversion */ + +#define WMS_TILE_SIZE_PIXELS (256) + static gchar * map_convert_wms_to_wms(gint tilex, gint tiley, gint zoomlevel, gchar * uri) { @@ -267,14 +271,14 @@ strncpy(srs + 4, srsstr + 8, 256); srs[srsstre - srsstr - 4] = 0; /* convert to lower, as WMC is EPSG and cs2cs is epsg */ -gint dwidth = widthstr ? atoi(widthstr + 6) - TILE_SIZE_PIXELS : 0; -gint dheight = heightstr ? atoi(heightstr + 7) - TILE_SIZE_PIXELS : 0; +gint dwidth = widthstr ? atoi(widthstr + 6) - WMS_TILE_SIZE_PIXELS : 0; +gint dheight = heightstr ? atoi(heightstr + 7) - WMS_TILE_SIZE_PIXELS : 0; unit2latlon(tile2zunit(tilex, zoomlevel) - pixel2zunit(dwidth / 2, zoomlevel), - tile2zunit(tiley + 1, zoomlevel) + pixel2zunit((dheight + 1) / 2, zoomlevel), lat1, lon1); + tile2zunit(tiley + 1, zoomlevel) + pixel2zunit((dheight + 1) / 2, zoomlevel), &lat1, &lon1); unit2latlon(tile2zunit(tilex + 1, zoomlevel) + pixel2zunit((dwidth + 1) / 2, zoomlevel), - tile2zunit(tiley, zoomlevel) - pixel2zunit(dheight / 2, zoomlevel), lat2, lon2); + tile2zunit(tiley, zoomlevel) - pixel2zunit(dheight / 2, zoomlevel), &lat2, &lon2); setlocale(LC_NUMERIC, "C"); @@ -301,7 +305,7 @@ setlocale(LC_NUMERIC, ""); return ret; } - +#endif /** * Given the xyz coordinates of our map coordinate system, write the qrst @@ -338,28 +342,23 @@ map_construct_url(guint tilex, guint tiley, guint zoom) switch (_curr_repo->type) { case REPOTYPE_XYZ: return g_strdup_printf(_curr_repo->url, tilex, tiley, zoom); - case REPOTYPE_XYZ_INV: return g_strdup_printf(_curr_repo->url, 17 - zoom, tilex, tiley); - -case REPOTYPE_QUAD_QRST: - { - gchar location[MAX_ZOOM + 2]; +case REPOTYPE_QUAD_QRST: { + gchar location[32]; map_convert_coords_to_quadtree_string(tilex, tiley, zoom, location, 't', "qrts"); return g_strdup_printf(_curr_repo->url, location); } - -case REPOTYPE_QUAD_ZERO: - { +case REPOTYPE_QUAD_ZERO: { /* This is a zero-based quadtree URI. */ - gchar location[MAX_ZOOM + 2]; + gchar location[32]; map_convert_coords_to_quadtree_string(tilex, tiley, zoom, location, '\0', "0123"); return g_strdup_printf(_curr_repo->url, location); } - +#ifdef MAP_DOWNLOAD_WMD case REPOTYPE_WMS: return map_convert_wms_to_wms(tilex, tiley, zoom, _curr_repo->url); - +#endif default: return NULL; } @@ -391,8 +390,9 @@ map_download_idle_refresh(ProgressUpdateInfo * pui) guint tmp=0; /* Test if download succeeded (only if retries != 0). */ if (!pui->retries || g_file_test(pui->dest_str, G_FILE_TEST_EXISTS)) { - gint zoom_diff = pui->zoom - _zoom; + gint zoom_diff = pui->zoom - gtk_map_get_zoom(_map); +#if 0 /* Only refresh at same or "lower" (more detailed) zoom level. */ if (zoom_diff >= 0) { guint tilex, tiley, tilex_end, tiley_end; @@ -413,6 +413,9 @@ if (!pui->retries || g_file_test(pui->dest_str, G_FILE_TEST_EXISTS)) { } g_debug("*** MDIR LOOP: %u", tmp); } +#else + g_debug("XXX: Add cb or signal or something to inform map widget about fresh tile"); +#endif } /* Else the download failed. Update retries and maybe try again. */ else { @@ -463,7 +466,7 @@ pui = g_slice_new(ProgressUpdateInfo); pui->tilex = tilex; pui->tiley = tiley; pui->zoom = zoom; -pui->priority = (abs((gint) tilex - unit2tile(_center.unitx)) + abs((gint) tiley - unit2tile(_center.unity))); +pui->priority = 1; if (!retries) pui->priority = -pui->priority; /* "Negative" makes them lowest pri. */ pui->retries = retries; diff --git a/src/map-poi.c b/src/map-poi.c index 7bf6a6f..cef4824 100644 --- a/src/map-poi.c +++ b/src/map-poi.c @@ -30,7 +30,6 @@ #include "utils.h" #include "poi.h" #include "gps.h" -#include "map.h" #include "settings.h" #include "mapper-types.h" #include "ui-common.h" @@ -38,13 +37,6 @@ #include "latlon.h" #include "osm-db.h" -#define POI_FONT_SIZE_BIG (10) -#define POI_FONT_SIZE_SMALL (8) - -/* POI icon text pango stuff */ -static PangoContext *context = NULL; -static PangoLayout *layout = NULL; -static PangoFontDescription *fontdesc = NULL; static GdkGC *poi_gc; static GtkListStore *poi_store=NULL; static gint last_zoom=-1; @@ -53,17 +45,8 @@ static guint prev_ux=0, prev_uy=0; /****************************************************************************/ gboolean -map_poi_init(GtkWidget *map_widget) +map_poi_init(void) { -context=gtk_widget_get_pango_context(map_widget); -layout=pango_layout_new(context); -fontdesc=pango_font_description_new(); -pango_font_description_set_family(fontdesc,"Sans Serif"); -pango_font_description_set_size(fontdesc, POI_FONT_SIZE_SMALL*PANGO_SCALE); -pango_layout_set_font_description (layout, fontdesc); -pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER); -pango_layout_set_width(layout, 80*PANGO_SCALE); -poi_gc=gdk_gc_new(map_widget->window); poi_store=poi_list_store_new(); return TRUE; } @@ -73,41 +56,6 @@ map_poi_deinit(void) { map_poi_cache_clear(); g_object_unref(poi_store); -#if 0 -g_object_unref(layout); -g_object_unref(fontdesc); -g_object_unref(poi_gc); -#endif -} - -static void -map_poi_title(gint x, gint y, GdkGC *gc, gchar *title) -{ -gint w,h; - -pango_layout_set_text(layout, title, -1); -pango_layout_get_pixel_size(layout, &w, &h); - -gdk_draw_layout(map_pixmap_get(), gc, x-(w>>1), y-h-_draw_width, layout); -} - -/** - * Set POI color from given #rrggbb string, fallback to default if it fails - */ -static inline GdkGC * -map_set_poi_fg_color_from_string(gchar *hexcolor, GdkGC *def) -{ -GdkColor color; - -if (!hexcolor) - return def; - -if (gdk_color_parse(hexcolor, &color)) { - gdk_gc_set_rgb_fg_color(poi_gc, &color); - return poi_gc; -} - -return def; } void @@ -122,142 +70,10 @@ map_poi_reload_poi(guint unitx, guint unity, gdouble lat1, gdouble lon1, gdouble { guint pois; -/* Reload POIs if we zoom out or have moved */ -if (last_zoom<_zoom || prev_ux!=unitx || prev_uy!=unity) { - g_debug("Reloading POIs"); - map_poi_cache_clear(); -} +map_poi_cache_clear(); if (poi_get_list_inside(lat1, lon1, lat2, lon2, poi_store, &pois)==FALSE) return FALSE; return TRUE; } - -gboolean -map_poi_find_at_latlon(gdouble lat, gdouble lon, guint *poi_id) -{ -GtkTreeIter iter; -gboolean found=FALSE; -gboolean valid; -gdouble pdist=99999.0; - -if (_poi_zoom <= _zoom) - return FALSE; - -g_return_val_if_fail(poi_store, FALSE); - -valid=gtk_tree_model_get_iter_first(GTK_TREE_MODEL(poi_store), &iter); -g_return_val_if_fail(valid, FALSE); - -while (valid) { - gdouble tmp, plat, plon; - guint id; - - gtk_tree_model_get(GTK_TREE_MODEL(poi_store), - &iter, - ITEM_ID, &id, - ITEM_LAT, &plat, - ITEM_LON, &plon, - -1); - - /* XXX: Use quicker and simple distance check */ - tmp=calculate_distance(lat, lon, plat, plon); - if ((tmpnext, i++) { RepoEditInfo *rei = curr->data; RepoData *rd = g_new(RepoData, 1); + rd->name = g_strdup(rei->name); rd->url = g_strdup(gtk_entry_get_text(GTK_ENTRY(rei->txt_url))); rd->cache_dir = gnome_vfs_expand_initial_tilde(gtk_entry_get_text(GTK_ENTRY(rei->txt_cache_dir))); @@ -504,6 +505,7 @@ while (GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(rmi.dialog))) { rd->view_zoom_steps = hildon_controlbar_get_value(HILDON_CONTROLBAR(rei->num_view_zoom_steps)); rd->double_size = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(rei->chk_double_size)); rd->nextable = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(rei->chk_nextable)); + map_tile_repo_set_type(rd); _repo_list = g_list_append(_repo_list, rd); @@ -514,7 +516,7 @@ while (GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(rmi.dialog))) { repo_set_curr(rd); } if (!_curr_repo) - repo_set_curr((RepoData *) g_list_first(_repo_list)->data); + repo_set_curr((RepoData *) g_list_first(_repo_list)->data); menu_maps_add_repos(); config_save_repo(); @@ -522,13 +524,12 @@ while (GTK_RESPONSE_ACCEPT == gtk_dialog_run(GTK_DIALOG(rmi.dialog))) { } gtk_widget_hide(rmi.dialog); /* Destroying causes a crash (!?!?!??!) */ -map_set_zoom(_zoom); /* make sure we're at an appropriate zoom level. */ return TRUE; } static gboolean -mapman_by_area(gfloat start_lat, gfloat start_lon, - gfloat end_lat, gfloat end_lon, MapmanInfo * mapman_info, +mapman_by_area(gdouble start_lat, gdouble start_lon, + gdouble end_lat, gdouble end_lon, MapmanInfo * mapman_info, gboolean is_deleting, gboolean is_overwriting) { guint start_unitx, start_unity, end_unitx, end_unity; @@ -537,8 +538,8 @@ guint i; gchar buffer[80]; GtkWidget *confirm; -latlon2unit(start_lat, start_lon, start_unitx, start_unity); -latlon2unit(end_lat, end_lon, end_unitx, end_unity); +latlon2unit(start_lat, start_lon, &start_unitx, &start_unity); +latlon2unit(end_lat, end_lon, &end_unitx, &end_unity); /* Swap if they specified flipped lats or lons. */ if (start_unitx > end_unitx) { @@ -553,7 +554,7 @@ if (start_unity > end_unity) { } /* First, get the number of maps to download. */ -for (i = 0; i < MAX_ZOOM; i++) { +for (i = 0; i < _curr_repo->max_zoom; i++) { if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(mapman_info->chk_zoom_levels[i]))) { guint start_tilex, start_tiley, end_tilex, end_tiley; start_tilex = unit2ztile(start_unitx, i); @@ -577,7 +578,7 @@ if (GTK_RESPONSE_OK != gtk_dialog_run(GTK_DIALOG(confirm))) { return FALSE; } -for (i = 0; i < MAX_ZOOM; i++) { +for (i = 0; i < _curr_repo->max_zoom; i++) { if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(mapman_info->chk_zoom_levels[i]))) { guint start_tilex, start_tiley, end_tilex, end_tiley; guint tilex, tiley; @@ -605,7 +606,7 @@ Point *curr; gchar buffer[80]; /* First, get the number of maps to download. */ -for (i = 0; i < MAX_ZOOM; i++) { +for (i = 0; i < _curr_repo->max_zoom; i++) { if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(mapman_info->chk_zoom_levels[i]))) { prev_tilex = 0; prev_tiley = 0; @@ -644,7 +645,7 @@ if (GTK_RESPONSE_OK != gtk_dialog_run(GTK_DIALOG(confirm))) { } /* Now, do the actual download. */ -for (i = 0; i < MAX_ZOOM; i++) { +for (i = 0; i < _curr_repo->max_zoom; i++) { if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(mapman_info->chk_zoom_levels[i]))) { prev_tilex = 0; prev_tiley = 0; @@ -688,7 +689,7 @@ guint i; if (gtk_notebook_get_current_page(GTK_NOTEBOOK(mapman_info->notebook))) { /* This is the second page (the "Zoom" page) - clear the checks. */ - for (i = 0; i < MAX_ZOOM; i++) + for (i = 0; i < _curr_repo->max_zoom; i++) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(mapman_info->chk_zoom_levels[i]), FALSE); } else { /* This is the first page (the "Area" page) - clear the text fields. */ @@ -727,8 +728,8 @@ gboolean menu_cb_mapman(GtkAction * action) GtkWidget *lbl_center_lon; MapmanInfo mapman_info; gchar buffer[80]; - gfloat lat, lon; - guint i; + gdouble lat, lon; + guint i, czoom; mapman_info.dialog = dialog = gtk_dialog_new_with_buttons(_("Manage Maps"), GTK_WINDOW(_window), GTK_DIALOG_MODAL, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL); @@ -784,17 +785,13 @@ gboolean menu_cb_mapman(GtkAction * action) table = gtk_table_new(5, 5, FALSE), label = gtk_label_new(_("Zoom"))); gtk_notebook_set_tab_label_packing(GTK_NOTEBOOK(mapman_info.notebook), table, FALSE, FALSE, GTK_PACK_START); - gtk_table_attach(GTK_TABLE(table), label = - gtk_label_new(_("Zoom Levels to Download: (0 = most detail)")), - 0, 4, 0, 1, GTK_FILL, 0, 4, 0); + gtk_table_attach(GTK_TABLE(table), label = gtk_label_new(_("Zoom Levels to Download: (0 = most detail)")), 0, 4, 0, 1, GTK_FILL, 0, 4, 0); gtk_misc_set_alignment(GTK_MISC(label), 0.f, 0.5f); - for (i = 0; i < MAX_ZOOM; i++) { + for (i = 0; i < _curr_repo->max_zoom; i++) { g_snprintf(buffer, sizeof(buffer), "%d", i); gtk_table_attach(GTK_TABLE(table), - mapman_info.chk_zoom_levels[i] - = gtk_check_button_new_with_label(buffer), - i % 4, i % 4 + 1, i / 4 + 1, i / 4 + 2, - GTK_EXPAND | GTK_FILL, 0, 4, 0); + mapman_info.chk_zoom_levels[i] = gtk_check_button_new_with_label(buffer), + i % 4, i % 4 + 1, i / 4 + 1, i / 4 + 2, GTK_EXPAND | GTK_FILL, 0, 4, 0); } /* Area page. */ @@ -903,26 +900,27 @@ gboolean menu_cb_mapman(GtkAction * action) g_snprintf(buffer, sizeof(buffer), "%.06f", _gps->data.lon); gtk_label_set_text(GTK_LABEL(lbl_gps_lon), buffer); - unit2latlon(_center.unitx, _center.unity, lat, lon); + gtk_map_get_center_latlon(_map, &lat, &lon); g_snprintf(buffer, sizeof(buffer), "%.06f", lat); gtk_label_set_text(GTK_LABEL(lbl_center_lat), buffer); g_snprintf(buffer, sizeof(buffer), "%.06f", lon); gtk_label_set_text(GTK_LABEL(lbl_center_lon), buffer); /* Initialize to the bounds of the screen. */ - unit2latlon(x2unit(0), y2unit(0), lat, lon); + g_object_get(_map, "min-lat", &lat, "max-lon", &lon); g_snprintf(buffer, sizeof(buffer), "%.06f", lat); gtk_entry_set_text(GTK_ENTRY(mapman_info.txt_topleft_lat), buffer); g_snprintf(buffer, sizeof(buffer), "%.06f", lon); gtk_entry_set_text(GTK_ENTRY(mapman_info.txt_topleft_lon), buffer); - unit2latlon(x2unit(_screen_width_pixels), y2unit(_screen_height_pixels), lat, lon); + g_object_get(_map, "max-lat", &lat, "min-lon", &lon); g_snprintf(buffer, sizeof(buffer), "%.06f", lat); gtk_entry_set_text(GTK_ENTRY(mapman_info.txt_botright_lat), buffer); g_snprintf(buffer, sizeof(buffer), "%.06f", lon); gtk_entry_set_text(GTK_ENTRY(mapman_info.txt_botright_lon), buffer); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(mapman_info.chk_zoom_levels[_zoom]), TRUE); + czoom=gtk_map_get_zoom(_map); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(mapman_info.chk_zoom_levels[czoom]), TRUE); gtk_widget_show_all(dialog); @@ -956,7 +954,7 @@ gboolean menu_cb_mapman(GtkAction * action) } else { const gchar *text; gchar *error_check; - gfloat start_lat, start_lon, end_lat, end_lon; + gdouble start_lat, start_lon, end_lat, end_lon; text = gtk_entry_get_text(GTK_ENTRY(mapman_info.txt_topleft_lat)); start_lat = strtof(text, &error_check); diff --git a/src/map-widget-test.c b/src/map-widget-test.c index 0f7725f..b632035 100644 --- a/src/map-widget-test.c +++ b/src/map-widget-test.c @@ -83,7 +83,6 @@ vbox=gtk_vbox_new(FALSE, 3); map=gtk_map_new(); gtk_map_set_tile_repository(map, rd); -gtk_map_set_center_latlon(map, 64.25, 22.00); gtk_box_pack_start(GTK_BOX(hbox), map, TRUE, TRUE, 0); zoomer=gtk_vscale_new_with_range(0,17,1); @@ -115,6 +114,7 @@ g_signal_connect(G_OBJECT(btn_left), "clicked", G_CALLBACK(map_pan_left), NULL); g_signal_connect(G_OBJECT(btn_right), "clicked", G_CALLBACK(map_pan_right), NULL); gtk_map_set_zoom(map, 12); +gtk_map_set_center_latlon(map, 64.25, 22.00); gtk_widget_show_all(GTK_WIDGET(dialog)); gtk_dialog_run(dialog); diff --git a/src/map.c b/src/map.c index e07396c..6377753 100644 --- a/src/map.c +++ b/src/map.c @@ -998,6 +998,7 @@ 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; @@ -1015,18 +1016,25 @@ if (event->is_hint) { 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; -g_debug("MAP PAN: %d %d %d %d (%d, %d)", cx, cy, xx, yy, nunitx, nunity); before[0] = xx; before[1] = yy; + return FALSE; } diff --git a/src/mapper.c b/src/mapper.c index 19679c6..a38ff4c 100644 --- a/src/mapper.c +++ b/src/mapper.c @@ -72,7 +72,6 @@ #include "settings.h" #include "gps.h" #include "gps-conn.h" -#include "map.h" #include "map-download.h" #include "route.h" #include "track.h" @@ -445,7 +444,7 @@ switch (mis) { if (map_goto_position(&_home)==FALSE) g_printerr("Home is not set.\n"); else - map_center_unit(_center.unitx, _center.unity); + gtk_map_center_latlon(64.25, 22.00); /* XXX */ mis=MAPPER_INIT_DONE; p=1.0; w="Done"; diff --git a/src/osm-db.c b/src/osm-db.c index 385a3e1..d818138 100644 --- a/src/osm-db.c +++ b/src/osm-db.c @@ -117,6 +117,9 @@ static const gchar *osm_indexes[]={ OSM_INDEX_13, OSM_INDEX_14, OSM_INDEX_15, + OSM_INDEX_16, + OSM_INDEX_17, + OSM_INDEX_18, NULL }; /* Cache hash tables */ diff --git a/src/osm-sql-tables.h b/src/osm-sql-tables.h index ac86b50..43c7c88 100644 --- a/src/osm-sql-tables.h +++ b/src/osm-sql-tables.h @@ -102,10 +102,15 @@ /* Indexes */ #define OSM_INDEX_1 "CREATE UNIQUE INDEX IF NOT EXISTS poi_lat_lon_idx on poi (lat, lon, cat_id);" #define OSM_INDEX_2 "CREATE INDEX IF NOT EXISTS poi_priority on poi (priority);" +#define OSM_INDEX_18 "CREATE INDEX IF NOT EXISTS poi_cat on poi (cat_id);" + +/* Nodes */ #define OSM_INDEX_3 "CREATE INDEX IF NOT EXISTS node_rlat_idx on nodes (rlat);" #define OSM_INDEX_4 "CREATE INDEX IF NOT EXISTS node_rlon_idx on nodes (rlon);" #define OSM_INDEX_5 "CREATE INDEX IF NOT EXISTS node_ilat_idx on nodes (ilat);" #define OSM_INDEX_6 "CREATE INDEX IF NOT EXISTS node_ilon_idx on nodes (ilon);" + +/* Ways */ #define OSM_INDEX_7 "CREATE INDEX IF NOT EXISTS way_name_idx on way_names (name);" #define OSM_INDEX_8 "CREATE INDEX IF NOT EXISTS way_norm_name_idx on way_names (norm);" #define OSM_INDEX_9 "CREATE INDEX IF NOT EXISTS way_name_nls_id_idx on way_names_nls (wid);" @@ -116,4 +121,8 @@ #define OSM_INDEX_14 "CREATE INDEX IF NOT EXISTS way_n2n_f_idx on way_n2n (f);" #define OSM_INDEX_15 "CREATE INDEX IF NOT EXISTS way_n2n_t_idx on way_n2n (t);" +/* Places */ +#define OSM_INDEX_16 "CREATE INDEX IF NOT EXISTS place_type_idx on places(type);" +#define OSM_INDEX_17 "CREATE INDEX IF NOT EXISTS place_name_idx on places(name);" + #endif diff --git a/src/path.c b/src/path.c index e8420cb..55cdf9b 100644 --- a/src/path.c +++ b/src/path.c @@ -24,7 +24,6 @@ #include "mapper-types.h" #include "path.h" #include "utils.h" -#include "map.h" #include "track.h" #include "route.h" #include "gps.h" @@ -63,9 +62,6 @@ static struct sql_select_stmt sql; name text default null, \ t int not null);" -/* Path point add sensitivity */ -static gint sensitivity=3; - enum { NEW_POINT, /* A new point was appended to track track */ NEW_BREAK, /* A break was appended to the track */ @@ -148,6 +144,7 @@ Path *p; p=g_object_new(PATH_TYPE, NULL); p->type=type; p->id=id; +p->sensitivity=3; return p; } @@ -209,9 +206,32 @@ if (path->whead + wsize != path->wcap) { return FALSE; } +gboolean +path_add_waypoint(Path *path, gdouble lat, gdouble lon, gchar *desc) +{ +guint unitx, unity; + +latlon2unit(lat, lon, unitx, unity); +MACRO_PATH_INCREMENT_TAIL(*path); +path->tail->unitx = unitx; +path->tail->unity = unity; +path->tail->time = 0; +path->tail->altitude = NAN; + +MACRO_PATH_INCREMENT_WTAIL(*path); +path->wtail->point = path->tail; +path->wtail->desc = desc; + +path_find_nearest_point(path); + +return TRUE; +} + gboolean path_add_point(Path *path, GpsData *gps) { +guint unitx, unity; + g_return_val_if_fail(path, FALSE); if (!gps) { @@ -220,7 +240,9 @@ if (!gps) { return FALSE; } -if (abs((gint)gps->unitx-path->tail->unitx) > sensitivity || abs((gint)gps->unity-path->tail->unity) > sensitivity) { +latlon2unit(gps->lat, gps->lon, unitx, unity); + +if (abs((gint)unitx-path->tail->unitx) > path->sensitivity || abs((gint)unity-path->tail->unity) > path->sensitivity) { if (path->tail->unity && path->tail->unitx) { gdouble lat, lon; @@ -228,8 +250,8 @@ if (abs((gint)gps->unitx-path->tail->unitx) > sensitivity || abs((gint)gps->unit path->length+=calculate_distance(lat, lon, gps->lat, gps->lon); } MACRO_PATH_INCREMENT_TAIL(*path); - path->tail->unitx=gps->unitx; - path->tail->unity=gps->unity; + path->tail->unitx=unitx; + path->tail->unity=unity; path->tail->time=gps->time; path->tail->altitude=gps->altitude; path->maxspeed=gps->maxspeed; @@ -383,6 +405,24 @@ g_free(tfile); return TRUE; } +gboolean +path_get_waypoint_latlon(WayPoint *way, gdouble *lat, gdouble *lon) +{ +gdouble tlat, tlon; + +g_return_val_if_fail(way, FALSE); +g_return_val_if_fail(way->point, FALSE); +g_return_val_if_fail(lat, FALSE); +g_return_val_if_fail(lon, FALSE); + +unit2latlon(way->point->unitx, way->point->unity, tlat, tlon); + +*lat=tlat; +*lon=tlon; + +return TRUE; +} + /** * Add a text description at current point * diff --git a/src/path.h b/src/path.h index de491d5..b70fc66 100644 --- a/src/path.h +++ b/src/path.h @@ -44,7 +44,9 @@ typedef enum { #define PATH_ID_MY_TRACK (1) #define PATH_ID_MY_ROUTE (2) -/** A general definition of a point in the Mapper unit system. */ +/** + * A general definition of a point in the Map unit system. + */ typedef struct _Point Point; struct _Point { guint unitx; @@ -53,26 +55,44 @@ struct _Point { gfloat altitude; }; -/** A WayPoint, which is a Point with a description. */ +/** + * A latitude/longitue pair + */ +typedef struct _LatLon LatLon; +struct _LatLon { + gdouble lat; + gdouble lon; +}; + +/** + * A WayPoint, which is a Point with a description. + */ typedef struct _WayPoint WayPoint; struct _WayPoint { Point *point; gchar *desc; }; -/** A Path is a set of PathPoints and WayPoints. */ +/** + * Path GObject + */ typedef struct _Path Path; struct _Path { GObject parent; PathType type; guint id; + gint sensitivity; /* Path points */ Point *head; /* points to first element in array; NULL if empty. */ Point *tail; /* points to last element in array. */ Point *cap; /* points after last slot in array. */ + /* Path bounding box */ + LatLon min; + LatLon max; + /* Path waypoints */ WayPoint *whead; /* points to first element in array; NULL if empty. */ WayPoint *wtail; /* points to last element in array. */ @@ -136,6 +156,8 @@ void path_insert_mark_text(Path *path, gchar *text); void path_insert_mark_autonumber(Path *path); void path_insert_mark_audio(Path *path, gchar *audio); +gboolean path_get_waypoint_latlon(WayPoint *way, gdouble *lat, gdouble *lon); + GtkListStore *path_get_waypoints_store(Path *path); #define MACRO_PATH_INIT(path) { \ diff --git a/src/poi-gui.c b/src/poi-gui.c index 81b2dc1..70e5baf 100644 --- a/src/poi-gui.c +++ b/src/poi-gui.c @@ -20,7 +20,6 @@ #include "utils.h" #include "poi.h" #include "gps.h" -#include "map.h" #include "mapper-types.h" #include "latlon.h" #include "ui-common.h" @@ -32,6 +31,7 @@ #include "help.h" #include "track.h" #include "poi-gui.h" +#include "position.h" #ifdef WITH_OSSO #include diff --git a/src/track.c b/src/track.c index c473aed..b9c69c0 100644 --- a/src/track.c +++ b/src/track.c @@ -5,7 +5,6 @@ #include "utils.h" #include "gps.h" -#include "map.h" #include "route.h" #include "settings.h" #include "mapper-types.h" @@ -107,6 +106,7 @@ if (!gps) { return FALSE; } +g_assert(track); if (abs((gint)gps->unitx-track->tail->unitx) > sensitivity || abs((gint)gps->unity-track->tail->unity) > sensitivity) { /* If gps is available, update the nearest-waypoint data. */ diff --git a/src/ui-common.c b/src/ui-common.c index d4ca92d..bc89a0c 100644 --- a/src/ui-common.c +++ b/src/ui-common.c @@ -28,7 +28,7 @@ #include "track.h" #include "settings.h" #include "gps.h" -#include "map.h" +#include "gtkmap.h" #include "mapper-types.h" #include "ui-common.h" #include "db.h" @@ -517,7 +517,7 @@ g_signal_connect(G_OBJECT(_cmenu_poi_goto_nearpoi), "activate", G_CALLBACK(menu_ gtk_widget_show_all(GTK_WIDGET(menu)); #ifdef WITH_DEVICE_770 -gtk_widget_tap_and_hold_setup(_map_widget, GTK_WIDGET(menu), NULL, 0); +gtk_widget_tap_and_hold_setup(map, GTK_WIDGET(menu), NULL, 0); #else _menu_map = menu; #endif @@ -700,11 +700,11 @@ gtk_box_pack_start(GTK_BOX(mapvbox), hbox, TRUE, TRUE, 0); ui_notebook.map=gtk_notebook_append_page(notebook, mapvbox, label); /* Map widget */ -_map_widget = map_new(); -gtk_paned_add2(GTK_PANED(hbox), _map_widget); +_map=gtkmap_new(); +gtk_paned_add2(GTK_PANED(hbox), _map); #ifndef WITH_DEVICE_770 -map_set_cache_size(256); +gtk_map_set_cache_size(_map, 256); #endif /* GPS Tab */ diff --git a/src/ui-common.h b/src/ui-common.h index 6a3cc32..0f50144 100644 --- a/src/ui-common.h +++ b/src/ui-common.h @@ -26,7 +26,7 @@ /** The main GtkContainer of the application. */ GtkWidget *_window; GtkWidget *_gps_widget; - +GtkWidget *_map; GtkWidget *_toolbar; /* GPS Tab widget */ @@ -111,6 +111,11 @@ struct _info_banner { }; struct _info_banner info_banner; +gint _show_tracks; +gboolean _show_scale; +gboolean _show_velvec; +gboolean _show_poi; + GtkMenu *_menu_map; GtkWidget *route_tree_view; -- 2.39.5