#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
#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
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
#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>
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);
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);
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);
+}
CHAMPLAIN_API GtkWidget *champlain_view_new (void);
+CHAMPLAIN_API void champlain_view_center_on (ChamplainView *view, gdouble longitude, gdouble latitude);
+
#endif
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);
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
*/
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 ();
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);
+
};
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)
{
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)
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;
+}
+
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)
{
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)
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)));
+}
+