[libchamplain] Improve bounding box use
- From: Jiří Techet <jiritechet src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libchamplain] Improve bounding box use
- Date: Mon, 14 Feb 2011 23:22:57 +0000 (UTC)
commit b048845f782218178bfcddabc42984bc8cb153c8
Author: JiÅ?Ã Techet <techet gmail com>
Date: Tue Feb 15 00:15:03 2011 +0100
Improve bounding box use
Add an ensure_visible function for layers in view, make bounding
box query a virtual function of layers and add some extra utility
functions to bounding box.
champlain/champlain-bounding-box.c | 65 +++++++++++++++++++++++++++++-
champlain/champlain-bounding-box.h | 5 ++
champlain/champlain-layer.c | 20 +++++++++
champlain/champlain-layer.h | 4 ++
champlain/champlain-marker-layer.c | 38 ++++--------------
champlain/champlain-marker-layer.h | 1 -
champlain/champlain-path-layer.c | 38 ++++-------------
champlain/champlain-path-layer.h | 2 -
champlain/champlain-view.c | 44 ++++++++++++++++++++
champlain/champlain-view.h | 2 +
docs/reference/libchamplain-sections.txt | 7 ++-
11 files changed, 161 insertions(+), 65 deletions(-)
---
diff --git a/champlain/champlain-bounding-box.c b/champlain/champlain-bounding-box.c
index 7915893..1833525 100644
--- a/champlain/champlain-bounding-box.c
+++ b/champlain/champlain-bounding-box.c
@@ -28,6 +28,7 @@
*/
#include "champlain-bounding-box.h"
+#include "champlain-defines.h"
GType
champlain_bounding_box_get_type (void)
@@ -59,7 +60,16 @@ champlain_bounding_box_get_type (void)
ChamplainBoundingBox *
champlain_bounding_box_new (void)
{
- return g_slice_new (ChamplainBoundingBox);
+ ChamplainBoundingBox *bbox;
+
+ bbox = g_slice_new (ChamplainBoundingBox);
+
+ bbox->left = CHAMPLAIN_MAX_LONGITUDE;
+ bbox->right = CHAMPLAIN_MIN_LONGITUDE;
+ bbox->bottom = CHAMPLAIN_MAX_LATITUDE;
+ bbox->top = CHAMPLAIN_MIN_LATITUDE;
+
+ return bbox;
}
@@ -153,3 +163,56 @@ champlain_bounding_box_compose (ChamplainBoundingBox *bbox,
bbox->bottom = other->bottom;
}
+
+/**
+ * champlain_bounding_box_extend:
+ * @bbox: a #ChamplainBoundingBox
+ * @latitude: latitude
+ * @longitude: longitude
+ *
+ * Extend the bounding box so it contains a point with @latitude and @longitude.
+ * Do nothing if the point is already inside the bounding box.
+ *
+ * Since: 0.10
+ */
+void champlain_bounding_box_extend (ChamplainBoundingBox *bbox,
+ gdouble latitude, gdouble longitude)
+{
+ g_return_if_fail (CHAMPLAIN_BOUNDING_BOX (bbox));
+
+ if (longitude < bbox->left)
+ bbox->left = longitude;
+
+ if (latitude < bbox->bottom)
+ bbox->bottom = latitude;
+
+ if (longitude > bbox->right)
+ bbox->right = longitude;
+
+ if (latitude > bbox->top)
+ bbox->top = latitude;
+}
+
+
+/**
+ * champlain_bounding_box_is_valid:
+ * @bbox: a #ChamplainBoundingBox
+ *
+ * Checks whether bbox represents a valid bounding box on the map.
+ *
+ * Returns: TRUE when the bounding box is valid, FALSE otherwise.
+ *
+ * Since: 0.10
+ */
+gboolean
+champlain_bounding_box_is_valid (ChamplainBoundingBox *bbox)
+{
+ g_return_val_if_fail (CHAMPLAIN_BOUNDING_BOX (bbox), FALSE);
+
+ return (bbox->left < bbox->right) && (bbox->bottom < bbox->top) &&
+ (bbox->left > CHAMPLAIN_MIN_LONGITUDE) && (bbox->left < CHAMPLAIN_MAX_LONGITUDE) &&
+ (bbox->right > CHAMPLAIN_MIN_LONGITUDE) && (bbox->right < CHAMPLAIN_MAX_LONGITUDE) &&
+ (bbox->bottom > CHAMPLAIN_MIN_LATITUDE) && (bbox->bottom < CHAMPLAIN_MAX_LATITUDE) &&
+ (bbox->top > CHAMPLAIN_MIN_LATITUDE) && (bbox->top < CHAMPLAIN_MAX_LATITUDE);
+}
+
diff --git a/champlain/champlain-bounding-box.h b/champlain/champlain-bounding-box.h
index 874519f..bbd3715 100644
--- a/champlain/champlain-bounding-box.h
+++ b/champlain/champlain-bounding-box.h
@@ -67,6 +67,11 @@ void champlain_bounding_box_get_center (ChamplainBoundingBox *bbox,
void champlain_bounding_box_compose (ChamplainBoundingBox *bbox,
ChamplainBoundingBox *other);
+void champlain_bounding_box_extend (ChamplainBoundingBox *bbox,
+ gdouble latitude, gdouble longitude);
+
+gboolean champlain_bounding_box_is_valid (ChamplainBoundingBox *bbox);
+
G_END_DECLS
#endif
diff --git a/champlain/champlain-layer.c b/champlain/champlain-layer.c
index 630d77f..fc77898 100644
--- a/champlain/champlain-layer.c
+++ b/champlain/champlain-layer.c
@@ -51,6 +51,7 @@ champlain_layer_class_init (ChamplainLayerClass *klass)
object_class->dispose = champlain_layer_dispose;
klass->set_view = NULL;
+ klass->get_bounding_box = NULL;
}
/**
@@ -75,6 +76,25 @@ void champlain_layer_set_view (ChamplainLayer *layer,
}
+/**
+ * champlain_layer_get_bounding_box:
+ * @layer: a #ChamplainLayer
+ *
+ * Gets the bounding box occupied by the elements inside the layer.
+ *
+ * Returns: The bounding box.
+ *
+ * Since: 0.10
+ */
+ChamplainBoundingBox *
+champlain_layer_get_bounding_box (ChamplainLayer *layer)
+{
+ g_return_val_if_fail (CHAMPLAIN_IS_LAYER (layer), NULL);
+
+ return CHAMPLAIN_LAYER_GET_CLASS (layer)->get_bounding_box (layer);
+}
+
+
static void
champlain_layer_init (ChamplainLayer *self)
{
diff --git a/champlain/champlain-layer.h b/champlain/champlain-layer.h
index f425ef3..aca14d6 100644
--- a/champlain/champlain-layer.h
+++ b/champlain/champlain-layer.h
@@ -25,6 +25,7 @@
#include <clutter/clutter.h>
#include <champlain/champlain-defines.h>
+#include <champlain/champlain-bounding-box.h>
G_BEGIN_DECLS
@@ -59,6 +60,7 @@ struct _ChamplainLayerClass
void (*set_view)(ChamplainLayer *layer,
ChamplainView *view);
+ ChamplainBoundingBox * (*get_bounding_box) (ChamplainLayer *layer);
};
GType champlain_layer_get_type (void);
@@ -67,6 +69,8 @@ GType champlain_layer_get_type (void);
void champlain_layer_set_view (ChamplainLayer *layer,
ChamplainView *view);
+ChamplainBoundingBox *champlain_layer_get_bounding_box (ChamplainLayer *layer);
+
G_END_DECLS
#endif /* __CHAMPLAIN_LAYER_H__ */
diff --git a/champlain/champlain-marker-layer.c b/champlain/champlain-marker-layer.c
index 9af841a..1356f28 100644
--- a/champlain/champlain-marker-layer.c
+++ b/champlain/champlain-marker-layer.c
@@ -70,6 +70,8 @@ static void marker_selected_cb (ChamplainMarker *marker,
static void set_view (ChamplainLayer *layer,
ChamplainView *view);
+static ChamplainBoundingBox *get_bounding_box (ChamplainLayer *layer);
+
static void
champlain_marker_layer_get_property (GObject *object,
@@ -256,7 +258,8 @@ champlain_marker_layer_class_init (ChamplainMarkerLayerClass *klass)
actor_class->unmap = unmap;
layer_class->set_view = set_view;
-
+ layer_class->get_bounding_box = get_bounding_box;
+
/**
* ChamplainMarkerLayer:selection-mode:
*
@@ -858,20 +861,9 @@ set_view (ChamplainLayer *layer,
}
}
-/**
- * champlain_marker_layer_get_bounding_box:
- * @layer: a #ChamplainMarkerLayer
- *
- * Gets the bounding box occupied by the markers in the layer
- *
- * Returns: The bounding box.
- *
- * FIXME: This doesn't take into account the marker's actor size yet
- *
- * Since: 0.10
- */
-ChamplainBoundingBox *
-champlain_marker_layer_get_bounding_box (ChamplainMarkerLayer *layer)
+
+static ChamplainBoundingBox *
+get_bounding_box (ChamplainLayer *layer)
{
ChamplainMarkerLayerPrivate *priv = GET_PRIVATE (layer);
GList *elem;
@@ -881,10 +873,6 @@ champlain_marker_layer_get_bounding_box (ChamplainMarkerLayer *layer)
g_return_val_if_fail (CHAMPLAIN_IS_MARKER_LAYER (layer), NULL);
bbox = champlain_bounding_box_new ();
- bbox->left = CHAMPLAIN_MAX_LONGITUDE;
- bbox->right = CHAMPLAIN_MIN_LONGITUDE;
- bbox->bottom = CHAMPLAIN_MAX_LATITUDE;
- bbox->top = CHAMPLAIN_MIN_LATITUDE;
markers = clutter_container_get_children (CLUTTER_CONTAINER (priv->content_group));
@@ -896,17 +884,7 @@ champlain_marker_layer_get_bounding_box (ChamplainMarkerLayer *layer)
g_object_get (G_OBJECT (marker), "latitude", &lat, "longitude", &lon,
NULL);
- if (lon < bbox->left)
- bbox->left = lon;
-
- if (lat < bbox->bottom)
- bbox->bottom = lat;
-
- if (lon > bbox->right)
- bbox->right = lon;
-
- if (lat > bbox->top)
- bbox->top = lat;
+ champlain_bounding_box_extend (bbox, lat, lon);
}
g_list_free (markers);
diff --git a/champlain/champlain-marker-layer.h b/champlain/champlain-marker-layer.h
index ccddab9..3f44649 100644
--- a/champlain/champlain-marker-layer.h
+++ b/champlain/champlain-marker-layer.h
@@ -109,7 +109,6 @@ void champlain_marker_layer_set_selection_mode (ChamplainMarkerLayer *layer,
ChamplainSelectionMode mode);
ChamplainSelectionMode champlain_marker_layer_get_selection_mode (
ChamplainMarkerLayer *layer);
-ChamplainBoundingBox *champlain_marker_layer_get_bounding_box (ChamplainMarkerLayer *layer);
G_END_DECLS
diff --git a/champlain/champlain-path-layer.c b/champlain/champlain-path-layer.c
index 45cf04a..67c1e02 100644
--- a/champlain/champlain-path-layer.c
+++ b/champlain/champlain-path-layer.c
@@ -91,6 +91,8 @@ static void redraw_path (ChamplainPathLayer *layer);
static void set_view (ChamplainLayer *layer,
ChamplainView *view);
+static ChamplainBoundingBox *get_bounding_box (ChamplainLayer *layer);
+
static void
champlain_path_layer_get_property (GObject *object,
@@ -340,7 +342,8 @@ champlain_path_layer_class_init (ChamplainPathLayerClass *klass)
actor_class->unmap = unmap;
layer_class->set_view = set_view;
-
+ layer_class->get_bounding_box = get_bounding_box;
+
/**
* ChamplainPathLayer:closed:
*
@@ -774,28 +777,15 @@ set_view (ChamplainLayer *layer,
}
}
-/**
- * champlain_path_layer_get_bounding_box:
- * @layer: a #ChamplainPathLayer
- *
- * Gets the bounding box occupied by the #ChamplainLocation objects in the layer
- *
- * Returns: The bounding box.
- *
- * Since: 0.10
- */
-ChamplainBoundingBox *
-champlain_path_layer_get_bounding_box (ChamplainPathLayer *layer)
+
+static ChamplainBoundingBox *
+get_bounding_box (ChamplainLayer *layer)
{
ChamplainPathLayerPrivate *priv = GET_PRIVATE (layer);
GList *elem;
ChamplainBoundingBox *bbox;
bbox = champlain_bounding_box_new ();
- bbox->left = CHAMPLAIN_MAX_LONGITUDE;
- bbox->right = CHAMPLAIN_MIN_LONGITUDE;
- bbox->bottom = CHAMPLAIN_MAX_LATITUDE;
- bbox->top = CHAMPLAIN_MIN_LATITUDE;
for (elem = priv->nodes; elem != NULL; elem = elem->next)
{
@@ -804,18 +794,8 @@ champlain_path_layer_get_bounding_box (ChamplainPathLayer *layer)
g_object_get (G_OBJECT (location), "latitude", &lat, "longitude", &lon,
NULL);
-
- if (lon < bbox->left)
- bbox->left = lon;
-
- if (lat < bbox->bottom)
- bbox->bottom = lat;
-
- if (lon > bbox->right)
- bbox->right = lon;
-
- if (lat > bbox->top)
- bbox->top = lat;
+
+ champlain_bounding_box_extend (bbox, lat, lon);
}
return bbox;
diff --git a/champlain/champlain-path-layer.h b/champlain/champlain-path-layer.h
index 93744d3..f132af9 100644
--- a/champlain/champlain-path-layer.h
+++ b/champlain/champlain-path-layer.h
@@ -82,8 +82,6 @@ void champlain_path_layer_insert_node (ChamplainPathLayer *layer,
guint position);
GList *champlain_path_layer_get_nodes (ChamplainPathLayer *layer);
-ChamplainBoundingBox *champlain_path_layer_get_bounding_box (ChamplainPathLayer *layer);
-
ClutterColor *champlain_path_layer_get_fill_color (ChamplainPathLayer *layer);
void champlain_path_layer_set_fill_color (ChamplainPathLayer *layer,
const ClutterColor *color);
diff --git a/champlain/champlain-view.c b/champlain/champlain-view.c
index 5663eb5..ad1a003 100644
--- a/champlain/champlain-view.c
+++ b/champlain/champlain-view.c
@@ -2265,6 +2265,9 @@ champlain_view_ensure_visible (ChamplainView *view,
guint zoom_level = priv->zoom_level;
gboolean good_size = FALSE;
gdouble lat, lon;
+
+ if (!champlain_bounding_box_is_valid (bbox))
+ return;
champlain_bounding_box_get_center (bbox, &lat, &lon);
@@ -2300,6 +2303,47 @@ champlain_view_ensure_visible (ChamplainView *view,
}
+/**
+ * champlain_view_ensure_layers_visible:
+ * @view: a #ChamplainView
+ * @animate: perform animation
+ *
+ * Changes the map's zoom level and center to make sure that the bounding
+ * boxes of all inserted layers are visible.
+ *
+ * Since: 0.10
+ */
+void
+champlain_view_ensure_layers_visible (ChamplainView *view,
+ gboolean animate)
+{
+ DEBUG_LOG ()
+
+ GList *layers, *elem;
+ ChamplainBoundingBox *bbox;
+
+ bbox = champlain_bounding_box_new ();
+
+ layers = clutter_container_get_children (CLUTTER_CONTAINER (view->priv->user_layers));
+
+ for (elem = layers; elem != NULL; elem = elem->next)
+ {
+ ChamplainLayer *layer = CHAMPLAIN_LAYER (elem->data);
+ ChamplainBoundingBox *other;
+
+ other = champlain_layer_get_bounding_box (layer);
+ champlain_bounding_box_compose (bbox, other);
+ champlain_bounding_box_free (other);
+ }
+
+ g_list_free (layers);
+
+ champlain_view_ensure_visible (view, bbox, animate);
+
+ champlain_bounding_box_free (bbox);
+}
+
+
/* Sets the zoom level, leaving the (x, y) at the exact same point in the view */
static gboolean
view_set_zoom_level_at (ChamplainView *view,
diff --git a/champlain/champlain-view.h b/champlain/champlain-view.h
index cc182bb..b253b6b 100644
--- a/champlain/champlain-view.h
+++ b/champlain/champlain-view.h
@@ -92,6 +92,8 @@ void champlain_view_set_max_zoom_level (ChamplainView *view,
void champlain_view_ensure_visible (ChamplainView *view,
ChamplainBoundingBox *bbox,
gboolean animate);
+void champlain_view_ensure_layers_visible (ChamplainView *view,
+ gboolean animate);
void champlain_view_set_map_source (ChamplainView *view,
ChamplainMapSource *map_source);
diff --git a/docs/reference/libchamplain-sections.txt b/docs/reference/libchamplain-sections.txt
index 0706bce..38855e3 100644
--- a/docs/reference/libchamplain-sections.txt
+++ b/docs/reference/libchamplain-sections.txt
@@ -128,6 +128,7 @@ champlain_view_set_zoom_level
champlain_view_set_min_zoom_level
champlain_view_set_max_zoom_level
champlain_view_ensure_visible
+champlain_view_ensure_layers_visible
champlain_view_set_map_source
champlain_view_set_decel_rate
champlain_view_set_kinetic_mode
@@ -290,6 +291,7 @@ ChamplainTilePrivate
<TITLE>ChamplainLayer</TITLE>
ChamplainLayer
champlain_layer_set_view
+champlain_layer_get_bounding_box
<SUBSECTION Standard>
CHAMPLAIN_LAYER
CHAMPLAIN_IS_LAYER
@@ -322,7 +324,6 @@ champlain_marker_layer_select_all_markers
champlain_marker_layer_unselect_all_markers
champlain_marker_layer_set_selection_mode
champlain_marker_layer_get_selection_mode
-champlain_marker_layer_get_bounding_box
<SUBSECTION Standard>
CHAMPLAIN_MARKER_LAYER
CHAMPLAIN_IS_MARKER_LAYER
@@ -459,6 +460,8 @@ champlain_bounding_box_copy
champlain_bounding_box_free
champlain_bounding_box_get_center
champlain_bounding_box_compose
+champlain_bounding_box_extend
+champlain_bounding_box_is_valid
<SUBSECTION Standard>
CHAMPLAIN_BOUNDING_BOX
CHAMPLAIN_TYPE_BOUNDING_BOX
@@ -695,6 +698,7 @@ ChamplainMemphisRendererClass
ChamplainMemphisRendererPrivate
</SECTION>
+
<SECTION>
<FILE>champlain-custom-marker</FILE>
<TITLE>ChamplainCustomMarker</TITLE>
@@ -723,7 +727,6 @@ champlain_path_layer_remove_node
champlain_path_layer_remove_all
champlain_path_layer_insert_node
champlain_path_layer_get_nodes
-champlain_path_layer_get_bounding_box
champlain_path_layer_get_fill_color
champlain_path_layer_set_fill_color
champlain_path_layer_get_stroke_color
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]