From: Pierre-Luc Beaudoin Date: Mon, 18 Aug 2008 02:50:26 +0000 (-0400) Subject: Center map on coordinates X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c4bc9c7737b4376d222b5f64a3539da3a7498988;p=libchamplain Center map on coordinates --- diff --git a/src/champlain.h b/src/champlain.h index 248f647..ec3f515 100644 --- a/src/champlain.h +++ b/src/champlain.h @@ -20,8 +20,12 @@ #ifndef CHAMPLAIN_H #define CHAMPLAIN_H +#define CHAMPLAIN_MIN_LAT -90 +#define CHAMPLAIN_MAX_LAT 90 +#define CHAMPLAIN_MIN_LONG -180 +#define CHAMPLAIN_MAX_LONG 180 + #include "champlain_defines.h" -#include "champlain_widget.h" -#include "champlain_map.h" +#include "champlainview.h" #endif diff --git a/src/champlain_defines.h b/src/champlain_defines.h index efb9e60..c036961 100644 --- a/src/champlain_defines.h +++ b/src/champlain_defines.h @@ -23,16 +23,9 @@ #define CHAMPLAIN_API __attribute__((visibility("default"))) #define CHAMPLAIN_OBSOLETE_API CHAMPLAIN_API __attribute__((deprecated)) -typedef struct _ChamplainWidget ChamplainWidget; -typedef struct _ChamplainWidgetClass ChamplainWidgetClass; +typedef struct _ChamplainView ChamplainView; +typedef struct _ChamplainViewClass ChamplainViewClass; -typedef enum -{ - CHAMPLAIN_MAP_SOURCE_DEBUG, - CHAMPLAIN_MAP_SOURCE_OPENSTREETMAP, - CHAMPLAIN_MAP_SOURCE_GOOGLE -} ChamplainMapSourceId; - -typedef struct _ChamplainMap ChamplainMap; +typedef struct _Map Map; #endif diff --git a/src/champlain_private.h b/src/champlain_private.h index bfbe0b1..9235a22 100644 --- a/src/champlain_private.h +++ b/src/champlain_private.h @@ -26,15 +26,6 @@ void champlain_map_create_tiles(gint zoom_level); - //gboolean tile_is_visible(ClutterUnit viewport_w, ClutterUnit viewport_h, ChamplainPoint position, ChamplainMapTile* tile); -ChamplainMapTile* champlain_map_tile_new(gint x, gint y, gint tile_size); - -#define CHAMPLAIN_MIN_LAT -90 -#define CHAMPLAIN_MAX_LAT 90 -#define CHAMPLAIN_MIN_LONG -180 -#define CHAMPLAIN_MAX_LONG 180 - - #endif diff --git a/src/champlainview.c b/src/champlainview.c index 9919041..a7fc27c 100644 --- a/src/champlainview.c +++ b/src/champlainview.c @@ -20,10 +20,10 @@ #include "config.h" #include "champlain_defines.h" -#include "champlain_view.h" -#include "map_tile.h" +#include "champlainview.h" +#include "tile.h" #include "map.h" -#include "map_zoom_level.h" +#include "zoomlevel.h" #include "champlain-marshal.h" #include @@ -114,13 +114,13 @@ view_size_allocated_cb (GtkWidget *view, GtkAllocation *allocation, ChamplainVie tidy_adjustment_get_values (hadjust, NULL, &lower, &upper, NULL, NULL, NULL); lower = 0; - upper = map_zoom_level_get_width(priv->map->current_level) - priv->viewportSize.x; + upper = zoom_level_get_width(priv->map->current_level) - priv->viewportSize.x; g_object_set (hadjust, "lower", lower, "upper", upper, "step-increment", 1.0, "elastic", TRUE, NULL); tidy_adjustment_get_values (vadjust, NULL, &lower, &upper, NULL, NULL, NULL); lower = 0; - upper = map_zoom_level_get_height(priv->map->current_level) - priv->viewportSize.y; + upper = zoom_level_get_height(priv->map->current_level) - priv->viewportSize.y; g_object_set (vadjust, "lower", lower, "upper", upper, "step-increment", 1.0, "elastic", TRUE, NULL); @@ -138,14 +138,14 @@ champlain_view_new () priv->viewportSize.x = 640; priv->viewportSize.y = 480; - + priv->clutterEmbed = gtk_clutter_embed_new (); g_signal_connect (priv->clutterEmbed, "size-allocate", G_CALLBACK (view_size_allocated_cb), view); - // Setup stage + // Setup stage stage = gtk_clutter_embed_get_stage (GTK_CLUTTER_EMBED (priv->clutterEmbed)); clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color); @@ -155,16 +155,29 @@ champlain_view_new () priv->viewport = tidy_viewport_new (); ClutterActor* group = clutter_group_new(); clutter_container_add_actor (CLUTTER_CONTAINER (priv->viewport), group); - + // Setup finger scroll priv->fingerScroll = tidy_finger_scroll_new(TIDY_FINGER_SCROLL_MODE_KINETIC); g_object_set (priv->fingerScroll, "decel-rate", 1.25, NULL); clutter_container_add_actor (CLUTTER_CONTAINER (priv->fingerScroll), priv->viewport); clutter_container_add_actor (CLUTTER_CONTAINER (stage), priv->fingerScroll); - - priv->map = map_new(CHAMPLAIN_MAP_SOURCE_OPENSTREETMAP);//OPENSTREETMAP - map_load(priv->map, 4); + + priv->map = map_new(CHAMPLAIN_MAP_SOURCE_OPENSTREETMAP);//OPENSTREETMAP + map_load(priv->map, 4); clutter_container_add_actor (CLUTTER_CONTAINER (group), priv->map->current_level->group); return GTK_WIDGET (view); } + +// FIXME: Animate this. Can be done in Tidy-Adjustment (like for elastic effect) +void +champlain_view_center_on (ChamplainView *champlainView, gdouble longitude, gdouble latitude) +{ + ChamplainViewPrivate *priv = CHAMPLAIN_VIEW_GET_PRIVATE (champlainView); + + gdouble x, y; + x = priv->map->longitude_to_x(priv->map, longitude, priv->map->current_level->level); + y = priv->map->latitude_to_y(priv->map, latitude, priv->map->current_level->level); + + tidy_viewport_set_origin(TIDY_VIEWPORT(priv->viewport), x - priv->viewportSize.x/2.0, y - priv->viewportSize.y/2.0, 0); +} diff --git a/src/champlainview.h b/src/champlainview.h index e9622f6..c665948 100644 --- a/src/champlainview.h +++ b/src/champlainview.h @@ -58,4 +58,6 @@ CHAMPLAIN_API GType champlain_view_get_type (void); CHAMPLAIN_API GtkWidget *champlain_view_new (void); +CHAMPLAIN_API void champlain_view_center_on (ChamplainView *view, gdouble longitude, gdouble latitude); + #endif diff --git a/src/launcher.c b/src/launcher.c index 8a215a3..447288c 100644 --- a/src/launcher.c +++ b/src/launcher.c @@ -32,11 +32,23 @@ on_destroy (GtkWidget * widget, gpointer data) gtk_main_quit (); } +static void +go_to_montreal (GtkWidget * widget, ChamplainView* view) +{ + champlain_view_center_on(view, -73.75, 45.466); +} + +static void +go_to_cambridge (GtkWidget * widget, ChamplainView* view) +{ + champlain_view_center_on(view, 0.1258, 52.2048); +} + int main (int argc, char *argv[]) { GtkWidget *window; - GtkWidget *widget; + GtkWidget *widget, *vbox, *bbox, *button, *viewport; GtkWidget *scrolled; gtk_clutter_init (&argc, &argv); @@ -51,8 +63,7 @@ main (int argc, char *argv[]) gtk_window_set_title (GTK_WINDOW (window), PACKAGE " " VERSION); /* open it a bit wider so that both the label and title show up */ - gtk_window_set_default_size (GTK_WINDOW (window), 640, 480); - + //gtk_window_set_default_size (GTK_WINDOW (window), 640, 480); /* Connect the destroy event of the window with our on_destroy function * When the window is about to be destroyed we get a notificaiton and @@ -60,14 +71,40 @@ main (int argc, char *argv[]) */ g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (on_destroy), NULL); + vbox = gtk_vbox_new(FALSE, 10); + widget = champlain_view_new (); + gtk_widget_set_size_request(widget, 640, 480); + + bbox = gtk_hbutton_box_new (); + gtk_button_box_set_layout (GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_START); + gtk_button_box_set_spacing (GTK_BUTTON_BOX(bbox), 10); + button = gtk_button_new_with_label ("Montréal"); + g_signal_connect (button, + "clicked", + G_CALLBACK (go_to_montreal), + widget); + gtk_container_add (GTK_CONTAINER (bbox), button); + button = gtk_button_new_with_label ("Cambridge"); + g_signal_connect (button, + "clicked", + G_CALLBACK (go_to_cambridge), + widget); + gtk_container_add (GTK_CONTAINER (bbox), button); + + viewport = gtk_viewport_new (NULL, NULL); + gtk_viewport_set_shadow_type (GTK_VIEWPORT(viewport), GTK_SHADOW_ETCHED_IN); + gtk_container_add (GTK_CONTAINER (viewport), widget); + + gtk_box_pack_start (GTK_BOX (vbox), bbox, FALSE, FALSE, 0); + gtk_container_add (GTK_CONTAINER (vbox), viewport); /* and insert it into the main window */ - gtk_container_add (GTK_CONTAINER (window), widget); + gtk_container_add (GTK_CONTAINER (window), vbox); /* make sure that everything, window and label, are visible */ gtk_widget_show_all (window); - + champlain_view_center_on(widget, 0.00, 0.0); /* start the main loop */ gtk_main (); diff --git a/src/map.h b/src/map.h index 44d9e7b..1755b85 100644 --- a/src/map.h +++ b/src/map.h @@ -40,6 +40,11 @@ struct _Map guint (* get_row_count) (Map* map, guint zoom_level); guint (* get_column_count) (Map* map, guint zoom_level); + gdouble (* longitude_to_x) (Map* map, gdouble longitude, guint zoom_level); + gdouble (* latitude_to_y) (Map* map, gdouble latitude, guint zoom_level); + gdouble (* x_to_longitude) (Map* map, gdouble x, guint zoom_level); + gdouble (* y_to_latitude) (Map* map, gdouble y, guint zoom_level); + }; diff --git a/src/sources/debugmap.c b/src/sources/debugmap.c index 5abc2ee..b4a5043 100644 --- a/src/sources/debugmap.c +++ b/src/sources/debugmap.c @@ -24,6 +24,11 @@ guint debugmap_row_count(Map* map, guint zoom_level); guint debugmap_column_count(Map* map, guint zoom_level); Tile* debugmap_get_tile (Map* map, guint zoom_level, guint x, guint y); +gdouble debugmap_longitude_to_x (Map* map, gdouble longitude, guint zoom_level); +gdouble debugmap_latitude_to_y (Map* map, gdouble latitude, guint zoom_level); +gdouble debugmap_x_to_longitude (Map* map, gdouble x, guint zoom_level); +gdouble debugmap_y_to_latitude (Map* map, gdouble y, guint zoom_level); + void debugmap_init(Map* map) { @@ -34,6 +39,11 @@ debugmap_init(Map* map) map->get_row_count = debugmap_row_count; map->get_column_count = debugmap_column_count; map->get_tile = debugmap_get_tile; + + map->longitude_to_x = debugmap_longitude_to_x; + map->latitude_to_y = debugmap_latitude_to_y; + map->x_to_longitude = debugmap_x_to_longitude; + map->y_to_latitude = debugmap_y_to_latitude; } guint debugmap_row_count(Map* map, guint zoom_level) @@ -79,11 +89,42 @@ Tile* debugmap_get_tile (Map* map, guint zoom_level, guint x, guint y) clutter_actor_show (actor); clutter_container_add_actor (CLUTTER_CONTAINER (tile->actor), actor); - actor = clutter_label_new_full ("Arial", g_strdup_printf("%d, %d", x, y), textColor); - clutter_actor_set_position (actor, x * map->tile_size + map->tile_size/2.25, y * map->tile_size + map->tile_size/2.25); + x *= map->tile_size; + y *= map->tile_size; + + gdouble lon, lat; + lon = debugmap_x_to_longitude(map, x, zoom_level); + lat = debugmap_y_to_latitude(map, x, zoom_level); + + actor = clutter_label_new_full ("Arial", g_strdup_printf("%.2f, %.2f", lon, lat), textColor); + clutter_actor_set_position (actor, x, y); clutter_container_add_actor (CLUTTER_CONTAINER (tile->actor), actor); g_object_ref(tile->actor); // to prevent actors to be destroyed when they are removed from groups return tile; } + +//FIXME: These functions need to be fixed +gdouble debugmap_longitude_to_x (Map* map, gdouble longitude, guint zoom_level) +{ + return ((longitude + 180.0) / 360.0 * pow(2.0, zoom_level)) * map->tile_size; +} + +gdouble debugmap_latitude_to_y (Map* map, gdouble latitude, guint zoom_level) +{ + return ((latitude + 90.0) / 180.0 * pow(2.0, zoom_level)) * map->tile_size; +} + +gdouble debugmap_x_to_longitude (Map* map, gdouble x, guint zoom_level) +{ + x /= map->tile_size; + return x / map->tile_size * pow(2.0, zoom_level) * 360.0 - 180; +} + +gdouble debugmap_y_to_latitude (Map* map, gdouble y, guint zoom_level) +{ + y /= map->tile_size; + return y / map->tile_size * pow(2.0, zoom_level) * 180.0 - 90; +} + diff --git a/src/sources/openstreetmap.c b/src/sources/openstreetmap.c index c55010f..6bf72ec 100644 --- a/src/sources/openstreetmap.c +++ b/src/sources/openstreetmap.c @@ -27,6 +27,11 @@ guint osm_row_count(Map* map, guint zoom_level); guint osm_column_count(Map* map, guint zoom_level); Tile* osm_get_tile (Map* map, guint zoom_level, guint x, guint y); +gdouble osm_longitude_to_x (Map* map, gdouble longitude, guint zoom_level); +gdouble osm_latitude_to_y (Map* map, gdouble latitude, guint zoom_level); +gdouble osm_x_to_longitude (Map* map, gdouble x, guint zoom_level); +gdouble osm_y_to_latitude (Map* map, gdouble y, guint zoom_level); + void osm_init(Map* map) { @@ -37,6 +42,11 @@ osm_init(Map* map) map->get_row_count = osm_row_count; map->get_column_count = osm_column_count; map->get_tile = osm_get_tile; + + map->longitude_to_x = osm_longitude_to_x; + map->latitude_to_y = osm_latitude_to_y; + map->x_to_longitude = osm_x_to_longitude; + map->y_to_latitude = osm_y_to_latitude; } guint osm_row_count(Map* map, guint zoom_level) @@ -71,3 +81,27 @@ Tile* osm_get_tile (Map* map, guint zoom_level, guint x, guint y) return tile; } + +gdouble osm_longitude_to_x (Map* map, gdouble longitude, guint zoom_level) +{ + return ((longitude + 180.0) / 360.0 * pow(2.0, zoom_level)) * map->tile_size; +} + +gdouble osm_latitude_to_y (Map* map, gdouble latitude, guint zoom_level) +{ + return ((1.0 - log( tan(latitude * M_PI/180.0) + 1.0 / cos(latitude * M_PI/180.0)) / M_PI) / 2.0 * pow(2.0, zoom_level)) * map->tile_size; +} + +gdouble osm_x_to_longitude (Map* map, gdouble x, guint zoom_level) +{ + x /= map->tile_size; + return x / map->tile_size * pow(2.0, zoom_level) * 360.0 - 180; +} + +gdouble osm_y_to_latitude (Map* map, gdouble y, guint zoom_level) +{ + y /= map->tile_size; + double n = M_PI - 2.0 * M_PI * y / pow(2.0, zoom_level); + return 180.0 / M_PI * atan(0.5 * (exp(n) - exp(-n))); +} +