[libchamplain] Introduce ChamplainLocation interface



commit 4d7a829632c3f3551ffdafd2e57ad5d8148b5098
Author: JiÅ?í Techet <techet gmail com>
Date:   Mon Feb 14 01:13:42 2011 +0100

    Introduce ChamplainLocation interface
    
    Used to define common behavior of classes having latitude and
    longitude. ChamplainMarker implements this interface.

 champlain/Makefile.am              |    6 +
 champlain/champlain-coordinate.c   |  237 ++++++++
 champlain/champlain-coordinate.h   |   77 +++
 champlain/champlain-label.c        |    2 +-
 champlain/champlain-location.c     |  114 ++++
 champlain/champlain-location.h     |   38 ++
 champlain/champlain-marker-layer.c |   14 +-
 champlain/champlain-marker.c       |  163 +++---
 champlain/champlain-marker.h       |    6 +-
 champlain/champlain-path-layer.c   | 1083 ++++++++++++++++++++++++++++++++++++
 champlain/champlain-path-layer.h   |  113 ++++
 champlain/champlain-view.c         |    4 +-
 champlain/champlain.h              |    3 +
 demos/animated-marker.c            |    2 +-
 demos/launcher-gtk.c               |    2 +-
 demos/markers.c                    |   10 +-
 demos/polygons.c                   |   33 +-
 demos/url-marker.c                 |    2 +-
 18 files changed, 1776 insertions(+), 133 deletions(-)
---
diff --git a/champlain/Makefile.am b/champlain/Makefile.am
index ea44410..af457c8 100644
--- a/champlain/Makefile.am
+++ b/champlain/Makefile.am
@@ -19,6 +19,9 @@ libchamplain_headers_public = 				\
 	$(srcdir)/champlain-view.h			\
 	$(srcdir)/champlain-layer.h 			\
 	$(srcdir)/champlain-marker-layer.h 			\
+	$(srcdir)/champlain-path-layer.h		\
+	$(srcdir)/champlain-location.h		\
+	$(srcdir)/champlain-coordinate.h		\
 	$(srcdir)/champlain-marker.h		\
 	$(srcdir)/champlain-label.h			\
 	$(srcdir)/champlain-scale.h			\
@@ -58,6 +61,9 @@ libchamplain_sources =					\
 	$(srcdir)/champlain-view.c 			\
 	$(srcdir)/champlain-layer.c 			\
 	$(srcdir)/champlain-marker-layer.c		\
+	$(srcdir)/champlain-path-layer.c		\
+	$(srcdir)/champlain-location.c		\
+	$(srcdir)/champlain-coordinate.c		\
 	$(srcdir)/champlain-marker.c	 		\
 	$(srcdir)/champlain-label.c 			\
 	$(srcdir)/champlain-scale.c			\
diff --git a/champlain/champlain-coordinate.c b/champlain/champlain-coordinate.c
new file mode 100644
index 0000000..f768895
--- /dev/null
+++ b/champlain/champlain-coordinate.c
@@ -0,0 +1,237 @@
+/*
+ * Copyright (C) 2011 Jiri Techet <techet gmail com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+/**
+ * SECTION:champlain-coordinate
+ * @short_description: A marker to identify points of interest on a map
+ *
+ * Markers reprensent points of interest on a map. Markers need to be
+ * placed on a layer (a #ChamplainMarkerLayer). Layers have to be added to a
+ * #champlainview for the markers to show on the map.
+ *
+ * A marker is nothing more than a regular #clutteractor. You can draw on
+ * it what ever you want.  Set the markers position
+ * on the map using #champlain_location_set_position.
+ *
+ * libchamplain has a more evoluted type of markers with text and image support.
+ * See #ChamplainLabel.
+ */
+
+#include "champlain-coordinate.h"
+
+#include "config.h"
+#include "champlain-marshal.h"
+#include "champlain-private.h"
+#include "champlain-location.h"
+
+enum
+{
+  PROP_0,
+  PROP_LONGITUDE,
+  PROP_LATITUDE,
+};
+
+
+static void set_position (ChamplainLocation *location,
+    gdouble latitude,
+    gdouble longitude);
+static gdouble get_latitude (ChamplainLocation *location);
+static gdouble get_longitude (ChamplainLocation *location);
+
+static void location_interface_init (ChamplainLocationIface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (ChamplainCoordinate, champlain_coordinate, G_TYPE_INITIALLY_UNOWNED,
+                         G_IMPLEMENT_INTERFACE (CHAMPLAIN_TYPE_LOCATION,
+                                                location_interface_init));
+
+#define CHAMPLAIN_COORDINATE_GET_PRIVATE(obj) \
+  (G_TYPE_INSTANCE_GET_PRIVATE ((obj), CHAMPLAIN_TYPE_COORDINATE, ChamplainCoordinatePrivate))
+
+struct _ChamplainCoordinatePrivate
+{
+  gdouble lon;
+  gdouble lat;
+};
+
+static void
+champlain_coordinate_get_property (GObject *object,
+    guint prop_id,
+    GValue *value,
+    GParamSpec *pspec)
+{
+  ChamplainCoordinate *coordinate = CHAMPLAIN_COORDINATE (object);
+  ChamplainCoordinatePrivate *priv = coordinate->priv;
+
+  switch (prop_id)
+    {
+    case PROP_LONGITUDE:
+      g_value_set_double (value, priv->lon);
+      break;
+
+    case PROP_LATITUDE:
+      g_value_set_double (value, priv->lat);
+      break;
+      
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+
+static void
+champlain_coordinate_set_property (GObject *object,
+    guint prop_id,
+    const GValue *value,
+    GParamSpec *pspec)
+{
+  ChamplainCoordinate *coordinate = CHAMPLAIN_COORDINATE (object);
+  ChamplainCoordinatePrivate *priv = coordinate->priv;
+
+  switch (prop_id)
+    {
+    case PROP_LONGITUDE:
+    {
+      gdouble lon = g_value_get_double (value);
+      set_position (CHAMPLAIN_LOCATION (coordinate), priv->lat, lon);
+      break;
+    }
+
+    case PROP_LATITUDE:
+    {
+      gdouble lat = g_value_get_double (value);
+      set_position (CHAMPLAIN_LOCATION (coordinate), lat, priv->lon);
+      break;
+    }
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+
+static void
+set_position (ChamplainLocation *location,
+    gdouble latitude,
+    gdouble longitude)
+{
+  g_return_if_fail (CHAMPLAIN_IS_COORDINATE (location));
+
+  ChamplainCoordinatePrivate *priv = CHAMPLAIN_COORDINATE (location)->priv;
+
+  priv->lon = longitude;
+  priv->lat = latitude;
+
+  g_object_notify (G_OBJECT (location), "latitude");
+  g_object_notify (G_OBJECT (location), "longitude");
+}
+
+
+static gdouble
+get_latitude (ChamplainLocation *location)
+{
+  g_return_val_if_fail (CHAMPLAIN_IS_COORDINATE (location), 0.0);
+
+  ChamplainCoordinatePrivate *priv = CHAMPLAIN_COORDINATE (location)->priv;
+
+  return priv->lat;
+}
+
+
+static gdouble
+get_longitude (ChamplainLocation *location)
+{
+  g_return_val_if_fail (CHAMPLAIN_IS_COORDINATE (location), 0.0);
+
+  ChamplainCoordinatePrivate *priv = CHAMPLAIN_COORDINATE (location)->priv;
+
+  return priv->lon;
+}
+
+
+static void
+location_interface_init (ChamplainLocationIface *iface)
+{
+  iface->get_latitude = get_latitude;
+  iface->get_longitude = get_longitude;
+  iface->set_position = set_position;
+}
+
+
+static void
+champlain_coordinate_dispose (GObject *object)
+{
+  G_OBJECT_CLASS (champlain_coordinate_parent_class)->dispose (object);
+}
+
+
+static void
+champlain_coordinate_finalize (GObject *object)
+{
+  G_OBJECT_CLASS (champlain_coordinate_parent_class)->finalize (object);
+}
+
+
+static void
+champlain_coordinate_class_init (ChamplainCoordinateClass *coordinate_class)
+{
+  g_type_class_add_private (coordinate_class, sizeof (ChamplainCoordinatePrivate));
+
+  GObjectClass *object_class = G_OBJECT_CLASS (coordinate_class);
+  object_class->finalize = champlain_coordinate_finalize;
+  object_class->dispose = champlain_coordinate_dispose;
+  object_class->get_property = champlain_coordinate_get_property;
+  object_class->set_property = champlain_coordinate_set_property;
+
+  g_object_class_override_property (object_class,
+                                    PROP_LONGITUDE,
+                                    "longitude");
+
+  g_object_class_override_property (object_class,
+                                    PROP_LATITUDE,
+                                    "latitude");
+}
+
+
+static void
+champlain_coordinate_init (ChamplainCoordinate *coordinate)
+{
+  ChamplainCoordinatePrivate *priv = CHAMPLAIN_COORDINATE_GET_PRIVATE (coordinate);
+
+  coordinate->priv = priv;
+
+  priv->lat = 0;
+  priv->lon = 0;
+}
+
+
+ChamplainCoordinate *
+champlain_coordinate_new ()
+{
+  return CHAMPLAIN_COORDINATE (g_object_new (CHAMPLAIN_TYPE_COORDINATE, NULL));
+}
+
+
+ChamplainCoordinate *
+champlain_coordinate_new_full (gdouble latitude, 
+    gdouble longitude)
+{
+  return CHAMPLAIN_COORDINATE (g_object_new (CHAMPLAIN_TYPE_COORDINATE, 
+      "latitude", latitude, 
+      "longitude", longitude, 
+      NULL));
+}
diff --git a/champlain/champlain-coordinate.h b/champlain/champlain-coordinate.h
new file mode 100644
index 0000000..f07353f
--- /dev/null
+++ b/champlain/champlain-coordinate.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2011 Jiri Techet <techet gmail com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#if !defined (__CHAMPLAIN_CHAMPLAIN_H_INSIDE__) && !defined (CHAMPLAIN_COMPILATION)
+#error "Only <champlain/champlain.h> can be included directly."
+#endif
+
+#ifndef CHAMPLAIN_COORDINATE_H
+#define CHAMPLAIN_COORDINATE_H
+
+#include <champlain/champlain-defines.h>
+#include <champlain/champlain-location.h>
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define CHAMPLAIN_TYPE_COORDINATE champlain_coordinate_get_type ()
+
+#define CHAMPLAIN_COORDINATE(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST ((obj), CHAMPLAIN_TYPE_COORDINATE, ChamplainCoordinate))
+
+#define CHAMPLAIN_COORDINATE_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST ((klass), CHAMPLAIN_TYPE_COORDINATE, ChamplainCoordinateClass))
+
+#define CHAMPLAIN_IS_COORDINATE(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CHAMPLAIN_TYPE_COORDINATE))
+
+#define CHAMPLAIN_IS_COORDINATE_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE ((klass), CHAMPLAIN_TYPE_COORDINATE))
+
+#define CHAMPLAIN_COORDINATE_GET_CLASS(obj) \
+  (G_TYPE_INSTANCE_GET_CLASS ((obj), CHAMPLAIN_TYPE_COORDINATE, ChamplainCoordinateClass))
+
+typedef struct _ChamplainCoordinatePrivate ChamplainCoordinatePrivate;
+
+typedef struct _ChamplainCoordinate ChamplainCoordinate;
+typedef struct _ChamplainCoordinateClass ChamplainCoordinateClass;
+
+
+struct _ChamplainCoordinate
+{
+  GInitiallyUnowned parent;
+
+  ChamplainCoordinatePrivate *priv;
+};
+
+struct _ChamplainCoordinateClass
+{
+  GInitiallyUnownedClass parent_class;
+};
+
+GType champlain_coordinate_get_type (void);
+
+ChamplainCoordinate *champlain_coordinate_new (void);
+
+ChamplainCoordinate *champlain_coordinate_new_full (gdouble latitude, 
+    gdouble longitude);
+
+G_END_DECLS
+
+#endif
diff --git a/champlain/champlain-label.c b/champlain/champlain-label.c
index 53e0d25..317fb98 100644
--- a/champlain/champlain-label.c
+++ b/champlain/champlain-label.c
@@ -26,7 +26,7 @@
  *
  * A marker is nothing more than a regular #ClutterActor.  You can draw on it
  * what ever you want. Set the markers position on the map
- * using #champlain_marker_set_position.
+ * using #champlain_location_set_position.
  *
  * Champlain has a default type of markers with text. To create one,
  * use #champlain_label_new_with_text.
diff --git a/champlain/champlain-location.c b/champlain/champlain-location.c
new file mode 100644
index 0000000..108def6
--- /dev/null
+++ b/champlain/champlain-location.c
@@ -0,0 +1,114 @@
+
+#include "champlain-location.h"
+#include "champlain-private.h"
+
+
+static void
+champlain_location_base_init (gpointer g_iface)
+{
+  static gboolean initialized = FALSE;
+
+  if (!initialized)
+    {
+      /**
+       * ChamplainMarker:longitude:
+       *
+       * The longitude coordonate of the map
+       *
+       * Since: 0.10
+       */
+      g_object_interface_install_property (g_iface,
+          g_param_spec_double ("longitude", "Longitude",
+              "The longitude coordonate of the marker",
+              -180.0f, 180.0f, 0.0f, CHAMPLAIN_PARAM_READWRITE));
+
+      /**
+       * ChamplainMarker:latitude:
+       *
+       * The latitude coordonate of the map
+       *
+       * Since: 0.10
+       */
+      g_object_interface_install_property (g_iface,
+          g_param_spec_double ("latitude", "Latitude",
+              "The latitude coordonate of the marker",
+              -90.0f, 90.0f, 0.0f, CHAMPLAIN_PARAM_READWRITE));
+
+      initialized = TRUE;
+    }
+}
+
+
+GType
+champlain_location_get_type (void)
+{
+  static GType type = 0;
+  if (type == 0)
+    {
+      static const GTypeInfo info =
+      {
+        sizeof (ChamplainLocationIface),
+        champlain_location_base_init,          /* base_init */
+        NULL,
+      };
+      type = g_type_register_static (G_TYPE_INTERFACE,
+                                     "ChamplainLocation", &info, 0);
+    }
+  return type;
+}
+
+
+/**
+ * champlain_location_set_position:
+ * @marker: a #ChamplainMarker
+ * @latitude: the longitude to center the map at
+ * @longitude: the longitude to center the map at
+ *
+ * Positions the marker on the map at the coordinates
+ *
+ * Since: 0.10
+ */
+void 
+champlain_location_set_position (ChamplainLocation *location,
+    gdouble latitude,
+    gdouble longitude)
+{
+  CHAMPLAIN_LOCATION_GET_IFACE (location)->set_position (location,
+                                                         latitude,
+                                                         longitude);
+}
+
+
+/**
+ * champlain_location_get_latitude:
+ * @marker: a #ChamplainMarker
+ *
+ * Gets the latitude of the marker.
+ *
+ * Returns: the latitude of the marker.
+ *
+ * Since: 0.10
+ */
+gdouble 
+champlain_location_get_latitude (ChamplainLocation *location)
+{
+  return CHAMPLAIN_LOCATION_GET_IFACE (location)->get_latitude (location);
+}
+
+
+/**
+ * champlain_location_get_longitude:
+ * @marker: a #ChamplainMarker
+ *
+ * Gets the longitude of the marker.
+ *
+ * Returns: the longitude of the marker.
+ *
+ * Since: 0.10
+ */
+gdouble 
+champlain_location_get_longitude (ChamplainLocation *location)
+{
+  return CHAMPLAIN_LOCATION_GET_IFACE (location)->get_longitude (location);
+}
+
diff --git a/champlain/champlain-location.h b/champlain/champlain-location.h
new file mode 100644
index 0000000..9c5756c
--- /dev/null
+++ b/champlain/champlain-location.h
@@ -0,0 +1,38 @@
+
+#ifndef __CHAMPLAIN_LOCATION_H__
+#define __CHAMPLAIN_LOCATION_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define CHAMPLAIN_TYPE_LOCATION            (champlain_location_get_type ())
+#define CHAMPLAIN_LOCATION(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), CHAMPLAIN_TYPE_LOCATION, ChamplainLocation))
+#define CHAMPLAIN_IS_LOCATION(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CHAMPLAIN_TYPE_LOCATION))
+#define CHAMPLAIN_LOCATION_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), CHAMPLAIN_TYPE_LOCATION, ChamplainLocationIface))
+
+typedef struct _ChamplainLocation ChamplainLocation; /* Dummy object */
+typedef struct _ChamplainLocationIface ChamplainLocationIface;
+
+struct _ChamplainLocationIface
+{
+  GTypeInterface parent;
+
+  gdouble (* get_latitude) (ChamplainLocation *location);
+  gdouble (* get_longitude) (ChamplainLocation *location);
+  void (* set_position) (ChamplainLocation *location,
+    gdouble latitude,
+    gdouble longitude);
+};
+
+GType champlain_location_get_type (void) G_GNUC_CONST;
+
+void champlain_location_set_position (ChamplainLocation *location,
+    gdouble latitude,
+    gdouble longitude);
+gdouble champlain_location_get_latitude (ChamplainLocation *location);
+gdouble champlain_location_get_longitude (ChamplainLocation *location);
+
+G_END_DECLS
+
+#endif /* __CHAMPLAIN_LOCATION_H__ */
diff --git a/champlain/champlain-marker-layer.c b/champlain/champlain-marker-layer.c
index 70b08eb..a5cb875 100644
--- a/champlain/champlain-marker-layer.c
+++ b/champlain/champlain-marker-layer.c
@@ -601,9 +601,9 @@ set_marker_position (ChamplainMarkerLayer *layer, ChamplainMarker *marker)
 
   champlain_view_get_viewport_origin (priv->view, &origin_x, &origin_y);
   x = champlain_view_longitude_to_x (priv->view, 
-    champlain_marker_get_longitude (marker)) + origin_x;
+    champlain_location_get_longitude (CHAMPLAIN_LOCATION (marker))) + origin_x;
   y = champlain_view_latitude_to_y (priv->view, 
-    champlain_marker_get_latitude (marker)) + origin_y;
+    champlain_location_get_latitude (CHAMPLAIN_LOCATION (marker))) + origin_y;
 
   clutter_actor_set_position (CLUTTER_ACTOR (marker), x, y);
 }
@@ -629,8 +629,8 @@ marker_move_by_cb (ChamplainMarker *marker,
   ChamplainView *view = priv->view;
   gdouble x, y, lat, lon;
 
-  x = champlain_view_longitude_to_x (view, champlain_marker_get_longitude (marker));
-  y = champlain_view_latitude_to_y (view, champlain_marker_get_latitude (marker));
+  x = champlain_view_longitude_to_x (view, champlain_location_get_longitude (CHAMPLAIN_LOCATION (marker)));
+  y = champlain_view_latitude_to_y (view, champlain_location_get_latitude (CHAMPLAIN_LOCATION (marker)));
   
   x += dx;
   y += dy;
@@ -638,7 +638,7 @@ marker_move_by_cb (ChamplainMarker *marker,
   lon = champlain_view_x_to_longitude (view, x);
   lat = champlain_view_y_to_latitude (view, y);
     
-  champlain_marker_set_position (marker, lat, lon);
+  champlain_location_set_position (CHAMPLAIN_LOCATION (marker), lat, lon);
 }
 
 
@@ -1115,8 +1115,8 @@ redraw_path (ChamplainMarkerLayer *layer)
       ChamplainMarker *marker = CHAMPLAIN_MARKER (elem->data);
       gfloat x, y;
 
-      x = champlain_view_longitude_to_x (view, champlain_marker_get_longitude (marker));
-      y = champlain_view_latitude_to_y (view, champlain_marker_get_latitude (marker));
+      x = champlain_view_longitude_to_x (view, champlain_location_get_longitude (CHAMPLAIN_LOCATION (marker)));
+      y = champlain_view_latitude_to_y (view, champlain_location_get_latitude (CHAMPLAIN_LOCATION (marker)));
 
       cairo_line_to (cr, x, y);
     }
diff --git a/champlain/champlain-marker.c b/champlain/champlain-marker.c
index 95841ee..e5881af 100644
--- a/champlain/champlain-marker.c
+++ b/champlain/champlain-marker.c
@@ -27,7 +27,7 @@
  *
  * A marker is nothing more than a regular #clutteractor. You can draw on
  * it what ever you want.  Set the markers position
- * on the map using #champlain_marker_set_position.
+ * on the map using #champlain_location_set_position.
  *
  * libchamplain has a more evoluted type of markers with text and image support.
  * See #ChamplainLabel.
@@ -72,7 +72,17 @@ enum
 
 /* static guint champlain_marker_signals[LAST_SIGNAL] = { 0, }; */
 
-G_DEFINE_ABSTRACT_TYPE (ChamplainMarker, champlain_marker, CLUTTER_TYPE_ACTOR);
+static void set_position (ChamplainLocation *location,
+    gdouble latitude,
+    gdouble longitude);
+static gdouble get_latitude (ChamplainLocation *location);
+static gdouble get_longitude (ChamplainLocation *location);
+
+static void location_interface_init (ChamplainLocationIface *iface);
+
+G_DEFINE_ABSTRACT_TYPE_WITH_CODE (ChamplainMarker, champlain_marker, CLUTTER_TYPE_ACTOR,
+                         G_IMPLEMENT_INTERFACE (CHAMPLAIN_TYPE_LOCATION,
+                                                location_interface_init));
 
 #define CHAMPLAIN_MARKER_GET_PRIVATE(obj) \
   (G_TYPE_INSTANCE_GET_PRIVATE ((obj), CHAMPLAIN_TYPE_MARKER, ChamplainMarkerPrivate))
@@ -140,14 +150,14 @@ champlain_marker_set_property (GObject *object,
     case PROP_LONGITUDE:
     {
       gdouble lon = g_value_get_double (value);
-      champlain_marker_set_position (marker, priv->lat, lon);
+      set_position (CHAMPLAIN_LOCATION (marker), priv->lat, lon);
       break;
     }
 
     case PROP_LATITUDE:
     {
       gdouble lat = g_value_get_double (value);
-      champlain_marker_set_position (marker, lat, priv->lon);
+      set_position (CHAMPLAIN_LOCATION (marker), lat, priv->lon);
       break;
     }
 
@@ -179,6 +189,54 @@ champlain_marker_set_property (GObject *object,
 
 
 static void
+set_position (ChamplainLocation *location,
+    gdouble latitude,
+    gdouble longitude)
+{
+  g_return_if_fail (CHAMPLAIN_IS_MARKER (location));
+
+  ChamplainMarkerPrivate *priv = CHAMPLAIN_MARKER (location)->priv;
+
+  priv->lon = longitude;
+  priv->lat = latitude;
+
+  g_object_notify (G_OBJECT (location), "latitude");
+  g_object_notify (G_OBJECT (location), "longitude");
+}
+
+
+static gdouble
+get_latitude (ChamplainLocation *location)
+{
+  g_return_val_if_fail (CHAMPLAIN_IS_MARKER (location), 0.0);
+
+  ChamplainMarkerPrivate *priv = CHAMPLAIN_MARKER (location)->priv;
+
+  return priv->lat;
+}
+
+
+static gdouble
+get_longitude (ChamplainLocation *location)
+{
+  g_return_val_if_fail (CHAMPLAIN_IS_MARKER (location), 0.0);
+
+  ChamplainMarkerPrivate *priv = CHAMPLAIN_MARKER (location)->priv;
+
+  return priv->lon;
+}
+
+
+static void
+location_interface_init (ChamplainLocationIface *iface)
+{
+  iface->get_latitude = get_latitude;
+  iface->get_longitude = get_longitude;
+  iface->set_position = set_position;
+}
+
+
+static void
 champlain_marker_dispose (GObject *object)
 {
   G_OBJECT_CLASS (champlain_marker_parent_class)->dispose (object);
@@ -204,30 +262,6 @@ champlain_marker_class_init (ChamplainMarkerClass *marker_class)
   object_class->set_property = champlain_marker_set_property;
 
   /**
-   * ChamplainMarker:longitude:
-   *
-   * The longitude coordonate of the map
-   *
-   * Since: 0.10
-   */
-  g_object_class_install_property (object_class, PROP_LONGITUDE,
-      g_param_spec_double ("longitude", "Longitude",
-          "The longitude coordonate of the marker",
-          -180.0f, 180.0f, 0.0f, CHAMPLAIN_PARAM_READWRITE));
-
-  /**
-   * ChamplainMarker:latitude:
-   *
-   * The latitude coordonate of the map
-   *
-   * Since: 0.10
-   */
-  g_object_class_install_property (object_class, PROP_LATITUDE,
-      g_param_spec_double ("latitude", "Latitude",
-          "The latitude coordonate of the marker",
-          -90.0f, 90.0f, 0.0f, CHAMPLAIN_PARAM_READWRITE));
-
-  /**
    * ChamplainMarker:selected:
    *
    * The selected state of the marker
@@ -301,7 +335,14 @@ champlain_marker_class_init (ChamplainMarkerClass *marker_class)
     g_signal_new ("drag-finish", G_OBJECT_CLASS_TYPE (object_class),
         G_SIGNAL_RUN_LAST, 0, NULL, NULL,
         g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
-        
+
+  g_object_class_override_property (object_class,
+                                    PROP_LONGITUDE,
+                                    "longitude");
+
+  g_object_class_override_property (object_class,
+                                    PROP_LATITUDE,
+                                    "latitude");
 }
 
 
@@ -425,70 +466,6 @@ champlain_marker_init (ChamplainMarker *marker)
 }
 
 
-/**
- * champlain_marker_set_position:
- * @marker: a #ChamplainMarker
- * @latitude: the longitude to center the map at
- * @longitude: the longitude to center the map at
- *
- * Positions the marker on the map at the coordinates
- *
- * Since: 0.10
- */
-void
-champlain_marker_set_position (ChamplainMarker *marker,
-    gdouble latitude,
-    gdouble longitude)
-{
-  g_return_if_fail (CHAMPLAIN_IS_MARKER (marker));
-
-  ChamplainMarkerPrivate *priv = marker->priv;
-
-  priv->lon = longitude;
-  priv->lat = latitude;
-
-  g_object_notify (G_OBJECT (marker), "latitude");
-  g_object_notify (G_OBJECT (marker), "longitude");
-}
-
-
-/**
- * champlain_marker_get_latitude:
- * @marker: a #ChamplainMarker
- *
- * Gets the latitude of the marker.
- *
- * Returns: the latitude of the marker.
- *
- * Since: 0.10
- */
-gdouble
-champlain_marker_get_latitude (ChamplainMarker *marker)
-{
-  g_return_val_if_fail (CHAMPLAIN_IS_MARKER (marker), 0.0);
-
-  return marker->priv->lat;
-}
-
-
-/**
- * champlain_marker_get_longitude:
- * @marker: a #ChamplainMarker
- *
- * Gets the longitude of the marker.
- *
- * Returns: the longitude of the marker.
- *
- * Since: 0.10
- */
-gdouble
-champlain_marker_get_longitude (ChamplainMarker *marker)
-{
-  g_return_val_if_fail (CHAMPLAIN_IS_MARKER (marker), 0.0);
-
-  return marker->priv->lon;
-}
-
 
 /**
  * champlain_marker_set_selected:
diff --git a/champlain/champlain-marker.h b/champlain/champlain-marker.h
index 9cd7472..29b2509 100644
--- a/champlain/champlain-marker.h
+++ b/champlain/champlain-marker.h
@@ -25,6 +25,7 @@
 #define CHAMPLAIN_MARKER_H
 
 #include <champlain/champlain-defines.h>
+#include <champlain/champlain-location.h>
 
 #include <glib-object.h>
 #include <clutter/clutter.h>
@@ -69,11 +70,6 @@ struct _ChamplainMarkerClass
 GType champlain_marker_get_type (void);
 
 
-void champlain_marker_set_position (ChamplainMarker *marker,
-    gdouble latitude,
-    gdouble longitude);
-gdouble champlain_marker_get_latitude (ChamplainMarker *marker);
-gdouble champlain_marker_get_longitude (ChamplainMarker *marker);
 
 void champlain_marker_set_selectable (ChamplainMarker *marker,
     gboolean value);
diff --git a/champlain/champlain-path-layer.c b/champlain/champlain-path-layer.c
new file mode 100644
index 0000000..8d5b930
--- /dev/null
+++ b/champlain/champlain-path-layer.c
@@ -0,0 +1,1083 @@
+/*
+ * Copyright (C) 2008-2009 Pierre-Luc Beaudoin <pierre-luc pierlux com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+/**
+ * SECTION:champlain-path-layer
+ * @short_description: A container for #ChamplainLocation
+ *
+ * A ChamplainPathLayer is little more than a #ClutterContainer. It keeps the
+ * paths ordered so that they display correctly.
+ *
+ * Use #clutter_container_add to add paths to the layer and
+ * #clutter_container_remove to remove them.
+ */
+
+#include "config.h"
+
+#include "champlain-path-layer.h"
+
+#include "champlain-defines.h"
+#include "champlain-enum-types.h"
+#include "champlain-private.h"
+#include "champlain-view.h"
+#include "champlain-group.h"
+
+#include <clutter/clutter.h>
+#include <glib.h>
+
+G_DEFINE_TYPE (ChamplainPathLayer, champlain_path_layer, CHAMPLAIN_TYPE_LAYER)
+
+#define GET_PRIVATE(obj)    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), CHAMPLAIN_TYPE_PATH_LAYER, ChamplainPathLayerPrivate))
+
+enum
+{
+  /* normal signals */
+  LAST_SIGNAL
+};
+
+enum
+{
+  PROP_0,
+  PROP_CLOSED_PATH,
+  PROP_STROKE_WIDTH,
+  PROP_STROKE_COLOR,
+  PROP_FILL,
+  PROP_FILL_COLOR,
+  PROP_STROKE,
+  PROP_VISIBLE,
+};
+
+static ClutterColor DEFAULT_FILL_COLOR = { 0xcc, 0x00, 0x00, 0xaa };
+static ClutterColor DEFAULT_STROKE_COLOR = { 0xa4, 0x00, 0x00, 0xff };
+
+//static guint signals[LAST_SIGNAL] = { 0, };
+
+struct _ChamplainPathLayerPrivate
+{
+  ChamplainView *view;
+  
+  gboolean closed_path;
+  ClutterColor *stroke_color;
+  gboolean fill;
+  ClutterColor *fill_color;
+  gboolean stroke;
+  gdouble stroke_width;
+  gboolean visible;
+  
+  ClutterGroup *content_group;
+  ClutterActor *path_actor;
+  GList *nodes;
+};
+
+
+static void redraw_path (ChamplainPathLayer *layer);
+
+static void set_view (ChamplainLayer *layer,
+    ChamplainView *view);
+
+
+static void
+champlain_path_layer_get_property (GObject *object,
+    guint property_id,
+    G_GNUC_UNUSED GValue *value,
+    GParamSpec *pspec)
+{
+  ChamplainPathLayer *self = CHAMPLAIN_PATH_LAYER (object);
+  ChamplainPathLayerPrivate *priv = self->priv;
+  
+  switch (property_id)
+    {
+    case PROP_CLOSED_PATH:
+      g_value_set_boolean (value, priv->closed_path);
+      break;
+
+    case PROP_FILL:
+      g_value_set_boolean (value, priv->fill);
+      break;
+
+    case PROP_STROKE:
+      g_value_set_boolean (value, priv->stroke);
+      break;
+
+    case PROP_FILL_COLOR:
+      clutter_value_set_color (value, priv->fill_color);
+      break;
+
+    case PROP_STROKE_COLOR:
+      clutter_value_set_color (value, priv->stroke_color);
+      break;
+
+    case PROP_STROKE_WIDTH:
+      g_value_set_double (value, priv->stroke_width);
+      break;
+
+    case PROP_VISIBLE:
+      g_value_set_boolean (value, priv->visible);
+      break;
+      
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+    }
+}
+
+
+static void
+champlain_path_layer_set_property (GObject *object,
+    guint property_id,
+    G_GNUC_UNUSED const GValue *value,
+    GParamSpec *pspec)
+{
+  ChamplainPathLayer *self = CHAMPLAIN_PATH_LAYER (object);
+  ChamplainPathLayerPrivate *priv = self->priv;
+  
+  switch (property_id)
+    {
+    case PROP_CLOSED_PATH:
+      priv->closed_path = g_value_get_boolean (value);
+      break;
+
+    case PROP_FILL:
+      champlain_path_layer_set_fill (CHAMPLAIN_PATH_LAYER (object),
+          g_value_get_boolean (value));
+      break;
+
+    case PROP_STROKE:
+      champlain_path_layer_set_stroke (CHAMPLAIN_PATH_LAYER (object),
+          g_value_get_boolean (value));
+      break;
+
+    case PROP_FILL_COLOR:
+      champlain_path_layer_set_fill_color (CHAMPLAIN_PATH_LAYER (object),
+          clutter_value_get_color (value));
+      break;
+
+    case PROP_STROKE_COLOR:
+      champlain_path_layer_set_stroke_color (CHAMPLAIN_PATH_LAYER (object),
+          clutter_value_get_color (value));
+      break;
+
+    case PROP_STROKE_WIDTH:
+      champlain_path_layer_set_stroke_width (CHAMPLAIN_PATH_LAYER (object),
+          g_value_get_double (value));
+      break;
+
+    case PROP_VISIBLE:
+        champlain_path_layer_set_visible (CHAMPLAIN_PATH_LAYER (object),
+            g_value_get_boolean (value));
+      break;
+      
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+    }
+}
+
+
+static void
+paint (ClutterActor *self)
+{
+  ChamplainPathLayerPrivate *priv = GET_PRIVATE (self);
+  
+  clutter_actor_paint (CLUTTER_ACTOR (priv->content_group));
+}
+
+
+static void
+pick (ClutterActor *self, 
+    const ClutterColor *color)
+{
+  ChamplainPathLayerPrivate *priv = GET_PRIVATE (self);
+
+  CLUTTER_ACTOR_CLASS (champlain_path_layer_parent_class)->pick (self, color);
+
+  clutter_actor_paint (CLUTTER_ACTOR (priv->content_group));
+}
+
+
+static void
+get_preferred_width (ClutterActor *self,
+    gfloat for_height,
+    gfloat *min_width_p,
+    gfloat *natural_width_p)
+{
+  ChamplainPathLayerPrivate *priv = GET_PRIVATE (self);
+
+  clutter_actor_get_preferred_width (CLUTTER_ACTOR (priv->content_group),
+      for_height,
+      min_width_p,
+      natural_width_p);
+}
+
+
+static void
+get_preferred_height (ClutterActor *self,
+    gfloat for_width,
+    gfloat *min_height_p,
+    gfloat *natural_height_p)
+{
+  ChamplainPathLayerPrivate *priv = GET_PRIVATE (self);
+
+  clutter_actor_get_preferred_height (CLUTTER_ACTOR (priv->content_group),
+      for_width,
+      min_height_p,
+      natural_height_p);
+}
+
+
+static void
+allocate (ClutterActor *self,
+    const ClutterActorBox *box,
+    ClutterAllocationFlags flags)
+{
+  ClutterActorBox child_box;
+
+  ChamplainPathLayerPrivate *priv = GET_PRIVATE (self);
+
+  CLUTTER_ACTOR_CLASS (champlain_path_layer_parent_class)->allocate (self, box, flags);
+
+  child_box.x1 = 0;
+  child_box.x2 = box->x2 - box->x1;
+  child_box.y1 = 0;
+  child_box.y2 = box->y2 - box->y1;
+
+  clutter_actor_allocate (CLUTTER_ACTOR (priv->content_group), &child_box, flags);
+}
+
+
+static void
+map (ClutterActor *self)
+{
+  ChamplainPathLayerPrivate *priv = GET_PRIVATE (self);
+
+  CLUTTER_ACTOR_CLASS (champlain_path_layer_parent_class)->map (self);
+
+  clutter_actor_map (CLUTTER_ACTOR (priv->content_group));
+}
+
+
+static void
+unmap (ClutterActor *self)
+{
+  ChamplainPathLayerPrivate *priv = GET_PRIVATE (self);
+
+  CLUTTER_ACTOR_CLASS (champlain_path_layer_parent_class)->unmap (self);
+
+  clutter_actor_unmap (CLUTTER_ACTOR (priv->content_group));
+}
+
+
+
+static void
+champlain_path_layer_dispose (GObject *object)
+{
+  ChamplainPathLayer *self = CHAMPLAIN_PATH_LAYER (object);
+  ChamplainPathLayerPrivate *priv = self->priv;
+  
+  if (priv->view != NULL)
+    {
+      set_view (CHAMPLAIN_LAYER (self), NULL);
+    }
+
+  if (priv->content_group)
+    {
+      clutter_actor_unparent (CLUTTER_ACTOR (priv->content_group));
+      priv->content_group = NULL;
+    }
+
+  G_OBJECT_CLASS (champlain_path_layer_parent_class)->dispose (object);
+}
+
+
+static void
+champlain_path_layer_finalize (GObject *object)
+{
+  ChamplainPathLayer *self = CHAMPLAIN_PATH_LAYER (object);
+  ChamplainPathLayerPrivate *priv = self->priv;
+  
+  clutter_color_free (priv->stroke_color);
+  clutter_color_free (priv->fill_color);
+  g_list_free (priv->nodes);
+
+  G_OBJECT_CLASS (champlain_path_layer_parent_class)->finalize (object);
+}
+
+
+static void
+champlain_path_layer_class_init (ChamplainPathLayerClass *klass)
+{
+  ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  ChamplainLayerClass *layer_class = CHAMPLAIN_LAYER_CLASS (klass);
+
+  g_type_class_add_private (klass, sizeof (ChamplainPathLayerPrivate));
+  
+  object_class->finalize = champlain_path_layer_finalize;
+  object_class->dispose = champlain_path_layer_dispose;
+  object_class->get_property = champlain_path_layer_get_property;
+  object_class->set_property = champlain_path_layer_set_property;
+  
+  actor_class->get_preferred_width = get_preferred_width;
+  actor_class->get_preferred_height = get_preferred_height;
+  actor_class->allocate = allocate;
+  actor_class->paint = paint;
+  actor_class->pick = pick;
+  actor_class->map = map;
+  actor_class->unmap = unmap;
+  
+  layer_class->set_view = set_view;
+  
+  /**
+   * ChamplainPathLayer:closed:
+   *
+   * The shape is a closed path
+   *
+   * Since: 0.10
+   */
+  g_object_class_install_property (object_class,
+      PROP_CLOSED_PATH,
+      g_param_spec_boolean ("closed",
+          "Closed Path",
+          "The Path is Closed",
+          FALSE, CHAMPLAIN_PARAM_READWRITE));
+
+  /**
+   * ChamplainPathLayer:fill:
+   *
+   * The shape should be filled
+   *
+   * Since: 0.10
+   */
+  g_object_class_install_property (object_class,
+      PROP_FILL,
+      g_param_spec_boolean ("fill",
+          "Fill",
+          "The shape is filled",
+          FALSE, CHAMPLAIN_PARAM_READWRITE));
+
+  /**
+   * ChamplainPathLayer:stroke:
+   *
+   * The shape should be stroked
+   *
+   * Since: 0.10
+   */
+  g_object_class_install_property (object_class,
+      PROP_STROKE,
+      g_param_spec_boolean ("stroke",
+          "Stroke",
+          "The shape is stroked",
+          TRUE, CHAMPLAIN_PARAM_READWRITE));
+
+  /**
+   * ChamplainPathLayer:stroke-color:
+   *
+   * The path's stroke color
+   *
+   * Since: 0.10
+   */
+  g_object_class_install_property (object_class,
+      PROP_STROKE_COLOR,
+      clutter_param_spec_color ("stroke-color",
+          "Stroke Color",
+          "The path's stroke color",
+          &DEFAULT_STROKE_COLOR,
+          CHAMPLAIN_PARAM_READWRITE));
+
+  /**
+   * ChamplainPathLayer:fill-color:
+   *
+   * The path's fill color
+   *
+   * Since: 0.10
+   */
+  g_object_class_install_property (object_class,
+      PROP_FILL_COLOR,
+      clutter_param_spec_color ("fill-color",
+          "Fill Color",
+          "The path's fill color",
+          &DEFAULT_FILL_COLOR,
+          CHAMPLAIN_PARAM_READWRITE));
+
+  /**
+   * ChamplainPathLayer:stroke-width:
+   *
+   * The path's stroke width (in pixels)
+   *
+   * Since: 0.10
+   */
+  g_object_class_install_property (object_class,
+      PROP_STROKE_WIDTH,
+      g_param_spec_double ("stroke-width",
+          "Stroke Width",
+          "The path's stroke width",
+          0, 100.0,
+          2.0,
+          CHAMPLAIN_PARAM_READWRITE));
+
+  /**
+   * ChamplainPathLayer:visible:
+   *
+   * Wether the path is visible
+   *
+   * Since: 0.10
+   */
+  g_object_class_install_property (object_class,
+      PROP_VISIBLE,
+      g_param_spec_boolean ("visible",
+          "Visible",
+          "The path's visibility",
+          FALSE,
+          CHAMPLAIN_PARAM_READWRITE));
+
+}
+
+
+static void
+champlain_path_layer_init (ChamplainPathLayer *self)
+{
+  ChamplainPathLayerPrivate *priv;
+  
+  self->priv = GET_PRIVATE (self);
+  priv = self->priv;
+  priv->view = NULL;
+
+  priv->visible = FALSE;
+  priv->fill = FALSE;
+  priv->stroke = TRUE;
+  priv->stroke_width = 2.0;
+  priv->nodes = NULL;
+
+  priv->fill_color = clutter_color_copy (&DEFAULT_FILL_COLOR);
+  priv->stroke_color = clutter_color_copy (&DEFAULT_STROKE_COLOR);
+
+  priv->content_group = CLUTTER_GROUP (clutter_group_new ());
+  clutter_actor_set_parent (CLUTTER_ACTOR (priv->content_group), CLUTTER_ACTOR (self));
+
+  //TODO destroy + ref()
+  priv->path_actor =  clutter_cairo_texture_new (256, 256);
+  clutter_container_add_actor (CLUTTER_CONTAINER (priv->content_group), priv->path_actor);
+
+  clutter_actor_queue_relayout (CLUTTER_ACTOR (self));
+}
+
+
+/**
+ * champlain_path_layer_new:
+ * @mode: Selection mode
+ *
+ * Creates a new instance of #ChamplainPathLayer.
+ *
+ * Returns: a new #ChamplainPathLayer ready to be used as a container for the markers.
+ *
+ * Since: 0.10
+ */
+ChamplainPathLayer *
+champlain_path_layer_new ()
+{
+  return g_object_new (CHAMPLAIN_TYPE_PATH_LAYER, NULL);
+}
+
+
+
+
+static void
+position_notify (ChamplainLocation *location,
+    G_GNUC_UNUSED GParamSpec *pspec,
+    ChamplainPathLayer *layer)
+{
+  redraw_path (layer);
+}
+
+
+
+static void
+add_node (ChamplainPathLayer *layer,
+    ChamplainLocation *location,
+    gboolean append,
+    guint position)
+{
+  ChamplainPathLayerPrivate *priv = GET_PRIVATE (layer);
+
+  g_return_if_fail (CHAMPLAIN_IS_PATH_LAYER (layer));
+  g_return_if_fail (CHAMPLAIN_IS_LOCATION (location));
+
+  g_signal_connect (G_OBJECT (location), "notify::latitude",
+      G_CALLBACK (position_notify), layer);
+
+  g_object_ref_sink (location);
+
+  if (append)
+    priv->nodes = g_list_append (priv->nodes, location);
+  else  
+    priv->nodes = g_list_insert (priv->nodes, location, position);
+  redraw_path (layer);
+}
+
+
+/**
+ * champlain_path_layer_add_node:
+ * @layer: a #ChamplainPathLayer
+ * @location: a #ChamplainLocation
+ *
+ * Adds the marker to the layer.
+ *
+ * Since: 0.10
+ */
+void
+champlain_path_layer_add_node (ChamplainPathLayer *layer,
+    ChamplainLocation *location)
+{
+  g_return_if_fail (CHAMPLAIN_IS_PATH_LAYER (layer));
+  g_return_if_fail (CHAMPLAIN_IS_LOCATION (location));
+
+  add_node (layer, location, TRUE, 0);
+}
+
+
+/**
+ * champlain_path_layer_remove_all:
+ * @layer: a #ChamplainPathLayer
+ *
+ * Removes all markers from the layer.
+ *
+ * Since: 0.10
+ */
+void champlain_path_layer_remove_all (ChamplainPathLayer *layer)
+{
+  ChamplainPathLayerPrivate *priv = GET_PRIVATE (layer);
+  GList *elem;
+  
+  g_return_if_fail (CHAMPLAIN_IS_PATH_LAYER (layer));
+
+  for (elem = priv->nodes; elem != NULL; elem = elem->next)
+    {
+      GObject *node = G_OBJECT (elem->data);
+      
+      g_signal_handlers_disconnect_by_func (node,
+          G_CALLBACK (position_notify), layer);
+          
+      g_object_unref (node);
+    }
+
+  g_list_free (priv->nodes);
+  priv->nodes = NULL;
+}
+
+
+/**
+ * champlain_path_layer_get_nodes:
+ * @layer: a #ChamplainPathLayer
+ *
+ * Gets a copy of the list of all markers inserted into the layer. You should
+ * free the list but not its contents.
+ * 
+ * Returns: (transfer container) (element-type ChamplainLocation): the list
+ *
+ * Since: 0.10
+ */
+GList *
+champlain_path_layer_get_nodes (ChamplainPathLayer *layer)
+{
+  ChamplainPathLayerPrivate *priv = GET_PRIVATE (layer);
+
+  return g_list_copy (priv->nodes);
+}
+
+
+/**
+ * champlain_path_layer_remove_node:
+ * @layer: a #ChamplainPathLayer
+ * @location: a #ChamplainLocation
+ *
+ * Removes the marker from the layer.
+ *
+ * Since: 0.10
+ */
+void
+champlain_path_layer_remove_node (ChamplainPathLayer *layer,
+    ChamplainLocation *location)
+{
+  ChamplainPathLayerPrivate *priv = GET_PRIVATE (layer);
+  
+  g_return_if_fail (CHAMPLAIN_IS_PATH_LAYER (layer));
+  g_return_if_fail (CHAMPLAIN_IS_LOCATION (location));
+
+  g_signal_handlers_disconnect_by_func (G_OBJECT (location),
+      G_CALLBACK (position_notify), layer);
+
+  priv->nodes = g_list_remove (priv->nodes, location);
+  g_object_unref (location);
+  redraw_path (layer);
+}
+
+
+/**
+ * champlain_path_layer_insert_node:
+ * @layer: a #ChamplainPathLayer
+ * @location: a #ChamplainLocation
+ * @position: position in the list where the marker should be inserted
+ *
+ * Inserts a marker to the specified position.
+ *
+ * Since: 0.10
+ */
+void 
+champlain_path_layer_insert_node (ChamplainPathLayer *layer,
+    ChamplainLocation *location,
+    guint position)
+{
+  g_return_if_fail (CHAMPLAIN_IS_PATH_LAYER (layer));
+  g_return_if_fail (CHAMPLAIN_IS_LOCATION (location));
+
+  add_node (layer, location, FALSE, position);
+}
+
+
+
+
+static void
+relocate_cb (G_GNUC_UNUSED GObject *gobject,
+    ChamplainPathLayer *layer)
+{
+  g_return_if_fail (CHAMPLAIN_IS_PATH_LAYER (layer));
+    
+  redraw_path (layer);
+}
+
+
+
+static void
+redraw_path (ChamplainPathLayer *layer)
+{
+  ChamplainPathLayerPrivate *priv = layer->priv;
+  cairo_t *cr;
+  gfloat width, height;
+  GList *elem;
+  ChamplainView *view = priv->view;
+  gdouble x, y;
+  guint last_width, last_height;
+  
+  /* layer not yet added to the view */
+  if (view == NULL)
+    return;
+
+  clutter_actor_get_size (CLUTTER_ACTOR (view), &width, &height);
+
+  if (!priv->visible || width == 0.0 || height == 0.0)
+    return;
+    
+  clutter_cairo_texture_get_surface_size (CLUTTER_CAIRO_TEXTURE (priv->path_actor), &last_width, &last_height);
+
+  if ((guint)width != last_width || (guint)height != last_height)
+    {
+      clutter_cairo_texture_set_surface_size (CLUTTER_CAIRO_TEXTURE (priv->path_actor), width, height);
+    }
+
+  champlain_view_get_viewport_origin (priv->view, &x, &y);
+  clutter_actor_set_position (priv->path_actor, x, y);
+
+  cr = clutter_cairo_texture_create (CLUTTER_CAIRO_TEXTURE (priv->path_actor));
+
+  /* Clear the drawing area */
+  cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
+  cairo_rectangle (cr, 0, 0, width, height);
+  cairo_fill (cr);
+
+  cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+  for (elem = priv->nodes; elem != NULL; elem = elem->next)
+    {
+      ChamplainLocation *location = CHAMPLAIN_LOCATION (elem->data);
+      gfloat x, y;
+
+      x = champlain_view_longitude_to_x (view, champlain_location_get_longitude (location));
+      y = champlain_view_latitude_to_y (view, champlain_location_get_latitude (location));
+
+      cairo_line_to (cr, x, y);
+    }
+
+  if (priv->closed_path)
+    cairo_close_path (cr);
+
+  cairo_set_source_rgba (cr,
+      priv->fill_color->red / 255.0,
+      priv->fill_color->green / 255.0,
+      priv->fill_color->blue / 255.0,
+      priv->fill_color->alpha / 255.0);
+
+  if (priv->fill)
+    cairo_fill_preserve (cr);
+
+  cairo_set_source_rgba (cr,
+      priv->stroke_color->red / 255.0,
+      priv->stroke_color->green / 255.0,
+      priv->stroke_color->blue / 255.0,
+      priv->stroke_color->alpha / 255.0);
+
+  cairo_set_line_width (cr, priv->stroke_width);
+
+  if (priv->stroke)
+    cairo_stroke (cr);
+
+  cairo_destroy (cr);
+}
+
+
+static void
+redraw_path_cb (G_GNUC_UNUSED GObject *gobject,
+    G_GNUC_UNUSED GParamSpec *arg1,
+    ChamplainPathLayer *layer)
+{
+  redraw_path (layer);
+}
+
+
+static void 
+set_view (ChamplainLayer *layer,
+    ChamplainView *view)
+{
+  g_return_if_fail (CHAMPLAIN_IS_PATH_LAYER (layer) && (CHAMPLAIN_IS_VIEW (view) || view == NULL));
+  
+  ChamplainPathLayer *path_layer = CHAMPLAIN_PATH_LAYER (layer);
+  
+  if (path_layer->priv->view != NULL)
+    {
+      g_signal_handlers_disconnect_by_func (path_layer->priv->view,
+        G_CALLBACK (relocate_cb), path_layer);
+      g_object_unref (path_layer->priv->view);
+    }
+  
+  path_layer->priv->view = view;
+
+  if (view != NULL)
+    {
+      g_object_ref (view);
+  
+      g_signal_connect (view, "layer-relocated",
+        G_CALLBACK (relocate_cb), layer);
+
+      g_signal_connect (view, "notify::latitude",
+        G_CALLBACK (redraw_path_cb), layer);
+        
+      redraw_path (path_layer);
+    }
+}
+
+/**
+ * champlain_path_layer_get_bounding_box:
+ * @layer: a #ChamplainPathLayer
+ *
+ * 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_path_layer_get_bounding_box (ChamplainPathLayer *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)
+    {
+      ChamplainLocation *location = CHAMPLAIN_LOCATION (elem->data);
+      gdouble lat, lon;
+      
+      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;
+    }
+
+  return bbox;
+}
+
+
+/**
+ * champlain_path_layer_set_fill_color:
+ * @layer: a #ChamplainPathLayer
+ * @color: (allow-none): The path's fill color or NULL to reset to the
+ *         default color. The color parameter is copied.
+ *
+ * Set the path's fill color.
+ *
+ * Since: 0.10
+ */
+void
+champlain_path_layer_set_fill_color (ChamplainPathLayer *layer,
+    const ClutterColor *color)
+{
+  g_return_if_fail (CHAMPLAIN_IS_PATH_LAYER (layer));
+
+  ChamplainPathLayerPrivate *priv = layer->priv;
+
+  if (priv->fill_color != NULL)
+    clutter_color_free (priv->fill_color);
+
+  if (color == NULL)
+    color = &DEFAULT_FILL_COLOR;
+
+  priv->fill_color = clutter_color_copy (color);
+  g_object_notify (G_OBJECT (layer), "fill-color");
+}
+
+
+/**
+ * champlain_path_layer_set_stroke_color:
+ * @layer: a #ChamplainPathLayer
+ * @color: (allow-none): The path's stroke color or NULL to reset to the
+ *         default color. The color parameter is copied.
+ *
+ * Set the path's stroke color.
+ *
+ * Since: 0.10
+ */
+void
+champlain_path_layer_set_stroke_color (ChamplainPathLayer *layer,
+    const ClutterColor *color)
+{
+  g_return_if_fail (CHAMPLAIN_IS_PATH_LAYER (layer));
+
+  ChamplainPathLayerPrivate *priv = layer->priv;
+
+  if (priv->stroke_color != NULL)
+    clutter_color_free (priv->stroke_color);
+
+  if (color == NULL)
+    color = &DEFAULT_STROKE_COLOR;
+
+  priv->stroke_color = clutter_color_copy (color);
+  g_object_notify (G_OBJECT (layer), "stroke-color");
+}
+
+
+/**
+ * champlain_path_layer_get_fill_color:
+ * @layer: a #ChamplainPathLayer
+ *
+ * Gets the path's fill color.
+ *
+ * Returns: the path's fill color.
+ *
+ * Since: 0.10
+ */
+ClutterColor *
+champlain_path_layer_get_fill_color (ChamplainPathLayer *layer)
+{
+  g_return_val_if_fail (CHAMPLAIN_IS_PATH_LAYER (layer), NULL);
+
+  return layer->priv->fill_color;
+}
+
+
+/**
+ * champlain_path_layer_get_stroke_color:
+ * @layer: a #ChamplainPathLayer
+ *
+ * Gets the path's stroke color.
+ *
+ * Returns: the path's stroke color.
+ *
+ * Since: 0.10
+ */
+ClutterColor *
+champlain_path_layer_get_stroke_color (ChamplainPathLayer *layer)
+{
+  g_return_val_if_fail (CHAMPLAIN_IS_PATH_LAYER (layer), NULL);
+
+  return layer->priv->stroke_color;
+}
+
+
+/**
+ * champlain_path_layer_set_stroke:
+ * @layer: a #ChamplainPathLayer
+ * @value: if the path is stroked
+ *
+ * Sets the path to be stroked
+ *
+ * Since: 0.10
+ */
+void
+champlain_path_layer_set_stroke (ChamplainPathLayer *layer,
+    gboolean value)
+{
+  g_return_if_fail (CHAMPLAIN_IS_PATH_LAYER (layer));
+
+  layer->priv->stroke = value;
+  g_object_notify (G_OBJECT (layer), "stroke");
+}
+
+
+/**
+ * champlain_path_layer_get_stroke:
+ * @layer: a #ChamplainPathLayer
+ *
+ * Checks whether the path is stroked.
+ *
+ * Returns: TRUE if the path is stroked, FALSE otherwise.
+ *
+ * Since: 0.10
+ */
+gboolean
+champlain_path_layer_get_stroke (ChamplainPathLayer *layer)
+{
+  g_return_val_if_fail (CHAMPLAIN_IS_PATH_LAYER (layer), FALSE);
+
+  return layer->priv->stroke;
+}
+
+
+/**
+ * champlain_path_layer_set_fill:
+ * @layer: a #ChamplainPathLayer
+ * @value: if the path is filled
+ *
+ * Sets the path to be filled
+ *
+ * Since: 0.10
+ */
+void
+champlain_path_layer_set_fill (ChamplainPathLayer *layer,
+    gboolean value)
+{
+  g_return_if_fail (CHAMPLAIN_IS_PATH_LAYER (layer));
+
+  layer->priv->fill = value;
+  g_object_notify (G_OBJECT (layer), "fill");
+}
+
+
+/**
+ * champlain_path_layer_get_fill:
+ * @layer: a #ChamplainPathLayer
+ *
+ * Checks whether the path is filled.
+ *
+ * Returns: TRUE if the path is filled, FALSE otherwise.
+ *
+ * Since: 0.10
+ */
+gboolean
+champlain_path_layer_get_fill (ChamplainPathLayer *layer)
+{
+  g_return_val_if_fail (CHAMPLAIN_IS_PATH_LAYER (layer), FALSE);
+
+  return layer->priv->fill;
+}
+
+
+/**
+ * champlain_path_layer_set_stroke_width:
+ * @layer: a #ChamplainPathLayer
+ * @value: the width of the stroke (in pixels)
+ *
+ * Sets the width of the stroke
+ *
+ * Since: 0.10
+ */
+void
+champlain_path_layer_set_stroke_width (ChamplainPathLayer *layer,
+    gdouble value)
+{
+  g_return_if_fail (CHAMPLAIN_IS_PATH_LAYER (layer));
+
+  layer->priv->stroke_width = value;
+  g_object_notify (G_OBJECT (layer), "stroke-width");
+}
+
+
+/**
+ * champlain_path_layer_get_stroke_width:
+ * @layer: a #ChamplainPathLayer
+ *
+ * Gets the width of the stroke.
+ *
+ * Returns: the width of the stroke
+ *
+ * Since: 0.10
+ */
+gdouble
+champlain_path_layer_get_stroke_width (ChamplainPathLayer *layer)
+{
+  g_return_val_if_fail (CHAMPLAIN_IS_PATH_LAYER (layer), 0);
+
+  return layer->priv->stroke_width;
+}
+
+
+/**
+ * champlain_path_layer_set_visible:
+ * @layer: a #ChamplainPathLayer
+ * @value: TRUE to make the path visible
+ *
+ * Sets path visibility.
+ *
+ * Since: 0.10
+ */
+void
+champlain_path_layer_set_visible (ChamplainPathLayer *layer,
+    gboolean value)
+{
+  g_return_if_fail (CHAMPLAIN_IS_PATH_LAYER (layer));
+
+  layer->priv->visible = value;
+  if (value)
+    clutter_actor_show (CLUTTER_ACTOR (layer->priv->path_actor));
+  else
+    clutter_actor_hide (CLUTTER_ACTOR (layer->priv->path_actor));
+  g_object_notify (G_OBJECT (layer), "visible");
+}
+
+
+/**
+ * champlain_path_layer_get_visible:
+ * @layer: a #ChamplainPathLayer
+ *
+ * Gets path visibility.
+ *
+ * Returns: TRUE when the path is visible, FALSE otherwise
+ *
+ * Since: 0.10
+ */
+gboolean 
+champlain_path_layer_get_visible (ChamplainPathLayer *layer)
+{
+  g_return_val_if_fail (CHAMPLAIN_IS_PATH_LAYER (layer), FALSE);
+
+  return layer->priv->visible;
+}
+
diff --git a/champlain/champlain-path-layer.h b/champlain/champlain-path-layer.h
new file mode 100644
index 0000000..93744d3
--- /dev/null
+++ b/champlain/champlain-path-layer.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2008 Pierre-Luc Beaudoin <pierre-luc pierlux com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#if !defined (__CHAMPLAIN_CHAMPLAIN_H_INSIDE__) && !defined (CHAMPLAIN_COMPILATION)
+#error "Only <champlain/champlain.h> can be included directly."
+#endif
+
+#ifndef CHAMPLAIN_PATH_LAYER_H
+#define CHAMPLAIN_PATH_LAYER_H
+
+#include <champlain/champlain-defines.h>
+#include <champlain/champlain-layer.h>
+#include <champlain/champlain-location.h>
+#include <champlain/champlain-bounding-box.h>
+
+#include <glib-object.h>
+#include <clutter/clutter.h>
+
+G_BEGIN_DECLS
+
+#define CHAMPLAIN_TYPE_PATH_LAYER champlain_path_layer_get_type ()
+
+#define CHAMPLAIN_PATH_LAYER(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST ((obj), CHAMPLAIN_TYPE_PATH_LAYER, ChamplainPathLayer))
+
+#define CHAMPLAIN_PATH_LAYER_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST ((klass), CHAMPLAIN_TYPE_PATH_LAYER, ChamplainPathLayerClass))
+
+#define CHAMPLAIN_IS_PATH_LAYER(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CHAMPLAIN_TYPE_PATH_LAYER))
+
+#define CHAMPLAIN_IS_PATH_LAYER_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE ((klass), CHAMPLAIN_TYPE_PATH_LAYER))
+
+#define CHAMPLAIN_PATH_LAYER_GET_CLASS(obj) \
+  (G_TYPE_INSTANCE_GET_CLASS ((obj), CHAMPLAIN_TYPE_PATH_LAYER, ChamplainPathLayerClass))
+
+typedef struct _ChamplainPathLayerPrivate ChamplainPathLayerPrivate;
+
+typedef struct _ChamplainPathLayer ChamplainPathLayer;
+typedef struct _ChamplainPathLayerClass ChamplainPathLayerClass;
+
+
+struct _ChamplainPathLayer
+{
+  ChamplainLayer parent;
+  
+  ChamplainPathLayerPrivate *priv;
+};
+
+struct _ChamplainPathLayerClass
+{
+  ChamplainLayerClass parent_class;
+};
+
+GType champlain_path_layer_get_type (void);
+
+ChamplainPathLayer *champlain_path_layer_new (void);
+
+void champlain_path_layer_add_node (ChamplainPathLayer *layer,
+    ChamplainLocation *location);
+void champlain_path_layer_remove_node (ChamplainPathLayer *layer,
+    ChamplainLocation *location);
+void champlain_path_layer_remove_all (ChamplainPathLayer *layer);
+void champlain_path_layer_insert_node (ChamplainPathLayer *layer,
+    ChamplainLocation *location,
+    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);
+
+ClutterColor *champlain_path_layer_get_stroke_color (ChamplainPathLayer *layer);
+void champlain_path_layer_set_stroke_color (ChamplainPathLayer *layer,
+    const ClutterColor *color);
+
+gboolean champlain_path_layer_get_fill (ChamplainPathLayer *layer);
+void champlain_path_layer_set_fill (ChamplainPathLayer *layer,
+    gboolean value);
+
+gboolean champlain_path_layer_get_stroke (ChamplainPathLayer *layer);
+void champlain_path_layer_set_stroke (ChamplainPathLayer *layer,
+    gboolean value);
+
+gdouble champlain_path_layer_get_stroke_width (ChamplainPathLayer *layer);
+void champlain_path_layer_set_stroke_width (ChamplainPathLayer *layer,
+    gdouble value);
+
+gboolean champlain_path_layer_get_visible (ChamplainPathLayer *layer);
+void champlain_path_layer_set_visible (ChamplainPathLayer *layer, 
+    gboolean value);
+
+G_END_DECLS
+
+#endif
diff --git a/champlain/champlain-view.c b/champlain/champlain-view.c
index 46d2cce..5663eb5 100644
--- a/champlain/champlain-view.c
+++ b/champlain/champlain-view.c
@@ -1676,7 +1676,7 @@ champlain_view_add_layer (ChamplainView *view,
   DEBUG_LOG ()
 
   g_return_if_fail (CHAMPLAIN_IS_VIEW (view));
-  g_return_if_fail (CHAMPLAIN_IS_MARKER_LAYER (layer));
+  g_return_if_fail (CHAMPLAIN_IS_LAYER (layer));
   
   clutter_container_add_actor (CLUTTER_CONTAINER (view->priv->user_layers),
       CLUTTER_ACTOR (layer));
@@ -1701,7 +1701,7 @@ champlain_view_remove_layer (ChamplainView *view,
   DEBUG_LOG ()
 
   g_return_if_fail (CHAMPLAIN_IS_VIEW (view));
-  g_return_if_fail (CHAMPLAIN_IS_MARKER_LAYER (layer));
+  g_return_if_fail (CHAMPLAIN_IS_LAYER (layer));
 
   champlain_layer_set_view (layer, NULL);      
 
diff --git a/champlain/champlain.h b/champlain/champlain.h
index 8c878ee..a6acabf 100644
--- a/champlain/champlain.h
+++ b/champlain/champlain.h
@@ -31,8 +31,11 @@
 
 #include "champlain/champlain-layer.h"
 #include "champlain/champlain-marker-layer.h"
+#include "champlain/champlain-path-layer.h"
 #include "champlain/champlain-point.h"
 #include "champlain/champlain-custom-marker.h"
+#include "champlain/champlain-location.h"
+#include "champlain/champlain-coordinate.h"
 #include "champlain/champlain-marker.h"
 #include "champlain/champlain-label.h"
 #include "champlain/champlain-view.h"
diff --git a/demos/animated-marker.c b/demos/animated-marker.c
index 512f5e1..a87dc48 100644
--- a/demos/animated-marker.c
+++ b/demos/animated-marker.c
@@ -111,7 +111,7 @@ gps_callback (GpsCallbackData *data)
   lat += 0.005;
   lon += 0.005;
   champlain_view_center_on (data->view, lat, lon);
-  champlain_marker_set_position (data->marker, lat, lon);
+  champlain_location_set_position (CHAMPLAIN_LOCATION (data->marker), lat, lon);
   return TRUE;
 }
 
diff --git a/demos/launcher-gtk.c b/demos/launcher-gtk.c
index 764b1cc..e26ed9a 100644
--- a/demos/launcher-gtk.c
+++ b/demos/launcher-gtk.c
@@ -208,7 +208,7 @@ append_point (ChamplainMarkerLayer *layer, gdouble lon, gdouble lat)
   static ClutterColor color = { 0xa4, 0x00, 0x00, 0xff };
   
   point = champlain_point_new_full (10, &color);
-  champlain_marker_set_position (CHAMPLAIN_MARKER (point), lon, lat);
+  champlain_location_set_position (CHAMPLAIN_LOCATION (point), lon, lat);
   champlain_marker_layer_add_marker (layer, CHAMPLAIN_MARKER (point));
 }
 
diff --git a/demos/markers.c b/demos/markers.c
index bcd0b2a..7494325 100644
--- a/demos/markers.c
+++ b/demos/markers.c
@@ -37,28 +37,28 @@ create_marker_layer (G_GNUC_UNUSED ChamplainView *view)
   champlain_label_set_alignment (CHAMPLAIN_LABEL (marker), PANGO_ALIGN_RIGHT);
   champlain_label_set_color (CHAMPLAIN_LABEL (marker), &orange);
 
-  champlain_marker_set_position (CHAMPLAIN_MARKER (marker),
+  champlain_location_set_position (CHAMPLAIN_LOCATION (marker),
       45.528178, -73.563788);
   champlain_marker_layer_add_marker (layer, CHAMPLAIN_MARKER (marker));
 
   marker = champlain_label_new_from_file ("/usr/share/icons/gnome/24x24/emblems/emblem-generic.png", NULL);
   champlain_label_set_text (CHAMPLAIN_LABEL (marker), "New York");
-  champlain_marker_set_position (CHAMPLAIN_MARKER (marker), 40.77, -73.98);
+  champlain_location_set_position (CHAMPLAIN_LOCATION (marker), 40.77, -73.98);
   champlain_marker_layer_add_marker (layer, CHAMPLAIN_MARKER (marker));
 
   marker = champlain_label_new_from_file ("/usr/share/icons/gnome/24x24/emblems/emblem-important.png", NULL);
-  champlain_marker_set_position (CHAMPLAIN_MARKER (marker), 47.130885,
+  champlain_location_set_position (CHAMPLAIN_LOCATION (marker), 47.130885,
       -70.764141);
   champlain_marker_layer_add_marker (layer, CHAMPLAIN_MARKER (marker));
 
   marker = champlain_point_new ();
-  champlain_marker_set_position (CHAMPLAIN_MARKER (marker), 45.130885,
+  champlain_location_set_position (CHAMPLAIN_LOCATION (marker), 45.130885,
       -65.764141);
   champlain_marker_layer_add_marker (layer, CHAMPLAIN_MARKER (marker));
 
   marker = champlain_label_new_from_file ("/usr/share/icons/gnome/24x24/emblems/emblem-favorite.png", NULL);
   champlain_label_set_draw_background (CHAMPLAIN_LABEL (marker), FALSE);
-  champlain_marker_set_position (CHAMPLAIN_MARKER (marker), 45.41484,
+  champlain_location_set_position (CHAMPLAIN_LOCATION (marker), 45.41484,
       -71.918907);
   champlain_marker_layer_add_marker (layer, CHAMPLAIN_MARKER (marker));
   
diff --git a/demos/polygons.c b/demos/polygons.c
index 45ecab8..bfee0d7 100644
--- a/demos/polygons.c
+++ b/demos/polygons.c
@@ -67,14 +67,12 @@ make_button (char *text)
 
 
 static void
-append_point (ChamplainMarkerLayer *layer, gdouble lon, gdouble lat)
+append_point (ChamplainPathLayer *layer, gdouble lon, gdouble lat)
 {
-  ClutterActor *point;  
-  static ClutterColor color = { 0xa4, 0x00, 0x00, 0xff };
+  ChamplainCoordinate *coord;  
   
-  point = champlain_point_new_full (10, &color);
-  champlain_marker_set_position (CHAMPLAIN_MARKER (point), lon, lat);
-  champlain_marker_layer_add_marker (layer, CHAMPLAIN_MARKER (point));
+  coord = champlain_coordinate_new_full (lon, lat);
+  champlain_path_layer_add_node (layer, CHAMPLAIN_LOCATION (coord));
 }
 
 
@@ -83,7 +81,7 @@ main (int argc,
     char *argv[])
 {
   ClutterActor *actor, *stage, *buttons, *button;
-  ChamplainMarkerLayer *layer;
+  ChamplainPathLayer *layer;
   gfloat width, total_width = 0;;
 
   g_thread_init (NULL);
@@ -122,9 +120,12 @@ main (int argc,
   clutter_container_add_actor (CLUTTER_CONTAINER (stage), buttons);
 
   /* draw a line */
-  layer = champlain_marker_layer_new_full (CHAMPLAIN_SELECTION_NONE);
+  layer = champlain_path_layer_new ();
+  champlain_path_layer_set_visible (layer, FALSE);
   /* Cheap approx of Highway 10 */
-  append_point (layer, 45.4095, -73.3197);
+  int i = 0;
+  for (i = 0; i < 50000; i++)
+    append_point (layer, 45.4095 + i / 10000.0, -73.3197 + i / 10000.0);
   append_point (layer, 45.4104, -73.2846);
   append_point (layer, 45.4178, -73.2239);
   append_point (layer, 45.4176, -73.2181);
@@ -133,22 +134,20 @@ main (int argc,
   append_point (layer, 45.3994, -73.1877);
   append_point (layer, 45.4000, -73.1815);
   append_point (layer, 45.4151, -73.1218);
-  champlain_marker_layer_set_path_stroke_width (layer, 5.0);
-  champlain_marker_layer_hide_all_markers (layer);
-  champlain_marker_layer_set_path_visible (layer, TRUE);
+  champlain_path_layer_set_stroke_width (layer, 5.0);
+  champlain_path_layer_set_visible (layer, TRUE);
   champlain_view_add_layer (CHAMPLAIN_VIEW (actor), CHAMPLAIN_LAYER (layer));
 
   /* draw a path */
-  layer = champlain_marker_layer_new_full (CHAMPLAIN_SELECTION_NONE);
+  layer = champlain_path_layer_new ();
   append_point (layer, 45.1386, -73.9196);
   append_point (layer, 45.1229, -73.8991);
   append_point (layer, 45.0946, -73.9531);
   append_point (layer, 45.1085, -73.9714);
   append_point (layer, 45.1104, -73.9761);
-  g_object_set (layer, "path-closed", TRUE, NULL);
-  g_object_set (layer, "path-fill", TRUE, NULL);
-  champlain_marker_layer_hide_all_markers (layer);
-  champlain_marker_layer_set_path_visible (layer, TRUE);
+  g_object_set (layer, "closed", TRUE, NULL);
+  g_object_set (layer, "fill", TRUE, NULL);
+  champlain_path_layer_set_visible (layer, TRUE);
   champlain_view_add_layer (CHAMPLAIN_VIEW (actor), CHAMPLAIN_LAYER (layer));
 
   /* Finish initialising the map view */
diff --git a/demos/url-marker.c b/demos/url-marker.c
index 8d8c1ab..d0ac051 100644
--- a/demos/url-marker.c
+++ b/demos/url-marker.c
@@ -190,7 +190,7 @@ image_downloaded_cb (SoupSession *session,
   /* Finally create a marker with the texture */
   marker = champlain_label_new_with_image (texture);
   texture = NULL;
-  champlain_marker_set_position (CHAMPLAIN_MARKER (marker),
+  champlain_location_set_position (CHAMPLAIN_LOCATION (marker),
       marker_data->latitude, marker_data->longitude);
   champlain_marker_layer_add_marker (marker_data->layer, CHAMPLAIN_MARKER (marker));
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]