]> err.no Git - libchamplain/commitdiff
Center map on coordinates
authorPierre-Luc Beaudoin <pierre-luc@squidy.info>
Mon, 18 Aug 2008 02:50:26 +0000 (22:50 -0400)
committerPierre-Luc Beaudoin <pierre-luc@squidy.info>
Mon, 18 Aug 2008 02:50:26 +0000 (22:50 -0400)
src/champlain.h
src/champlain_defines.h
src/champlain_private.h
src/champlainview.c
src/champlainview.h
src/launcher.c
src/map.h
src/sources/debugmap.c
src/sources/openstreetmap.c

index 248f64783c1d23d41329e1982568f941208aa276..ec3f5151a375b50aa8d906d8d98f6830d56f0c30 100644 (file)
 #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
index efb9e60ee288e325a201417db053ce5fbbbf5a17..c03696129f99230cd246fbecdae119eadde820e5 100644 (file)
 #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
index bfbe0b1ed8f9bffab0ff46a7f223842c277ccc88..9235a22184df8ed45cb9d35cd13a77e9df1d4702 100644 (file)
 
 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
index 9919041c474e1c57b68dd02756d2e790749772b5..a7fc27cee5d0a7dc9221674915e6c17f893ddcdd 100644 (file)
 #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 <tidy-finger-scroll.h>
@@ -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);
+}
index e9622f6fdec69544e53450eb29fdd8dfc14ce081..c6659489f228e7fe02d5d451c7738020d7d93100 100644 (file)
@@ -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
index 8a215a371bbfa884f7aa9f07eda8d329d73d60bc..447288c7b22668ffd2775e005afe34e287d44a2b 100644 (file)
@@ -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 ();
 
index 44d9e7bc4c40aebb3b77872d86288401d0a04381..1755b8557362d9ab01ce16be13440b182f7777a1 100644 (file)
--- 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);
+  
 };
 
 
index 5abc2ee72667550ffc1e2a1a32e1b218f7a29b14..b4a504356253a3c50578985bb3ed37ce4f025e37 100644 (file)
@@ -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;
+}
+
index c55010f71961a32e9a56276c911e759e806edb7d..6bf72ec64ca5c61ef407fe50c070b2e29c624794 100644 (file)
@@ -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)));
+}
+