]> err.no Git - libchamplain/commitdiff
Tile loading
authorPierre-Luc Beaudoin <pierre-luc@squidy.info>
Tue, 19 Aug 2008 01:37:20 +0000 (21:37 -0400)
committerPierre-Luc Beaudoin <pierre-luc@squidy.info>
Tue, 19 Aug 2008 01:37:20 +0000 (21:37 -0400)
src/champlain.h
src/champlain_private.h [deleted file]
src/champlainview.c
src/map.c
src/map.h
src/sources/openstreetmap.c
src/tile.c
src/zoomlevel.c

index ec3f5151a375b50aa8d906d8d98f6830d56f0c30..26909f159dc2cb50e62750f8a4cd45c79d4164d6 100644 (file)
 #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"
 
diff --git a/src/champlain_private.h b/src/champlain_private.h
deleted file mode 100644 (file)
index 9235a22..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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
index a7fc27cee5d0a7dc9221674915e6c17f893ddcdd..f4925d0ade216b4b76548784c90abcdca3b16158 100644 (file)
@@ -19,6 +19,7 @@
 
 #include "config.h"
 
+#include "champlain.h"
 #include "champlain_defines.h"
 #include "champlainview.h"
 #include "tile.h"
@@ -53,20 +54,12 @@ static guint champlain_view_signals[LAST_SIGNAL] = { 0, };
 
 #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;
 };
 
@@ -97,16 +90,36 @@ champlain_view_init (ChamplainView *champlainView)
   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);
   
@@ -114,16 +127,20 @@ view_size_allocated_cb (GtkWidget *view, GtkAllocation *allocation, ChamplainVie
   
   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 *
@@ -136,9 +153,6 @@ champlain_view_new ()
   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",
@@ -154,7 +168,12 @@ champlain_view_new ()
   // 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);
@@ -165,7 +184,7 @@ champlain_view_new ()
   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);
 }
 
@@ -179,5 +198,8 @@ champlain_view_center_on (ChamplainView *champlainView, gdouble longitude, gdoub
   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);
 }
index 01f1af61ef76c4ad87ed0bcef6ac4b8e4005be36..ea8dc580896608c6ced21746e17603270c63a352 100644 (file)
--- a/src/map.c
+++ b/src/map.c
@@ -46,6 +46,43 @@ map_load(Map* map, gint zoom_level)
     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);
+            }
+        }
+    }
+}
index 1755b8557362d9ab01ce16be13440b182f7777a1..c9fbd96f576e416901d417b772c2afd246f8ff18 100644 (file)
--- a/src/map.h
+++ b/src/map.h
@@ -20,6 +20,7 @@
 #ifndef MAP_H
 #define MAP_H
 
+#include "champlain.h"
 #include "champlainview.h"
 #include "champlain_defines.h"
 #include "zoomlevel.h"
@@ -50,5 +51,6 @@ struct _Map
 
 CHAMPLAIN_API Map* champlain_map_new (ChamplainMapSource source);
 
+void map_load_visible_tiles (Map* map, ChamplainRect viewport);
 
 #endif
index 6bf72ec64ca5c61ef407fe50c070b2e29c624794..811ab770e6494a75336c7e73f165c10bccd7d2a5 100644 (file)
@@ -20,6 +20,7 @@
 #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
 
@@ -54,12 +55,14 @@ guint osm_row_count(Map* map, guint zoom_level)
   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);
   
@@ -82,23 +85,27 @@ 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_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);
index ad1386c428793356b04e1f85954800eb19fc874d..b3b28fcfc5da6fe1b7d757e1fb13d4269fde4d8a 100644 (file)
@@ -43,3 +43,5 @@ tile_is_visible(ClutterUnit viewport_w, ClutterUnit viewport_h, ChamplainPoint p
   return TRUE;
 
 }*/
+
+
index e56d47c2cc5ca638d06fa312ebcdbb780b544f30..634964e5d4c0dc435f9f1976b89f874f4d50eb10 100644 (file)
@@ -20,7 +20,6 @@
 #include <zoomlevel.h>
 #include <tile.h>
 #include "map.h"
-#include <champlain_private.h>
 #include <clutter/clutter.h>
 
 ZoomLevel* 
@@ -38,30 +37,14 @@ zoom_level_new(gint zoom_level, gint row, gint column, gint tile_size)
   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;
 }