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)
map-tile-repo.h \
map-repo.c \
map-repo.h \
- map.c \
- map.h \
mapper.c \
mapper.h \
path.c \
#include "track.h"
#include "settings.h"
#include "gps.h"
-#include "map.h"
#include "mapper-types.h"
#include "ui-common.h"
#include "db.h"
#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)
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));
}
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);
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);
}
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);
}
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);
}
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);
}
gboolean
-menu_cb_track_filter(GtkAction * action)
+menu_cb_track_filter(GtkAction *action)
{
filter_dialog(_window);
return TRUE;
_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();
}
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);
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;
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;
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."));
}
}
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."));
}
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));
}
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) {
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();
}
}
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. */
}
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",
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);
}
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);
{
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);
}
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;
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);
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;
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);
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) {
{
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;
}
gboolean
-cmenu_cb_way_delete(GtkAction * action)
+cmenu_cb_way_delete(GtkAction *action)
{
WayPoint *way;
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. */
}
_route->wtail--;
- route_find_nearest_point(_route);
- map_force_redraw();
+ path_find_nearest_point(_route);
}
gtk_widget_destroy(confirm);
}
}
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;
}
}
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."));
#include "utils.h"
#include "gps.h"
-#include "map.h"
#include "mapper-types.h"
#include "ui-common.h"
#include "settings.h"
#include "utils.h"
#include "settings.h"
#include "gps.h"
-#include "map.h"
#include "ui-common.h"
#include "gps-conn.h"
#include "gps.h"
#include "latlon.h"
-#include "map.h"
#include "gps-conn.h"
#include "gps-nmea-parse.h"
#include "position.h"
}
/**
- * 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
struct _GpsData {
gdouble lat;
gdouble lon;
- guint unitx;
- guint unity;
time_t time;
GpsFix fix;
gboolean newly_fixed;
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];
#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"
WRITE_STRING("</trkseg>\n<trkseg>\n");
trkseg_break = FALSE;
}
- unit2latlon(curr->unitx, curr->unity, lat, lon);
+ unit2latlon(curr->unitx, curr->unity, &lat, &lon);
WRITE_STRING("<trkpt lat=\"");
g_ascii_formatd(buffer, sizeof(buffer), "%.06f", lat);
WRITE_STRING(buffer);
}
if (has_lat && has_lon) {
MACRO_PATH_INCREMENT_TAIL(data->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;
#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)
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;
PangoLayout *scale_layout;
PangoFontDescription *scale_font;
+ PangoContext *marker_context;
+ PangoLayout *marker_layout;
+ PangoFontDescription *marker_font;
+
GdkGC *gc_track;
GdkGC *gc_route;
GdkGC *gc_waypoint;
ImageCache *icache;
GSList *markers;
+ GtkListStore *marker_store;
+ GdkGC *marker_gc;
+ gint marker_zoom;
/* Cached Location dot x,y values */
gint mark_x1;
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)
/* 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 };
#define MERCATOR_SPAN (-6.28318377773622f)
#define MERCATOR_TOP (3.14159188886811f)
+/******************************************************************************/
+
void
latlon2unit(gdouble lat, gdouble lon, guint *unitx, guint *unity)
{
*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)
{
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
}
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
{
GtkMapPriv *priv;
-g_debug("GTKMAP: %s", __PRETTY_FUNCTION__);
priv=GTK_MAP_GET_PRIVATE(map);
priv->base_tilex=-5;
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;
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)
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
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);
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));
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;
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);
}
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);
}
return TRUE;
}
-static void
-gtk_map_render_markers(GtkWidget *widget, GdkEventExpose *event)
-{
-
-}
-
static void
gtk_map_render_waypoint(GtkWidget *widget, guint x1, guint y1)
{
gdk_window_process_all_updates();
}
+/******************************************************************************/
+
static void
gtk_map_speed_draw(GtkWidget *widget, GdkEventExpose *event)
{
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 ((dist<pdist) && (dist<0.011)) {
+ found=TRUE;
+ pdist=dist;
+ *id=id;
+ }
+
+ valid=gtk_tree_model_iter_next(GTK_TREE_MODEL(priv->marker_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.
*/
map=GTK_MAP(widget);
priv=GTK_MAP_GET_PRIVATE(map);
+g_return_if_fail(rd);
+
priv->curr_repo=rd;
}
return TRUE;
}
+/******************************************************************************/
+
void
gtk_map_set_center(GtkWidget *widget, guint unitx, guint unity)
{
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);
{
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)
{
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);
}
gtk_widget_queue_draw(widget);
}
+/******************************************************************************/
+
gint
gtk_map_get_zoom(GtkWidget *widget)
{
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)
{
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;
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);
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:
#include <gtk/gtk.h>
#include "path.h"
+#include "position.h"
#include "map-tile-repo.h"
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
/* 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 */
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
#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,
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;
#include <osso-ic-dbus.h>
#endif
-#include "map.h"
-#include "map-download.h"
#include "route.h"
#include "track.h"
#include "mapper-types.h"
#include "hildon-mapper.h"
#include "utils.h"
-#include "map.h"
#include "osm.h"
#include "db.h"
#include "osm-db.h"
#include "map-download.h"
#include "iap.h"
#include "map-repo.h"
+#include "gtkmap.h"
static guint _num_downloads=0;
static guint _curr_download=0;
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)
{
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");
return ret;
}
-
+#endif
/**
* Given the xyz coordinates of our map coordinate system, write the qrst
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;
}
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;
}
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 {
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;
#include "utils.h"
#include "poi.h"
#include "gps.h"
-#include "map.h"
#include "settings.h"
#include "mapper-types.h"
#include "ui-common.h"
#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;
/****************************************************************************/
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;
}
{
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
{
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 ((tmp<pdist) && (tmp<0.011)) {
- found=TRUE;
- pdist=tmp;
- *poi_id=id;
- }
-
- valid=gtk_tree_model_iter_next(GTK_TREE_MODEL(poi_store), &iter);
-}
-
-return found;
-}
-
-/**
- * Render all the POI data.
- * This should be done before rendering track data.
- */
-void
-map_render_all_pois(guint width, guint height)
-{
-GtkTreeIter iter;
-guint unitx, unity;
-gint poix, poiy;
-gdouble lat1, lat2, lon1, lon2;
-gboolean valid;
-
-if (_poi_zoom <= _zoom)
- return;
-
-unitx=x2unit(0);
-unity=y2unit(height);
-unit2latlon(unitx, unity, lat1, lon1);
-
-unitx=x2unit(width);
-unity=y2unit(0);
-unit2latlon(unitx, unity, lat2, lon2);
-
-if (map_poi_reload_poi(unitx, unity, lat1, lon1, lat2, lon2)==FALSE)
- return;
-
-g_assert(poi_store);
-valid=gtk_tree_model_get_iter_first(GTK_TREE_MODEL(poi_store), &iter);
-if (!valid)
- return;
-
-pango_font_description_set_size(fontdesc, POI_FONT_SIZE_SMALL*PANGO_SCALE);
-pango_layout_set_font_description (layout, fontdesc);
-pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_NONE);
-
-last_zoom=_zoom;
-prev_ux=unitx;
-prev_uy=unity;
-
-while (valid) {
- GdkPixbuf *pixbuf;
- GdkGC *gc;
- gchar *label;
- gchar *icon=NULL, *color=NULL;
-
- gtk_tree_model_get(GTK_TREE_MODEL(poi_store),
- &iter,
- ITEM_LAT, &lat1,
- ITEM_LON, &lon1,
- ITEM_LABEL, &label,
- ITEM_ICON, &icon,
- ITEM_COLOR, &color,
- -1);
-
- pixbuf=poi_get_icon(icon, _zoom<2 ? TRUE : FALSE);
- gc=map_set_poi_fg_color_from_string(color, _gc[COLORABLE_POI]);
-
- latlon2unit(lat1, lon1, unitx, unity);
- poix=unit2bufx(unitx);
- poiy=unit2bufy(unity);
-
- if (!pixbuf) {
- /* No icon for POI or for category - draw default. */
- gdk_draw_arc(map_pixmap_get(), gc, FALSE, poix - _draw_width, poiy - _draw_width,
- (MAX_ZOOM-_zoom)/6 * _draw_width, (MAX_ZOOM-_zoom)/6 * _draw_width, 0, 360 * 64);
- } else {
- guint w,h;
-
- w=gdk_pixbuf_get_width(pixbuf);
- h=gdk_pixbuf_get_height(pixbuf);
- gdk_draw_pixbuf(map_pixmap_get(), 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(map_pixmap_get(), gc, FALSE, poix-w/2-1, poiy-h/2-1, w+1, h+1);
-#endif
- }
-
- if (_zoom<2 && label) {
- map_poi_title(poix, poiy, gc, label);
- }
-
- valid=gtk_tree_model_iter_next(GTK_TREE_MODEL(poi_store), &iter);
-}
-}
#ifndef _MAPPER_MAP_POI_H
#define _MAPPER_MAP_POI_H
-gboolean map_poi_init(GtkWidget *map_widget);
+gboolean map_poi_init(void);
void map_poi_deinit(void);
void map_render_poi(void);
-void map_render_all_pois(guint width, guint height);
void map_poi_cache_clear(void);
-gboolean map_poi_find_at_latlon(gdouble lat, gdouble lon, guint *poi_id);
#endif
#include "utils.h"
#include "gps.h"
-#include "map.h"
#include "latlon.h"
#include "route.h"
#include "track.h"
#include "help.h"
#include "map-repo.h"
#include "map-tile-repo.h"
+#include "gtkmap.h"
#define MAP_REPO_LIST_URL "http://www.gnuite.com/nokia770/maemo-mapper/repos.txt"
GtkWidget *txt_botright_lon;
/* The "Zoom" tab. */
- GtkWidget *chk_zoom_levels[MAX_ZOOM];
+ GtkWidget *chk_zoom_levels[20];
};
gboolean
for (i = 0, curr = rmi.repo_edits; curr; curr = curr->next, 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)));
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);
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();
}
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;
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) {
}
/* 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);
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;
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;
}
/* 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;
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. */
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);
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. */
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);
} 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);
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);
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);
gint xx, yy;
guint unitx, unity, nunitx, nunity;
guint cx, cy;
+gboolean lat,lon;
if (!(event->state & GDK_BUTTON1_MASK)) {
map_drag_id=0;
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;
}
#include "settings.h"
#include "gps.h"
#include "gps-conn.h"
-#include "map.h"
#include "map-download.h"
#include "route.h"
#include "track.h"
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";
OSM_INDEX_13,
OSM_INDEX_14,
OSM_INDEX_15,
+ OSM_INDEX_16,
+ OSM_INDEX_17,
+ OSM_INDEX_18,
NULL };
/* Cache hash tables */
/* 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);"
#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
#include "mapper-types.h"
#include "path.h"
#include "utils.h"
-#include "map.h"
#include "track.h"
#include "route.h"
#include "gps.h"
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 */
p=g_object_new(PATH_TYPE, NULL);
p->type=type;
p->id=id;
+p->sensitivity=3;
return p;
}
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) {
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;
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;
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
*
#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;
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. */
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) { \
#include "utils.h"
#include "poi.h"
#include "gps.h"
-#include "map.h"
#include "mapper-types.h"
#include "latlon.h"
#include "ui-common.h"
#include "help.h"
#include "track.h"
#include "poi-gui.h"
+#include "position.h"
#ifdef WITH_OSSO
#include <libosso.h>
#include "utils.h"
#include "gps.h"
-#include "map.h"
#include "route.h"
#include "settings.h"
#include "mapper-types.h"
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. */
#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"
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
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 */
/** The main GtkContainer of the application. */
GtkWidget *_window;
GtkWidget *_gps_widget;
-
+GtkWidget *_map;
GtkWidget *_toolbar;
/* GPS Tab widget */
};
struct _info_banner info_banner;
+gint _show_tracks;
+gboolean _show_scale;
+gboolean _show_velvec;
+gboolean _show_poi;
+
GtkMenu *_menu_map;
GtkWidget *route_tree_view;