#define CHAMPLAIN_MIN_LONG -180
#define CHAMPLAIN_MAX_LONG 180
+#include <glib.h>
+
+typedef struct {
+ gint x;
+ gint y;
+ guint width;
+ guint height;
+} ChamplainRect;
+
#include "champlain_defines.h"
#include "champlainview.h"
+++ /dev/null
-/*
- * Copyright (C) 2008 Pierre-Luc Beaudoin <pierre-luc@squidy.info>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB. If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-
-#ifndef CHAMPLAIN_PRIVATE_H
-#define CHAMPLAIN_PRIVATE_H
-
-#include <clutter/clutter.h>
-#include <clutter/clutter.h>
-
-void champlain_map_create_tiles(gint zoom_level);
-
-//gboolean tile_is_visible(ClutterUnit viewport_w, ClutterUnit viewport_h, ChamplainPoint position, ChamplainMapTile* tile);
-
-#endif
#include "config.h"
+#include "champlain.h"
#include "champlain_defines.h"
#include "champlainview.h"
#include "tile.h"
#define CHAMPLAIN_VIEW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), CHAMPLAIN_TYPE_VIEW, ChamplainViewPrivate))
-typedef struct
-{
- /* Units to store the origin of a click when scrolling */
- ClutterUnit x;
- ClutterUnit y;
-} ChamplainPoint;
-
struct _ChamplainViewPrivate
{
GtkWidget *clutterEmbed;
ClutterActor *viewport;
- ChamplainPoint viewportSize;
ClutterActor *fingerScroll;
-
+ ChamplainRect viewportSize;
Map *map;
};
ChamplainViewPrivate *priv = CHAMPLAIN_VIEW_GET_PRIVATE (champlainView);
}
+void viewport_x_changed_cb(GObject *gobject,
+ GParamSpec *arg1,
+ ChamplainView *champlainView)
+{
+ ChamplainViewPrivate *priv = CHAMPLAIN_VIEW_GET_PRIVATE (champlainView);
+
+ ChamplainRect rect;
+ tidy_viewport_get_origin(TIDY_VIEWPORT(priv->viewport), &rect.x, &rect.y, NULL);
+ if (rect.x < 0 || rect.y < 0)
+ return;
+ if (rect.x == priv->viewportSize.x &&
+ rect.y == priv->viewportSize.y &&
+ rect.width == priv->viewportSize.width &&
+ rect.height == priv->viewportSize.height)
+ return;
+ priv->viewportSize.x = rect.x;
+ priv->viewportSize.y = rect.y;
+
+ map_load_visible_tiles (priv->map, priv->viewportSize);
+}
+
static void
view_size_allocated_cb (GtkWidget *view, GtkAllocation *allocation, ChamplainView *champlainView)
-{
+{
gdouble lower, upper;
TidyAdjustment *hadjust, *vadjust;
ChamplainViewPrivate *priv = CHAMPLAIN_VIEW_GET_PRIVATE (champlainView);
- priv->viewportSize.x = allocation->width;
- priv->viewportSize.y = allocation->height;
- clutter_actor_set_size (priv->fingerScroll, priv->viewportSize.x, priv->viewportSize.y);
+
+ clutter_actor_set_size (priv->fingerScroll, allocation->width, allocation->height);
g_object_set (G_OBJECT (priv->viewport), "sync-adjustments", FALSE, NULL);
tidy_adjustment_get_values (hadjust, NULL, &lower, &upper, NULL, NULL, NULL);
lower = 0;
- upper = zoom_level_get_width(priv->map->current_level) - priv->viewportSize.x;
+ upper = zoom_level_get_width(priv->map->current_level) - allocation->width;
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 = zoom_level_get_height(priv->map->current_level) - priv->viewportSize.y;
+ upper = zoom_level_get_height(priv->map->current_level) - allocation->height;
g_object_set (vadjust, "lower", lower, "upper", upper,
"step-increment", 1.0, "elastic", TRUE, NULL);
+ priv->viewportSize.width = allocation->width;
+ priv->viewportSize.height = allocation->height;
+
+ map_load_visible_tiles (priv->map, priv->viewportSize);
}
GtkWidget *
view = CHAMPLAIN_VIEW (g_object_new (CHAMPLAIN_TYPE_VIEW, NULL));
ChamplainViewPrivate *priv = CHAMPLAIN_VIEW_GET_PRIVATE (view);
- priv->viewportSize.x = 640;
- priv->viewportSize.y = 480;
-
priv->clutterEmbed = gtk_clutter_embed_new ();
g_signal_connect (priv->clutterEmbed,
"size-allocate",
// Setup viewport
priv->viewport = tidy_viewport_new ();
ClutterActor* group = clutter_group_new();
+
clutter_container_add_actor (CLUTTER_CONTAINER (priv->viewport), group);
+ g_signal_connect (priv->viewport,
+ "notify::x-origin",
+ G_CALLBACK (viewport_x_changed_cb),
+ view);
// Setup finger scroll
priv->fingerScroll = tidy_finger_scroll_new(TIDY_FINGER_SCROLL_MODE_KINETIC);
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);
-
+ clutter_actor_show (group);
return GTK_WIDGET (view);
}
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);
+ ChamplainRect rect;
+ clutter_actor_get_size(priv->viewport, &rect.width, &rect.height);
+
+ tidy_viewport_set_origin(TIDY_VIEWPORT(priv->viewport), x - rect.width/2.0, y - rect.height/2.0, 0);
}
guint column_count = map->get_column_count(map, zoom_level);
map->current_level = zoom_level_new(zoom_level, row_count, column_count, map->tile_size);
- zoom_level_create(map, zoom_level);
}
+void
+map_load_visible_tiles (Map* map, ChamplainRect viewport)
+{
+ gint x_count = ceil((float)viewport.width / map->tile_size) + 1;
+ gint y_count = ceil((float)viewport.height / map->tile_size) + 1;
+
+ gint x_first = viewport.x / map->tile_size;
+ gint y_first = viewport.y / map->tile_size;
+
+ x_count += x_first;
+ y_count += y_first;
+
+ int i, j, k;
+ for (i = x_first; i < x_count; i++)
+ {
+ for (j = y_first; j < y_count; j++)
+ {
+ if(i >= map->current_level->row_count || j >= map->current_level->column_count)
+ continue;
+
+ gboolean exist = FALSE;
+ for (k = 0; k < map->current_level->tiles->len && !exist; k++)
+ {
+ Tile* tile = g_ptr_array_index(map->current_level->tiles, k);
+ if ( tile->x == i && tile->y == j)
+ exist = TRUE;
+ }
+
+ if(!exist)
+ {
+ Tile* tile = map->get_tile(map, map->current_level->level, i, j);
+
+ g_ptr_array_add (map->current_level->tiles, tile);
+ clutter_container_add (CLUTTER_CONTAINER (map->current_level->group), tile->actor, NULL);
+ }
+ }
+ }
+}
#ifndef MAP_H
#define MAP_H
+#include "champlain.h"
#include "champlainview.h"
#include "champlain_defines.h"
#include "zoomlevel.h"
CHAMPLAIN_API Map* champlain_map_new (ChamplainMapSource source);
+void map_load_visible_tiles (Map* map, ChamplainRect viewport);
#endif
#include "sources/openstreetmap.h"
#include <map.h>
#include <math.h>
+#include <clutter/clutter.h>
//http://wiki.openstreetmap.org/index.php/Slippy_map_tilenames#C.2FC.2B.2B
return pow (2, zoom_level);
}
-guint osm_column_count(Map* map, guint zoom_level)
+guint
+osm_column_count(Map* map, guint zoom_level)
{
return pow (2, zoom_level);
}
-Tile* osm_get_tile (Map* map, guint zoom_level, guint x, guint y)
+Tile*
+osm_get_tile (Map* map, guint zoom_level, guint x, guint y)
{
Tile* tile = g_new0(Tile, 1);
}
-gdouble osm_longitude_to_x (Map* map, gdouble longitude, guint zoom_level)
+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)
+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)
+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)
+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);
#include <zoomlevel.h>
#include <tile.h>
#include "map.h"
-#include <champlain_private.h>
#include <clutter/clutter.h>
ZoomLevel*
return level;
}
-void
-zoom_level_create(Map* map, gint zoom_level)
-{
- int i;
- for (i = 0; i < map->current_level->row_count * map->current_level->column_count; i++)
- {
- int x = i % map->current_level->column_count;
- int y = i / map->current_level->column_count;
-
- Tile* tile = map->get_tile(map, zoom_level, x, y);
-
- clutter_container_add (CLUTTER_CONTAINER (map->current_level->group), tile->actor, NULL);
- g_ptr_array_add (map->current_level->tiles, tile);
- }
-}
-
guint
zoom_level_get_width(ZoomLevel* level)
{
- return (level->column_count + 1) * level->tile_size;
+ return (level->column_count) * level->tile_size;
}
guint
zoom_level_get_height(ZoomLevel* level)
{
- return (level->row_count + 1) * level->tile_size;
+ return (level->row_count) * level->tile_size;
}