[osm-gps-map] 49/153: Imported Upstream version 0.7.0

Ross Gammon ross-guest at moszumanska.debian.org
Tue May 13 19:58:59 UTC 2014


This is an automated email from the git hooks/post-receive script.

ross-guest pushed a commit to branch master
in repository osm-gps-map.

commit a9010f5297597863981c06971c7c7758f53dead3
Author: David Paleino <dapal at debian.org>
Date:   Thu Jun 3 07:54:19 2010 +0200

    Imported Upstream version 0.7.0
---
 .gitignore                                         |    4 +-
 ChangeLog                                          |    0
 Makefile.am                                        |   31 +-
 NEWS                                               |   41 +
 autogen.sh                                         |  151 +-
 configure.ac                                       |   39 +-
 docs/Makefile.am                                   |    1 +
 docs/reference/Makefile.am                         |   95 +
 docs/reference/libosmgpsmap-docs.xml               |   38 +
 docs/reference/libosmgpsmap-overrides.txt          |    0
 docs/reference/libosmgpsmap-sections.txt           |  112 ++
 docs/reference/libosmgpsmap.types                  |    6 +
 docs/reference/version.xml.in                      |    1 +
 examples/.gitignore                                |    1 +
 examples/Makefile.am                               |   35 +
 examples/env.sh                                    |    3 +
 examples/mapviewer.c                               |  391 ++++
 examples/mapviewer.js                              |   28 +
 {python => examples}/mapviewer.py                  |   56 +-
 examples/mapviewer.ui                              |  378 ++++
 {src => examples}/poi.png                          |  Bin
 m4/.gitignore                                      |    1 +
 m4/gtk-doc.m4                                      |   61 +
 m4/introspection.m4                                |   94 +
 python/.gitignore                                  |    2 +
 python/COPYING                                     |    1 +
 python/Makefile.am                                 |   20 +-
 python/configure.ac                                |   42 +-
 python/m4/.gitignore                               |    1 +
 .../am_check_python_headers.m4}                    |   38 -
 python/osmgpsmap-compat.defs                       |  113 ++
 python/osmgpsmap.defs                              |  508 ++++--
 python/osmgpsmap.override                          |  199 ++-
 python/setup.py                                    |    9 +-
 src/.gitignore                                     |    2 +
 src/Makefile.am                                    |  134 +-
 src/main.c                                         |  318 ----
 src/osm-gps-map-compat.c                           |  163 ++
 src/osm-gps-map-compat.h                           |   27 +
 src/osm-gps-map-image.c                            |  194 ++
 src/osm-gps-map-image.h                            |   44 +
 src/osm-gps-map-layer.h                            |    2 +-
 src/osm-gps-map-osd.c                              |   35 +-
 src/osm-gps-map-point.c                            |   71 +
 src/osm-gps-map-point.h                            |   33 +
 src/osm-gps-map-source.c                           |  182 ++
 src/osm-gps-map-source.h                           |   39 +
 src/osm-gps-map-track.c                            |  241 +++
 src/osm-gps-map-track.h                            |   46 +
 src/osm-gps-map-types.h                            |   66 +-
 src/{osm-gps-map.c => osm-gps-map-widget.c}        | 1858 ++++++++++++--------
 src/osm-gps-map-widget.h                           |  117 ++
 src/osm-gps-map.h                                  |  145 +-
 53 files changed, 4400 insertions(+), 1817 deletions(-)

diff --git a/.gitignore b/.gitignore
index 7aa6331..d1b5eb8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,8 +6,11 @@
 *.deps/
 *.libs/
 *.tar.gz
+*.stamp
+*.bak
 INSTALL
 Makefile
+aclocal.m4
 autom4te.cache/
 compile
 config.guess
@@ -32,4 +35,3 @@ src/Makefile
 src/mapviewer
 stamp-h1
 ChangeLog
-
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..e69de29
diff --git a/Makefile.am b/Makefile.am
index 60d2cf3..fe5e987 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,7 +1,12 @@
 ## Process this file with automake to produce Makefile.in
-## Created by Anjuta
 
-SUBDIRS = src
+SUBDIRS = src examples docs
+DISTCHECK_CONFIGURE_FLAGS =                     \
+    --enable-gtk-doc                            \
+    --enable-maintainer-flags                   \
+    --enable-introspection
+
+ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
 
 osm_gps_mapdocdir = ${prefix}/doc/osm-gps-map
 osm_gps_mapdoc_DATA =                           \
@@ -17,21 +22,11 @@ pkgconfig_DATA = osmgpsmap.pc
 
 EXTRA_DIST = $(openstreetmap_gps_mapdoc_DATA)   \
 	osmgpsmap.pc.in                             \
-	python/Makefile.am                          \
-	python/Makefile.in                          \
-	python/acinclude.m4                         \
-	python/ChangeLog                            \
-	python/osmgpsmap.defs                       \
-	python/setup.py                             \
-	python/aclocal.m4                           \
-	python/configure                            \
-	python/osmgpsmapmodule.c                    \
-	python/mapviewer.py                         \
-	python/AUTHORS                              \
-	python/configure.ac                         \
-	python/osmgpsmap.override                   \
-	python/NEWS                                 \
-	python/README
+	gtk-doc.make		                        \
+	m4/introspection.m4                         \
+	m4/gtk-doc.m4
+
+DISTCLEANFILES = gtk-doc.make
 
 # ChangeLog generation from nautils
 distclean-local:
@@ -42,7 +37,7 @@ distclean-local:
 ChangeLog:
 	@echo Creating $@
 	@if test -d "$(srcdir)/.git"; then \
-	  (GIT_DIR=$(top_srcdir)/.git ./missing --run git log 0.5.. --stat -M -C --name-status  --date=short --no-color) | fmt --split-only > $@.tmp \
+	  (GIT_DIR=$(top_srcdir)/.git ./missing --run git log 0.6.0.. --stat -M -C --name-status  --date=short --no-color) | fmt --split-only > $@.tmp \
 	  && mv -f $@.tmp $@ \
 	  || ($(RM) $@.tmp; \
 	      echo Failed to generate ChangeLog, your ChangeLog may be outdated >&2; \
diff --git a/NEWS b/NEWS
index 4edd31c..47c2135 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,44 @@
+Changes in 0.7.0
+======================
+  * Map auto center threshold is now adjustable via the auto-center-threshold
+    property.
+  * Build fixes
+  * Provide a notify signal for tiles-queued and zoom
+  * Improvements to changing source and tile-cache after map is constructed
+  * Drawing of the gps marker can now be completely controlled by applications
+    by implementing the draw_gps_point vfunc
+  * GPS marker visibility can also be controlled using the show-gps-point property
+  * GObject introspection support
+  * Documentation using gtk-doc
+  * Gtk-3.0 compatible (builds with -DGSEAL_ENABLE)
+  * Massive improvements to the Image and Track functions and additional
+    API cleanup. This release is not ABI compatible, however it is API compatible.
+    All users are advised to update to the new API.
+    A summary of these changes, and a porting guide follow;
+     * Replace coord_t -> OsmGpsMapPoint
+     * osm_gps_map_add_image -> osm_gps_map_image_add and now returns a
+       OsmGpsMapImage * type that should be used when removing or modifying images
+     * osm_gps_map_remove_image -> osm_gps_map_image_remove and now
+       accepts this returned OsmGpsMapImage * pointer
+     * osm_gps_map_clear_images -> osm_gps_map_image_remove_all
+     * Track management is now done using the OsmGpsMapTrack object. This
+       is a wrapper around a GSList of OsmGpsMapPoints. You should keep a
+       copy of this object around. You can add single points to the track by
+       calling osm_gps_map_track_add_point, and the map will update
+       accordingly. You can change the visual appearance of the track via
+       this object properties.
+     * osm_gps_map_add_track -> osm_gps_map_track_add
+     * osm_gps_map_replace_track. Modify the OsmGpsMapTrack object instead
+     * osm_gps_map_clear_tracks -> osm_gps_map_track_remove_all
+     * The gps functions are now just convenience wrappers around an
+       internal OsmGpsMapTrack object
+     * osm_gps_map_draw_gps -> osm_gps_map_gps_add
+     * osm_gps_map_clear_gps -> osm_gps_map_gps_clear
+     * osm_gps_map_screen_to_geographic -> osm_gps_map_convert_screen_to_geographic
+     * osm_gps_map_geographic_to_screen -> osm_gps_map_convert_geographic_to_screen
+     * osm_gps_map_get_co_ordinates -> osm_gps_map_get_event_location
+     * osm_gps_map_set_mapcenter -> osm_gps_map_set_center_and_zoom
+
 Changes in 0.6.0
 ======================
   * Support libsoup-2.2 and libsoup-2.4
diff --git a/autogen.sh b/autogen.sh
index 9ab346a..cd268fb 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -4,156 +4,19 @@
 srcdir=`dirname $0`
 test -z "$srcdir" && srcdir=.
 
-DIE=0
-
-if [ -n "$GNOME2_DIR" ]; then
-	ACLOCAL_FLAGS="-I $GNOME2_DIR/share/aclocal $ACLOCAL_FLAGS"
-	LD_LIBRARY_PATH="$GNOME2_DIR/lib:$LD_LIBRARY_PATH"
-	PATH="$GNOME2_DIR/bin:$PATH"
-	export PATH
-	export LD_LIBRARY_PATH
-fi
+PKG_NAME="osm-gps-map"
+# REQUIRED_M4MACROS=introspection.m4
 
 (test -f $srcdir/configure.ac) || {
     echo -n "**Error**: Directory "\`$srcdir\'" does not look like the"
-    echo " top-level package directory"
+    echo " top-level $PKG_NAME directory"
     exit 1
 }
 
-(autoconf --version) < /dev/null > /dev/null 2>&1 || {
-  echo
-  echo "**Error**: You must have \`autoconf' installed."
-  echo "Download the appropriate package for your distribution,"
-  echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
-  DIE=1
-}
-
-(grep "^IT_PROG_INTLTOOL" $srcdir/configure.ac >/dev/null) && {
-  (intltoolize --version) < /dev/null > /dev/null 2>&1 || {
-    echo 
-    echo "**Error**: You must have \`intltool' installed."
-    echo "You can get it from:"
-    echo "  ftp://ftp.gnome.org/pub/GNOME/"
-    DIE=1
-  }
-}
-
-(grep "^AM_PROG_XML_I18N_TOOLS" $srcdir/configure.ac >/dev/null) && {
-  (xml-i18n-toolize --version) < /dev/null > /dev/null 2>&1 || {
-    echo
-    echo "**Error**: You must have \`xml-i18n-toolize' installed."
-    echo "You can get it from:"
-    echo "  ftp://ftp.gnome.org/pub/GNOME/"
-    DIE=1
-  }
-}
-
-(grep "^AM_PROG_LIBTOOL" $srcdir/configure.ac >/dev/null) && {
-  (libtool --version) < /dev/null > /dev/null 2>&1 || {
-    echo
-    echo "**Error**: You must have \`libtool' installed."
-    echo "You can get it from: ftp://ftp.gnu.org/pub/gnu/"
-    DIE=1
-  }
-}
-
-(grep "^AM_GLIB_GNU_GETTEXT" $srcdir/configure.ac >/dev/null) && {
-  (grep "sed.*POTFILES" $srcdir/configure.ac) > /dev/null || \
-  (glib-gettextize --version) < /dev/null > /dev/null 2>&1 || {
-    echo
-    echo "**Error**: You must have \`glib' installed."
-    echo "You can get it from: ftp://ftp.gtk.org/pub/gtk"
-    DIE=1
-  }
-}
-
-(automake --version) < /dev/null > /dev/null 2>&1 || {
-  echo
-  echo "**Error**: You must have \`automake' installed."
-  echo "You can get it from: ftp://ftp.gnu.org/pub/gnu/"
-  DIE=1
-  NO_AUTOMAKE=yes
+which gnome-autogen.sh || {
+	echo "You need to install gnome-common from the GNOME SVN"
+	exit 1
 }
 
+. gnome-autogen.sh --enable-gtk-doc "$@"
 
-# if no automake, don't bother testing for aclocal
-test -n "$NO_AUTOMAKE" || (aclocal --version) < /dev/null > /dev/null 2>&1 || {
-  echo
-  echo "**Error**: Missing \`aclocal'.  The version of \`automake'"
-  echo "installed doesn't appear recent enough."
-  echo "You can get automake from ftp://ftp.gnu.org/pub/gnu/"
-  DIE=1
-}
-
-if test "$DIE" -eq 1; then
-  exit 1
-fi
-
-if test -z "$*"; then
-  echo "**Warning**: I am going to run \`configure' with no arguments."
-  echo "If you wish to pass any to it, please specify them on the"
-  echo \`$0\'" command line."
-  echo
-fi
-
-case $CC in
-xlc )
-  am_opt=--include-deps;;
-esac
-
-for coin in `find $srcdir -path $srcdir/CVS -prune -o -name configure.ac -print`
-do 
-  dr=`dirname $coin`
-  if test -f $dr/NO-AUTO-GEN; then
-    echo skipping $dr -- flagged as no auto-gen
-  else
-    echo processing $dr
-    ( cd $dr
-
-      aclocalinclude="$ACLOCAL_FLAGS"
-
-      if grep "^AM_GLIB_GNU_GETTEXT" configure.ac >/dev/null; then
-	echo "Creating $dr/aclocal.m4 ..."
-	test -r $dr/aclocal.m4 || touch $dr/aclocal.m4
-	echo "Running glib-gettextize...  Ignore non-fatal messages."
-	echo "no" | glib-gettextize --force --copy
-	echo "Making $dr/aclocal.m4 writable ..."
-	test -r $dr/aclocal.m4 && chmod u+w $dr/aclocal.m4
-      fi
-      if grep "^IT_PROG_INTLTOOL" configure.ac >/dev/null; then
-        echo "Running intltoolize..."
-	intltoolize --copy --force --automake
-      fi
-      if grep "^AM_PROG_XML_I18N_TOOLS" configure.ac >/dev/null; then
-        echo "Running xml-i18n-toolize..."
-	xml-i18n-toolize --copy --force --automake
-      fi
-      if grep "^AM_PROG_LIBTOOL" configure.ac >/dev/null; then
-	if test -z "$NO_LIBTOOLIZE" ; then 
-	  echo "Running libtoolize..."
-	  libtoolize --force --copy
-	fi
-      fi
-      echo "Running aclocal $aclocalinclude ..."
-      aclocal $aclocalinclude
-      if grep "^AM_CONFIG_HEADER" configure.ac >/dev/null; then
-	echo "Running autoheader..."
-	autoheader
-      fi
-      echo "Running automake --gnu $am_opt ..."
-      automake --add-missing --gnu $am_opt
-      echo "Running autoconf ..."
-      autoconf
-    )
-  fi
-done
-
-conf_flags="--enable-maintainer-mode"
-
-if test x$NOCONFIGURE = x; then
-  echo Running $srcdir/configure $conf_flags "$@" ...
-  $srcdir/configure $conf_flags "$@" \
-  && echo Now type \`make\' to compile. || exit 1
-else
-  echo Skipping configure process.
-fi
diff --git a/configure.ac b/configure.ac
index e1168ed..b79955c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,22 +1,26 @@
-AC_INIT(osm-gps-map, 0.6.0)
-AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION)
+AC_PREREQ([2.62])
+AC_INIT([osm-gps-map],
+        [0.7.0],
+        [http://github.com/nzjrs/osm-gps-map/issues],
+        [osm-gps-map])
+AM_INIT_AUTOMAKE([1.10])
 
-AC_CONFIG_SRCDIR(osmgpsmap.pc.in)
-AM_CONFIG_HEADER(config.h)
+AC_CONFIG_HEADER([config.h])
+AC_CONFIG_SRCDIR([src/osm-gps-map.h])
+AC_CONFIG_MACRO_DIR([m4])
 
 AM_MAINTAINER_MODE
 
-AC_ISC_POSIX
-AC_PROG_CC
-AM_PROG_CC_STDC
-AC_HEADER_STDC
+AM_PROG_CC_C_O
 
 AC_LIBTOOL_WIN32_DLL
 AM_PROG_LIBTOOL
 
 m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
 
-PKG_CHECK_MODULES(OPENSTREETMAP_GPS_MAP, [gtk+-2.0 glib-2.0 >= 2.18 cairo >= 1.8])
+PKG_CHECK_MODULES(GLIB, [glib-2.0 >= 2.16])
+PKG_CHECK_MODULES(GTK, [gtk+-2.0])
+PKG_CHECK_MODULES(CAIRO, [cairo >= 1.6])
 
 PKG_CHECK_MODULES(SOUP24, libsoup-2.4,
     soup_ver=2.4, [
@@ -25,12 +29,6 @@ PKG_CHECK_MODULES(SOUP24, libsoup-2.4,
             AC_DEFINE(USE_LIBSOUP22, 1, Use libsoup 2.2 instead of libsoup-2.4 to download tiles)],
                 AC_ERROR([libsoup-2.4 (preferred) or libsoup-2.2 not found]))])
 
-OPENSTREETMAP_GPS_MAP_CFLAGS="$OPENSTREETMAP_GPS_MAP_CFLAGS $SOUP24_CFLAGS $SOUP22_CFLAGS"
-OPENSTREETMAP_GPS_MAP_LIBS="$OPENSTREETMAP_GPS_MAP_LIBS $SOUP24_LIBS $SOUP22_LIBS"
-
-AC_SUBST(OPENSTREETMAP_GPS_MAP_CFLAGS)
-AC_SUBST(OPENSTREETMAP_GPS_MAP_LIBS)
-
 AC_MSG_CHECKING([for Win32])
 case "$host" in
   *-*-mingw*)
@@ -50,15 +48,22 @@ AM_CONDITIONAL(OS_WIN32, [test $os_win32 = yes])
 # - If binary compatibility has been broken (eg removed or changed interfaces)
 #   change to C+1:0:0
 # - If the interface is the same as the previous version, change to C:R+1:A
-LT_VERSION_INFO=1:0:1
+LT_VERSION_INFO=2:0:0
 AC_SUBST(LT_VERSION_INFO)
 
-CFLAGS="$CFLAGS -Wall -Wswitch-enum"
+GTK_DOC_CHECK([1.12])
+GOBJECT_INTROSPECTION_CHECK([0.6.7])
+GNOME_COMPILE_WARNINGS([maximum])
+GNOME_MAINTAINER_MODE_DEFINES
 
 AC_OUTPUT([
 osmgpsmap.pc
 Makefile
 src/Makefile
+docs/Makefile
+examples/Makefile
+docs/reference/Makefile
+docs/reference/version.xml
 ])
 
 echo
diff --git a/docs/Makefile.am b/docs/Makefile.am
new file mode 100644
index 0000000..f3ddc22
--- /dev/null
+++ b/docs/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = reference
diff --git a/docs/reference/Makefile.am b/docs/reference/Makefile.am
new file mode 100644
index 0000000..d90ab09
--- /dev/null
+++ b/docs/reference/Makefile.am
@@ -0,0 +1,95 @@
+## Process this file with automake to produce Makefile.in
+
+# We require automake 1.6 at least.
+AUTOMAKE_OPTIONS = 1.6
+
+# This is a blank Makefile.am for using gtk-doc.
+# Copy this to your project's API docs directory and modify the variables to
+# suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples
+# of using the various options.
+
+# The name of the module, e.g. 'glib'.
+DOC_MODULE=libosmgpsmap
+
+# The top-level SGML file. You can change this if you want to.
+DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.xml
+
+# The directory containing the source code. Relative to $(srcdir).
+# gtk-doc will search all .c & .h files beneath here for inline comments
+# documenting the functions and macros.
+# e.g. DOC_SOURCE_DIR=../../../gtk
+DOC_SOURCE_DIR=../../src
+
+# Extra options to pass to gtkdoc-scangobj. Not normally needed.
+SCANGOBJ_OPTIONS=
+
+# Extra options to supply to gtkdoc-scan.
+# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED"
+SCAN_OPTIONS=
+
+# Extra options to supply to gtkdoc-mkdb.
+# e.g. MKDB_OPTIONS=--sgml-mode --output-format=xml
+MKDB_OPTIONS=--sgml-mode --output-format=xml --name-space=osm_gps_map_
+
+# Extra options to supply to gtkdoc-mktmpl
+# e.g. MKTMPL_OPTIONS=--only-section-tmpl
+MKTMPL_OPTIONS=
+
+# Extra options to supply to gtkdoc-fixref. Not normally needed.
+# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html
+FIXXREF_OPTIONS=
+
+# Add the builddir to the HTML path so that version.xml is found
+MKHTML_OPTIONS=--path="$(abs_builddir)"
+
+# Used for dependencies. The docs will be rebuilt if any of these change.
+# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h
+# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c
+HFILE_GLOB=$(top_srcdir)/src/*.h
+CFILE_GLOB=$(top_srcdir)/src/*.c
+
+# Header files to ignore when scanning.
+# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h
+IGNORE_HFILES=						\
+	converter.h
+
+# Images to copy into HTML directory.
+# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png
+HTML_IMAGES=
+
+# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE).
+# e.g. content_files=running.sgml building.sgml changes-2.0.sgml
+content_files=version.xml
+
+# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded
+# These files must be listed here *and* in content_files
+# e.g. expand_content_files=running.sgml
+expand_content_files=
+
+# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library.
+# Only needed if you are using gtkdoc-scangobj to dynamically query widget
+# signals and properties.
+# e.g. INCLUDES=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS)
+# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib)
+INCLUDES=-I$(top_srcdir) -I$(top_builddir) \
+	$(GLIB_CFLAGS) \
+	$(GTK_CFLAGS) \
+	$(CAIRO_CFLAGS) \
+	$(SOUP22_CFLAGS) $(SOUP24_CFLAGS)
+GTKDOC_LIBS=$(top_builddir)/src/libosmgpsmap.la \
+	$(GLIB_LIBS) \
+	$(GTK_LIBS) \
+	$(CAIRO_LIBS) \
+	$(SOUP22_LIBS) $(SOUP24_LIBS)
+
+# This includes the standard gtk-doc make rules, copied by gtkdocize.
+include $(top_srcdir)/gtk-doc.make
+
+# Other files to distribute
+# e.g. EXTRA_DIST += version.xml.in
+EXTRA_DIST += version.xml.in
+
+if ENABLE_GTK_DOC
+TESTS_ENVIRONMENT = cd $(srcdir) &&
+TESTS = $(GTKDOC_CHECK)
+endif
diff --git a/docs/reference/libosmgpsmap-docs.xml b/docs/reference/libosmgpsmap-docs.xml
new file mode 100644
index 0000000..72a446c
--- /dev/null
+++ b/docs/reference/libosmgpsmap-docs.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
+	<!ENTITY % local.common.attrib "xmlns:xi  CDATA  #FIXED 'http://www.w3.org/2003/XInclude'">
+	<!ENTITY version SYSTEM "version.xml">
+	<!ENTITY slash "/">
+]>
+<book id="index" xmlns:xi="http://www.w3.org/2003/XInclude">
+	<bookinfo>
+		<title>OsmGpsMap Reference Manual</title>
+	</bookinfo>
+
+	<chapter id="api-reference">
+		<title>API Reference</title>
+		<xi:include href="xml/osm-gps-map.xml"/>
+		<xi:include href="xml/osm-gps-map-layer.xml"/>
+		<xi:include href="xml/osm-gps-map-image.xml"/>
+		<xi:include href="xml/osm-gps-map-track.xml"/>
+		<xi:include href="xml/osm-gps-map-point.xml"/>
+	</chapter>
+
+	<chapter id="api-reference-deprecated">
+		<title>Deprecated API</title>
+		<xi:include href="xml/osm-gps-map-deprecated.xml"/>
+	</chapter>
+
+	<index id="api-index-full">
+		<title>Index of all symbols</title>
+		<xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include>
+	</index>
+	<index id="api-index-deprecated" role="deprecated">
+		<title>Index of deprecated symbols</title>
+		<xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include>
+	</index>
+	<index id="annotation-glossary">
+		<title>Annotation glossary</title>
+		<xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
+	</index>
+</book>
diff --git a/docs/reference/libosmgpsmap-overrides.txt b/docs/reference/libosmgpsmap-overrides.txt
new file mode 100644
index 0000000..e69de29
diff --git a/docs/reference/libosmgpsmap-sections.txt b/docs/reference/libosmgpsmap-sections.txt
new file mode 100644
index 0000000..ba04d98
--- /dev/null
+++ b/docs/reference/libosmgpsmap-sections.txt
@@ -0,0 +1,112 @@
+<SECTION>
+<FILE>osm-gps-map</FILE>
+<TITLE>OsmGpsMap</TITLE>
+OsmGpsMap
+OsmGpsMapClass
+OSM_GPS_MAP_INVALID
+OSM_GPS_MAP_CACHE_DISABLED
+OSM_GPS_MAP_CACHE_AUTO
+OSM_GPS_MAP_CACHE_FRIENDLY
+osm_gps_map_get_default_cache_directory
+OsmGpsMapSource_t
+osm_gps_map_source_get_friendly_name
+osm_gps_map_source_get_repo_uri
+osm_gps_map_source_get_image_format
+osm_gps_map_source_get_min_zoom
+osm_gps_map_source_get_max_zoom
+osm_gps_map_source_is_valid
+osm_gps_map_download_maps
+osm_gps_map_get_bbox
+osm_gps_map_set_center
+osm_gps_map_set_center_and_zoom
+osm_gps_map_set_zoom
+osm_gps_map_zoom_in
+osm_gps_map_zoom_out
+osm_gps_map_scroll
+osm_gps_map_get_scale
+OsmGpsMapKey_t
+osm_gps_map_set_keyboard_shortcut
+osm_gps_map_get_event_location
+osm_gps_map_convert_geographic_to_screen
+osm_gps_map_convert_screen_to_geographic
+osm_gps_map_gps_add
+osm_gps_map_gps_clear
+osm_gps_map_gps_get_track
+osm_gps_map_track_add
+osm_gps_map_track_remove
+osm_gps_map_track_remove_all
+osm_gps_map_image_add
+osm_gps_map_image_add_with_alignment
+osm_gps_map_image_remove
+osm_gps_map_image_remove_all
+osm_gps_map_layer_add
+osm_gps_map_layer_remove
+osm_gps_map_layer_remove_all
+</SECTION>
+
+<SECTION>
+<FILE>osm-gps-map-deprecated</FILE>
+<TITLE>OsmGpsMap Deprecated</TITLE>
+osm_gps_map_draw_gps
+osm_gps_map_clear_gps
+osm_gps_map_add_track
+osm_gps_map_replace_track
+osm_gps_map_clear_tracks
+osm_gps_map_add_image
+osm_gps_map_add_image_with_alignment
+osm_gps_map_remove_image
+osm_gps_map_clear_images
+osm_gps_map_add_layer
+osm_gps_map_get_co_ordinates
+osm_gps_map_screen_to_geographic
+osm_gps_map_geographic_to_screen
+osm_gps_map_set_mapcenter
+</SECTION>
+
+<SECTION>
+<FILE>osm-gps-map-layer</FILE>
+<TITLE>OsmGpsMapLayer</TITLE>
+OsmGpsMapLayer
+OsmGpsMapLayerClass
+osm_gps_map_layer_render
+osm_gps_map_layer_draw
+osm_gps_map_layer_busy
+osm_gps_map_layer_button_press
+OsmGpsMapOsd
+OsmGpsMapOsdClass
+osm_gps_map_osd_new
+</SECTION>
+
+<SECTION>
+<FILE>osm-gps-map-image</FILE>
+<TITLE>OsmGpsMapImage</TITLE>
+OsmGpsMapImage
+OsmGpsMapImageClass
+osm_gps_map_image_draw
+osm_gps_map_image_get_point
+osm_gps_map_image_get_type
+osm_gps_map_image_new
+</SECTION>
+
+<SECTION>
+<FILE>osm-gps-map-point</FILE>
+<TITLE>OsmGpsMapPoint</TITLE>
+OsmGpsMapPoint
+osm_gps_map_point_get_degrees
+osm_gps_map_point_get_radians
+osm_gps_map_point_new_degrees
+osm_gps_map_point_new_radians
+osm_gps_map_point_set_degrees
+osm_gps_map_point_set_radians
+</SECTION>
+
+<SECTION>
+<FILE>osm-gps-map-track</FILE>
+<TITLE>OsmGpsMapTrack</TITLE>
+OsmGpsMapTrack
+OsmGpsMapTrackClass
+osm_gps_map_track_add_point
+osm_gps_map_track_get_color
+osm_gps_map_track_get_points
+osm_gps_map_track_new
+</SECTION>
diff --git a/docs/reference/libosmgpsmap.types b/docs/reference/libosmgpsmap.types
new file mode 100644
index 0000000..d6e0d78
--- /dev/null
+++ b/docs/reference/libosmgpsmap.types
@@ -0,0 +1,6 @@
+osm_gps_map_get_type
+osm_gps_map_layer_get_type
+osm_gps_map_osd_get_type
+osm_gps_map_image_get_type
+osm_gps_map_track_get_type
+osm_gps_map_point_get_type
diff --git a/docs/reference/version.xml.in b/docs/reference/version.xml.in
new file mode 100644
index 0000000..fde90a0
--- /dev/null
+++ b/docs/reference/version.xml.in
@@ -0,0 +1 @@
+ at AC_PACKAGE_VERSION@
diff --git a/examples/.gitignore b/examples/.gitignore
new file mode 100644
index 0000000..055a5eb
--- /dev/null
+++ b/examples/.gitignore
@@ -0,0 +1 @@
+mapviewer
diff --git a/examples/Makefile.am b/examples/Makefile.am
new file mode 100644
index 0000000..5fc0bf5
--- /dev/null
+++ b/examples/Makefile.am
@@ -0,0 +1,35 @@
+## Process this file with automake to produce Makefile.in
+
+OSMGPSMAP_CFLAGS =          \
+	$(GLIB_CFLAGS)          \
+	$(GTK_CFLAGS)           \
+	$(CAIRO_CFLAGS)         \
+	$(SOUP22_CFLAGS)        \
+    $(SOUP24_CFLAGS)
+
+OSMGPSMAP_LIBS =            \
+    $(GLIB_LIBS)            \
+    $(GTK_LIBS)             \
+    $(CAIRO_LIBS)           \
+    $(SOUP22_LIBS)          \
+    $(SOUP24_LIBS)
+
+## Demo Application
+bin_PROGRAMS = mapviewer
+
+mapviewer_SOURCES =         \
+	mapviewer.c
+
+mapviewer_CFLAGS =          \
+    -I$(top_srcdir)/src     \
+    $(WARN_CFLAGS)          \
+    $(DISABLE_DEPRECATED)   \
+    $(OSMGPSMAP_CFLAGS)
+
+mapviewer_LDADD =           \
+    $(OSMGPSMAP_LIBS)       \
+	$(top_builddir)/src/libosmgpsmap.la
+
+## Misc
+EXTRA_DIST = poi.png mapviewer.ui mapviewer.js
+
diff --git a/examples/env.sh b/examples/env.sh
new file mode 100644
index 0000000..4b7566d
--- /dev/null
+++ b/examples/env.sh
@@ -0,0 +1,3 @@
+export LD_LIBRARY_PATH=../src/.libs/
+export GI_TYPELIB_PATH=$GI_TYPELIB_PATH:../src/
+export PYTHONPATH=../python/
diff --git a/examples/mapviewer.c b/examples/mapviewer.c
new file mode 100644
index 0000000..fe4c80c
--- /dev/null
+++ b/examples/mapviewer.c
@@ -0,0 +1,391 @@
+/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 4 -*- */
+/* vim:set et sw=4 ts=4 cino=t0,(0: */
+/*
+ * main.c
+ * Copyright (C) John Stowers 2008 <john.stowers at gmail.com>
+ *
+ * This is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2.
+ *
+ * This program 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 General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include <math.h>
+#include <glib.h>
+#include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
+
+#include "osm-gps-map.h"
+
+static OsmGpsMapSource_t opt_map_provider = OSM_GPS_MAP_SOURCE_OPENSTREETMAP;
+static gboolean opt_default_cache = FALSE;
+static gboolean opt_no_cache = FALSE;
+static gboolean opt_debug = FALSE;
+static char *opt_cache_base_dir = NULL;
+static GOptionEntry entries[] =
+{
+  { "default-cache", 'D', 0, G_OPTION_ARG_NONE, &opt_default_cache, "Store maps using default cache style (md5)", NULL },
+  { "no-cache", 'n', 0, G_OPTION_ARG_NONE, &opt_no_cache, "Disable cache", NULL },
+  { "cache-basedir", 'b', 0, G_OPTION_ARG_FILENAME, &opt_cache_base_dir, "Cache basedir", NULL },
+  { "debug", 'd', 0, G_OPTION_ARG_NONE, &opt_debug, "Enable debugging", NULL },
+  { "map", 'm', 0, G_OPTION_ARG_INT, &opt_map_provider, "Map source", "N" },
+  { NULL }
+};
+
+static GdkPixbuf *g_star_image = NULL;
+static OsmGpsMapImage *g_last_image = NULL;
+
+static gboolean
+on_button_press_event (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
+{
+    OsmGpsMapPoint coord;
+    float lat, lon;
+    OsmGpsMap *map = OSM_GPS_MAP(widget);
+    OsmGpsMapTrack *othertrack = OSM_GPS_MAP_TRACK(user_data);
+
+    if (event->type == GDK_3BUTTON_PRESS) {
+        if (event->button == 1) {
+            if (g_last_image)
+                osm_gps_map_image_remove (map, g_last_image);
+        }
+        if (event->button == 3) {
+            osm_gps_map_track_remove(map, othertrack);
+        }
+    }
+
+    if (event->type == GDK_2BUTTON_PRESS) {
+        osm_gps_map_convert_screen_to_geographic(map, event->x, event->y, &coord);
+        osm_gps_map_point_get_degrees(&coord, &lat, &lon);
+        if (event->button == 1) {
+            osm_gps_map_gps_add (map,
+                                 lat,
+                                 lon,
+                                 g_random_double_range(0,360));
+        }
+        if (event->button == 3) {
+            OsmGpsMapPoint *pt = g_boxed_copy(OSM_TYPE_GPS_MAP_POINT, &coord);
+            osm_gps_map_track_add_point(othertrack, pt);
+        }
+    }
+
+    if (event->type == GDK_BUTTON_PRESS) {
+        if (event->button == 2) {
+        osm_gps_map_convert_screen_to_geographic(map, event->x, event->y, &coord);
+        osm_gps_map_point_get_degrees(&coord, &lat, &lon);
+            g_last_image = osm_gps_map_image_add (
+                                    map,
+                                    lat,
+                                    lon,
+                                    g_star_image);
+        }
+    }
+    return FALSE;
+}
+
+static gboolean
+on_button_release_event (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
+{
+    float lat,lon;
+    GtkEntry *entry = GTK_ENTRY(user_data);
+    OsmGpsMap *map = OSM_GPS_MAP(widget);
+
+    g_object_get(map, "latitude", &lat, "longitude", &lon, NULL);
+    gchar *msg = g_strdup_printf("%f,%f",lat,lon);
+    gtk_entry_set_text(entry, msg);
+    g_free(msg);
+
+    return FALSE;
+}
+
+static gboolean
+on_zoom_in_clicked_event (GtkWidget *widget, gpointer user_data)
+{
+    int zoom;
+    OsmGpsMap *map = OSM_GPS_MAP(user_data);
+    g_object_get(map, "zoom", &zoom, NULL);
+    osm_gps_map_set_zoom(map, zoom+1);
+    return FALSE;
+}
+
+static gboolean
+on_zoom_out_clicked_event (GtkWidget *widget, gpointer user_data)
+{
+    int zoom;
+    OsmGpsMap *map = OSM_GPS_MAP(user_data);
+    g_object_get(map, "zoom", &zoom, NULL);
+    osm_gps_map_set_zoom(map, zoom-1);
+    return FALSE;
+}
+
+static gboolean
+on_home_clicked_event (GtkWidget *widget, gpointer user_data)
+{
+    OsmGpsMap *map = OSM_GPS_MAP(user_data);
+    osm_gps_map_set_center_and_zoom(map, -43.5326,172.6362,12);
+    return FALSE;
+}
+
+static gboolean
+on_cache_clicked_event (GtkWidget *widget, gpointer user_data)
+{
+    OsmGpsMap *map = OSM_GPS_MAP(user_data);
+    if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) {
+        int zoom,max_zoom;
+        OsmGpsMapPoint pt1, pt2;
+        osm_gps_map_get_bbox(map, &pt1, &pt2);
+        g_object_get(map, "zoom", &zoom, "max-zoom", &max_zoom, NULL);
+        osm_gps_map_download_maps(map, &pt1, &pt2, zoom, max_zoom);
+    } else {
+        osm_gps_map_download_cancel_all(map);
+    }
+    return FALSE;
+}
+
+static void
+on_tiles_queued_changed (OsmGpsMap *image, GParamSpec *pspec, gpointer user_data)
+{
+    gchar *s;
+    int tiles;
+    GtkLabel *label = GTK_LABEL(user_data);
+    g_object_get(image, "tiles-queued", &tiles, NULL);
+    s = g_strdup_printf("%d", tiles);
+    gtk_label_set_text(label, s);
+    g_free(s);
+}
+
+static void
+on_gps_alpha_changed (GtkAdjustment *adjustment, gpointer user_data)
+{
+    OsmGpsMap *map = OSM_GPS_MAP(user_data);
+    OsmGpsMapTrack *track = osm_gps_map_gps_get_track (map);
+    float f = gtk_adjustment_get_value(adjustment);
+    g_object_set (track, "alpha", f, NULL);}
+
+static void
+on_gps_width_changed (GtkAdjustment *adjustment, gpointer user_data)
+{
+    OsmGpsMap *map = OSM_GPS_MAP(user_data);
+    OsmGpsMapTrack *track = osm_gps_map_gps_get_track (map);
+    float f = gtk_adjustment_get_value(adjustment);
+    g_object_set (track, "line-width", f, NULL);
+}
+
+static void
+on_star_align_changed (GtkAdjustment *adjustment, gpointer user_data)
+{
+    const char *propname = user_data;
+    float f = gtk_adjustment_get_value(adjustment);
+    if (g_last_image)
+        g_object_set (g_last_image, propname, f, NULL);
+}
+
+static void
+on_gps_color_changed (GtkColorButton *widget, gpointer user_data)
+{
+    GdkColor c;
+    OsmGpsMapTrack *track = OSM_GPS_MAP_TRACK(user_data);
+    gtk_color_button_get_color (widget, &c);
+    g_object_set(track, "color", &c, NULL);
+}
+
+static void
+on_close (GtkWidget *widget, gpointer user_data)
+{
+    gtk_widget_destroy(widget);
+    gtk_main_quit();
+}
+
+static void
+usage (GOptionContext *context)
+{
+    int i;
+
+    puts(g_option_context_get_help(context, TRUE, NULL));
+
+    printf("Valid map sources:\n");
+    for(i=OSM_GPS_MAP_SOURCE_NULL; i <= OSM_GPS_MAP_SOURCE_LAST; i++)
+    {
+        const char *name = osm_gps_map_source_get_friendly_name(i);
+        const char *uri = osm_gps_map_source_get_repo_uri(i);
+        if (uri != NULL)
+            printf("\t%d:\t%s\n",i,name);
+    }
+}
+
+int
+main (int argc, char **argv)
+{
+    GtkBuilder *builder;
+    GtkWidget *widget;
+    OsmGpsMap *map;
+    OsmGpsMapLayer *osd;
+    OsmGpsMapTrack *rightclicktrack;
+    const char *repo_uri;
+    const char *friendly_name;
+    char *cachedir, *cachebasedir;
+    GError *error = NULL;
+    GOptionContext *context;
+
+    g_thread_init(NULL);
+    gtk_init (&argc, &argv);
+
+    context = g_option_context_new ("- Map browser");
+    g_option_context_set_help_enabled(context, FALSE);
+    g_option_context_add_main_entries (context, entries, NULL);
+
+    if (!g_option_context_parse (context, &argc, &argv, &error)) {
+        usage(context);
+        return 1;
+    }
+
+    /* Only use the repo_uri to check if the user has supplied a
+    valid map source ID */
+    repo_uri = osm_gps_map_source_get_repo_uri(opt_map_provider);
+    if ( repo_uri == NULL ) {
+        usage(context);
+        return 2;
+    }
+
+    friendly_name = osm_gps_map_source_get_friendly_name(opt_map_provider);
+    cachebasedir = osm_gps_map_get_default_cache_directory();
+
+    if (opt_cache_base_dir && g_file_test(opt_cache_base_dir, G_FILE_TEST_IS_DIR)) {
+        cachedir = g_strdup(OSM_GPS_MAP_CACHE_AUTO);
+        cachebasedir = g_strdup(opt_cache_base_dir);
+    } else if (opt_default_cache) {
+        cachedir = g_strdup(OSM_GPS_MAP_CACHE_AUTO);
+    } else if (opt_no_cache) {
+        cachedir = g_strdup(OSM_GPS_MAP_CACHE_DISABLED);
+    } else {
+        cachedir = g_build_filename(cachebasedir,friendly_name,NULL);
+    }
+
+    if (opt_debug)
+        gdk_window_set_debug_updates(TRUE);
+
+    g_debug("Map Cache Dir: %s", cachedir);
+    g_debug("Map Provider: %s (%d)", friendly_name, opt_map_provider);
+
+    map = g_object_new (OSM_TYPE_GPS_MAP,
+                        "map-source",opt_map_provider,
+                        "tile-cache",cachedir,
+                        "tile-cache-base", cachebasedir,
+                        "proxy-uri",g_getenv("http_proxy"),
+                        NULL);
+
+    osd = g_object_new (OSM_TYPE_GPS_MAP_OSD,
+                        "show-scale",TRUE,
+                        "show-coordinates",TRUE,
+                        "show-crosshair",TRUE,
+                        "show-dpad",TRUE,
+                        "show-zoom",TRUE,
+                        "show-gps-in-dpad",TRUE,
+                        "show-gps-in-zoom",FALSE,
+                        "dpad-radius", 30,
+                        NULL);
+    osm_gps_map_layer_add(OSM_GPS_MAP(map), osd);
+    g_object_unref(G_OBJECT(osd));
+
+    //Add a second track for right clicks
+    rightclicktrack = osm_gps_map_track_new();
+    osm_gps_map_track_add(OSM_GPS_MAP(map), rightclicktrack);
+
+    g_free(cachedir);
+    g_free(cachebasedir);
+
+    //Enable keyboard navigation
+    osm_gps_map_set_keyboard_shortcut(map, OSM_GPS_MAP_KEY_FULLSCREEN, GDK_F11);
+    osm_gps_map_set_keyboard_shortcut(map, OSM_GPS_MAP_KEY_UP, GDK_Up);
+    osm_gps_map_set_keyboard_shortcut(map, OSM_GPS_MAP_KEY_DOWN, GDK_Down);
+    osm_gps_map_set_keyboard_shortcut(map, OSM_GPS_MAP_KEY_LEFT, GDK_Left);
+    osm_gps_map_set_keyboard_shortcut(map, OSM_GPS_MAP_KEY_RIGHT, GDK_Right);
+
+    //Build the UI
+    g_star_image = gdk_pixbuf_new_from_file_at_size ("poi.png", 24,24,NULL);
+
+    builder = gtk_builder_new();
+    gtk_builder_add_from_file (builder, "mapviewer.ui", &error);
+    if (error)
+        g_error ("ERROR: %s\n", error->message);
+
+    gtk_box_pack_start (
+                GTK_BOX(gtk_builder_get_object(builder, "map_box")),
+                GTK_WIDGET(map), TRUE, TRUE, 0);
+
+    //Init values
+    float lw,a;
+    GdkColor c;
+    OsmGpsMapTrack *gpstrack = osm_gps_map_gps_get_track (map);
+    g_object_get (gpstrack, "line-width", &lw, "alpha", &a, NULL);
+    osm_gps_map_track_get_color(gpstrack, &c);
+    gtk_adjustment_set_value (
+                GTK_ADJUSTMENT(gtk_builder_get_object(builder, "gps_width_adjustment")),
+                lw);
+    gtk_adjustment_set_value (
+                GTK_ADJUSTMENT(gtk_builder_get_object(builder, "gps_alpha_adjustment")),
+                a);
+    gtk_adjustment_set_value (
+                GTK_ADJUSTMENT(gtk_builder_get_object(builder, "star_xalign_adjustment")),
+                0.5);
+    gtk_adjustment_set_value (
+                GTK_ADJUSTMENT(gtk_builder_get_object(builder, "star_yalign_adjustment")),
+                0.5);
+    gtk_color_button_set_color (
+                GTK_COLOR_BUTTON(gtk_builder_get_object(builder, "gps_colorbutton")),
+                &c);
+
+    //Connect to signals
+    g_signal_connect (
+                gtk_builder_get_object(builder, "zoom_in_button"), "clicked",
+                G_CALLBACK (on_zoom_in_clicked_event), (gpointer) map);
+    g_signal_connect (
+                gtk_builder_get_object(builder, "zoom_out_button"), "clicked",
+                G_CALLBACK (on_zoom_out_clicked_event), (gpointer) map);
+    g_signal_connect (
+                gtk_builder_get_object(builder, "home_button"), "clicked",
+                G_CALLBACK (on_home_clicked_event), (gpointer) map);
+    g_signal_connect (
+                gtk_builder_get_object(builder, "cache_button"), "clicked",
+                G_CALLBACK (on_cache_clicked_event), (gpointer) map);
+    g_signal_connect (
+                gtk_builder_get_object(builder, "gps_alpha_adjustment"), "value-changed",
+                G_CALLBACK (on_gps_alpha_changed), (gpointer) map);
+    g_signal_connect (
+                gtk_builder_get_object(builder, "gps_width_adjustment"), "value-changed",
+                G_CALLBACK (on_gps_width_changed), (gpointer) map);
+    g_signal_connect (
+                gtk_builder_get_object(builder, "star_xalign_adjustment"), "value-changed",
+                G_CALLBACK (on_star_align_changed), (gpointer) "x-align");
+    g_signal_connect (
+                gtk_builder_get_object(builder, "star_yalign_adjustment"), "value-changed",
+                G_CALLBACK (on_star_align_changed), (gpointer) "y-align");
+    g_signal_connect (
+                gtk_builder_get_object(builder, "gps_colorbutton"), "color-set",
+                G_CALLBACK (on_gps_color_changed), (gpointer) gpstrack);
+    g_signal_connect (G_OBJECT (map), "button-press-event",
+                G_CALLBACK (on_button_press_event), (gpointer) rightclicktrack);
+    g_signal_connect (G_OBJECT (map), "button-release-event",
+                G_CALLBACK (on_button_release_event),
+                (gpointer) gtk_builder_get_object(builder, "text_entry"));
+    g_signal_connect (G_OBJECT (map), "notify::tiles-queued",
+                G_CALLBACK (on_tiles_queued_changed),
+                (gpointer) gtk_builder_get_object(builder, "cache_label"));
+
+    widget = GTK_WIDGET(gtk_builder_get_object(builder, "window1"));
+    g_signal_connect (widget, "destroy",
+                      G_CALLBACK (on_close), (gpointer) map);
+    gtk_widget_show_all (widget);
+
+    g_log_set_handler ("OsmGpsMap", G_LOG_LEVEL_MASK, g_log_default_handler, NULL);
+    gtk_main ();
+
+    return 0;
+}
diff --git a/examples/mapviewer.js b/examples/mapviewer.js
new file mode 100755
index 0000000..3ee688b
--- /dev/null
+++ b/examples/mapviewer.js
@@ -0,0 +1,28 @@
+#!/usr/bin/seed
+
+const Gtk = imports.gi.Gtk;
+const Osm = imports.gi.OsmGpsMap;
+
+Gtk.init(0, null);
+
+var win = new Gtk.Window({ type: Gtk.WindowType.TOPLEVEL });
+win.set_border_width(10);
+win.set_default_size(400,400);
+
+// Fuck you GNOME
+// GJS makes me do this
+//win.connect("delete-event", Gtk.main_quit);
+// Seed makes me do this
+win.signal.delete_event.connect(Gtk.main_quit);
+
+var map = new Osm.OsmGpsMap()
+var osd = new Osm.Osd()
+
+map.layer_add(osd)
+win.add(map);
+
+win.show_all();
+
+Gtk.main();
+
+
diff --git a/python/mapviewer.py b/examples/mapviewer.py
similarity index 83%
rename from python/mapviewer.py
rename to examples/mapviewer.py
index efc25eb..ecfea18 100755
--- a/python/mapviewer.py
+++ b/examples/mapviewer.py
@@ -17,7 +17,6 @@ You should have received a copy of the GNU General Public License
 along with this program; if not, see <http://www.gnu.org/licenses/>.
 """
 
-import math
 import sys
 import os.path
 import gtk.gdk
@@ -28,11 +27,16 @@ gtk.gdk.threads_init()
 
 #Try static lib first
 mydir = os.path.dirname(os.path.abspath(__file__))
-libdir = os.path.join(mydir, ".libs")
+libdir = os.path.abspath(os.path.join(mydir, "..", "python", ".libs"))
 sys.path.insert(0, libdir)
 
 import osmgpsmap
-print "using library: %s" % osmgpsmap.__file__
+print "using library: %s (version %s)" % (osmgpsmap.__file__, osmgpsmap.__version__)
+
+class DummyMapNoGpsPoint(osmgpsmap.GpsMap):
+    def do_draw_gps_point(self, drawable):
+        pass
+gobject.type_register(DummyMapNoGpsPoint)
 
 class DummyLayer(gobject.GObject, osmgpsmap.GpsMapLayer):
     def __init__(self):
@@ -62,12 +66,15 @@ class UI(gtk.Window):
         self.vbox = gtk.VBox(False, 0)
         self.add(self.vbox)
 
-        self.osm = osmgpsmap.GpsMap()
-        self.osm.add_layer(
+        if 0:
+            self.osm = DummyMapNoGpsPoint()
+        else:
+            self.osm = osmgpsmap.GpsMap()
+        self.osm.layer_add(
                     osmgpsmap.GpsMapOsd(
                         show_dpad=True,
                         show_zoom=True))
-        self.osm.add_layer(
+        self.osm.layer_add(
                     DummyLayer())
 
         self.osm.connect('button_release_event', self.map_clicked)
@@ -105,9 +112,8 @@ class UI(gtk.Window):
         self.repouri_entry.set_text(self.osm.props.repo_uri)
         self.image_format_entry = gtk.Entry()
         self.image_format_entry.set_text(self.osm.props.image_format)
-        gobtn = gtk.Button("Load Map URI")
-        gobtn.connect("clicked", self.load_map_clicked)
-        exp = gtk.Label(
+
+        lbl = gtk.Label(
 """
 Enter an repository URL to fetch map tiles from in the box below. Special metacharacters may be included in this url
 
@@ -120,12 +126,12 @@ Enter an repository URL to fetch map tiles from in the box below. Special metach
 \t#W\tQuadtree encoded tile (1234)
 \t#U\tEncoding not implemeted
 \t#R\tRandom integer, 0-4""")
-        exp.props.xalign = 0
-        exp.props.use_markup = True
-        exp.props.wrap = True
+        lbl.props.xalign = 0
+        lbl.props.use_markup = True
+        lbl.props.wrap = True
 
         ex.add(vb)
-        vb.pack_start(exp, False)
+        vb.pack_start(lbl, False)
 
         hb = gtk.HBox()
         hb.pack_start(gtk.Label("URI: "), False)
@@ -137,14 +143,27 @@ Enter an repository URL to fetch map tiles from in the box below. Special metach
         hb.pack_start(self.image_format_entry, True)
         vb.pack_start(hb, False)
 
+        gobtn = gtk.Button("Load Map URI")
+        gobtn.connect("clicked", self.load_map_clicked)
         vb.pack_start(gobtn, False)
 
+        cb = gtk.CheckButton("Disable Cache")
+        cb.props.active = False
+        cb.connect("toggled", self.disable_cache_toggled)
+
+        self.vbox.pack_end(cb, False)
         self.vbox.pack_end(ex, False)
         self.vbox.pack_end(self.latlon_entry, False)
         self.vbox.pack_end(hbox, False)
 
         gobject.timeout_add(500, self.print_tiles)
 
+    def disable_cache_toggled(self, btn):
+        if btn.props.active:
+            self.osm.props.tile_cache = osmgpsmap.CACHE_DISABLED
+        else:
+            self.osm.props.tile_cache = osmgpsmap.CACHE_AUTO
+
     def load_map_clicked(self, button):
         uri = self.repouri_entry.get_text()
         format = self.image_format_entry.get_text()
@@ -178,7 +197,7 @@ Enter an repository URL to fetch map tiles from in the box below. Special metach
         self.osm.set_zoom(self.osm.props.zoom - 1)
 
     def home_clicked(self, button):
-        self.osm.set_mapcenter(-44.39, 171.25, 12)
+        self.osm.set_center_and_zoom(-44.39, 171.25, 12)
  
     def cache_clicked(self, button):
         bbox = self.osm.get_bbox()
@@ -197,12 +216,9 @@ Enter an repository URL to fetch map tiles from in the box below. Special metach
                 )
             )
         elif event.button == 2:
-            rlat, rlon = self.osm.get_co_ordinates(event.x, event.y)
-            self.osm.draw_gps(
-                    math.degrees(rlat),
-                    math.degrees(rlon),
-                    osmgpsmap.INVALID);
- 
+            p = self.osm.get_event_location(event)
+            lat,lon = p.get_degrees()
+            self.osm.gps_add(lat, lon, heading=osmgpsmap.INVALID);
 
 if __name__ == "__main__":
     u = UI()
diff --git a/examples/mapviewer.ui b/examples/mapviewer.ui
new file mode 100644
index 0000000..b4d095d
--- /dev/null
+++ b/examples/mapviewer.ui
@@ -0,0 +1,378 @@
+<?xml version="1.0"?>
+<interface>
+  <requires lib="gtk+" version="2.16"/>
+  <!-- interface-naming-policy project-wide -->
+  <object class="GtkWindow" id="window1">
+    <property name="default_width">400</property>
+    <property name="default_height">400</property>
+    <child>
+      <object class="GtkAlignment" id="alignment1">
+        <property name="visible">True</property>
+        <property name="top_padding">4</property>
+        <property name="bottom_padding">4</property>
+        <property name="left_padding">4</property>
+        <property name="right_padding">4</property>
+        <child>
+          <object class="GtkVBox" id="vbox1">
+            <property name="visible">True</property>
+            <property name="spacing">4</property>
+            <child>
+              <object class="GtkHBox" id="map_box">
+                <property name="visible">True</property>
+                <child>
+                  <placeholder/>
+                </child>
+              </object>
+              <packing>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkHBox" id="hbox3">
+                <property name="visible">True</property>
+                <property name="homogeneous">True</property>
+                <child>
+                  <object class="GtkButton" id="zoom_in_button">
+                    <property name="label">gtk-zoom-in</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <property name="use_stock">True</property>
+                  </object>
+                  <packing>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkButton" id="zoom_out_button">
+                    <property name="label">gtk-zoom-out</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <property name="use_stock">True</property>
+                  </object>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkButton" id="home_button">
+                    <property name="label">gtk-home</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                    <property name="use_stock">True</property>
+                  </object>
+                  <packing>
+                    <property name="position">2</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkToggleButton" id="cache_button">
+                    <property name="label" translatable="yes">Cache</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">True</property>
+                  </object>
+                  <packing>
+                    <property name="position">3</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkHBox" id="hbox2">
+                <property name="visible">True</property>
+                <property name="spacing">4</property>
+                <child>
+                  <object class="GtkEntry" id="text_entry">
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="invisible_char">&#x2022;</property>
+                  </object>
+                  <packing>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="cache_label">
+                    <property name="visible">True</property>
+                    <property name="xalign">1</property>
+                    <property name="label" translatable="yes">0</property>
+                    <property name="width_chars">5</property>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="position">2</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkExpander" id="expander1">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <child>
+                  <object class="GtkAlignment" id="alignment2">
+                    <property name="visible">True</property>
+                    <property name="left_padding">4</property>
+                    <child>
+                      <object class="GtkVBox" id="vbox2">
+                        <property name="visible">True</property>
+                        <child>
+                          <object class="GtkHBox" id="hbox1">
+                            <property name="visible">True</property>
+                            <property name="spacing">4</property>
+                            <child>
+                              <object class="GtkLabel" id="label2">
+                                <property name="visible">True</property>
+                                <property name="xalign">0</property>
+                                <property name="label" translatable="yes">Color</property>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="position">0</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkColorButton" id="gps_colorbutton">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="receives_default">True</property>
+                                <property name="color">#000000000000</property>
+                              </object>
+                              <packing>
+                                <property name="position">1</property>
+                              </packing>
+                            </child>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkHBox" id="hbox4">
+                            <property name="visible">True</property>
+                            <property name="spacing">4</property>
+                            <child>
+                              <object class="GtkLabel" id="label3">
+                                <property name="visible">True</property>
+                                <property name="xalign">0</property>
+                                <property name="label" translatable="yes">Alpha</property>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="position">0</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkHScale" id="hscale1">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="update_policy">delayed</property>
+                                <property name="adjustment">gps_alpha_adjustment</property>
+                                <property name="restrict_to_fill_level">False</property>
+                                <property name="fill_level">0</property>
+                                <property name="draw_value">False</property>
+                              </object>
+                              <packing>
+                                <property name="position">1</property>
+                              </packing>
+                            </child>
+                          </object>
+                          <packing>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkHBox" id="hbox5">
+                            <property name="visible">True</property>
+                            <property name="spacing">4</property>
+                            <child>
+                              <object class="GtkLabel" id="label4">
+                                <property name="visible">True</property>
+                                <property name="xalign">0</property>
+                                <property name="label" translatable="yes">Width</property>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="position">0</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkHScale" id="hscale2">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="update_policy">delayed</property>
+                                <property name="adjustment">gps_width_adjustment</property>
+                                <property name="restrict_to_fill_level">False</property>
+                                <property name="fill_level">0</property>
+                                <property name="draw_value">False</property>
+                              </object>
+                              <packing>
+                                <property name="position">1</property>
+                              </packing>
+                            </child>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="position">2</property>
+                          </packing>
+                        </child>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+                <child type="label">
+                  <object class="GtkLabel" id="label1">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">GPS Track Appearance</property>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="position">3</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkExpander" id="expander2">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <child>
+                  <object class="GtkAlignment" id="alignment3">
+                    <property name="visible">True</property>
+                    <property name="left_padding">4</property>
+                    <child>
+                      <object class="GtkVBox" id="vbox3">
+                        <property name="visible">True</property>
+                        <child>
+                          <object class="GtkHBox" id="hbox6">
+                            <property name="visible">True</property>
+                            <property name="spacing">4</property>
+                            <child>
+                              <object class="GtkLabel" id="label6">
+                                <property name="visible">True</property>
+                                <property name="xalign">0</property>
+                                <property name="label" translatable="yes">X Offset</property>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="position">0</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkHScale" id="hscale3">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="update_policy">delayed</property>
+                                <property name="adjustment">star_xalign_adjustment</property>
+                                <property name="restrict_to_fill_level">False</property>
+                                <property name="fill_level">0</property>
+                                <property name="draw_value">False</property>
+                              </object>
+                              <packing>
+                                <property name="position">1</property>
+                              </packing>
+                            </child>
+                          </object>
+                          <packing>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <object class="GtkHBox" id="hbox7">
+                            <property name="visible">True</property>
+                            <property name="spacing">4</property>
+                            <child>
+                              <object class="GtkLabel" id="label7">
+                                <property name="visible">True</property>
+                                <property name="xalign">0</property>
+                                <property name="label" translatable="yes">Y Offset</property>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="position">0</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkHScale" id="hscale4">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="update_policy">delayed</property>
+                                <property name="adjustment">star_yalign_adjustment</property>
+                                <property name="restrict_to_fill_level">False</property>
+                                <property name="fill_level">0</property>
+                                <property name="draw_value">False</property>
+                              </object>
+                              <packing>
+                                <property name="position">1</property>
+                              </packing>
+                            </child>
+                          </object>
+                          <packing>
+                            <property name="position">1</property>
+                          </packing>
+                        </child>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+                <child type="label">
+                  <object class="GtkLabel" id="label5">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">Star Image Appearance</property>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="position">4</property>
+              </packing>
+            </child>
+          </object>
+        </child>
+      </object>
+    </child>
+  </object>
+  <object class="GtkAdjustment" id="gps_alpha_adjustment">
+    <property name="upper">1</property>
+    <property name="step_increment">0.10000000000000001</property>
+    <property name="page_increment">0.10000000000000001</property>
+  </object>
+  <object class="GtkAdjustment" id="gps_width_adjustment">
+    <property name="upper">10</property>
+    <property name="step_increment">0.5</property>
+    <property name="page_increment">0.5</property>
+  </object>
+  <object class="GtkSizeGroup" id="sizegroup1">
+    <widgets>
+      <widget name="label7"/>
+      <widget name="label6"/>
+      <widget name="label4"/>
+      <widget name="label3"/>
+      <widget name="label2"/>
+    </widgets>
+  </object>
+  <object class="GtkAdjustment" id="star_xalign_adjustment">
+    <property name="value">0.5</property>
+    <property name="upper">1</property>
+    <property name="step_increment">0.10000000000000001</property>
+    <property name="page_increment">0.10000000000000001</property>
+  </object>
+  <object class="GtkAdjustment" id="star_yalign_adjustment">
+    <property name="value">0.5</property>
+    <property name="upper">1</property>
+    <property name="step_increment">0.10000000000000001</property>
+    <property name="page_increment">0.10000000000000001</property>
+  </object>
+</interface>
diff --git a/src/poi.png b/examples/poi.png
similarity index 100%
rename from src/poi.png
rename to examples/poi.png
diff --git a/m4/.gitignore b/m4/.gitignore
new file mode 100644
index 0000000..ab78ba9
--- /dev/null
+++ b/m4/.gitignore
@@ -0,0 +1 @@
+l*.m4
diff --git a/m4/gtk-doc.m4 b/m4/gtk-doc.m4
new file mode 100644
index 0000000..2cfa1e7
--- /dev/null
+++ b/m4/gtk-doc.m4
@@ -0,0 +1,61 @@
+dnl -*- mode: autoconf -*-
+
+# serial 1
+
+dnl Usage:
+dnl   GTK_DOC_CHECK([minimum-gtk-doc-version])
+AC_DEFUN([GTK_DOC_CHECK],
+[
+  AC_BEFORE([AC_PROG_LIBTOOL],[$0])dnl setup libtool first
+  AC_BEFORE([AM_PROG_LIBTOOL],[$0])dnl setup libtool first
+
+  dnl check for tools we added during development
+  AC_PATH_PROG([GTKDOC_CHECK],[gtkdoc-check])
+  AC_PATH_PROGS([GTKDOC_REBASE],[gtkdoc-rebase],[true])
+  AC_PATH_PROG([GTKDOC_MKPDF],[gtkdoc-mkpdf])
+
+  dnl for overriding the documentation installation directory
+  AC_ARG_WITH([html-dir],
+    AS_HELP_STRING([--with-html-dir=PATH], [path to installed docs]),,
+    [with_html_dir='${datadir}/gtk-doc/html'])
+  HTML_DIR="$with_html_dir"
+  AC_SUBST([HTML_DIR])
+
+  dnl enable/disable documentation building
+  AC_ARG_ENABLE([gtk-doc],
+    AS_HELP_STRING([--enable-gtk-doc],
+                   [use gtk-doc to build documentation [[default=no]]]),,
+    [enable_gtk_doc=no])
+
+  if test x$enable_gtk_doc = xyes; then
+    ifelse([$1],[],
+      [PKG_CHECK_EXISTS([gtk-doc],,
+                        AC_MSG_ERROR([gtk-doc not installed and --enable-gtk-doc requested]))],
+      [PKG_CHECK_EXISTS([gtk-doc >= $1],,
+                        AC_MSG_ERROR([You need to have gtk-doc >= $1 installed to build $PACKAGE_NAME]))])
+  fi
+
+  AC_MSG_CHECKING([whether to build gtk-doc documentation])
+  AC_MSG_RESULT($enable_gtk_doc)
+
+  dnl enable/disable output formats
+  AC_ARG_ENABLE([gtk-doc-html],
+    AS_HELP_STRING([--enable-gtk-doc-html],
+                   [build documentation in html format [[default=yes]]]),,
+    [enable_gtk_doc_html=yes])
+    AC_ARG_ENABLE([gtk-doc-pdf],
+      AS_HELP_STRING([--enable-gtk-doc-pdf],
+                     [build documentation in pdf format [[default=no]]]),,
+      [enable_gtk_doc_pdf=no])
+
+  if test -z "$GTKDOC_MKPDF"; then
+    enable_gtk_doc_pdf=no
+  fi
+
+
+  AM_CONDITIONAL([ENABLE_GTK_DOC], [test x$enable_gtk_doc = xyes])
+  AM_CONDITIONAL([GTK_DOC_BUILD_HTML], [test x$enable_gtk_doc_html = xyes])
+  AM_CONDITIONAL([GTK_DOC_BUILD_PDF], [test x$enable_gtk_doc_pdf = xyes])
+  AM_CONDITIONAL([GTK_DOC_USE_LIBTOOL], [test -n "$LIBTOOL"])
+  AM_CONDITIONAL([GTK_DOC_USE_REBASE], [test -n "$GTKDOC_REBASE"])
+])
diff --git a/m4/introspection.m4 b/m4/introspection.m4
new file mode 100644
index 0000000..589721c
--- /dev/null
+++ b/m4/introspection.m4
@@ -0,0 +1,94 @@
+dnl -*- mode: autoconf -*-
+dnl Copyright 2009 Johan Dahlin
+dnl
+dnl This file is free software; the author(s) gives unlimited
+dnl permission to copy and/or distribute it, with or without
+dnl modifications, as long as this notice is preserved.
+dnl
+
+# serial 1
+
+m4_define([_GOBJECT_INTROSPECTION_CHECK_INTERNAL],
+[
+    AC_BEFORE([AC_PROG_LIBTOOL],[$0])dnl setup libtool first
+    AC_BEFORE([AM_PROG_LIBTOOL],[$0])dnl setup libtool first
+    AC_BEFORE([LT_INIT],[$0])dnl setup libtool first
+
+    dnl enable/disable introspection
+    m4_if([$2], [require],
+    [dnl
+        enable_introspection=yes
+    ],[dnl
+        AC_ARG_ENABLE(introspection,
+                  AS_HELP_STRING([--enable-introspection[=@<:@no/auto/yes@:>@]],
+                                 [Enable introspection for this build]),, 
+                                 [enable_introspection=auto])
+    ])dnl
+
+    AC_MSG_CHECKING([for gobject-introspection])
+
+    dnl presence/version checking
+    AS_CASE([$enable_introspection],
+    [no], [dnl
+        found_introspection="no (disabled, use --enable-introspection to enable)"
+    ],dnl
+    [yes],[dnl
+        PKG_CHECK_EXISTS([gobject-introspection-1.0],,
+                         AC_MSG_ERROR([gobject-introspection-1.0 is not installed]))
+        PKG_CHECK_EXISTS([gobject-introspection-1.0 >= $1],
+                         found_introspection=yes,
+                         AC_MSG_ERROR([You need to have gobject-introspection >= $1 installed to build AC_PACKAGE_NAME]))
+    ],dnl
+    [auto],[dnl
+        PKG_CHECK_EXISTS([gobject-introspection-1.0 >= $1], found_introspection=yes, found_introspection=no)
+    ],dnl
+    [dnl	
+        AC_MSG_ERROR([invalid argument passed to --enable-introspection, should be one of @<:@no/auto/yes@:>@])
+    ])dnl
+
+    AC_MSG_RESULT([$found_introspection])
+
+    INTROSPECTION_SCANNER=
+    INTROSPECTION_COMPILER=
+    INTROSPECTION_GENERATE=
+    INTROSPECTION_GIRDIR=
+    INTROSPECTION_TYPELIBDIR=
+    if test "x$found_introspection" = "xyes"; then
+       INTROSPECTION_SCANNER=`$PKG_CONFIG --variable=g_ir_scanner gobject-introspection-1.0`
+       INTROSPECTION_COMPILER=`$PKG_CONFIG --variable=g_ir_compiler gobject-introspection-1.0`
+       INTROSPECTION_GENERATE=`$PKG_CONFIG --variable=g_ir_generate gobject-introspection-1.0`
+       INTROSPECTION_GIRDIR=`$PKG_CONFIG --variable=girdir gobject-introspection-1.0`
+       INTROSPECTION_TYPELIBDIR="$($PKG_CONFIG --variable=typelibdir gobject-introspection-1.0)"
+       INTROSPECTION_CFLAGS=`$PKG_CONFIG --cflags gobject-introspection-1.0`
+       INTROSPECTION_LIBS=`$PKG_CONFIG --libs gobject-introspection-1.0`
+       INTROSPECTION_MAKEFILE=`$PKG_CONFIG --variable=datadir gobject-introspection-1.0`/gobject-introspection-1.0/Makefile.introspection
+    fi
+    AC_SUBST(INTROSPECTION_SCANNER)
+    AC_SUBST(INTROSPECTION_COMPILER)
+    AC_SUBST(INTROSPECTION_GENERATE)
+    AC_SUBST(INTROSPECTION_GIRDIR)
+    AC_SUBST(INTROSPECTION_TYPELIBDIR)
+    AC_SUBST(INTROSPECTION_CFLAGS)
+    AC_SUBST(INTROSPECTION_LIBS)
+    AC_SUBST(INTROSPECTION_MAKEFILE)
+
+    AM_CONDITIONAL(HAVE_INTROSPECTION, test "x$found_introspection" = "xyes")
+])
+
+
+dnl Usage:
+dnl   GOBJECT_INTROSPECTION_CHECK([minimum-g-i-version])
+
+AC_DEFUN([GOBJECT_INTROSPECTION_CHECK],
+[
+  _GOBJECT_INTROSPECTION_CHECK_INTERNAL([$1])
+])
+
+dnl Usage:
+dnl   GOBJECT_INTROSPECTION_REQUIRE([minimum-g-i-version])
+
+
+AC_DEFUN([GOBJECT_INTROSPECTION_REQUIRE],
+[
+  _GOBJECT_INTROSPECTION_CHECK_INTERNAL([$1], [require])
+])
diff --git a/python/.gitignore b/python/.gitignore
new file mode 100644
index 0000000..3cff5b3
--- /dev/null
+++ b/python/.gitignore
@@ -0,0 +1,2 @@
+aclocal.m4
+osmgpsmap-new.defs
diff --git a/python/COPYING b/python/COPYING
new file mode 120000
index 0000000..6168a39
--- /dev/null
+++ b/python/COPYING
@@ -0,0 +1 @@
+/usr/share/automake-1.11/COPYING
\ No newline at end of file
diff --git a/python/Makefile.am b/python/Makefile.am
index e9c1e34..5128166 100644
--- a/python/Makefile.am
+++ b/python/Makefile.am
@@ -1,8 +1,11 @@
+ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
+
 defsdir = $(datadir)/pygtk/2.0/defs
-defs_DATA = osmgpsmap.defs
+defs_DATA = osmgpsmap.defs osmgpsmap-compat.defs
 
 INCLUDES = \
 	$(OSMGPSMAP_CFLAGS) \
+	$(SOUP24_CFLAGS) \
 	$(GTK_CFLAGS) \
 	$(PYGTK_CFLAGS) \
 	$(PYTHON_INCLUDES)
@@ -12,30 +15,29 @@ pkgpyexecdir = $(pyexecdir)/gtk-2.0
 
 pkgpyexec_LTLIBRARIES = osmgpsmap.la
 osmgpsmap_la_LDFLAGS = -module -avoid-version -export-symbols-regex initosmgpsmap
-osmgpsmap_la_LIBADD = $(OSMGPSMAP_LIBS) $(GTK_LIBS) $(PYGTK_LIBS)
+osmgpsmap_la_LIBADD = $(OSMGPSMAP_LIBS) $(SOUP24_LIBS) $(GTK_LIBS) $(PYGTK_LIBS)
 osmgpsmap_la_SOURCES = osmgpsmapmodule.c osmgpsmap.c
 #nodist_osmgpsmap_la_SOURCES = osmgpsmap.c
 
 CLEANFILES = osmgpsmap.c
-EXTRA_DIST = \
-	setup.py \
-	mapviewer.py \
-	osmgpsmap.override \
+EXTRA_DIST =                \
+	setup.py                \
+	osmgpsmap.override      \
 	$(defs_DATA)
 
 osmgpsmap.c: osmgpsmap.defs osmgpsmap.override
 .defs.c:
 	(cd $(srcdir)\
-	 && pygtk-codegen-2.0 \
+	 && $(PYTHON) $(CODEGENDIR)/codegen.py \
 		--register $(PYGTK_DEFSDIR)/gtk-types.defs \
-	    --register $(PYGTK_DEFSDIR)/gdk-base-types.defs \
+	    --register $(PYGTK_DEFSDIR)/gdk-types.defs \
 		--override $*.override \
 		--prefix py$* $*.defs) > gen-$*.c \
 	&& cp gen-$*.c $*.c \
 	&& rm -f gen-$*.c
 
 update-defs:
-	$(PYGTK_H2DEF) ../src/osm-gps-map.h ../src/osm-gps-map-osd.h ../src/osm-gps-map-layer.h > osmgpsmap-new.defs
+	$(PYTHON) $(CODEGENDIR)/h2def.py ../src/osm-gps-map-{widget,osd,image,layer,track,point,source}.h  > osmgpsmap-new.defs
 	
 release: dist
 	scp @PACKAGE at -@VERSION at .tar.gz root at greenbirdsystems.com:/var/www/johnstowers.co.nz/files/osm-gps-map/
diff --git a/python/configure.ac b/python/configure.ac
index f783558..e55c7d7 100644
--- a/python/configure.ac
+++ b/python/configure.ac
@@ -1,14 +1,18 @@
-AC_PREREQ(2.53)
-AC_INIT(python-osmgpsmap, 0.6.0)
-AC_CONFIG_SRCDIR(osmgpsmap.defs)
-AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION)
+AC_PREREQ([2.62])
+AC_INIT([python-osmgpsmap],
+        [0.7.0],
+        [http://github.com/nzjrs/osm-gps-map/issues],
+        [python-osmgpsmap])
+AM_INIT_AUTOMAKE([1.10])
+
+AC_CONFIG_SRCDIR([osmgpsmap.defs])
+AC_CONFIG_MACRO_DIR([m4])
 
 AM_MAINTAINER_MODE
 AC_PROG_MAKE_SET
 
 AC_PROG_CC
-AM_PROG_CC_STDC
-AC_HEADER_STDC
+AM_PROG_CC_C_O
 
 AM_PROG_LIBTOOL
 
@@ -28,33 +32,29 @@ fi
 AM_PATH_PYTHON()
 AM_CHECK_PYTHON_HEADERS(,AC_MSG_ERROR([install python-devel]))
 
-PKG_CHECK_MODULES(PYGTK, [pygtk-2.0 >= 2.10.0])
+PKG_CHECK_MODULES(PYGTK, [pygtk-2.0 >= 2.10.0 pygobject-2.0 >= 2.16.0])
 
-AC_MSG_CHECKING(for pygtk defs)
+AC_MSG_CHECKING([for pygtk defs])
 PYGTK_DEFSDIR=`$PKG_CONFIG --variable=defsdir pygtk-2.0`
 AC_SUBST(PYGTK_DEFSDIR)
 AC_MSG_RESULT($PYGTK_DEFSDIR)
 
-AC_MSG_CHECKING(for pygtk codegen)
-PYGTK_CODEGEN="$PYTHON `$PKG_CONFIG --variable=codegendir pygtk-2.0`/codegen.py"
-AC_SUBST(PYGTK_CODEGEN)
-AC_MSG_RESULT($PYGTK_CODEGEN)
-
-AC_MSG_CHECKING(for pygtk h2def)
-PYGTK_H2DEF="$PYTHON `$PKG_CONFIG --variable=codegendir pygtk-2.0`/h2def.py"
-AC_SUBST(PYGTK_H2DEF)
-AC_MSG_RESULT($PYGTK_H2DEF)
+AC_MSG_CHECKING([for codegen])
+CODEGENDIR=`$PKG_CONFIG --variable codegendir pygobject-2.0`
+AC_SUBST([CODEGENDIR])
+AC_MSG_RESULT($CODEGENDIR)
 
 if test -f ../src/libosmgpsmap.la; then
 	#Because we are building against a non installed lib, the pkgconfig
 	#file cannot tell us to also include/link gtk/soup, so we must manually do it
-	PKG_CHECK_MODULES(OSMGPSMAP, [gtk+-2.0 libsoup-2.4])
+	PKG_CHECK_MODULES(GTK, [gtk+-2.0])
+	PKG_CHECK_MODULES(SOUP24, [libsoup-2.4])
 
 	#and we must link to the local lib
-	OSMGPSMAP_CFLAGS="$OSMGPSMAP_CFLAGS -I../src/"
-	OSMGPSMAP_LIBS="$OSMGPSMAP_LIBS -L../src/.libs/ -losmgpsmap"
+	OSMGPSMAP_CFLAGS="-I\$(top_srcdir)/../src/"
+	OSMGPSMAP_LIBS="\$(top_builddir)/../src/libosmgpsmap.la"
 else
-	PKG_CHECK_MODULES(OSMGPSMAP, osmgpsmap)
+	PKG_CHECK_MODULES(OSMGPSMAP, osmgpsmap = 0.7.0)
 fi
 
 AC_OUTPUT([Makefile])
diff --git a/python/m4/.gitignore b/python/m4/.gitignore
new file mode 100644
index 0000000..ab78ba9
--- /dev/null
+++ b/python/m4/.gitignore
@@ -0,0 +1 @@
+l*.m4
diff --git a/python/acinclude.m4 b/python/m4/am_check_python_headers.m4
similarity index 52%
rename from python/acinclude.m4
rename to python/m4/am_check_python_headers.m4
index fe90156..70b4c6e 100644
--- a/python/acinclude.m4
+++ b/python/m4/am_check_python_headers.m4
@@ -1,41 +1,3 @@
-## this one is commonly used with AM_PATH_PYTHONDIR ...
-dnl AM_CHECK_PYMOD(MODNAME [,SYMBOL [,ACTION-IF-FOUND [,ACTION-IF-NOT-FOUND]]])
-dnl Check if a module containing a given symbol is visible to python.
-AC_DEFUN([AM_CHECK_PYMOD],
-[AC_REQUIRE([AM_PATH_PYTHON])
-py_mod_var=`echo $1['_']$2 | sed 'y%./+-%__p_%'`
-AC_MSG_CHECKING(for ifelse([$2],[],,[$2 in ])python module $1)
-AC_CACHE_VAL(py_cv_mod_$py_mod_var, [
-ifelse([$2],[], [prog="
-import sys
-try:
-        import $1
-except ImportError:
-        sys.exit(1)
-except:
-        sys.exit(0)
-sys.exit(0)"], [prog="
-import $1
-$1.$2"])
-if $PYTHON -c "$prog" 1>&AC_FD_CC 2>&AC_FD_CC
-  then
-    eval "py_cv_mod_$py_mod_var=yes"
-  else
-    eval "py_cv_mod_$py_mod_var=no"
-  fi
-])
-py_val=`eval "echo \`echo '$py_cv_mod_'$py_mod_var\`"`
-if test "x$py_val" != xno; then
-  AC_MSG_RESULT(yes)
-  ifelse([$3], [],, [$3
-])dnl
-else
-  AC_MSG_RESULT(no)
-  ifelse([$4], [],, [$4
-])dnl
-fi
-])
-
 dnl a macro to check for ability to create python extensions
 dnl  AM_CHECK_PYTHON_HEADERS([ACTION-IF-POSSIBLE], [ACTION-IF-NOT-POSSIBLE])
 dnl function also defines PYTHON_INCLUDES
diff --git a/python/osmgpsmap-compat.defs b/python/osmgpsmap-compat.defs
new file mode 100644
index 0000000..a1d9bb5
--- /dev/null
+++ b/python/osmgpsmap-compat.defs
@@ -0,0 +1,113 @@
+;; -*- scheme -*-
+(define-method add_track
+  (of-object "OsmGpsMap")
+  (c-name "osm_gps_map_add_track")
+  (return-type "none")
+  (parameters
+    '("GSList*" "track")
+  )
+)
+
+(define-method clear_tracks
+  (of-object "OsmGpsMap")
+  (c-name "osm_gps_map_clear_tracks")
+  (return-type "none")
+)
+
+(define-method add_image
+  (of-object "OsmGpsMap")
+  (c-name "osm_gps_map_add_image")
+  (return-type "none")
+  (parameters
+    '("float" "latitude")
+    '("float" "longitude")
+    '("GdkPixbuf*" "image")
+  )
+)
+
+(define-method remove_image
+  (of-object "OsmGpsMap")
+  (c-name "osm_gps_map_remove_image")
+  (return-type "gboolean")
+  (parameters
+    '("GdkPixbuf*" "image")
+  )
+)
+
+(define-method clear_images
+  (of-object "OsmGpsMap")
+  (c-name "osm_gps_map_clear_images")
+  (return-type "none")
+)
+
+(define-method draw_gps
+  (of-object "OsmGpsMap")
+  (c-name "osm_gps_map_draw_gps")
+  (return-type "none")
+  (parameters
+    '("float" "latitude")
+    '("float" "longitude")
+    '("float" "heading")
+  )
+)
+
+(define-method clear_gps
+  (of-object "OsmGpsMap")
+  (c-name "osm_gps_map_clear_gps")
+  (return-type "none")
+)
+
+(define-method add_layer
+  (of-object "OsmGpsMap")
+  (c-name "osm_gps_map_add_layer")
+  (return-type "none")
+  (parameters
+    '("OsmGpsMapLayer*" "layer")
+  )
+)
+
+(define-method get_co_ordinates
+  (of-object "OsmGpsMap")
+  (c-name "osm_gps_map_get_co_ordinates")
+  (return-type "coord_t")
+  (parameters
+    '("int" "pixel_x")
+    '("int" "pixel_y")
+  )
+)
+
+(define-method screen_to_geographic
+  (of-object "OsmGpsMap")
+  (c-name "osm_gps_map_screen_to_geographic")
+  (return-type "none")
+  (parameters
+    '("int" "pixel_x")
+    '("int" "pixel_y")
+    '("float*" "latitude")
+    '("float*" "longitude")
+  )
+)
+
+(define-method geographic_to_screen
+  (of-object "OsmGpsMap")
+  (c-name "osm_gps_map_geographic_to_screen")
+  (return-type "none")
+  (parameters
+    '("float" "latitude")
+    '("float" "longitude")
+    '("int*" "pixel_x")
+    '("int*" "pixel_y")
+  )
+)
+
+(define-method set_mapcenter
+  (of-object "OsmGpsMap")
+  (c-name "osm_gps_map_set_mapcenter")
+  (return-type "none")
+  (parameters
+    '("float" "latitude")
+    '("float" "longitude")
+    '("int" "zoom")
+  )
+)
+
diff --git a/python/osmgpsmap.defs b/python/osmgpsmap.defs
index 079304a..989fdb3 100644
--- a/python/osmgpsmap.defs
+++ b/python/osmgpsmap.defs
@@ -1,4 +1,7 @@
 ;; -*- scheme -*-
+
+(include "osmgpsmap-compat.defs")
+
 ; object definitions ...
 (define-object GpsMap
   (in-module "Osm")
@@ -7,6 +10,20 @@
   (gtype-id "OSM_TYPE_GPS_MAP")
 )
 
+(define-object GpsMapImage
+  (in-module "Osm")
+  (parent "GObject")
+  (c-name "OsmGpsMapImage")
+  (gtype-id "OSM_TYPE_GPS_MAP_IMAGE")
+)
+
+(define-interface GpsMapLayer
+  (in-module "Osm")
+  (c-name "OsmGpsMapLayer")
+  (gtype-id "OSM_TYPE_GPS_MAP_LAYER")
+  (prerequisite "GObject")
+)
+
 (define-object GpsMapOsd
   (in-module "Osm")
   (parent "GObject")
@@ -14,6 +31,26 @@
   (gtype-id "OSM_TYPE_GPS_MAP_OSD")
 )
 
+(define-object GpsMapTrack
+  (in-module "Osm")
+  (parent "GObject")
+  (c-name "OsmGpsMapTrack")
+  (gtype-id "OSM_TYPE_GPS_MAP_TRACK")
+)
+
+(define-boxed Point
+  (in-module "Osm")
+  (c-name "OsmGpsMapPoint")
+  (gtype-id "OSM_TYPE_GPS_MAP_POINT")
+  (copy-func "osm_gps_map_point_copy")
+  (release-func "g_free")
+  (fields
+    '("gfloat" "rlat")
+    '("gfloat" "rlon")
+  )
+)
+
+
 ;; Enumerations and flags ...
 (define-enum MapSource
   (in-module "Osm")
@@ -50,63 +87,53 @@
   )
 )
 
-;; From osm-gps-map.h
+;; From osm-gps-map-widget.h
 
 (define-function osm_gps_map_get_type
   (c-name "osm_gps_map_get_type")
   (return-type "GType")
 )
 
-(define-function get_default_cache_directory
-  (c-name "osm_gps_map_get_default_cache_directory")
-  (return-type "char*")
-)
-
-(define-function source_get_friendly_name
-  (c-name "osm_gps_map_source_get_friendly_name")
-  (return-type "const-char*")
-  (parameters
-    '("OsmGpsMapSource_t" "source")
-  )
-)
-
-(define-function source_get_repo_uri
-  (c-name "osm_gps_map_source_get_repo_uri")
-  (return-type "const-char*")
-  (parameters
-    '("OsmGpsMapSource_t" "source")
-  )
-)
-
-(define-function source_get_image_format
-  (c-name "osm_gps_map_source_get_image_format")
-  (return-type "const-char*")
-  (parameters
-    '("OsmGpsMapSource_t" "source")
-  )
-)
-
-(define-function source_get_min_zoom
-  (c-name "osm_gps_map_source_get_min_zoom")
-  (return-type "int")
-  (parameters
-    '("OsmGpsMapSource_t" "source")
+(define-function osm_gps_map_new
+  (c-name "osm_gps_map_new")
+  (is-constructor-of "OsmGpsMap")
+  (return-type "GtkWidget*")
+  (properties
+    '("auto_center" (optional))
+    '("auto_center_threshold" (optional))
+    '("record_trip_history" (optional))
+    '("show_trip_history" (optional))
+    '("show_gps_point" (optional))
+    '("auto_download" (optional))
+    '("repo_uri" (optional))
+    '("proxy_uri" (optional))
+    '("tile_cache" (optional))
+    '("tile_cache_base" (optional))
+    '("tile_cache_is_full_path" (optional))
+    '("zoom" (optional))
+    '("max_zoom" (optional))
+    '("min_zoom" (optional))
+    '("map_x" (optional))
+    '("map_y" (optional))
+    '("gps_track_width" (optional))
+    '("gps_track_point_radius" (optional))
+    '("gps_track_highlight_radius" (optional))
+    '("map_source" (optional))
+    '("image_format" (optional))
+    '("drag_limit" (optional))
   )
 )
 
-(define-function source_get_max_zoom
-  (c-name "osm_gps_map_source_get_max_zoom")
-  (return-type "int")
-  (parameters
-    '("OsmGpsMapSource_t" "source")
-  )
+(define-function get_default_cache_directory
+  (c-name "osm_gps_map_get_default_cache_directory")
+  (return-type "gchar*")
 )
 
-(define-function osm_gps_map_source_is_valid
-  (c-name "osm_gps_map_source_is_valid")
-  (return-type "gboolean")
+(define-virtual draw_gps_point
+  (of-object "OsmGpsMap")
+  (return-type "none")
   (parameters
-    '("OsmGpsMapSource_t" "source")
+    '("GdkDrawable*" "drawable")
   )
 )
 
@@ -115,26 +142,32 @@
   (c-name "osm_gps_map_download_maps")
   (return-type "none")
   (parameters
-    '("coord_t*" "pt1")
-    '("coord_t*" "pt2")
+    '("OsmGpsMapPoint*" "pt1")
+    '("OsmGpsMapPoint*" "pt2")
     '("int" "zoom_start")
     '("int" "zoom_end")
   )
 )
 
+(define-method download_cancel_all
+  (of-object "OsmGpsMap")
+  (c-name "osm_gps_map_download_cancel_all")
+  (return-type "none")
+)
+
 (define-method get_bbox
   (of-object "OsmGpsMap")
   (c-name "osm_gps_map_get_bbox")
   (return-type "none")
   (parameters
-    '("coord_t*" "pt1")
-    '("coord_t*" "pt2")
+    '("OsmGpsMapPoint*" "pt1")
+    '("OsmGpsMapPoint*" "pt2")
   )
 )
 
-(define-method set_mapcenter
+(define-method set_center_and_zoom
   (of-object "OsmGpsMap")
-  (c-name "osm_gps_map_set_mapcenter")
+  (c-name "osm_gps_map_set_center_and_zoom")
   (return-type "none")
   (parameters
     '("float" "latitude")
@@ -174,158 +207,174 @@
   (return-type "int")
 )
 
-(define-method add_track
+(define-method scroll
   (of-object "OsmGpsMap")
-  (c-name "osm_gps_map_add_track")
+  (c-name "osm_gps_map_scroll")
   (return-type "none")
   (parameters
-    '("GSList*" "track")
+    '("gint" "dx")
+    '("gint" "dy")
   )
 )
 
-(define-method clear_tracks
+(define-method get_scale
   (of-object "OsmGpsMap")
-  (c-name "osm_gps_map_clear_tracks")
-  (return-type "none")
+  (c-name "osm_gps_map_get_scale")
+  (return-type "float")
 )
 
-(define-method add_image
+(define-method set_keyboard_shortcut
   (of-object "OsmGpsMap")
-  (c-name "osm_gps_map_add_image")
+  (c-name "osm_gps_map_set_keyboard_shortcut")
   (return-type "none")
   (parameters
-    '("float" "latitude")
-    '("float" "longitude")
-    '("GdkPixbuf*" "image")
+    '("OsmGpsMapKey_t" "key")
+    '("guint" "keyval")
   )
 )
 
-(define-method remove_image
+(define-method track_add
   (of-object "OsmGpsMap")
-  (c-name "osm_gps_map_remove_image")
-  (return-type "gboolean")
+  (c-name "osm_gps_map_track_add")
+  (return-type "none")
   (parameters
-    '("GdkPixbuf*" "image")
+    '("OsmGpsMapTrack*" "track")
   )
 )
 
-(define-method clear_images
+(define-method track_remove_all
   (of-object "OsmGpsMap")
-  (c-name "osm_gps_map_clear_images")
+  (c-name "osm_gps_map_track_remove_all")
   (return-type "none")
 )
 
-(define-method draw_gps
+(define-method track_remove
   (of-object "OsmGpsMap")
-  (c-name "osm_gps_map_draw_gps")
+  (c-name "osm_gps_map_track_remove")
+  (return-type "gboolean")
+  (parameters
+    '("OsmGpsMapTrack*" "track")
+  )
+)
+
+(define-method gps_add
+  (of-object "OsmGpsMap")
+  (c-name "osm_gps_map_gps_add")
   (return-type "none")
   (parameters
     '("float" "latitude")
     '("float" "longitude")
-    '("float" "heading")
+    '("float" "heading" (default "OSM_GPS_MAP_INVALID"))
   )
 )
 
-(define-method clear_gps
+(define-method gps_clear
   (of-object "OsmGpsMap")
-  (c-name "osm_gps_map_clear_gps")
+  (c-name "osm_gps_map_gps_clear")
   (return-type "none")
 )
 
-(define-method get_co_ordinates
+(define-method gps_get_track
+  (of-object "OsmGpsMap")
+  (c-name "osm_gps_map_gps_get_track")
+  (return-type "OsmGpsMapTrack*")
+  (caller-owns-return #f)
+)
+
+(define-method image_add
   (of-object "OsmGpsMap")
-  (c-name "osm_gps_map_get_co_ordinates")
-  (return-type "coord_t")
+  (c-name "osm_gps_map_image_add")
+  (return-type "OsmGpsMapImage*")
+  (caller-owns-return #t)
   (parameters
-    '("int" "pixel_x")
-    '("int" "pixel_y")
+    '("float" "latitude")
+    '("float" "longitude")
+    '("GdkPixbuf*" "image")
   )
 )
 
-(define-function osm_gps_map_new
-  (c-name "osm_gps_map_new")
-  (is-constructor-of "OsmGpsMap")
-  (return-type "GtkWidget*")
-  (properties
-    '("auto_center" (optional))
-    '("record_trip_history" (optional))
-    '("show_trip-history" (optional))
-    '("auto_download" (optional))
-    '("repo_uri" (optional))
-    '("proxy_uri" (optional))
-    '("tile_cache" (optional))
-    '("tile_cache_base" (optional))
-    '("tile_cache_is_full_path" (optional))
-    '("zoom" (optional))
-    '("max_zoom" (optional))
-    '("min_zoom" (optional))
-    '("map_x" (optional))
-    '("map_y" (optional))
-    '("gps_track_width" (optional))
-    '("gps_track_point_radius" (optional))
-    '("gps_track_highlight_radius" (optional))
-    '("map_source" (optional))
-    '("image_format" (optional))
-    '("drag_limit" (optional))
+(define-method image_add_with_alignment
+  (of-object "OsmGpsMap")
+  (c-name "osm_gps_map_image_add_with_alignment")
+  (return-type "OsmGpsMapImage*")
+  (caller-owns-return #t)
+  (parameters
+    '("float" "latitude")
+    '("float" "longitude")
+    '("GdkPixbuf*" "image")
+    '("float" "xalign")
+    '("float" "yalign")
   )
 )
 
-(define-method screen_to_geographic
+(define-method image_remove
   (of-object "OsmGpsMap")
-  (c-name "osm_gps_map_screen_to_geographic")
-  (return-type "none")
+  (c-name "osm_gps_map_image_remove")
+  (return-type "gboolean")
   (parameters
-    '("int" "pixel_x")
-    '("int" "pixel_y")
-    '("float*" "latitude")
-    '("float*" "longitude")
+    '("OsmGpsMapImage*" "image")
   )
 )
 
-(define-method geographic_to_screen
+(define-method image_remove_all
+  (of-object "OsmGpsMap")
+  (c-name "osm_gps_map_image_remove_all")
+  (return-type "none")
+)
+
+(define-method layer_add
   (of-object "OsmGpsMap")
-  (c-name "osm_gps_map_geographic_to_screen")
+  (c-name "osm_gps_map_layer_add")
   (return-type "none")
   (parameters
-    '("float" "latitude")
-    '("float" "longitude")
-    '("int*" "pixel_x")
-    '("int*" "pixel_y")
+    '("OsmGpsMapLayer*" "layer")
   )
 )
 
-(define-method scroll
+(define-method layer_remove
   (of-object "OsmGpsMap")
-  (c-name "osm_gps_map_scroll")
-  (return-type "none")
+  (c-name "osm_gps_map_layer_remove")
+  (return-type "gboolean")
   (parameters
-    '("gint" "dx")
-    '("gint" "dy")
+    '("OsmGpsMapLayer*" "layer")
   )
 )
 
-(define-method get_scale
+(define-method layer_remove_all
   (of-object "OsmGpsMap")
-  (c-name "osm_gps_map_get_scale")
-  (return-type "float")
+  (c-name "osm_gps_map_layer_remove_all")
+  (return-type "none")
 )
 
-(define-method set_keyboard_shortcut
+(define-method convert_screen_to_geographic
   (of-object "OsmGpsMap")
-  (c-name "osm_gps_map_set_keyboard_shortcut")
+  (c-name "osm_gps_map_convert_screen_to_geographic")
   (return-type "none")
   (parameters
-    '("OsmGpsMapKey_t" "key")
-    '("guint" "keyval")
+    '("gint" "pixel_x")
+    '("gint" "pixel_y")
+    '("OsmGpsMapPoint*" "pt")
   )
 )
 
-(define-method add_layer
+(define-method convert_geographic_to_screen
   (of-object "OsmGpsMap")
-  (c-name "osm_gps_map_add_layer")
+  (c-name "osm_gps_map_convert_geographic_to_screen")
   (return-type "none")
   (parameters
-    '("OsmGpsMapLayer*" "layer")
+    '("OsmGpsMapPoint*" "pt")
+    '("gint*" "pixel_x")
+    '("gint*" "pixel_y")
+  )
+)
+
+(define-method get_event_location
+  (of-object "OsmGpsMap")
+  (c-name "osm_gps_map_get_event_location")
+  (return-type "OsmGpsMapPoint*")
+  (caller-owns-return #t)
+  (parameters
+    '("GdkEventButton*" "event")
   )
 )
 
@@ -358,15 +407,40 @@
 
 
 
-;; From osm-gps-map-layer.h
+;; From osm-gps-map-image.h
 
-(define-interface GpsMapLayer
-  (in-module "Osm")
-  (c-name "OsmGpsMapLayer")
-  (gtype-id "OSM_TYPE_GPS_MAP_LAYER")
-  (prerequisite "GObject")
+(define-function osm_gps_map_image_get_type
+  (c-name "osm_gps_map_image_get_type")
+  (return-type "GType")
 )
 
+(define-function osm_gps_map_image_new
+  (c-name "osm_gps_map_image_new")
+  (is-constructor-of "OsmGpsMapImage")
+  (return-type "OsmGpsMapImage*")
+)
+
+(define-method draw
+  (of-object "OsmGpsMapImage")
+  (c-name "osm_gps_map_image_draw")
+  (return-type "none")
+  (parameters
+    '("GdkDrawable*" "drawable")
+    '("GdkGC*" "gc")
+    '("GdkRectangle*" "rect")
+  )
+)
+
+(define-method get_point
+  (of-object "OsmGpsMapImage")
+  (c-name "osm_gps_map_image_get_point")
+  (return-type "const-OsmGpsMapPoint*")
+)
+
+
+
+;; From osm-gps-map-layer.h
+
 (define-function osm_gps_map_layer_get_type
   (c-name "osm_gps_map_layer_get_type")
   (return-type "GType")
@@ -406,3 +480,163 @@
     '("GdkEventButton*" "event")
   )
 )
+
+
+
+;; From osm-gps-map-track.h
+
+(define-function osm_gps_map_track_get_type
+  (c-name "osm_gps_map_track_get_type")
+  (return-type "GType")
+)
+
+(define-function osm_gps_map_track_new
+  (c-name "osm_gps_map_track_new")
+  (is-constructor-of "OsmGpsMapTrack")
+  (return-type "OsmGpsMapTrack*")
+)
+
+(define-method add_point
+  (of-object "OsmGpsMapTrack")
+  (c-name "osm_gps_map_track_add_point")
+  (return-type "none")
+  (parameters
+    '("OsmGpsMapPoint*" "point")
+  )
+)
+
+(define-method get_points
+  (of-object "OsmGpsMapTrack")
+  (c-name "osm_gps_map_track_get_points")
+  (return-type "GSList*")
+)
+
+(define-method get_color
+  (of-object "OsmGpsMapTrack")
+  (c-name "osm_gps_map_track_get_color")
+  (return-type "none")
+  (parameters
+    '("GdkColor*" "color")
+  )
+)
+
+
+
+;; From osm-gps-map-point.h
+
+(define-function osm_gps_map_point_get_type
+  (c-name "osm_gps_map_point_get_type")
+  (return-type "GType")
+)
+
+(define-function point_new_degrees
+  (c-name "osm_gps_map_point_new_degrees")
+  (return-type "OsmGpsMapPoint*")
+  (parameters
+    '("float" "lat")
+    '("float" "lon")
+  )
+)
+
+(define-function point_new_radians
+  (c-name "osm_gps_map_point_new_radians")
+  (return-type "OsmGpsMapPoint*")
+  (parameters
+    '("float" "rlat")
+    '("float" "rlon")
+  )
+)
+
+(define-method get_degrees
+  (of-object "OsmGpsMapPoint")
+  (c-name "osm_gps_map_point_get_degrees")
+  (return-type "none")
+  (parameters
+    '("float*" "lat")
+    '("float*" "lon")
+  )
+)
+
+(define-method get_radians
+  (of-object "OsmGpsMapPoint")
+  (c-name "osm_gps_map_point_get_radians")
+  (return-type "none")
+  (parameters
+    '("float*" "rlat")
+    '("float*" "rlon")
+  )
+)
+
+(define-method set_degrees
+  (of-object "OsmGpsMapPoint")
+  (c-name "osm_gps_map_point_set_degrees")
+  (return-type "none")
+  (parameters
+    '("float" "lat")
+    '("float" "lon")
+  )
+)
+
+(define-method set_radians
+  (of-object "OsmGpsMapPoint")
+  (c-name "osm_gps_map_point_set_radians")
+  (return-type "none")
+  (parameters
+    '("float" "rlat")
+    '("float" "rlon")
+  )
+)
+
+
+
+;; From osm-gps-map-source.h
+
+(define-function source_get_friendly_name
+  (c-name "osm_gps_map_source_get_friendly_name")
+  (return-type "const-char*")
+  (parameters
+    '("OsmGpsMapSource_t" "source")
+  )
+)
+
+(define-function source_get_repo_uri
+  (c-name "osm_gps_map_source_get_repo_uri")
+  (return-type "const-char*")
+  (parameters
+    '("OsmGpsMapSource_t" "source")
+  )
+)
+
+(define-function source_get_image_format
+  (c-name "osm_gps_map_source_get_image_format")
+  (return-type "const-char*")
+  (parameters
+    '("OsmGpsMapSource_t" "source")
+  )
+)
+
+(define-function source_get_min_zoom
+  (c-name "osm_gps_map_source_get_min_zoom")
+  (return-type "int")
+  (parameters
+    '("OsmGpsMapSource_t" "source")
+  )
+)
+
+(define-function source_get_max_zoom
+  (c-name "osm_gps_map_source_get_max_zoom")
+  (return-type "int")
+  (parameters
+    '("OsmGpsMapSource_t" "source")
+  )
+)
+
+(define-function osm_gps_map_source_is_valid
+  (c-name "osm_gps_map_source_is_valid")
+  (return-type "gboolean")
+  (parameters
+    '("OsmGpsMapSource_t" "source")
+  )
+)
+
+
diff --git a/python/osmgpsmap.override b/python/osmgpsmap.override
index 3e1c158..65a9e3f 100644
--- a/python/osmgpsmap.override
+++ b/python/osmgpsmap.override
@@ -1,11 +1,9 @@
 %%
 headers
 #include <Python.h>
+#include <pygobject.h>
+#include <pygtk/pygtk.h>
 #include "osm-gps-map.h"
-#include "osm-gps-map-osd.h"
-#include "osm-gps-map-layer.h"
-#include "pygobject.h"
-#include <stdio.h>
 %%
 modulename osmgpsmap
 %%
@@ -13,6 +11,8 @@ import gobject.GObject as PyGObject_Type
 import gtk.DrawingArea as PyGtkDrawingArea_Type
 import gtk.gdk.Pixbuf as PyGdkPixbuf_Type 
 import gtk.gdk.Drawable as PyGdkDrawable_Type
+import gtk.gdk.GC as PyGdkGC_Type
+import gtk.gdk.Rectangle as PyGtkRectangle_Type
 %%
 ignore-glob
 	*_get_type
@@ -21,13 +21,118 @@ override osm_gps_map_get_bbox noargs
 static PyObject *
 _wrap_osm_gps_map_get_bbox(PyGObject *self)
 {
-    coord_t pt1,pt2;
+    OsmGpsMapPoint pt1,pt2;
 
     osm_gps_map_get_bbox(OSM_GPS_MAP(self->obj), &pt1, &pt2);
 
     return Py_BuildValue("(dddd)", pt1.rlat, pt1.rlon, pt2.rlat, pt2.rlon);
 }
 %%
+override osm_gps_map_set_center
+static PyObject *
+_wrap_osm_gps_map_set_center(PyGObject *self, PyObject *args)
+{
+    double latitude, longitude;
+
+    if (PyTuple_Size(args) == 1)
+        args = PyTuple_GetItem(args, 0);
+    if (!PyArg_ParseTuple(args, "dd;OsmGpsMap.set_center takes two floats (also in a tuple)",
+                          &latitude, &longitude))
+        return NULL;
+    osm_gps_map_set_center(OSM_GPS_MAP(self->obj), latitude, longitude);
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+%%
+override osm_gps_map_scroll
+static PyObject *
+_wrap_osm_gps_map_scroll(PyGObject *self, PyObject *args)
+{
+    int dx, dy;
+
+    if (PyTuple_Size(args) == 1)
+        args = PyTuple_GetItem(args, 0);
+    if (!PyArg_ParseTuple(args, "ii:OsmGpsMap.scroll takes two "
+                          "integers (also in a tuple)", &dx, &dy))
+        return NULL;
+
+    osm_gps_map_scroll(OSM_GPS_MAP(self->obj), dx, dy);
+
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+%%
+override osm_gps_map_download_maps kwargs
+static PyObject *
+_wrap_osm_gps_map_download_maps(PyGObject *self, PyObject *args, 
+                                     PyObject *kwargs)
+{
+    static char *kwlist[] = { "lat1", "lon1", "lat2", "lon2", "zoom_start", "zoom_end", NULL };
+    int zoom_start, zoom_end;
+    OsmGpsMapPoint pt1, pt2;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+				        "ffffii:GpsMap.download_maps",
+				        kwlist, &pt1.rlat,&pt1.rlon,&pt2.rlat, &pt2.rlon,
+                        &zoom_start, &zoom_end))
+        return NULL;
+
+    osm_gps_map_download_maps(OSM_GPS_MAP(self->obj), &pt1, &pt2, zoom_start, zoom_end);
+
+    Py_RETURN_NONE;
+}
+%%
+override osm_gps_map_convert_geographic_to_screen
+static PyObject *
+_wrap_osm_gps_map_convert_geographic_to_screen(PyGObject *self, PyObject *args, PyObject *kwargs)
+{
+    static char *kwlist[] = { "pt", "pixel_x", "pixel_y", NULL };
+    int pixel_x, pixel_y;
+    PyObject *py_pt;
+    OsmGpsMapPoint *pt = NULL;
+
+    if (!PyArg_ParseTupleAndKeywords(args, kwargs,"Oii:Osm.GpsMap.convert_geographic_to_screen", kwlist, &py_pt, &pixel_x, &pixel_y))
+        return NULL;
+    if (pyg_boxed_check(py_pt, OSM_TYPE_GPS_MAP_POINT))
+        pt = pyg_boxed_get(py_pt, OsmGpsMapPoint);
+    else {
+        PyErr_SetString(PyExc_TypeError, "pt should be a OsmGpsMapPoint");
+        return NULL;
+    }
+
+    osm_gps_map_convert_geographic_to_screen(OSM_GPS_MAP(self->obj), pt, &pixel_x, &pixel_y);
+
+    return Py_BuildValue("(ii)", pixel_x, pixel_y);
+}
+%%
+override osm_gps_map_point_get_degrees noargs
+static PyObject *
+_wrap_osm_gps_map_point_get_degrees(PyGObject *self)
+{
+    float lat, lon;
+
+    osm_gps_map_point_get_degrees(pyg_boxed_get(self, OsmGpsMapPoint), &lat, &lon);
+
+    return Py_BuildValue("(ff)", lat, lon);
+}
+%%
+override osm_gps_map_point_get_radians noargs
+static PyObject *
+_wrap_osm_gps_map_point_get_radians(PyGObject *self)
+{
+    float rlat, rlon;
+
+    osm_gps_map_point_get_radians(pyg_boxed_get(self, OsmGpsMapPoint), &rlat, &rlon);
+
+    return Py_BuildValue("(ff)", rlat, rlon);
+}
+%%
+%%
+%% DEPRECIATED WRAPPERS FOLLOW, THESE SHOULD BE IN ANOTHER FILE. 
+%% BUT I COULD NOT GET THE INCLUDE.override TO WORK
+%%
+%%
 override osm_gps_map_get_co_ordinates kwargs
 static PyObject *
 _wrap_osm_gps_map_get_co_ordinates(PyGObject *self, PyObject *args, 
@@ -35,7 +140,7 @@ _wrap_osm_gps_map_get_co_ordinates(PyGObject *self, PyObject *args,
 {
     static char *kwlist[] = { "pixel_x", "pixel_y", NULL };
     int pixel_x = -1, pixel_y = -1;
-    coord_t coord;
+    OsmGpsMapPoint coord;
 
     if (!PyArg_ParseTupleAndKeywords(args, kwargs,
 				     "|ii:GpsMap.get_co_ordinates",
@@ -47,34 +152,18 @@ _wrap_osm_gps_map_get_co_ordinates(PyGObject *self, PyObject *args,
     	return NULL;
 	}
 
-    coord = osm_gps_map_get_co_ordinates(OSM_GPS_MAP(self->obj), pixel_x, pixel_y);
+    osm_gps_map_convert_screen_to_geographic(OSM_GPS_MAP(self->obj), pixel_x, pixel_y, &coord);
 
     return Py_BuildValue("(dd)", coord.rlat, coord.rlon);
 }
 %%
-override osm_gps_map_set_center
-static PyObject *
-_wrap_osm_gps_map_set_center(PyGObject *self, PyObject *args)
-{
-    double latitude, longitude;
-
-    if (PyTuple_Size(args) == 1)
-        args = PyTuple_GetItem(args, 0);
-    if (!PyArg_ParseTuple(args, "dd;OsmGpsMap.set_center takes two floats (also in a tuple)",
-                          &latitude, &longitude))
-        return NULL;
-    osm_gps_map_set_center(OSM_GPS_MAP(self->obj), latitude, longitude);
-
-    Py_INCREF(Py_None);
-    return Py_None;
-}
-%%
 override osm_gps_map_screen_to_geographic
 static PyObject *
 _wrap_osm_gps_map_screen_to_geographic(PyGObject *self, PyObject *args)
 {
     int pixel_x, pixel_y;
-    gfloat latitude, longitude;
+    OsmGpsMapPoint coord;
+    gfloat lat, lon;
 
     if (PyTuple_Size(args) == 1)
         args = PyTuple_GetItem(args, 0);
@@ -82,10 +171,10 @@ _wrap_osm_gps_map_screen_to_geographic(PyGObject *self, PyObject *args)
                           "integers (also in a tuple)", &pixel_x, &pixel_y))
         return NULL;
 
-    osm_gps_map_screen_to_geographic(OSM_GPS_MAP(self->obj), pixel_x, pixel_y,
-                                     &latitude, &longitude);
+    osm_gps_map_convert_screen_to_geographic(OSM_GPS_MAP(self->obj), pixel_x, pixel_y, &coord);
+    osm_gps_map_point_get_degrees(&coord, &lat, &lon);
 
-    return Py_BuildValue("(ff)", latitude, longitude);
+    return Py_BuildValue("(ff)", lat, lon);
 }
 %%
 override osm_gps_map_geographic_to_screen
@@ -93,40 +182,21 @@ static PyObject *
 _wrap_osm_gps_map_geographic_to_screen(PyGObject *self, PyObject *args)
 {
     int pixel_x, pixel_y;
-    gfloat latitude, longitude;
+    gfloat lat, lon;
+    OsmGpsMapPoint coord;
 
     if (PyTuple_Size(args) == 1)
         args = PyTuple_GetItem(args, 0);
     if (!PyArg_ParseTuple(args, "ff:OsmGpsMap.geographic_to_screen takes two"
-                          "floats (also in a tuple)", &latitude, &longitude))
+                          "floats (also in a tuple)", &lat, &lon))
         return NULL;
 
-    osm_gps_map_geographic_to_screen(OSM_GPS_MAP(self->obj),
-                                     latitude, longitude,
-                                     &pixel_x, &pixel_y);
+    osm_gps_map_point_set_degrees(&coord, lat, lon);
+    osm_gps_map_convert_geographic_to_screen(OSM_GPS_MAP(self->obj), &coord, &pixel_x, &pixel_y);
 
     return Py_BuildValue("(ii)", pixel_x, pixel_y);
 }
 %%
-override osm_gps_map_scroll
-static PyObject *
-_wrap_osm_gps_map_scroll(PyGObject *self, PyObject *args)
-{
-    int dx, dy;
-
-    if (PyTuple_Size(args) == 1)
-        args = PyTuple_GetItem(args, 0);
-    if (!PyArg_ParseTuple(args, "ii:OsmGpsMap.scroll takes two "
-                          "integers (also in a tuple)", &dx, &dy))
-        return NULL;
-
-    osm_gps_map_scroll(OSM_GPS_MAP(self->obj), dx, dy);
-
-    Py_INCREF(Py_None);
-    return Py_None;
-}
-
-%%
 override osm_gps_map_add_track kwargs
 static PyObject *
 _wrap_osm_gps_map_add_track(PyGObject *self, PyObject *args, 
@@ -149,9 +219,7 @@ _wrap_osm_gps_map_add_track(PyGObject *self, PyObject *args,
         coords = PyList_GetItem(list,i);
         if(PyArg_ParseTuple(coords,"ff",&rlat,&rlon)) 
         {
-            coord_t *c = g_new0(coord_t, 1);
-            c->rlat = rlat;
-            c->rlon = rlon;
+            OsmGpsMapPoint *c = osm_gps_map_point_new_radians (rlat, rlon);
             track = g_slist_append(track, c);
         }
         else
@@ -177,25 +245,4 @@ _wrap_osm_gps_map_add_track(PyGObject *self, PyObject *args,
     }
     Py_RETURN_NONE;
 }
-%%
-override osm_gps_map_download_maps kwargs
-static PyObject *
-_wrap_osm_gps_map_download_maps(PyGObject *self, PyObject *args, 
-                                     PyObject *kwargs)
-{
-    static char *kwlist[] = { "lat1", "lon1", "lat2", "lon2", "zoom_start", "zoom_end", NULL };
-    int zoom_start, zoom_end;
-    coord_t pt1, pt2;
-
-    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
-				        "ffffii:GpsMap.download_maps",
-				        kwlist, &pt1.rlat,&pt1.rlon,&pt2.rlat, &pt2.rlon,
-                        &zoom_start, &zoom_end))
-        return NULL;
-
-    osm_gps_map_download_maps(OSM_GPS_MAP(self->obj), &pt1, &pt2, zoom_start, zoom_end);
-
-    Py_RETURN_NONE;
-}
-
 // vim: filetype=c
diff --git a/python/setup.py b/python/setup.py
index 48572f8..438aa48 100644
--- a/python/setup.py
+++ b/python/setup.py
@@ -17,19 +17,18 @@ def get_lib_dirs(pkg):
 def get_libs(pkg):
     return pkg_config_parse(pkg,'--libs-only-l')
 
-#print get_libs('osmgpsmap pygobject-2.0')
-#print get_libs('osmgpsmap pygobject-2.0')
-#print get_libs('osmgpsmap pygobject-2.0')
+VERSION = "0.7.0"
 
 _osmgpsmap = Extension(name = 'osmgpsmap',
             sources= ['osmgpsmapmodule.c','osmgpsmap.c'],
             include_dirs = get_include('osmgpsmap pygobject-2.0'),
             library_dirs = get_lib_dirs('osmgpsmap pygobject-2.0'),
             libraries = get_libs('osmgpsmap pygobject-2.0'),
-        )
+            define_macros = [('VERSION', '"""%s"""' % VERSION)],
+            )
 
 setup( name = "python-osmgpsmap",
-    version = "0.6.0",
+    version = VERSION,
     description = "python interface for osmgpsmap",
     ext_modules = [_osmgpsmap],
     )
diff --git a/src/.gitignore b/src/.gitignore
new file mode 100644
index 0000000..99a5ea7
--- /dev/null
+++ b/src/.gitignore
@@ -0,0 +1,2 @@
+OsmGpsMap-1.0.gir
+OsmGpsMap-1.0.typelib
diff --git a/src/Makefile.am b/src/Makefile.am
index f4cfab0..9c6f465 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,41 +1,25 @@
 ## Process this file with automake to produce Makefile.in
-
-## Created by Anjuta
-
-AM_CPPFLAGS = \
-	-DPACKAGE_LOCALE_DIR=\""$(prefix)/$(DATADIRNAME)/locale"\" \
-	-DPACKAGE_SRC_DIR=\""$(srcdir)"\" \
-	-DPACKAGE_DATA_DIR=\""$(datadir)"\" $(OPENSTREETMAP_GPS_MAP_CFLAGS)
-
-AM_CFLAGS =\
-	 -Wall\
-	 -g
-
-bin_PROGRAMS = mapviewer
-
-mapviewer_SOURCES = \
-	main.c
-
-mapviewer_DEPENDENCIES = \
-	libosmgpsmap.la
-
-mapviewer_LDFLAGS = \
-	-losmgpsmap -lgthread-2.0
-
-mapviewer_LDADD = \
-	$(OPENSTREETMAP_GPS_MAP_LIBS)
-
-lib_LTLIBRARIES = \
-	libosmgpsmap.la
-
-libosmgpsmap_la_SOURCES = \
-	converter.c \
-	osm-gps-map.c \
-	osm-gps-map-osd.c \
-	osm-gps-map-layer.c \
-	osd-utils.c
-
-libosmgpsmap_la_CFLAGS = \
+lib_LTLIBRARIES = libosmgpsmap.la
+
+OSMGPSMAP_CFLAGS =          \
+	$(GLIB_CFLAGS)          \
+	$(GTK_CFLAGS)           \
+	$(CAIRO_CFLAGS)         \
+	$(SOUP22_CFLAGS)        \
+    $(SOUP24_CFLAGS)
+
+OSMGPSMAP_LIBS =            \
+    $(GLIB_LIBS)            \
+    $(GTK_LIBS)             \
+    $(CAIRO_LIBS)           \
+    $(SOUP22_LIBS)          \
+    $(SOUP24_LIBS)
+
+## Shared library
+libosmgpsmap_la_CFLAGS =    \
+    $(WARN_CFLAGS)          \
+    $(DISABLE_DEPRECATED)   \
+    $(OSMGPSMAP_CFLAGS)     \
 	-DG_LOG_DOMAIN=\"OsmGpsMap\"
 
 if OS_WIN32
@@ -46,19 +30,69 @@ libosmgpsmap_la_LDFLAGS = \
 	-version-info $(LT_VERSION_INFO)    \
 	$(no_undefined)
 
-libosmgpsmap_la_LIBADD = \
-	$(OPENSTREETMAP_GPS_MAP_LIBS)
+libosmgpsmap_la_LIBADD =    \
+    $(OSMGPSMAP_LIBS)
 
-libosmgpsmapincdir = $(includedir)/osmgpsmap
-libosmgpsmapinc_HEADERS = \
-	osm-gps-map.h \
-	osm-gps-map-layer.h \
-	osm-gps-map-osd.h
-
-noinst_HEADERS = \
-	converter.h \
-	osd-utils.h \
+sources_private_h =         \
+	converter.h             \
+	osd-utils.h             \
 	osm-gps-map-types.h
 
-EXTRA_DIST = \
-	poi.png
+sources_public_h =          \
+    osm-gps-map.h           \
+    osm-gps-map-osd.h       \
+    osm-gps-map-layer.h     \
+    osm-gps-map-track.h     \
+    osm-gps-map-point.h     \
+    osm-gps-map-image.h     \
+    osm-gps-map-source.h    \
+    osm-gps-map-widget.h    \
+    osm-gps-map-compat.h
+
+sources_c =                 \
+    converter.c             \
+    osd-utils.c             \
+    osm-gps-map-osd.c       \
+    osm-gps-map-layer.c     \
+    osm-gps-map-track.c     \
+    osm-gps-map-point.c     \
+    osm-gps-map-image.c     \
+    osm-gps-map-source.c    \
+    osm-gps-map-widget.c    \
+    osm-gps-map-compat.c
+
+libosmgpsmap_la_SOURCES =   \
+	$(sources_public_h)     \
+	$(sources_private_h)    \
+	$(sources_c)
+
+libosmgpsmapincdir = $(includedir)/osmgpsmap
+libosmgpsmapinc_HEADERS = $(sources_public_h)
+
+## Misc
+CLEANFILES =
+
+## GObject Introspection Support
+-include $(INTROSPECTION_MAKEFILE)
+INTROSPECTION_GIRS =
+INTROSPECTION_SCANNER_ARGS = --add-include-path=$(srcdir) --add-include-path=$(builddir)
+INTROSPECTION_COMPILER_ARGS = --includedir=$(srcdir)
+
+if HAVE_INTROSPECTION
+introspection_sources = $(sources_c) $(sources_public_h)
+
+OsmGpsMap-1.0.gir: libosmgpsmap.la
+OsmGpsMap_1_0_gir_INCLUDES = GObject-2.0 Gtk-2.0
+OsmGpsMap_1_0_gir_CFLAGS = $(OSMGPSMAP_CFLAGS)
+OsmGpsMap_1_0_gir_LIBS = libosmgpsmap.la
+OsmGpsMap_1_0_gir_FILES = $(introspection_sources)
+INTROSPECTION_GIRS += OsmGpsMap-1.0.gir
+
+girdir = $(datadir)/gir-1.0
+dist_gir_DATA = $(INTROSPECTION_GIRS)
+
+typelibdir = $(libdir)/girepository-1.0
+typelib_DATA = $(INTROSPECTION_GIRS:.gir=.typelib)
+
+CLEANFILES += $(dist_gir_DATA) $(typelib_DATA)
+endif
diff --git a/src/main.c b/src/main.c
deleted file mode 100644
index 3bc52d2..0000000
--- a/src/main.c
+++ /dev/null
@@ -1,318 +0,0 @@
-/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 4 -*- */
-/* vim:set et sw=4 ts=4 cino=t0,(0: */
-/*
- * main.c
- * Copyright (C) John Stowers 2008 <john.stowers at gmail.com>
- *
- * This is free software: you can redistribute it and/or modify it
- * under the terms of the GNU General Public License
- * as published by the Free Software Foundation; version 2.
- *
- * This program 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 General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdlib.h>
-#include <math.h>
-#include <glib.h>
-#include <gtk/gtk.h>
-#include <gdk/gdkkeysyms.h>
-#include "osm-gps-map.h"
-#include "osm-gps-map-osd.h"
-
-static OsmGpsMapSource_t map_provider = OSM_GPS_MAP_SOURCE_OPENSTREETMAP;
-static gboolean default_cache = FALSE;
-static gboolean no_cache = FALSE;
-static gboolean debug = FALSE;
-static GOptionEntry entries[] =
-{
-  { "default-cache", 'D', 0, G_OPTION_ARG_NONE, &default_cache, "Store maps in default cache", NULL },
-  { "no-cache", 'n', 0, G_OPTION_ARG_NONE, &no_cache, "Disable cache", NULL },
-  { "debug", 'd', 0, G_OPTION_ARG_NONE, &debug, "Enable debugging", NULL },
-  { "map", 'm', 0, G_OPTION_ARG_INT, &map_provider, "Map source", "N" },
-  { NULL }
-};
-
-static GdkPixbuf *STAR_IMAGE;
-
-typedef struct {
-    OsmGpsMap *map;
-    GtkWidget *entry;
-} timeout_cb_t;
-
-#define DEG2RAD(deg) (deg * M_PI / 180.0)
-#define RAD2DEG(rad) (rad / M_PI * 180.0)
-
-gboolean
-on_timeout_check_tiles_in_queue(gpointer user_data)
-{
-    gchar *msg;
-    int remaining;
-    timeout_cb_t *data = (timeout_cb_t *)user_data;
-    g_object_get(data->map, "tiles-queued", &remaining,NULL);
-
-    msg = g_strdup_printf("%d tiles queued",remaining);
-    gtk_entry_set_text(GTK_ENTRY(data->entry), msg);
-    g_free(msg);
-
-    return remaining > 0;
-}
-
-gboolean
-on_button_press_event (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
-{
-    coord_t coord;
-    OsmGpsMap *map = OSM_GPS_MAP(widget);
-
-    if (    ((event->button == 1) || (event->button == 3)) 
-            && (event->type == GDK_2BUTTON_PRESS) )
-    {
-        g_debug("Double clicked %f %f", event->x, event->y);
-        coord = osm_gps_map_get_co_ordinates(map, (int)event->x, (int)event->y);
-        osm_gps_map_draw_gps (map,
-                              RAD2DEG(coord.rlat),
-                              RAD2DEG(coord.rlon),
-                              (event->button == 1 ? OSM_GPS_MAP_INVALID : g_random_double_range(0,360)));
-    }
-
-    if ( (event->button == 2) && (event->type == GDK_BUTTON_PRESS) )
-    {
-        coord = osm_gps_map_get_co_ordinates(map, (int)event->x, (int)event->y);
-        osm_gps_map_add_image (map,
-                               RAD2DEG(coord.rlat),
-                               RAD2DEG(coord.rlon),
-                               STAR_IMAGE);
-    }
-    return FALSE;
-}
-
-gboolean
-on_button_release_event (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
-{
-    float lat,lon;
-    GtkEntry *entry = GTK_ENTRY(user_data);
-    OsmGpsMap *map = OSM_GPS_MAP(widget);
-
-    g_object_get(map, "latitude", &lat, "longitude", &lon, NULL);
-    gchar *msg = g_strdup_printf("%f,%f",lat,lon);
-    gtk_entry_set_text(entry, msg);
-    g_free(msg);
-
-    return FALSE;
-}
-
-gboolean
-on_zoom_in_clicked_event (GtkWidget *widget, gpointer user_data)
-{
-    int zoom;
-    OsmGpsMap *map = OSM_GPS_MAP(user_data);
-    g_object_get(map, "zoom", &zoom, NULL);
-    osm_gps_map_set_zoom(map, zoom+1);
-    return FALSE;
-}
-
-gboolean
-on_zoom_out_clicked_event (GtkWidget *widget, gpointer user_data)
-{
-    int zoom;
-    OsmGpsMap *map = OSM_GPS_MAP(user_data);
-    g_object_get(map, "zoom", &zoom, NULL);
-    osm_gps_map_set_zoom(map, zoom-1);
-    return FALSE;
-}
-
-gboolean
-on_home_clicked_event (GtkWidget *widget, gpointer user_data)
-{
-    OsmGpsMap *map = OSM_GPS_MAP(user_data);
-    osm_gps_map_set_mapcenter(map, -43.5326,172.6362,12);
-    return FALSE;
-}
-
-gboolean
-on_cache_clicked_event (GtkWidget *widget, gpointer user_data)
-{
-    int zoom,max_zoom;
-    coord_t pt1, pt2;
-    timeout_cb_t *data;
-
-    data = (timeout_cb_t *)user_data;
-    osm_gps_map_get_bbox(data->map, &pt1, &pt2);
-    g_object_get(data->map, "zoom", &zoom, "max-zoom", &max_zoom, NULL);
-    osm_gps_map_download_maps(data->map, &pt1, &pt2, zoom, max_zoom);
-    g_timeout_add(500, on_timeout_check_tiles_in_queue, user_data);
-
-    return FALSE;
-}
-
-void
-on_close (GtkWidget *widget, gpointer user_data)
-{
-    gtk_widget_destroy(widget);
-    gtk_main_quit();
-}
-
-void
-usage (GOptionContext *context)
-{
-    int i;
-
-    puts(g_option_context_get_help(context, TRUE, NULL));
-
-    printf("Valid map sources:\n");
-    for(i=OSM_GPS_MAP_SOURCE_NULL; i <= OSM_GPS_MAP_SOURCE_LAST; i++)
-    {
-        const char *name = osm_gps_map_source_get_friendly_name(i);
-        const char *uri = osm_gps_map_source_get_repo_uri(i);
-        if (uri != NULL)
-            printf("\t%d:\t%s\n",i,name);
-    }
-}
-
-int
-main (int argc, char **argv)
-{
-    GtkWidget *vbox;
-    GtkWidget *bbox;
-    GtkWidget *entry;
-    GtkWidget *window;
-    GtkWidget *zoomInbutton;
-    GtkWidget *zoomOutbutton;
-    GtkWidget *homeButton;
-    GtkWidget *cacheButton;
-    OsmGpsMap *map;
-    OsmGpsMapLayer *osd;
-    const char *repo_uri;
-    const char *friendly_name;
-    char *cachedir;
-    GError *error = NULL;
-    GOptionContext *context;
-    timeout_cb_t *data;
-
-    g_thread_init(NULL);
-    gtk_init (&argc, &argv);
-
-    context = g_option_context_new ("- Map browser");
-    g_option_context_set_help_enabled(context, FALSE);
-    g_option_context_add_main_entries (context, entries, NULL);
-
-    if (!g_option_context_parse (context, &argc, &argv, &error)) {
-        usage(context);
-        return 1;
-    }
-
-    /* Only use the repo_uri to check if the user has supplied a
-    valid map source ID */
-    repo_uri = osm_gps_map_source_get_repo_uri(map_provider);
-    if ( repo_uri == NULL ) {
-        usage(context);
-        return 2;
-    }
-
-    friendly_name = osm_gps_map_source_get_friendly_name(map_provider);
-
-    if (default_cache) {
-        cachedir = OSM_GPS_MAP_CACHE_AUTO;
-    } else if (no_cache) {
-        cachedir = OSM_GPS_MAP_CACHE_DISABLED;
-    } else {
-        char *mapcachedir;
-        mapcachedir = osm_gps_map_get_default_cache_directory();
-        cachedir = g_build_filename(mapcachedir,friendly_name,NULL);
-        g_free(mapcachedir);
-    }
-
-    if (debug)
-        gdk_window_set_debug_updates(TRUE);
-
-    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-    gtk_window_set_default_size(GTK_WINDOW(window), 400, 400);
-
-    STAR_IMAGE = gdk_pixbuf_new_from_file_at_size ("poi.png", 24,24,NULL);
-
-    g_debug("Map Cache Dir: %s", cachedir);
-    g_debug("Map Provider: %s (%d)", friendly_name, map_provider);
-
-    map = g_object_new (OSM_TYPE_GPS_MAP,
-                        "map-source",map_provider,
-                        "tile-cache",cachedir,
-                        "proxy-uri",g_getenv("http_proxy"),
-                        NULL);
-
-    osd = g_object_new (OSM_TYPE_GPS_MAP_OSD,
-                        "show-scale",TRUE,
-                        "show-coordinates",TRUE,
-                        "show-crosshair",TRUE,
-                        "show-dpad",TRUE,
-                        "show-zoom",TRUE,
-                        "show-gps-in-dpad",TRUE,
-                        "show-gps-in-zoom",FALSE,
-                        "dpad-radius", 30,
-                        NULL);
-    osm_gps_map_add_layer(OSM_GPS_MAP(map), osd);
-    g_object_unref(G_OBJECT(osd));
-
-    //Enable keyboard navigation
-    osm_gps_map_set_keyboard_shortcut(map, OSM_GPS_MAP_KEY_FULLSCREEN, GDK_F11);
-    osm_gps_map_set_keyboard_shortcut(map, OSM_GPS_MAP_KEY_UP, GDK_Up);
-    osm_gps_map_set_keyboard_shortcut(map, OSM_GPS_MAP_KEY_DOWN, GDK_Down);
-    osm_gps_map_set_keyboard_shortcut(map, OSM_GPS_MAP_KEY_LEFT, GDK_Left);
-    osm_gps_map_set_keyboard_shortcut(map, OSM_GPS_MAP_KEY_RIGHT, GDK_Right);
-
-    vbox = gtk_vbox_new (FALSE, 2);
-    gtk_container_add (GTK_CONTAINER (window), vbox);
-
-    //Add the map to the box
-    gtk_box_pack_start (GTK_BOX(vbox), GTK_WIDGET(map), TRUE, TRUE, 0);
-    //And add a box for the buttons
-    bbox = gtk_hbox_new (TRUE, 0);
-    gtk_box_pack_start (GTK_BOX(vbox), bbox, FALSE, TRUE, 0);
-    //And add the lat/long entry
-    entry = gtk_entry_new();
-    gtk_box_pack_start (GTK_BOX(vbox), entry, FALSE, TRUE, 0);
-
-    //Add buttons to the bbox
-    zoomInbutton = gtk_button_new_from_stock (GTK_STOCK_ZOOM_IN);
-    g_signal_connect (G_OBJECT (zoomInbutton), "clicked",
-                      G_CALLBACK (on_zoom_in_clicked_event), (gpointer) map);
-    gtk_box_pack_start (GTK_BOX(bbox), zoomInbutton, FALSE, TRUE, 0);
-
-    zoomOutbutton = gtk_button_new_from_stock (GTK_STOCK_ZOOM_OUT);
-    g_signal_connect (G_OBJECT (zoomOutbutton), "clicked",
-                      G_CALLBACK (on_zoom_out_clicked_event), (gpointer) map);
-    gtk_box_pack_start (GTK_BOX(bbox), zoomOutbutton, FALSE, TRUE, 0);
-
-    homeButton = gtk_button_new_from_stock (GTK_STOCK_HOME);
-    g_signal_connect (G_OBJECT (homeButton), "clicked",
-                      G_CALLBACK (on_home_clicked_event), (gpointer) map);
-    gtk_box_pack_start (GTK_BOX(bbox), homeButton, FALSE, TRUE, 0);
-
-    data = g_new0(timeout_cb_t, 1);
-    data->map = map;
-    data->entry = entry;
-    cacheButton = gtk_button_new_with_label ("Cache");
-    g_signal_connect (G_OBJECT (cacheButton), "clicked",
-                      G_CALLBACK (on_cache_clicked_event), (gpointer) data);
-    gtk_box_pack_start (GTK_BOX(bbox), cacheButton, FALSE, TRUE, 0);
-
-    //Connect to map events
-    g_signal_connect (G_OBJECT (map), "button-press-event",
-                      G_CALLBACK (on_button_press_event), (gpointer) entry);
-    g_signal_connect (G_OBJECT (map), "button-release-event",
-                      G_CALLBACK (on_button_release_event), (gpointer) entry);
-
-    g_signal_connect (window, "destroy",
-                      G_CALLBACK (on_close), (gpointer) map);
-
-    gtk_widget_show_all (window);
-
-    g_log_set_handler ("OsmGpsMap", G_LOG_LEVEL_MASK, g_log_default_handler, NULL);
-    gtk_main ();
-
-    return 0;
-}
diff --git a/src/osm-gps-map-compat.c b/src/osm-gps-map-compat.c
new file mode 100644
index 0000000..73bba14
--- /dev/null
+++ b/src/osm-gps-map-compat.c
@@ -0,0 +1,163 @@
+#include "converter.h"
+#include "osm-gps-map-compat.h"
+
+/**
+ * osm_gps_map_draw_gps:
+ *
+ * Deprecated: 0.7.0: Use osm_gps_map_gps_add() instead.
+ **/
+void
+osm_gps_map_draw_gps (OsmGpsMap *map, float latitude, float longitude, float heading)
+{
+    g_warning("%s is deprecated", G_STRFUNC);
+    osm_gps_map_gps_add (map, latitude, longitude, heading);
+}
+
+/**
+ * osm_gps_map_clear_gps:
+ *
+ * Deprecated: 0.7.0: Use osm_gps_map_gps_clear() instead.
+ **/
+void
+osm_gps_map_clear_gps (OsmGpsMap *map)
+{
+    g_warning("%s is deprecated", G_STRFUNC);
+    osm_gps_map_gps_clear (map);
+}
+
+/**
+ * osm_gps_map_add_track:
+ *
+ * Deprecated: 0.7.0: Use osm_gps_map_track_add() instead.
+ **/
+void
+osm_gps_map_add_track (OsmGpsMap *map, GSList *list)
+{
+    OsmGpsMapTrack *track;
+    g_warning("%s is deprecated", G_STRFUNC);
+    track = g_object_new (OSM_TYPE_GPS_MAP_TRACK, "track", list, NULL);
+    osm_gps_map_track_add (map, track);
+}
+
+/**
+ * osm_gps_map_clear_tracks:
+ *
+ * Deprecated: 0.7.0: Use osm_gps_map_track_remove_all() instead.
+ **/
+void
+osm_gps_map_clear_tracks (OsmGpsMap *map)
+{
+    g_warning("%s is deprecated", G_STRFUNC);
+    osm_gps_map_track_remove_all (map);
+}
+
+/**
+ * osm_gps_map_add_image_with_alignment:
+ *
+ * Deprecated: 0.7.0: Use osm_gps_map_image_add_with_alignment() instead.
+ **/
+void
+osm_gps_map_add_image_with_alignment (OsmGpsMap *map, float latitude, float longitude, GdkPixbuf *image, float xalign, float yalign)
+{
+    g_warning("%s is deprecated", G_STRFUNC);
+    osm_gps_map_image_add_with_alignment (map, latitude, longitude, image, xalign, yalign);
+}
+
+/**
+ * osm_gps_map_add_image:
+ *
+ * Deprecated: 0.7.0: Use osm_gps_map_image_add() instead.
+ **/
+void
+osm_gps_map_add_image (OsmGpsMap *map, float latitude, float longitude, GdkPixbuf *image)
+{
+    g_warning("%s is deprecated", G_STRFUNC);
+    osm_gps_map_image_add_with_alignment (map, latitude, longitude, image, 0.5, 0.5);
+}
+
+/**
+ * osm_gps_map_clear_images:
+ *
+ * Deprecated: 0.7.0: Use osm_gps_map_image_remove_all() instead.
+ **/
+void
+osm_gps_map_clear_images (OsmGpsMap *map)
+{
+    g_warning("%s is deprecated", G_STRFUNC);
+    osm_gps_map_image_remove_all (map);
+}
+
+/**
+ * osm_gps_map_add_layer:
+ *
+ * Deprecated: 0.7.0: Use osm_gps_map_layer_add() instead.
+ **/
+void
+osm_gps_map_add_layer (OsmGpsMap *map, OsmGpsMapLayer *layer)
+{
+    g_warning("%s is deprecated", G_STRFUNC);
+    osm_gps_map_layer_add (map, layer);
+}
+
+/**
+ * osm_gps_map_screen_to_geographic:
+ *
+ * Deprecated: 0.7.0: Use osm_gps_map_convert_screen_to_geographic() instead.
+ **/
+void
+osm_gps_map_screen_to_geographic (OsmGpsMap *map, gint pixel_x, gint pixel_y,
+                                  gfloat *latitude, gfloat *longitude)
+{
+    OsmGpsMapPoint p;
+    g_warning("%s is deprecated", G_STRFUNC);
+    osm_gps_map_convert_screen_to_geographic(map, pixel_x, pixel_y, &p);
+    if (latitude)
+        *latitude = rad2deg(p.rlat);
+    if (longitude)
+        *longitude = rad2deg(p.rlon);
+}
+
+/**
+ * osm_gps_map_geographic_to_screen:
+ *
+ * Deprecated: 0.7.0: Use osm_gps_map_convert_geographic_to_screen() instead.
+ **/
+void
+osm_gps_map_geographic_to_screen (OsmGpsMap *map,
+                                  gfloat latitude, gfloat longitude,
+                                  gint *pixel_x, gint *pixel_y)
+{
+    OsmGpsMapPoint p;
+    g_warning("%s is deprecated", G_STRFUNC);
+    osm_gps_map_point_set_degrees(&p, latitude, longitude);
+    osm_gps_map_convert_geographic_to_screen(map, &p, pixel_x, pixel_y);
+}
+
+/**
+ * osm_gps_map_get_co_ordinates:
+ *
+ * Deprecated: 0.7.0: Use osm_gps_map_convert_screen_to_geographic() or 
+ * osm_gps_map_get_event_location() instead.
+ **/
+OsmGpsMapPoint
+osm_gps_map_get_co_ordinates (OsmGpsMap *map, int pixel_x, int pixel_y)
+{
+    OsmGpsMapPoint p;
+    g_warning("%s is deprecated", G_STRFUNC);
+    osm_gps_map_convert_screen_to_geographic(map, pixel_x, pixel_y, &p);
+    return p;
+}
+
+/**
+ * osm_gps_map_set_mapcenter:
+ *
+ * Deprecated: 0.7.0: Use osm_gps_map_set_center_and_zoom() instead.
+ **/
+void
+osm_gps_map_set_mapcenter (OsmGpsMap *map, float latitude, float longitude, int zoom)
+{
+    g_warning("%s is deprecated", G_STRFUNC);
+    osm_gps_map_set_center_and_zoom (map, latitude, longitude, zoom);
+}
+
+
diff --git a/src/osm-gps-map-compat.h b/src/osm-gps-map-compat.h
new file mode 100644
index 0000000..e7ad063
--- /dev/null
+++ b/src/osm-gps-map-compat.h
@@ -0,0 +1,27 @@
+#ifndef _OSM_GPS_MAP_COMPAT_H
+#define _OSM_GPS_MAP_COMPAT_H
+
+#include "osm-gps-map-widget.h"
+
+G_BEGIN_DECLS
+
+/* Depreciated Functions */
+#define coord_t OsmGpsMapPoint
+void        osm_gps_map_add_track                   (OsmGpsMap *map, GSList *track)                                     G_GNUC_DEPRECATED;
+void        osm_gps_map_replace_track               (OsmGpsMap *map, GSList *old_track, GSList *new_track)              G_GNUC_DEPRECATED;
+void        osm_gps_map_clear_tracks                (OsmGpsMap *map)                                                    G_GNUC_DEPRECATED;
+void        osm_gps_map_draw_gps                    (OsmGpsMap *map, float latitude, float longitude, float heading)    G_GNUC_DEPRECATED;
+void        osm_gps_map_clear_gps                   (OsmGpsMap *map)                                                    G_GNUC_DEPRECATED;
+void        osm_gps_map_add_image                   (OsmGpsMap *map, float latitude, float longitude, GdkPixbuf *image) G_GNUC_DEPRECATED;
+void        osm_gps_map_add_image_with_alignment    (OsmGpsMap *map, float latitude, float longitude, GdkPixbuf *image, float xalign, float yalign) G_GNUC_DEPRECATED;
+gboolean    osm_gps_map_remove_image                (OsmGpsMap *map, GdkPixbuf *image)                                  G_GNUC_DEPRECATED;
+void        osm_gps_map_clear_images                (OsmGpsMap *map)                                                    G_GNUC_DEPRECATED;
+void        osm_gps_map_add_layer                   (OsmGpsMap *map, OsmGpsMapLayer *layer)                             G_GNUC_DEPRECATED;
+void        osm_gps_map_screen_to_geographic        (OsmGpsMap *map, gint pixel_x, gint pixel_y, gfloat *latitude, gfloat *longitude) G_GNUC_DEPRECATED;
+void        osm_gps_map_geographic_to_screen        (OsmGpsMap *map, gfloat latitude, gfloat longitude, gint *pixel_x, gint *pixel_y) G_GNUC_DEPRECATED;
+OsmGpsMapPoint  osm_gps_map_get_co_ordinates        (OsmGpsMap *map, int pixel_x, int pixel_y)                          G_GNUC_DEPRECATED;
+void        osm_gps_map_set_mapcenter               (OsmGpsMap *map, float latitude, float longitude, int zoom)         G_GNUC_DEPRECATED;
+
+G_END_DECLS
+
+#endif /* _OSM_GPS_MAP_COMPAT_H */
diff --git a/src/osm-gps-map-image.c b/src/osm-gps-map-image.c
new file mode 100644
index 0000000..59d3dbf
--- /dev/null
+++ b/src/osm-gps-map-image.c
@@ -0,0 +1,194 @@
+/* osm-gps-map-image.c */
+
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+#include "converter.h"
+#include "osm-gps-map-track.h"
+#include "osm-gps-map-image.h"
+
+G_DEFINE_TYPE (OsmGpsMapImage, osm_gps_map_image, G_TYPE_OBJECT)
+
+enum
+{
+    PROP_0,
+    PROP_PIXBUF,
+    PROP_X_ALIGN,
+    PROP_Y_ALIGN,
+    PROP_POINT,
+};
+
+struct _OsmGpsMapImagePrivate
+{
+    OsmGpsMapPoint  *pt;
+    GdkPixbuf       *pixbuf;
+    int             w;
+    int             h;
+    gfloat          xalign;
+    gfloat          yalign;
+};
+
+static void
+osm_gps_map_image_get_property (GObject    *object,
+                                guint       property_id,
+                                GValue     *value,
+                                GParamSpec *pspec)
+{
+    OsmGpsMapImagePrivate *priv = OSM_GPS_MAP_IMAGE(object)->priv;
+    switch (property_id)
+    {
+        case PROP_PIXBUF:
+            g_value_set_object (value, priv->pixbuf);
+            break;
+        case PROP_X_ALIGN:
+            g_value_set_float (value, priv->xalign);
+            break;
+        case PROP_Y_ALIGN:
+            g_value_set_float (value, priv->yalign);
+            break;
+        case PROP_POINT:
+            g_value_set_boxed (value, priv->pt);
+            break;
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+    }
+}
+
+static void
+osm_gps_map_image_set_property (GObject      *object,
+                                guint         property_id,
+                                const GValue *value,
+                                GParamSpec   *pspec)
+{
+    OsmGpsMapImagePrivate *priv = OSM_GPS_MAP_IMAGE(object)->priv;
+    switch (property_id)
+    {
+        case PROP_PIXBUF:
+            if (priv->pixbuf)
+                g_object_unref (priv->pixbuf);
+            priv->pixbuf = g_value_dup_object (value);
+            priv->w = gdk_pixbuf_get_width(priv->pixbuf);
+            priv->h = gdk_pixbuf_get_width(priv->pixbuf);
+            break;
+        case PROP_X_ALIGN:
+            priv->xalign = g_value_get_float (value);
+            break;
+        case PROP_Y_ALIGN:
+            priv->yalign = g_value_get_float (value);
+            break;
+        case PROP_POINT:
+            priv->pt = g_value_dup_boxed (value);
+            break;
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+    }
+}
+
+static void
+osm_gps_map_image_dispose (GObject *object)
+{
+    OsmGpsMapImagePrivate *priv = OSM_GPS_MAP_IMAGE(object)->priv;
+
+    if (priv->pixbuf)
+        g_object_unref (priv->pixbuf);
+
+    G_OBJECT_CLASS (osm_gps_map_image_parent_class)->dispose (object);
+}
+
+static void
+osm_gps_map_image_finalize (GObject *object)
+{
+    G_OBJECT_CLASS (osm_gps_map_image_parent_class)->finalize (object);
+}
+
+static void
+osm_gps_map_image_class_init (OsmGpsMapImageClass *klass)
+{
+    GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+    g_type_class_add_private (klass, sizeof (OsmGpsMapImagePrivate));
+
+    object_class->get_property = osm_gps_map_image_get_property;
+    object_class->set_property = osm_gps_map_image_set_property;
+    object_class->dispose = osm_gps_map_image_dispose;
+    object_class->finalize = osm_gps_map_image_finalize;
+
+    g_object_class_install_property (object_class,
+                                     PROP_PIXBUF,
+                                     g_param_spec_object ("pixbuf",
+                                                          "pixbuf",
+                                                          "the pixbuf for this image",
+                                                          GDK_TYPE_PIXBUF,
+                                                          G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
+
+    g_object_class_install_property (object_class,
+                                     PROP_X_ALIGN,
+                                     g_param_spec_float ("x-align",
+                                                         "x-align",
+                                                         "image x-alignment",
+                                                         0.0, /* minimum property value */
+                                                         1.0, /* maximum property value */
+                                                         0.5,
+                                                         G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
+
+    g_object_class_install_property (object_class,
+                                     PROP_Y_ALIGN,
+                                     g_param_spec_float ("y-align",
+                                                         "y-align",
+                                                         "image y-alignment",
+                                                         0.0, /* minimum property value */
+                                                         1.0, /* maximum property value */
+                                                         0.5,
+                                                         G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
+
+    g_object_class_install_property (object_class,
+                                     PROP_POINT,
+                                     g_param_spec_boxed ("point",
+                                                         "point",
+                                                         "location point",
+                                                         OSM_TYPE_GPS_MAP_POINT,
+                                                         G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
+}
+
+static void
+osm_gps_map_image_init (OsmGpsMapImage *self)
+{
+    self->priv = G_TYPE_INSTANCE_GET_PRIVATE ((self), OSM_TYPE_GPS_MAP_IMAGE, OsmGpsMapImagePrivate);
+}
+
+OsmGpsMapImage *
+osm_gps_map_image_new (void)
+{
+    return g_object_new (OSM_TYPE_GPS_MAP_IMAGE, NULL);
+}
+
+void
+osm_gps_map_image_draw (OsmGpsMapImage *object, GdkDrawable *drawable, GdkGC *gc, GdkRectangle *rect)
+{
+    OsmGpsMapImagePrivate *priv;
+    int xoffset, yoffset;
+
+    g_return_if_fail (OSM_IS_GPS_MAP_IMAGE (object));
+    priv = OSM_GPS_MAP_IMAGE(object)->priv;
+    xoffset =  priv->xalign * priv->w;
+    yoffset =  priv->yalign * priv->h;
+
+    gdk_draw_pixbuf (
+                     drawable,
+                     gc,
+                     priv->pixbuf,
+                     0,0,
+                     rect->x - xoffset,
+                     rect->y - yoffset,
+                     priv->w,
+                     priv->h,
+                     GDK_RGB_DITHER_NONE, 0, 0);
+    rect->width = priv->w;
+    rect->height = priv->w;
+}
+
+const OsmGpsMapPoint *
+osm_gps_map_image_get_point(OsmGpsMapImage *object)
+{
+    g_return_val_if_fail (OSM_IS_GPS_MAP_IMAGE (object), NULL);
+    return object->priv->pt;
+}
diff --git a/src/osm-gps-map-image.h b/src/osm-gps-map-image.h
new file mode 100644
index 0000000..16d382b
--- /dev/null
+++ b/src/osm-gps-map-image.h
@@ -0,0 +1,44 @@
+/* osm-gps-map-image.h */
+
+#ifndef _OSM_GPS_MAP_IMAGE_H
+#define _OSM_GPS_MAP_IMAGE_H
+
+#include <glib-object.h>
+#include <gdk/gdk.h>
+
+#include "osm-gps-map-point.h"
+
+G_BEGIN_DECLS
+
+#define OSM_TYPE_GPS_MAP_IMAGE              osm_gps_map_image_get_type()
+#define OSM_GPS_MAP_IMAGE(obj)              (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSM_TYPE_GPS_MAP_IMAGE, OsmGpsMapImage))
+#define OSM_GPS_MAP_IMAGE_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), OSM_TYPE_GPS_MAP_IMAGE, OsmGpsMapImageClass))
+#define OSM_IS_GPS_MAP_IMAGE(obj)           (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSM_TYPE_GPS_MAP_IMAGE))
+#define OSM_IS_GPS_MAP_IMAGE_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), OSM_TYPE_GPS_MAP_IMAGE))
+#define OSM_GPS_MAP_IMAGE_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), OSM_TYPE_GPS_MAP_IMAGE, OsmGpsMapImageClass))
+
+typedef struct _OsmGpsMapImage OsmGpsMapImage;
+typedef struct _OsmGpsMapImageClass OsmGpsMapImageClass;
+typedef struct _OsmGpsMapImagePrivate OsmGpsMapImagePrivate;
+
+struct _OsmGpsMapImage
+{
+    GObject parent;
+
+    OsmGpsMapImagePrivate *priv;
+};
+
+struct _OsmGpsMapImageClass
+{
+    GObjectClass parent_class;
+};
+
+GType osm_gps_map_image_get_type (void) G_GNUC_CONST;
+
+OsmGpsMapImage *osm_gps_map_image_new (void);
+void            osm_gps_map_image_draw (OsmGpsMapImage *object, GdkDrawable *drawable, GdkGC *gc, GdkRectangle *rect);
+const OsmGpsMapPoint *osm_gps_map_image_get_point(OsmGpsMapImage *object);
+
+G_END_DECLS
+
+#endif /* _OSM_GPS_MAP_IMAGE_H */
diff --git a/src/osm-gps-map-layer.h b/src/osm-gps-map-layer.h
index a189063..26fb51a 100644
--- a/src/osm-gps-map-layer.h
+++ b/src/osm-gps-map-layer.h
@@ -39,7 +39,7 @@ G_BEGIN_DECLS
 typedef struct _OsmGpsMapLayer          OsmGpsMapLayer;             /* dummy object */
 typedef struct _OsmGpsMapLayerIface     OsmGpsMapLayerIface;
 
-#include "osm-gps-map.h"
+#include "osm-gps-map-widget.h"
 
 struct _OsmGpsMapLayerIface {
     GTypeInterface parent;
diff --git a/src/osm-gps-map-osd.c b/src/osm-gps-map-osd.c
index d7458c6..0861a34 100644
--- a/src/osm-gps-map-osd.c
+++ b/src/osm-gps-map-osd.c
@@ -46,6 +46,7 @@ enum
 typedef struct _OsdScale {
     cairo_surface_t *surface;
     int zoom;
+    float lat;
 } OsdScale_t;
 
 typedef struct _OsdCoordinates {
@@ -247,6 +248,7 @@ osm_gps_map_osd_constructor (GType gtype, guint n_properties, GObjectConstructPa
     priv->scale = g_new0(OsdScale_t, 1);
     priv->scale->surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, OSD_SCALE_W, OSD_SCALE_H);
     priv->scale->zoom = -1;
+    priv->scale->lat = 360.0; /* init to an invalid lat so we get re-rendered */
 
     priv->coordinates = g_new0(OsdCoordinates_t, 1);
     priv->coordinates->surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, OSD_COORDINATES_W, OSD_COORDINATES_H);
@@ -464,24 +466,24 @@ osm_gps_map_osd_draw (OsmGpsMapLayer *osd,
     cairo_t *cr;
     OsmGpsMapOsd *self;
     OsmGpsMapOsdPrivate *priv;
-    GtkAllocation *allocation;
+    GtkAllocation allocation;
 
     g_return_if_fail(OSM_IS_GPS_MAP_OSD(osd));
 
     self = OSM_GPS_MAP_OSD(osd);
     priv = self->priv;
-    allocation = &(GTK_WIDGET(map)->allocation);
 
+    gtk_widget_get_allocation(GTK_WIDGET(map), &allocation);
     cr = gdk_cairo_create(drawable);
 
     if (priv->show_scale)
-        scale_draw(self, allocation, cr);
+        scale_draw(self, &allocation, cr);
     if (priv->show_coordinates)
-        coordinates_draw(self, allocation, cr);
+        coordinates_draw(self, &allocation, cr);
     if (priv->show_crosshair)
-        crosshair_draw(self, allocation, cr);
+        crosshair_draw(self, &allocation, cr);
     if (priv->show_zoom || priv->show_dpad)
-        controls_draw(self, allocation, cr);
+        controls_draw(self, &allocation, cr);
 
     cairo_destroy(cr);
 }
@@ -501,23 +503,23 @@ osm_gps_map_osd_button_press (OsmGpsMapLayer *osd,
     OsdControlPress_t but = OSD_NONE;
     OsmGpsMapOsd *self;
     OsmGpsMapOsdPrivate *priv;
-    GtkAllocation *allocation;
+    GtkAllocation allocation;
 
     g_return_val_if_fail(OSM_IS_GPS_MAP_OSD(osd), FALSE);
 
     self = OSM_GPS_MAP_OSD(osd);
     priv = self->priv;
-    allocation = &(GTK_WIDGET(map)->allocation);
+    gtk_widget_get_allocation(GTK_WIDGET(map), &allocation);
 
     if ((event->button == 1) && (event->type == GDK_BUTTON_PRESS)) {
         gint mx = event->x - priv->osd_x;
         gint my = event->y - priv->osd_y;
 
         if(priv->osd_x < 0)
-            mx -= (allocation->width - priv->osd_w);
+            mx -= (allocation.width - priv->osd_w);
     
         if(priv->osd_y < 0)
-            my -= (allocation->height - priv->osd_h);
+            my -= (allocation.height - priv->osd_h);
 
         /* first do a rough test for the OSD area. */
         /* this is just to avoid an unnecessary detailed test */
@@ -588,13 +590,15 @@ scale_render(OsmGpsMapOsd *self, OsmGpsMap *map)
     if(!scale->surface)
         return;
 
-    /* this only needs to be rendered if the zoom has changed */
+    /* this only needs to be rendered if the zoom or latitude has changed */
     gint zoom;
-    g_object_get(G_OBJECT(map), "zoom", &zoom, NULL);
-    if(zoom == scale->zoom)
+    gfloat lat;
+    g_object_get(G_OBJECT(map), "zoom", &zoom, "latitude", &lat, NULL);
+    if(zoom == scale->zoom && lat == scale->lat)
         return;
 
     scale->zoom = zoom;
+    scale->lat = lat;
 
     float m_per_pix = osm_gps_map_get_scale(map);
 
@@ -852,8 +856,9 @@ controls_render(OsmGpsMapOsd *self, OsmGpsMap *map)
 
     controls->rendered = TRUE;
 
-    GdkColor bg = GTK_WIDGET(map)->style->bg[GTK_STATE_NORMAL];
-    GdkColor fg = GTK_WIDGET(map)->style->fg[GTK_STATE_NORMAL];
+    GtkStyle *style = gtk_widget_get_style(GTK_WIDGET(map));
+    GdkColor bg = style->bg[GTK_STATE_NORMAL];
+    GdkColor fg = style->fg[GTK_STATE_NORMAL];
     //GdkColor da = GTK_WIDGET(map)->style->fg[GTK_STATE_INSENSITIVE];
 
     /* first fill with transparency */
diff --git a/src/osm-gps-map-point.c b/src/osm-gps-map-point.c
new file mode 100644
index 0000000..6c07ee7
--- /dev/null
+++ b/src/osm-gps-map-point.c
@@ -0,0 +1,71 @@
+/* osm-gps-map-point.c */
+
+#include "converter.h"
+#include "osm-gps-map-point.h"
+
+OsmGpsMapPoint *
+osm_gps_map_point_new_degrees(float lat, float lon)
+{
+    OsmGpsMapPoint *p = g_new0(OsmGpsMapPoint, 1);
+    p->rlat = deg2rad(lat);
+    p->rlon = deg2rad(lon);
+    return p;
+}
+
+OsmGpsMapPoint *
+osm_gps_map_point_new_radians(float rlat, float rlon)
+{
+    OsmGpsMapPoint *p = g_new0(OsmGpsMapPoint, 1);
+    p->rlat = rlat;
+    p->rlon = rlon;
+    return p;
+}
+
+void
+osm_gps_map_point_get_degrees(OsmGpsMapPoint *point, float *lat, float *lon)
+{
+    *lat = rad2deg(point->rlat);
+    *lon = rad2deg(point->rlon);
+}
+
+void
+osm_gps_map_point_get_radians(OsmGpsMapPoint *point, float *rlat, float *rlon)
+{
+    *rlat = point->rlat;
+    *rlon = point->rlon;
+}
+
+void
+osm_gps_map_point_set_degrees(OsmGpsMapPoint *point, float lat, float lon)
+{
+    point->rlat = deg2rad(lat);
+    point->rlon = deg2rad(lon);
+}
+
+void
+osm_gps_map_point_set_radians(OsmGpsMapPoint *point, float rlat, float rlon)
+{
+    point->rlat = rlat;
+    point->rlon = rlon;
+}
+
+static OsmGpsMapPoint *
+osm_gps_map_point_copy (const OsmGpsMapPoint *point)
+{
+    OsmGpsMapPoint *result = g_new (OsmGpsMapPoint, 1);
+    *result = *point;
+
+    return result;
+}
+
+GType
+osm_gps_map_point_get_type (void)
+{
+    static GType our_type = 0;
+
+    if (our_type == 0)
+        our_type = g_boxed_type_register_static (g_intern_static_string ("OsmGpsMapPoint"),
+				         (GBoxedCopyFunc)osm_gps_map_point_copy,
+				         (GBoxedFreeFunc)g_free);
+    return our_type;
+}
diff --git a/src/osm-gps-map-point.h b/src/osm-gps-map-point.h
new file mode 100644
index 0000000..a6f0c69
--- /dev/null
+++ b/src/osm-gps-map-point.h
@@ -0,0 +1,33 @@
+/* osm-gps-map-point.h */
+
+#ifndef _OSM_GPS_MAP_POINT_H
+#define _OSM_GPS_MAP_POINT_H
+
+#include <glib.h>
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define OSM_TYPE_GPS_MAP_POINT              osm_gps_map_point_get_type()
+
+typedef struct _OsmGpsMapPoint OsmGpsMapPoint;
+
+struct _OsmGpsMapPoint
+{
+    /* radians */
+    float  rlat;
+    float  rlon;
+};
+
+GType osm_gps_map_point_get_type (void) G_GNUC_CONST;
+
+OsmGpsMapPoint *    osm_gps_map_point_new_degrees   (float lat, float lon);
+OsmGpsMapPoint *    osm_gps_map_point_new_radians   (float rlat, float rlon);
+void                osm_gps_map_point_get_degrees   (OsmGpsMapPoint *point, float *lat, float *lon);
+void                osm_gps_map_point_get_radians   (OsmGpsMapPoint *point, float *rlat, float *rlon);
+void                osm_gps_map_point_set_degrees   (OsmGpsMapPoint *point, float lat, float lon);
+void                osm_gps_map_point_set_radians   (OsmGpsMapPoint *point, float rlat, float rlon);
+
+G_END_DECLS
+
+#endif /* _OSM_GPS_MAP_POINT_H */
diff --git a/src/osm-gps-map-source.c b/src/osm-gps-map-source.c
new file mode 100644
index 0000000..dacc024
--- /dev/null
+++ b/src/osm-gps-map-source.c
@@ -0,0 +1,182 @@
+#include "osm-gps-map-source.h"
+#include "osm-gps-map-types.h"
+
+const char* 
+osm_gps_map_source_get_friendly_name(OsmGpsMapSource_t source)
+{
+    switch(source)
+    {
+        case OSM_GPS_MAP_SOURCE_NULL:
+            return "None";
+        case OSM_GPS_MAP_SOURCE_OPENSTREETMAP:
+            return "OpenStreetMap I";
+        case OSM_GPS_MAP_SOURCE_OPENSTREETMAP_RENDERER:
+            return "OpenStreetMap II";
+        case OSM_GPS_MAP_SOURCE_OPENAERIALMAP:
+            return "OpenAerialMap";
+        case OSM_GPS_MAP_SOURCE_OPENCYCLEMAP:
+            return "OpenCycleMap";
+        case OSM_GPS_MAP_SOURCE_OSM_PUBLIC_TRANSPORT:
+            return "Public Transport";
+        case OSM_GPS_MAP_SOURCE_OSMC_TRAILS:
+            return "OSMC Trails";
+        case OSM_GPS_MAP_SOURCE_MAPS_FOR_FREE:
+            return "Maps-For-Free";
+        case OSM_GPS_MAP_SOURCE_GOOGLE_STREET:
+            return "Google Maps";
+        case OSM_GPS_MAP_SOURCE_GOOGLE_SATELLITE:
+            return "Google Satellite";
+        case OSM_GPS_MAP_SOURCE_GOOGLE_HYBRID:
+            return "Google Hybrid";
+        case OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_STREET:
+            return "Virtual Earth";
+        case OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_SATELLITE:
+            return "Virtual Earth Satellite";
+        case OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_HYBRID:
+            return "Virtual Earth Hybrid";
+        case OSM_GPS_MAP_SOURCE_YAHOO_STREET:
+            return "Yahoo Maps";
+        case OSM_GPS_MAP_SOURCE_YAHOO_SATELLITE:
+            return "Yahoo Satellite";
+        case OSM_GPS_MAP_SOURCE_YAHOO_HYBRID:
+            return "Yahoo Hybrid";
+        case OSM_GPS_MAP_SOURCE_LAST:
+        default:
+            return NULL;
+    }
+    return NULL;
+}
+
+//http://www.internettablettalk.com/forums/showthread.php?t=5209
+//https://garage.maemo.org/plugins/scmsvn/viewcvs.php/trunk/src/maps.c?root=maemo-mapper&view=markup
+//http://www.ponies.me.uk/maps/GoogleTileUtils.java
+//http://www.mgmaps.com/cache/MapTileCacher.perl
+const char* 
+osm_gps_map_source_get_repo_uri(OsmGpsMapSource_t source)
+{
+    switch(source)
+    {
+        case OSM_GPS_MAP_SOURCE_NULL:
+            return "none://";
+        case OSM_GPS_MAP_SOURCE_OPENSTREETMAP:
+            return OSM_REPO_URI;
+        case OSM_GPS_MAP_SOURCE_OPENAERIALMAP:
+            /* OpenAerialMap is down, offline till furthur notice
+               http://openaerialmap.org/pipermail/talk_openaerialmap.org/2008-December/000055.html */
+            return NULL;
+        case OSM_GPS_MAP_SOURCE_OPENSTREETMAP_RENDERER:
+            return "http://tah.openstreetmap.org/Tiles/tile/#Z/#X/#Y.png";
+        case OSM_GPS_MAP_SOURCE_OPENCYCLEMAP:
+            return "http://c.andy.sandbox.cloudmade.com/tiles/cycle/#Z/#X/#Y.png";
+        case OSM_GPS_MAP_SOURCE_OSM_PUBLIC_TRANSPORT:
+            return "http://tile.xn--pnvkarte-m4a.de/tilegen/#Z/#X/#Y.png";
+        case OSM_GPS_MAP_SOURCE_OSMC_TRAILS:
+            return "http://topo.geofabrik.de/trails/#Z/#X/#Y.png";
+        case OSM_GPS_MAP_SOURCE_MAPS_FOR_FREE:
+            return "http://maps-for-free.com/layer/relief/z#Z/row#Y/#Z_#X-#Y.jpg";
+        case OSM_GPS_MAP_SOURCE_GOOGLE_STREET:
+            return "http://mt#R.google.com/vt/lyrs=m@126&hl=en&x=#X&s=&y=#Y&z=#Z";
+        case OSM_GPS_MAP_SOURCE_GOOGLE_HYBRID:
+            return "http://mt#R.google.com/vt/lyrs=h@126&hl=en&x=#X&s=&y=#Y&z=#Z";
+        case OSM_GPS_MAP_SOURCE_GOOGLE_SATELLITE:
+            return "http://khm#R.google.com/kh/v=61&x=#X&y=#Y&z=#Z";
+        case OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_STREET:
+            return "http://a#R.ortho.tiles.virtualearth.net/tiles/r#W.jpeg?g=50";
+        case OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_SATELLITE:
+            return "http://a#R.ortho.tiles.virtualearth.net/tiles/a#W.jpeg?g=50";
+        case OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_HYBRID:
+            return "http://a#R.ortho.tiles.virtualearth.net/tiles/h#W.jpeg?g=50";
+        case OSM_GPS_MAP_SOURCE_YAHOO_STREET:
+        case OSM_GPS_MAP_SOURCE_YAHOO_SATELLITE:
+        case OSM_GPS_MAP_SOURCE_YAHOO_HYBRID:
+            /* TODO: Implement signed Y, aka U
+             * http://us.maps3.yimg.com/aerial.maps.yimg.com/ximg?v=1.7&t=a&s=256&x=%d&y=%-d&z=%d 
+             *  x = tilex,
+             *  y = (1 << (MAX_ZOOM - zoom)) - tiley - 1,
+             *  z = zoom - (MAX_ZOOM - 17));
+             */
+            return NULL;
+        case OSM_GPS_MAP_SOURCE_LAST:
+        default:
+            return NULL;
+    }
+    return NULL;
+}
+
+const char *
+osm_gps_map_source_get_image_format(OsmGpsMapSource_t source)
+{
+    switch(source) {
+        case OSM_GPS_MAP_SOURCE_NULL:
+        case OSM_GPS_MAP_SOURCE_OPENSTREETMAP:
+        case OSM_GPS_MAP_SOURCE_OPENSTREETMAP_RENDERER:
+        case OSM_GPS_MAP_SOURCE_OPENCYCLEMAP:
+        case OSM_GPS_MAP_SOURCE_OSM_PUBLIC_TRANSPORT:
+        case OSM_GPS_MAP_SOURCE_OSMC_TRAILS:
+            return "png";
+        case OSM_GPS_MAP_SOURCE_OPENAERIALMAP:
+        case OSM_GPS_MAP_SOURCE_GOOGLE_STREET:
+        case OSM_GPS_MAP_SOURCE_GOOGLE_HYBRID:
+        case OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_STREET:
+        case OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_SATELLITE:
+        case OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_HYBRID:
+        case OSM_GPS_MAP_SOURCE_YAHOO_STREET:
+        case OSM_GPS_MAP_SOURCE_YAHOO_SATELLITE:
+        case OSM_GPS_MAP_SOURCE_YAHOO_HYBRID:
+        case OSM_GPS_MAP_SOURCE_MAPS_FOR_FREE:
+        case OSM_GPS_MAP_SOURCE_GOOGLE_SATELLITE:
+            return "jpg";
+        case OSM_GPS_MAP_SOURCE_LAST:
+        default:
+            return "bin";
+    }
+    return "bin";
+}
+
+
+int 
+osm_gps_map_source_get_min_zoom(OsmGpsMapSource_t source)
+{
+    return 1;
+}
+
+int 
+osm_gps_map_source_get_max_zoom(OsmGpsMapSource_t source)
+{
+    switch(source) {
+        case OSM_GPS_MAP_SOURCE_NULL:
+            return 18;
+        case OSM_GPS_MAP_SOURCE_OPENSTREETMAP:
+        case OSM_GPS_MAP_SOURCE_OPENCYCLEMAP:
+        case OSM_GPS_MAP_SOURCE_OSM_PUBLIC_TRANSPORT:
+            return OSM_MAX_ZOOM;
+        case OSM_GPS_MAP_SOURCE_OPENSTREETMAP_RENDERER:
+        case OSM_GPS_MAP_SOURCE_OPENAERIALMAP:
+        case OSM_GPS_MAP_SOURCE_GOOGLE_STREET:
+        case OSM_GPS_MAP_SOURCE_GOOGLE_HYBRID:
+        case OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_STREET:
+        case OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_SATELLITE:
+        case OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_HYBRID:
+        case OSM_GPS_MAP_SOURCE_YAHOO_STREET:
+        case OSM_GPS_MAP_SOURCE_YAHOO_SATELLITE:
+        case OSM_GPS_MAP_SOURCE_YAHOO_HYBRID:
+            return 17;
+        case OSM_GPS_MAP_SOURCE_OSMC_TRAILS:
+            return 15;
+        case OSM_GPS_MAP_SOURCE_MAPS_FOR_FREE:
+            return 11;
+        case OSM_GPS_MAP_SOURCE_GOOGLE_SATELLITE:
+            return 18;
+        case OSM_GPS_MAP_SOURCE_LAST:
+        default:
+            return 17;
+    }
+    return 17;
+}
+
+gboolean
+osm_gps_map_source_is_valid(OsmGpsMapSource_t source)
+{
+    return osm_gps_map_source_get_repo_uri(source) != NULL;
+}
+
diff --git a/src/osm-gps-map-source.h b/src/osm-gps-map-source.h
new file mode 100644
index 0000000..94bfc23
--- /dev/null
+++ b/src/osm-gps-map-source.h
@@ -0,0 +1,39 @@
+#ifndef _OSM_GPS_MAP_SOURCE_H_
+#define _OSM_GPS_MAP_SOURCE_H_
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+typedef enum {
+    OSM_GPS_MAP_SOURCE_NULL,
+    OSM_GPS_MAP_SOURCE_OPENSTREETMAP,
+    OSM_GPS_MAP_SOURCE_OPENSTREETMAP_RENDERER,
+    OSM_GPS_MAP_SOURCE_OPENAERIALMAP,
+    OSM_GPS_MAP_SOURCE_MAPS_FOR_FREE,
+    OSM_GPS_MAP_SOURCE_OPENCYCLEMAP,
+    OSM_GPS_MAP_SOURCE_OSM_PUBLIC_TRANSPORT,
+    OSM_GPS_MAP_SOURCE_GOOGLE_STREET,
+    OSM_GPS_MAP_SOURCE_GOOGLE_SATELLITE,
+    OSM_GPS_MAP_SOURCE_GOOGLE_HYBRID,
+    OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_STREET,
+    OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_SATELLITE,
+    OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_HYBRID,
+    OSM_GPS_MAP_SOURCE_YAHOO_STREET,
+    OSM_GPS_MAP_SOURCE_YAHOO_SATELLITE,
+    OSM_GPS_MAP_SOURCE_YAHOO_HYBRID,
+    OSM_GPS_MAP_SOURCE_OSMC_TRAILS,
+
+    OSM_GPS_MAP_SOURCE_LAST
+} OsmGpsMapSource_t;
+
+const char* osm_gps_map_source_get_friendly_name    (OsmGpsMapSource_t source);
+const char* osm_gps_map_source_get_repo_uri         (OsmGpsMapSource_t source);
+const char* osm_gps_map_source_get_image_format     (OsmGpsMapSource_t source);
+int         osm_gps_map_source_get_min_zoom         (OsmGpsMapSource_t source);
+int         osm_gps_map_source_get_max_zoom         (OsmGpsMapSource_t source);
+gboolean    osm_gps_map_source_is_valid             (OsmGpsMapSource_t source);
+
+G_END_DECLS
+
+#endif /* _OSM_GPS_MAP_SOURCE_H_ */
diff --git a/src/osm-gps-map-track.c b/src/osm-gps-map-track.c
new file mode 100644
index 0000000..74a642e
--- /dev/null
+++ b/src/osm-gps-map-track.c
@@ -0,0 +1,241 @@
+/* osm-gps-map-track.c */
+
+#include <gdk/gdk.h>
+
+#include "converter.h"
+#include "osm-gps-map-track.h"
+
+G_DEFINE_TYPE (OsmGpsMapTrack, osm_gps_map_track, G_TYPE_OBJECT)
+
+enum
+{
+    PROP_0,
+    PROP_VISIBLE,
+    PROP_TRACK,
+    PROP_LINE_WIDTH,
+    PROP_ALPHA,
+    PROP_COLOR
+};
+
+enum
+{
+	POINT_ADDED,
+	LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = {0,};
+
+struct _OsmGpsMapTrackPrivate
+{
+    GSList *track;
+    gboolean visible;
+    gfloat linewidth;
+    gfloat alpha;
+    GdkColor color;
+};
+
+#define DEFAULT_R   (60000)
+#define DEFAULT_G   (0)
+#define DEFAULT_B   (0)
+#define DEFAULT_A   (0.6)
+
+static void
+osm_gps_map_track_get_property (GObject    *object,
+                                guint       property_id,
+                                GValue     *value,
+                                GParamSpec *pspec)
+{
+    OsmGpsMapTrackPrivate *priv = OSM_GPS_MAP_TRACK(object)->priv;
+
+    switch (property_id)
+    {
+        case PROP_VISIBLE:
+            g_value_set_boolean(value, priv->visible);
+            break;
+        case PROP_TRACK:
+            g_value_set_pointer(value, priv->track);
+            break;
+        case PROP_LINE_WIDTH:
+            g_value_set_float(value, priv->linewidth);
+            break;
+        case PROP_ALPHA:
+            g_value_set_float(value, priv->alpha);
+            break;
+        case PROP_COLOR:
+            g_value_set_boxed(value, &priv->color);
+            break;
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+    }
+}
+
+static void
+osm_gps_map_track_set_property (GObject      *object,
+                                guint         property_id,
+                                const GValue *value,
+                                GParamSpec   *pspec)
+{
+    OsmGpsMapTrackPrivate *priv = OSM_GPS_MAP_TRACK(object)->priv;
+
+    switch (property_id)
+    {
+        case PROP_VISIBLE:
+            priv->visible = g_value_get_boolean (value);
+            break;
+        case PROP_TRACK:
+            priv->track = g_value_get_pointer (value);
+            break;
+        case PROP_LINE_WIDTH:
+            priv->linewidth = g_value_get_float (value);
+            break;
+        case PROP_ALPHA:
+            priv->alpha = g_value_get_float (value);
+            break;
+        case PROP_COLOR: {
+            GdkColor *c = g_value_get_boxed (value);
+            priv->color.red = c->red;
+            priv->color.green = c->green;
+            priv->color.blue = c->blue;
+            } break;
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+    }
+}
+
+static void
+osm_gps_map_track_dispose (GObject *object)
+{
+    g_return_if_fail (OSM_IS_GPS_MAP_TRACK (object));
+    OsmGpsMapTrackPrivate *priv = OSM_GPS_MAP_TRACK(object)->priv;
+
+    if (priv->track) {
+        g_slist_foreach(priv->track, (GFunc) g_free, NULL);
+        g_slist_free(priv->track);
+        priv->track = NULL;
+    }
+
+    G_OBJECT_CLASS (osm_gps_map_track_parent_class)->dispose (object);
+}
+
+static void
+osm_gps_map_track_finalize (GObject *object)
+{
+    G_OBJECT_CLASS (osm_gps_map_track_parent_class)->finalize (object);
+}
+
+static void
+osm_gps_map_track_class_init (OsmGpsMapTrackClass *klass)
+{
+    GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+    g_type_class_add_private (klass, sizeof (OsmGpsMapTrackPrivate));
+
+    object_class->get_property = osm_gps_map_track_get_property;
+    object_class->set_property = osm_gps_map_track_set_property;
+    object_class->dispose = osm_gps_map_track_dispose;
+    object_class->finalize = osm_gps_map_track_finalize;
+
+    g_object_class_install_property (object_class,
+                                     PROP_VISIBLE,
+                                     g_param_spec_boolean ("visible",
+                                                           "visible",
+                                                           "should this track be visible",
+                                                           TRUE,
+                                                           G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
+
+    g_object_class_install_property (object_class,
+                                     PROP_TRACK,
+                                     g_param_spec_pointer ("track",
+                                                           "track",
+                                                           "list of points for the track",
+                                                           G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
+
+    g_object_class_install_property (object_class,
+                                     PROP_LINE_WIDTH,
+                                     g_param_spec_float ("line-width",
+                                                         "line-width",
+                                                         "width of the lines drawn for the track",
+                                                         0.0,       /* minimum property value */
+                                                         100.0,     /* maximum property value */
+                                                         4.0,
+                                                         G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
+
+    g_object_class_install_property (object_class,
+                                     PROP_ALPHA,
+                                     g_param_spec_float ("alpha",
+                                                         "alpha",
+                                                         "alpha transparency of the track",
+                                                         0.0,       /* minimum property value */
+                                                         1.0,       /* maximum property value */
+                                                         DEFAULT_A,
+                                                         G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
+
+    g_object_class_install_property (object_class,
+                                     PROP_COLOR,
+                                     g_param_spec_boxed ("color",
+                                                         "color",
+                                                         "color of the track",
+                                                         GDK_TYPE_COLOR,
+                                                         G_PARAM_READABLE | G_PARAM_WRITABLE));
+
+	/**
+	 * OsmGpsMapTrack::point-added:
+	 * @self: A #OsmGpsMapTrack
+	 *
+	 * The point-added signal.
+	 */
+	signals [POINT_ADDED] = g_signal_new ("point-added",
+	                            OSM_TYPE_GPS_MAP_TRACK,
+	                            G_SIGNAL_RUN_FIRST,
+	                            0,
+	                            NULL,
+	                            NULL,
+	                            g_cclosure_marshal_VOID__BOXED,
+	                            G_TYPE_NONE,
+	                            1,
+                                OSM_TYPE_GPS_MAP_POINT);
+}
+
+static void
+osm_gps_map_track_init (OsmGpsMapTrack *self)
+{
+    self->priv = G_TYPE_INSTANCE_GET_PRIVATE((self), OSM_TYPE_GPS_MAP_TRACK, OsmGpsMapTrackPrivate);
+
+    self->priv->color.red = DEFAULT_R;
+    self->priv->color.green = DEFAULT_G;
+    self->priv->color.blue = DEFAULT_B;
+}
+
+void
+osm_gps_map_track_add_point (OsmGpsMapTrack *track, OsmGpsMapPoint *point)
+{
+    g_return_if_fail (OSM_IS_GPS_MAP_TRACK (track));
+    OsmGpsMapTrackPrivate *priv = track->priv;
+
+    priv->track = g_slist_append (priv->track, point);
+    g_signal_emit (track, signals[POINT_ADDED], 0, point);
+}
+
+GSList *
+osm_gps_map_track_get_points (OsmGpsMapTrack *track)
+{
+    g_return_val_if_fail (OSM_IS_GPS_MAP_TRACK (track), NULL);
+    return track->priv->track;
+}
+
+void
+osm_gps_map_track_get_color (OsmGpsMapTrack *track, GdkColor *color)
+{
+    g_return_if_fail (OSM_IS_GPS_MAP_TRACK (track));
+    color->red = track->priv->color.red;
+    color->green = track->priv->color.green;
+    color->blue = track->priv->color.blue;
+}
+
+
+OsmGpsMapTrack *
+osm_gps_map_track_new (void)
+{
+    return g_object_new (OSM_TYPE_GPS_MAP_TRACK, NULL);
+}
+
diff --git a/src/osm-gps-map-track.h b/src/osm-gps-map-track.h
new file mode 100644
index 0000000..b31645f
--- /dev/null
+++ b/src/osm-gps-map-track.h
@@ -0,0 +1,46 @@
+/* osm-gps-map-track.h */
+
+#ifndef _OSM_GPS_MAP_TRACK_H
+#define _OSM_GPS_MAP_TRACK_H
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gdk/gdk.h>
+
+#include "osm-gps-map-point.h"
+
+G_BEGIN_DECLS
+
+#define OSM_TYPE_GPS_MAP_TRACK              osm_gps_map_track_get_type()
+#define OSM_GPS_MAP_TRACK(obj)              (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSM_TYPE_GPS_MAP_TRACK, OsmGpsMapTrack))
+#define OSM_GPS_MAP_TRACK_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), OSM_TYPE_GPS_MAP_TRACK, OsmGpsMapTrackClass))
+#define OSM_IS_GPS_MAP_TRACK(obj)           (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSM_TYPE_GPS_MAP_TRACK))
+#define OSM_IS_GPS_MAP_TRACK_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), OSM_TYPE_GPS_MAP_TRACK))
+#define OSM_GPS_MAP_TRACK_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), OSM_TYPE_GPS_MAP_TRACK, OsmGpsMapTrackClass))
+
+typedef struct _OsmGpsMapTrack OsmGpsMapTrack;
+typedef struct _OsmGpsMapTrackClass OsmGpsMapTrackClass;
+typedef struct _OsmGpsMapTrackPrivate OsmGpsMapTrackPrivate;
+
+struct _OsmGpsMapTrack
+{
+    GObject parent;
+
+    OsmGpsMapTrackPrivate *priv;
+};
+
+struct _OsmGpsMapTrackClass
+{
+    GObjectClass parent_class;
+};
+
+GType osm_gps_map_track_get_type (void) G_GNUC_CONST;
+
+OsmGpsMapTrack *    osm_gps_map_track_new           (void);
+void                osm_gps_map_track_add_point     (OsmGpsMapTrack *track, OsmGpsMapPoint *point);
+GSList *            osm_gps_map_track_get_points    (OsmGpsMapTrack *track);
+void                osm_gps_map_track_get_color     (OsmGpsMapTrack *track, GdkColor *color);
+
+G_END_DECLS
+
+#endif /* _OSM_GPS_MAP_TRACK_H */
diff --git a/src/osm-gps-map-types.h b/src/osm-gps-map-types.h
index dec708d..a9b13a3 100644
--- a/src/osm-gps-map-types.h
+++ b/src/osm-gps-map-types.h
@@ -24,13 +24,13 @@
 #ifndef _OSM_GPS_MAP_TYPES_H_
 #define _OSM_GPS_MAP_TYPES_H_
 
-#include "config.h"
-
+#include <glib.h>
 #include <gdk/gdk.h>
+#include <gtk/gtk.h>
 #if USE_LIBSOUP22
 #include <libsoup/soup.h>
 #endif
-#include "osm-gps-map.h"
+#include "osm-gps-map-widget.h"
 
 #define TILESIZE 256
 #define MAX_ZOOM 20
@@ -64,39 +64,37 @@
 /* equatorial radius in meters */
 #define OSM_EQ_RADIUS   (6378137.0)
 
-typedef struct {
-    int x1;
-    int y1;
-    int x2;
-    int y2;
-} bbox_pixel_t;
-
-typedef struct {
-    /* The details of the tile to download */
-    char *uri;
-    char *folder;
-    char *filename;
-    OsmGpsMap *map;
-    /* whether to redraw the map when the tile arrives */
-    gboolean redraw;
-#if USE_LIBSOUP22
-    SoupSession *session;
+#if !GLIB_CHECK_VERSION (2, 16, 0)
+int g_strcmp0(const char *str1, const char *str2)
+{
+    if( str1 == NULL && str2 == NULL ) return 0;
+    if( str1 == NULL ) return -1;
+    if( str2 == NULL ) return 1;
+    return strcmp(str1, str2);
+}
 #endif
-} tile_download_t;
 
-typedef struct {
-    int x;
-    int y;
-    int zoom;
-} tile_t;
+#if !GTK_CHECK_VERSION (2, 20, 0)
+#define gtk_widget_get_realized(widget)                         (GTK_WIDGET_REALIZED (widget))
+#define gtk_widget_get_mapped(widget)                           (GTK_WIDGET_MAPPED (widget))
+#endif /* GTK < 2.20.0 */
 
-typedef struct {
-    coord_t pt;
-    GdkPixbuf *image;
-    int w;
-    int h;
-    int xoffset;
-    int yoffset;
-} image_t;
+#if !GTK_CHECK_VERSION (2, 18, 0)
+#define gtk_cell_renderer_get_alignment(cell, xalign, yalign)   g_object_get (cell, "xalign", xalign, "yalign", yalign, NULL);
+#define gtk_cell_renderer_get_padding(cell, xpad, ypad)         g_object_get (cell, "xpad", xpad, "ypad", ypad, NULL);
+#define gtk_cell_renderer_set_padding(cell, xpad, ypad)         g_object_set (cell, "xpad", xpad, "ypad", ypad, NULL);
+#define gtk_widget_get_allocation(widget, alloc)                (*(alloc) = (widget)->allocation)
+#define gtk_widget_set_allocation(widget, alloc)                ((widget)->allocation = *(alloc))
+#define gtk_widget_get_app_paintable(widget)                    (GTK_WIDGET_APP_PAINTABLE (widget))
+#define gtk_widget_set_can_default(widget, can_default)         ((can_default) ? (GTK_WIDGET_SET_FLAGS (w, GTK_CAN_DEFAULT)) : (GTK_WIDGET_UNSET_FLAGS (w, GTK_CAN_DEFAULT)))
+#define gtk_widget_set_can_focus(widget, can_focus)             ((can_focus) ? (GTK_WIDGET_SET_FLAGS (w, GTK_CAN_FOCUS)) : (GTK_WIDGET_UNSET_FLAGS (w, GTK_CAN_FOCUS)))
+#define gtk_widget_set_double_buffered(widget, double_buffered) ((double_buffered) ? (GTK_WIDGET_SET_FLAGS (w, GTK_DOUBLE_BUFFERED)) : (GTK_WIDGET_UNSET_FLAGS (w, GTK_DOUBLE_BUFFERED)))
+#define gtk_widget_is_drawable(widget)                          (GTK_WIDGET_DRAWABLE (widget))
+#define gtk_widget_has_focus(widget)                            (GTK_WIDGET_HAS_FOCUS (widget))
+#define gtk_widget_get_has_window(widget)                       (!GTK_WIDGET_NO_WINDOW (widget))
+#define gtk_widget_get_state(widget)                            ((widget)->state)
+#define gtk_widget_get_visible(widget)                          (GTK_WIDGET_VISIBLE (widget))
+#define gtk_widget_set_window(widget, _window)                  ((widget)->window = _window)
+#endif /* GTK+ < 2.18.0 */
 
 #endif /* _OSM_GPS_MAP_TYPES_H_ */
diff --git a/src/osm-gps-map.c b/src/osm-gps-map-widget.c
similarity index 65%
rename from src/osm-gps-map.c
rename to src/osm-gps-map-widget.c
index eb0445f..f88147f 100644
--- a/src/osm-gps-map.c
+++ b/src/osm-gps-map-widget.c
@@ -39,8 +39,10 @@
 #include <cairo.h>
 
 #include "converter.h"
+#include "osm-gps-map-source.h"
 #include "osm-gps-map-types.h"
-#include "osm-gps-map.h"
+#include "osm-gps-map-widget.h"
+#include "osm-gps-map-compat.h"
 
 #define ENABLE_DEBUG                (0)
 #define EXTRA_BORDER                (TILESIZE / 2)
@@ -56,11 +58,12 @@ struct _OsmGpsMapPrivate
     int map_zoom;
     int max_zoom;
     int min_zoom;
-    gboolean map_auto_center;
-    gboolean map_auto_download;
     int map_x;
     int map_y;
 
+    /* Controls auto centering the map when a new GPS position arrives */
+    gfloat map_auto_center_threshold;
+
     /* Latitude and longitude of the center of the map, in radians */
     gfloat center_rlat;
     gfloat center_rlon;
@@ -87,16 +90,14 @@ struct _OsmGpsMapPrivate
     char *repo_uri;
     char *image_format;
     int uri_format;
-    //flag indicating if the map source is located on the google
-    gboolean the_google;
 
     //gps tracking state
-    gboolean record_trip_history;
-    gboolean show_trip_history;
     GSList *trip_history;
-    coord_t *gps;
     float gps_heading;
-    gboolean gps_valid;
+
+    OsmGpsMapPoint *gps;
+    OsmGpsMapTrack *gps_track;
+    gboolean gps_track_used;
 
 #ifdef OSD_DOUBLE_BUFFER
     GdkPixmap *dbuf_pixmap;
@@ -124,21 +125,30 @@ struct _OsmGpsMapPrivate
     int drag_start_map_x;
     int drag_start_map_y;
     int drag_limit;
-    guint drag_expose;
+    guint drag_expose_source;
 
-    //for customizing the redering of the gps track
-    int ui_gps_track_width;
+    /* for customizing the redering of the gps track */
     int ui_gps_point_inner_radius;
     int ui_gps_point_outer_radius;
 
-    //For storing keybindings
+    /* For storing keybindings */
     guint keybindings[OSM_GPS_MAP_KEY_MAX];
 
-    guint fullscreen : 1;
+    /* flags controlling which features are enabled */
     guint keybindings_enabled : 1;
+    guint map_auto_download_enabled : 1;
+    guint map_auto_center_enabled : 1;
+    guint trip_history_record_enabled : 1;
+    guint trip_history_show_enabled : 1;
+    guint gps_point_enabled : 1;
+
+    /* state flags */
     guint is_disposed : 1;
-    guint dragging : 1;
-    guint button_down : 1;
+    guint is_constructed : 1;
+    guint is_dragging : 1;
+    guint is_button_down : 1;
+    guint is_fullscreen : 1;
+    guint is_google : 1;
 };
 
 #define OSM_GPS_MAP_PRIVATE(o)  (OSM_GPS_MAP (o)->priv)
@@ -151,10 +161,22 @@ typedef struct
     guint redraw_cycle;
 } OsmCachedTile;
 
+typedef struct {
+    /* The details of the tile to download */
+    char *uri;
+    char *folder;
+    char *filename;
+    OsmGpsMap *map;
+    /* whether to redraw the map when the tile arrives */
+    gboolean redraw;
+#if USE_LIBSOUP22
+    SoupSession *session;
+#endif
+} OsmTileDownload;
+
 enum
 {
     PROP_0,
-
     PROP_AUTO_CENTER,
     PROP_RECORD_TRIP_HISTORY,
     PROP_SHOW_TRIP_HISTORY,
@@ -178,6 +200,8 @@ enum
     PROP_MAP_SOURCE,
     PROP_IMAGE_FORMAT,
     PROP_DRAG_LIMIT,
+    PROP_AUTO_CENTER_THRESHOLD,
+    PROP_SHOW_GPS_POINT
 };
 
 G_DEFINE_TYPE (OsmGpsMap, osm_gps_map, GTK_TYPE_DRAWING_AREA);
@@ -186,10 +210,7 @@ G_DEFINE_TYPE (OsmGpsMap, osm_gps_map, GTK_TYPE_DRAWING_AREA);
  * Drawing function forward defintions
  */
 static gchar    *replace_string(const gchar *src, const gchar *from, const gchar *to);
-static void     inspect_map_uri(OsmGpsMap *map);
 static gchar    *replace_map_uri(OsmGpsMap *map, const gchar *uri, int zoom, int x, int y);
-static void     osm_gps_map_print_images (OsmGpsMap *map);
-static void     osm_gps_map_draw_gps_point (OsmGpsMap *map);
 static void     osm_gps_map_blit_tile(OsmGpsMap *map, GdkPixbuf *pixbuf, int offset_x, int offset_y);
 #if USE_LIBSOUP22
 static void     osm_gps_map_tile_download_complete (SoupMessage *msg, gpointer user_data);
@@ -322,11 +343,10 @@ map_convert_coords_to_quadtree_string(OsmGpsMap *map, gint x, gint y, gint zooml
 
 
 static void
-inspect_map_uri(OsmGpsMap *map)
+inspect_map_uri(OsmGpsMapPrivate *priv)
 {
-    OsmGpsMapPrivate *priv = map->priv;
     priv->uri_format = 0;
-    priv->the_google = FALSE;
+    priv->is_google = FALSE;
 
     if (g_strrstr(priv->repo_uri, URI_MARKER_X))
         priv->uri_format |= URI_HAS_X;
@@ -353,9 +373,9 @@ inspect_map_uri(OsmGpsMap *map)
         priv->uri_format |= URI_HAS_R;
 
     if (g_strrstr(priv->repo_uri, "google.com"))
-        priv->the_google = TRUE;
+        priv->is_google = TRUE;
 
-    g_debug("URI Format: 0x%X (google: %X)", priv->uri_format, priv->the_google);
+    g_debug("URI Format: 0x%X (google: %X)", priv->uri_format, priv->is_google);
 
 }
 
@@ -380,28 +400,23 @@ replace_map_uri(OsmGpsMap *map, const gchar *uri, int zoom, int x, int y)
             case URI_HAS_X:
                 s = g_strdup_printf("%d", x);
                 url = replace_string(url, URI_MARKER_X, s);
-                //g_debug("FOUND " URI_MARKER_X);
                 break;
             case URI_HAS_Y:
                 s = g_strdup_printf("%d", y);
                 url = replace_string(url, URI_MARKER_Y, s);
-                //g_debug("FOUND " URI_MARKER_Y);
                 break;
             case URI_HAS_Z:
                 s = g_strdup_printf("%d", zoom);
                 url = replace_string(url, URI_MARKER_Z, s);
-                //g_debug("FOUND " URI_MARKER_Z);
                 break;
             case URI_HAS_S:
                 s = g_strdup_printf("%d", priv->max_zoom-zoom);
                 url = replace_string(url, URI_MARKER_S, s);
-                //g_debug("FOUND " URI_MARKER_S);
                 break;
             case URI_HAS_Q:
                 map_convert_coords_to_quadtree_string(map,x,y,zoom,location,'t',"qrts");
                 s = g_strdup_printf("%s", location);
                 url = replace_string(url, URI_MARKER_Q, s);
-                //g_debug("FOUND " URI_MARKER_Q);
                 break;
             case URI_HAS_Q0:
                 map_convert_coords_to_quadtree_string(map,x,y,zoom,location,'\0', "0123");
@@ -421,7 +436,6 @@ replace_map_uri(OsmGpsMap *map, const gchar *uri, int zoom, int x, int y)
             case URI_HAS_R:
                 s = g_strdup_printf("%d", g_random_int_range(0,4));
                 url = replace_string(url, URI_MARKER_R, s);
-                //g_debug("FOUND " URI_MARKER_R);
                 break;
             default:
                 s = NULL;
@@ -454,63 +468,34 @@ osm_gps_map_get_scale_at_point(int zoom, float rlat, float rlon)
     return cos(rlat) * M_PI * OSM_EQ_RADIUS / (1<<(7+zoom));
 }
 
-/* clears the trip list and all resources */
-static void
-osm_gps_map_free_trip (OsmGpsMap *map)
+static GSList *
+gslist_remove_one_gobject(GSList **list, GObject *gobj)
 {
-    OsmGpsMapPrivate *priv = map->priv;
-    if (priv->trip_history) {
-        g_slist_foreach(priv->trip_history, (GFunc) g_free, NULL);
-        g_slist_free(priv->trip_history);
-        priv->trip_history = NULL;
+    GSList *data = g_slist_find(*list, gobj);
+    if (data) {
+        g_object_unref(gobj);
+        *list = g_slist_delete_link(*list, data);
     }
+    return data;
 }
 
-/* clears the tracks and all resources */
 static void
-osm_gps_map_free_tracks (OsmGpsMap *map)
+gslist_of_gobjects_free(GSList **list)
 {
-    OsmGpsMapPrivate *priv = map->priv;
-    if (priv->tracks)
-    {
-        GSList* tmp = priv->tracks;
-        while (tmp != NULL)
-        {
-            g_slist_foreach(tmp->data, (GFunc) g_free, NULL);
-            g_slist_free(tmp->data);
-            tmp = g_slist_next(tmp);
-        }
-        g_slist_free(priv->tracks);
-        priv->tracks = NULL;
+    if (list) {
+        g_slist_foreach(*list, (GFunc) g_object_unref, NULL);
+        g_slist_free(*list);
+        *list = NULL;
     }
 }
 
-/* free the poi image lists */
 static void
-osm_gps_map_free_images (OsmGpsMap *map)
+gslist_of_data_free (GSList **list)
 {
-    OsmGpsMapPrivate *priv = map->priv;
-    if (priv->images) {
-        GSList *list;
-        for(list = priv->images; list != NULL; list = list->next)
-        {
-            image_t *im = list->data;
-            g_object_unref(im->image);
-            g_free(im);
-        }
-        g_slist_free(priv->images);
-        priv->images = NULL;
-    }
-}
-
-static void
-osm_gps_map_free_layers(OsmGpsMap *map)
-{
-    OsmGpsMapPrivate *priv = map->priv;
-    if (priv->layers) {
-        g_slist_foreach(priv->layers, (GFunc) g_object_unref, NULL);
-        g_slist_free(priv->layers);
-        priv->layers = NULL;
+    if (list) {
+        g_slist_foreach(*list, (GFunc) g_free, NULL);
+        g_slist_free(*list);
+        *list = NULL;
     }
 }
 
@@ -518,7 +503,6 @@ static void
 osm_gps_map_print_images (OsmGpsMap *map)
 {
     GSList *list;
-    int x,y,pixel_x,pixel_y;
     int min_x = 0,min_y = 0,max_x = 0,max_y = 0;
     int map_x0, map_y0;
     OsmGpsMapPrivate *priv = map->priv;
@@ -527,33 +511,24 @@ osm_gps_map_print_images (OsmGpsMap *map)
     map_y0 = priv->map_y - EXTRA_BORDER;
     for(list = priv->images; list != NULL; list = list->next)
     {
-        image_t *im = list->data;
+        GdkRectangle loc;
+        OsmGpsMapImage *im = OSM_GPS_MAP_IMAGE(list->data);
+        const OsmGpsMapPoint *pt = osm_gps_map_image_get_point(im);
 
-        // pixel_x,y, offsets
-        pixel_x = lon2pixel(priv->map_zoom, im->pt.rlon);
-        pixel_y = lat2pixel(priv->map_zoom, im->pt.rlat);
+        /* pixel_x,y, offsets */
+        loc.x = lon2pixel(priv->map_zoom, pt->rlon) - map_x0;
+        loc.y = lat2pixel(priv->map_zoom, pt->rlat) - map_y0;
 
-        g_debug("Image %dx%d @: %f,%f (%d,%d)",
-                im->w, im->h,
-                im->pt.rlat, im->pt.rlon,
-                pixel_x, pixel_y);
-
-        x = pixel_x - map_x0;
-        y = pixel_y - map_y0;
-
-        gdk_draw_pixbuf (
+        osm_gps_map_image_draw (
+                         im,
                          priv->pixmap,
                          priv->gc_map,
-                         im->image,
-                         0,0,
-                         x-im->xoffset,y-im->yoffset,
-                         im->w,im->h,
-                         GDK_RGB_DITHER_NONE, 0, 0);
-
-        max_x = MAX(x+im->w,max_x);
-        min_x = MIN(x-im->w,min_x);
-        max_y = MAX(y+im->h,max_y);
-        min_y = MIN(y-im->h,min_y);
+                         &loc);
+
+        max_x = MAX(loc.x + loc.width, max_x);
+        min_x = MIN(loc.x - loc.width, min_x);
+        max_y = MAX(loc.y + loc.height, max_y);
+        min_y = MIN(loc.y - loc.height, min_y);
     }
 
     gtk_widget_queue_draw_area (
@@ -564,78 +539,74 @@ osm_gps_map_print_images (OsmGpsMap *map)
 }
 
 static void
-osm_gps_map_draw_gps_point (OsmGpsMap *map)
+osm_gps_map_draw_gps_point (OsmGpsMap *map, GdkDrawable *drawable)
 {
     OsmGpsMapPrivate *priv = map->priv;
+    cairo_t *cr;
+    int map_x0, map_y0;
+    int x, y;
+    int r, r2, mr;
 
-    //incase we get called before we have got a gps point
-    if (priv->gps_valid) {
-        int map_x0, map_y0;
-        int x, y;
-        int r = priv->ui_gps_point_inner_radius;
-        int r2 = priv->ui_gps_point_outer_radius;
-        int mr = MAX(3*r,r2);
-
-        map_x0 = priv->map_x - EXTRA_BORDER;
-        map_y0 = priv->map_y - EXTRA_BORDER;
-        x = lon2pixel(priv->map_zoom, priv->gps->rlon) - map_x0;
-        y = lat2pixel(priv->map_zoom, priv->gps->rlat) - map_y0;
-        cairo_t *cr;
-        cairo_pattern_t *pat;
-
-        cr = gdk_cairo_create(priv->pixmap);
-
-        // draw transparent area
-        if (r2 > 0) {
-            cairo_set_line_width (cr, 1.5);
-            cairo_set_source_rgba (cr, 0.75, 0.75, 0.75, 0.4);
-            cairo_arc (cr, x, y, r2, 0, 2 * M_PI);
-            cairo_fill (cr);
-            // draw transparent area border
-            cairo_set_source_rgba (cr, 0.55, 0.55, 0.55, 0.4);
-            cairo_arc (cr, x, y, r2, 0, 2 * M_PI);
-            cairo_stroke(cr);
-        }
-
-        // draw ball gradient
-        if (r > 0) {
-            // draw direction arrow
-            if(!isnan(priv->gps_heading)) 
-            {
-                cairo_move_to (cr, x-r*cos(priv->gps_heading), y-r*sin(priv->gps_heading));
-                cairo_line_to (cr, x+3*r*sin(priv->gps_heading), y-3*r*cos(priv->gps_heading));
-                cairo_line_to (cr, x+r*cos(priv->gps_heading), y+r*sin(priv->gps_heading));
-                cairo_close_path (cr);
+    r = priv->ui_gps_point_inner_radius;
+    r2 = priv->ui_gps_point_outer_radius;
+    mr = MAX(3*r,r2);
+    map_x0 = priv->map_x - EXTRA_BORDER;
+    map_y0 = priv->map_y - EXTRA_BORDER;
+    x = lon2pixel(priv->map_zoom, priv->gps->rlon) - map_x0;
+    y = lat2pixel(priv->map_zoom, priv->gps->rlat) - map_y0;
+
+    cr = gdk_cairo_create(drawable);
+
+    /* draw transparent area */
+    if (r2 > 0) {
+        cairo_set_line_width (cr, 1.5);
+        cairo_set_source_rgba (cr, 0.75, 0.75, 0.75, 0.4);
+        cairo_arc (cr, x, y, r2, 0, 2 * M_PI);
+        cairo_fill (cr);
+        /* draw transparent area border */
+        cairo_set_source_rgba (cr, 0.55, 0.55, 0.55, 0.4);
+        cairo_arc (cr, x, y, r2, 0, 2 * M_PI);
+        cairo_stroke(cr);
+    }
 
-                cairo_set_source_rgba (cr, 0.3, 0.3, 1.0, 0.5);
-                cairo_fill_preserve (cr);
+    /* draw ball gradient */
+    if (r > 0) {
+        cairo_pattern_t *pat;
+        /* draw direction arrow */
+        if(!isnan(priv->gps_heading)) {
+            cairo_move_to (cr, x-r*cos(priv->gps_heading), y-r*sin(priv->gps_heading));
+            cairo_line_to (cr, x+3*r*sin(priv->gps_heading), y-3*r*cos(priv->gps_heading));
+            cairo_line_to (cr, x+r*cos(priv->gps_heading), y+r*sin(priv->gps_heading));
+            cairo_close_path (cr);
 
-                cairo_set_line_width (cr, 1.0);
-                cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.5);
-                cairo_stroke(cr);
-            }
+            cairo_set_source_rgba (cr, 0.3, 0.3, 1.0, 0.5);
+            cairo_fill_preserve (cr);
 
-            pat = cairo_pattern_create_radial (x-(r/5), y-(r/5), (r/5), x,  y, r);
-            cairo_pattern_add_color_stop_rgba (pat, 0, 1, 1, 1, 1.0);
-            cairo_pattern_add_color_stop_rgba (pat, 1, 0, 0, 1, 1.0);
-            cairo_set_source (cr, pat);
-            cairo_arc (cr, x, y, r, 0, 2 * M_PI);
-            cairo_fill (cr);
-            cairo_pattern_destroy (pat);
-            // draw ball border
             cairo_set_line_width (cr, 1.0);
-            cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 1.0);
-            cairo_arc (cr, x, y, r, 0, 2 * M_PI);
+            cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.5);
             cairo_stroke(cr);
         }
 
-        cairo_destroy(cr);
-        gtk_widget_queue_draw_area (GTK_WIDGET(map),
-                                    x-mr,
-                                    y-mr,
-                                    mr*2,
-                                    mr*2);
+        pat = cairo_pattern_create_radial (x-(r/5), y-(r/5), (r/5), x,  y, r);
+        cairo_pattern_add_color_stop_rgba (pat, 0, 1, 1, 1, 1.0);
+        cairo_pattern_add_color_stop_rgba (pat, 1, 0, 0, 1, 1.0);
+        cairo_set_source (cr, pat);
+        cairo_arc (cr, x, y, r, 0, 2 * M_PI);
+        cairo_fill (cr);
+        cairo_pattern_destroy (pat);
+        /* draw ball border */
+        cairo_set_line_width (cr, 1.0);
+        cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 1.0);
+        cairo_arc (cr, x, y, r, 0, 2 * M_PI);
+        cairo_stroke(cr);
     }
+
+    cairo_destroy(cr);
+    gtk_widget_queue_draw_area (GTK_WIDGET(map),
+                                x-mr,
+                                y-mr,
+                                mr*2,
+                                mr*2);
 }
 
 static void
@@ -676,57 +647,44 @@ osm_gps_map_tile_download_complete (SoupSession *session, SoupMessage *msg, gpoi
 #endif
 {
     FILE *file;
-    tile_download_t *dl = (tile_download_t *)user_data;
+    OsmTileDownload *dl = (OsmTileDownload *)user_data;
     OsmGpsMap *map = OSM_GPS_MAP(dl->map);
     OsmGpsMapPrivate *priv = map->priv;
     gboolean file_saved = FALSE;
 
-    if (SOUP_STATUS_IS_SUCCESSFUL (msg->status_code))
-    {
+    if (SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
         /* save tile into cachedir if one has been specified */
-        if (priv->cache_dir)
-        {
-            if (g_mkdir_with_parents(dl->folder,0700) == 0)
-            {
+        if (priv->cache_dir) {
+            if (g_mkdir_with_parents(dl->folder,0700) == 0) {
                 file = g_fopen(dl->filename, "wb");
-                if (file != NULL)
-                {
+                if (file != NULL) {
                     fwrite (MSG_RESPONSE_BODY(msg), 1, MSG_RESPONSE_LEN(msg), file);
                     file_saved = TRUE;
                     g_debug("Wrote "MSG_RESPONSE_LEN_FORMAT" bytes to %s", MSG_RESPONSE_LEN(msg), dl->filename);
                     fclose (file);
 
                 }
-            }
-            else
-            {
-                g_warning("Error creating tile download directory: %s", 
-                          dl->folder);
+            } else {
+                g_warning("Error creating tile download directory: %s", dl->folder);
                 perror("perror:");
             }
         }
 
-        if (dl->redraw)
-        {
+        if (dl->redraw) {
             GdkPixbuf *pixbuf = NULL;
 
             /* if the file was actually stored on disk, we can simply */
             /* load and decode it from that file */
-            if (priv->cache_dir)
-            {
-                if (file_saved)
-                {
+            if (priv->cache_dir) {
+                if (file_saved) {
                     pixbuf = gdk_pixbuf_new_from_file (dl->filename, NULL);
                 }
-            }
-            else
-            {
+            } else {
                 GdkPixbufLoader *loader;
                 char *extension = strrchr (dl->filename, '.');
 
                 /* parse file directly from memory */
-                if (extension)
-                {
+                if (extension) {
                     loader = gdk_pixbuf_loader_new_with_type (extension+1, NULL);
                     if (!gdk_pixbuf_loader_write (loader, (unsigned char*)MSG_RESPONSE_BODY(msg), MSG_RESPONSE_LEN(msg), NULL))
                     {
@@ -739,16 +697,13 @@ osm_gps_map_tile_download_complete (SoupSession *session, SoupMessage *msg, gpoi
                     /* give up loader but keep the pixbuf */
                     g_object_ref(pixbuf);
                     g_object_unref(loader);
-                }
-                else
-                {
+                } else {
                     g_warning("Error: Unable to determine image file format");
                 }
             }
                 
             /* Store the tile into the cache */
-            if (G_LIKELY (pixbuf))
-            {
+            if (G_LIKELY (pixbuf)) {
                 OsmCachedTile *tile = g_slice_new (OsmCachedTile);
                 tile->pixbuf = pixbuf;
                 tile->redraw_cycle = priv->redraw_cycle;
@@ -763,26 +718,22 @@ osm_gps_map_tile_download_complete (SoupSession *session, SoupMessage *msg, gpoi
             osm_gps_map_map_redraw_idle (map);
         }
         g_hash_table_remove(priv->tile_queue, dl->uri);
+        g_object_notify(G_OBJECT(map), "tiles-queued");
 
-        g_free(dl->uri);
         g_free(dl->folder);
         g_free(dl->filename);
         g_free(dl);
-    }
-    else
-    {
-        g_warning("Error downloading tile: %d - %s", msg->status_code, msg->reason_phrase);
-        if (msg->status_code == SOUP_STATUS_NOT_FOUND)
-        {
+    } else {
+        if (msg->status_code == SOUP_STATUS_NOT_FOUND) {
             g_hash_table_insert(priv->missing_tiles, dl->uri, NULL);
             g_hash_table_remove(priv->tile_queue, dl->uri);
-        }
-        else if (msg->status_code == SOUP_STATUS_CANCELLED)
-        {
-            ;//application exiting
-        }
-        else
-        {
+            g_object_notify(G_OBJECT(map), "tiles-queued");
+        } else if (msg->status_code == SOUP_STATUS_CANCELLED) {
+            /* called as application exit or after osm_gps_map_download_cancel_all */
+            g_hash_table_remove(priv->tile_queue, dl->uri);
+            g_object_notify(G_OBJECT(map), "tiles-queued");
+        } else {
+            g_warning("Error downloading tile: %d - %s", msg->status_code, msg->reason_phrase);
 #if USE_LIBSOUP22
             soup_session_requeue_message(dl->session, msg);
 #else
@@ -800,7 +751,7 @@ osm_gps_map_download_tile (OsmGpsMap *map, int zoom, int x, int y, gboolean redr
 {
     SoupMessage *msg;
     OsmGpsMapPrivate *priv = map->priv;
-    tile_download_t *dl = g_new0(tile_download_t,1);
+    OsmTileDownload *dl = g_new0(OsmTileDownload,1);
 
     //calculate the uri to download
     dl->uri = replace_map_uri(map, priv->repo_uri, zoom, x, y);
@@ -835,7 +786,7 @@ osm_gps_map_download_tile (OsmGpsMap *map, int zoom, int x, int y, gboolean redr
 
         msg = soup_message_new (SOUP_METHOD_GET, dl->uri);
         if (msg) {
-            if (priv->the_google) {
+            if (priv->is_google) {
                 //Set maps.google.com as the referrer
                 g_debug("Setting Google Referrer");
                 soup_message_headers_append(msg->request_headers, "Referer", "http://maps.google.com/");
@@ -855,6 +806,8 @@ osm_gps_map_download_tile (OsmGpsMap *map, int zoom, int x, int y, gboolean redr
 #endif
 
             g_hash_table_insert (priv->tile_queue, dl->uri, msg);
+            g_object_notify (G_OBJECT (map), "tiles-queued");
+            /* the soup session unrefs the message when the download finishes */
             soup_session_queue_message (priv->soup_session, msg, osm_gps_map_tile_download_complete, dl);
         } else {
             g_warning("Could not create soup message");
@@ -895,6 +848,10 @@ osm_gps_map_load_cached_tile (OsmGpsMap *map, int zoom, int x, int y)
             tile->pixbuf = pixbuf;
             g_hash_table_insert (priv->tile_cache, filename, tile);
         }
+        else
+        {
+            g_free (filename);
+        }
     }
 
     /* set/update the redraw_cycle timestamp on the tile */
@@ -987,22 +944,19 @@ osm_gps_map_load_tile (OsmGpsMap *map, int zoom, int x, int y, int offset_x, int
     if(!(pixbuf = osm_gps_map_load_cached_tile(map, zoom, x, y)))
         pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
 
-    if(pixbuf)
-    {
+    if(pixbuf) {
         g_debug("Found tile %s", filename);
         osm_gps_map_blit_tile(map, pixbuf, offset_x,offset_y);
         g_object_unref (pixbuf);
-    }
-    else
-    {
-        if (priv->map_auto_download)
+    } else {
+        if (priv->map_auto_download_enabled) {
             osm_gps_map_download_tile(map, zoom, x, y, TRUE);
+        }
 
         /* try to render the tile by scaling cached tiles from other zoom
          * levels */
         pixbuf = osm_gps_map_render_missing_tile (map, zoom, x, y);
-        if (pixbuf)
-        {
+        if (pixbuf) {
             gdk_draw_pixbuf (priv->pixmap,
                              priv->gc_map,
                              pixbuf,
@@ -1011,13 +965,13 @@ osm_gps_map_load_tile (OsmGpsMap *map, int zoom, int x, int y, int offset_x, int
                              TILESIZE,TILESIZE,
                              GDK_RGB_DITHER_NONE, 0, 0);
             g_object_unref (pixbuf);
-        }
-        else
-        {
-            //prevent some artifacts when drawing not yet loaded areas.
+        } else {
+            /* prevent some artifacts when drawing not yet loaded areas. */
+            GtkStyle *style = gtk_widget_get_style(GTK_WIDGET(map));
             gdk_draw_rectangle (priv->pixmap,
-                                GTK_WIDGET(map)->style->white_gc,
-                                TRUE, offset_x, offset_y, TILESIZE, TILESIZE);
+                                style->white_gc,
+                                TRUE,
+                                offset_x, offset_y, TILESIZE, TILESIZE);
         }
     }
     g_free(filename);
@@ -1027,7 +981,9 @@ static void
 osm_gps_map_fill_tiles_pixel (OsmGpsMap *map)
 {
     OsmGpsMapPrivate *priv = map->priv;
-    int i,j, width, height, tile_x0, tile_y0, tiles_nx, tiles_ny;
+    GtkAllocation allocation;
+    GtkStyle *style;
+    int i,j, tile_x0, tile_y0, tiles_nx, tiles_ny;
     int offset_xn = 0;
     int offset_yn = 0;
     int offset_x;
@@ -1035,6 +991,9 @@ osm_gps_map_fill_tiles_pixel (OsmGpsMap *map)
 
     g_debug("Fill tiles: %d,%d z:%d", priv->map_x, priv->map_y, priv->map_zoom);
 
+    gtk_widget_get_allocation(GTK_WIDGET(map), &allocation);
+    style = gtk_widget_get_style(GTK_WIDGET(map));
+
     offset_x = - priv->map_x % TILESIZE;
     offset_y = - priv->map_y % TILESIZE;
     if (offset_x > 0) offset_x -= TILESIZE;
@@ -1043,11 +1002,8 @@ osm_gps_map_fill_tiles_pixel (OsmGpsMap *map)
     offset_xn = offset_x + EXTRA_BORDER;
     offset_yn = offset_y + EXTRA_BORDER;
 
-    width  = GTK_WIDGET(map)->allocation.width;
-    height = GTK_WIDGET(map)->allocation.height;
-
-    tiles_nx = (width  - offset_x) / TILESIZE + 1;
-    tiles_ny = (height - offset_y) / TILESIZE + 1;
+    tiles_nx = (allocation.width  - offset_x) / TILESIZE + 1;
+    tiles_ny = (allocation.height - offset_y) / TILESIZE + 1;
 
     tile_x0 =  floor((float)priv->map_x / (float)TILESIZE);
     tile_y0 =  floor((float)priv->map_y / (float)TILESIZE);
@@ -1060,7 +1016,7 @@ osm_gps_map_fill_tiles_pixel (OsmGpsMap *map)
             if( j<0 || i<0 || i>=exp(priv->map_zoom * M_LN2) || j>=exp(priv->map_zoom * M_LN2))
             {
                 gdk_draw_rectangle (priv->pixmap,
-                                    GTK_WIDGET(map)->style->white_gc,
+                                    style->white_gc,
                                     TRUE,
                                     offset_xn, offset_yn,
                                     TILESIZE,TILESIZE);
@@ -1080,34 +1036,45 @@ osm_gps_map_fill_tiles_pixel (OsmGpsMap *map)
 }
 
 static void
-osm_gps_map_print_track (OsmGpsMap *map, GSList *trackpoint_list)
+osm_gps_map_print_track (OsmGpsMap *map, OsmGpsMapTrack *track)
 {
     OsmGpsMapPrivate *priv = map->priv;
 
-    GSList *list;
+    GSList *pt,*points;
     int x,y;
     int min_x = 0,min_y = 0,max_x = 0,max_y = 0;
-    int lw = priv->ui_gps_track_width;
+    gfloat lw, alpha;
     int map_x0, map_y0;
     cairo_t *cr;
+    GdkColor color;
+
+    g_object_get (track,
+            "track", &points,
+            "line-width", &lw,
+            "alpha", &alpha,
+            NULL);
+    osm_gps_map_track_get_color(track, &color);
+
+    if (points == NULL)
+        return;
 
     cr = gdk_cairo_create(priv->pixmap);
     cairo_set_line_width (cr, lw);
-    cairo_set_source_rgba (cr, 60000.0/65535.0, 0.0, 0.0, 0.6);
+    cairo_set_source_rgba (cr, color.red/65535.0, color.green/65535.0, color.blue/65535.0, alpha);
     cairo_set_line_cap (cr, CAIRO_LINE_CAP_ROUND);
     cairo_set_line_join (cr, CAIRO_LINE_JOIN_ROUND);
 
     map_x0 = priv->map_x - EXTRA_BORDER;
     map_y0 = priv->map_y - EXTRA_BORDER;
-    for(list = trackpoint_list; list != NULL; list = list->next)
+    for(pt = points; pt != NULL; pt = pt->next)
     {
-        coord_t *tp = list->data;
+        OsmGpsMapPoint *tp = pt->data;
 
         x = lon2pixel(priv->map_zoom, tp->rlon) - map_x0;
         y = lat2pixel(priv->map_zoom, tp->rlat) - map_y0;
 
-        // first time through loop
-        if (list == trackpoint_list) {
+        /* first time through loop */
+        if (pt == points) {
             cairo_move_to(cr, x, y);
         }
 
@@ -1134,17 +1101,17 @@ osm_gps_map_print_track (OsmGpsMap *map, GSList *trackpoint_list)
 static void
 osm_gps_map_print_tracks (OsmGpsMap *map)
 {
+    GSList *tmp;
     OsmGpsMapPrivate *priv = map->priv;
 
-    if (priv->show_trip_history)
-        osm_gps_map_print_track (map, priv->trip_history);
+    if (priv->trip_history_show_enabled) {
+        osm_gps_map_print_track (map, priv->gps_track);
+    }
 
-    if (priv->tracks)
-    {
-        GSList* tmp = priv->tracks;
-        while (tmp != NULL)
-        {
-            osm_gps_map_print_track (map, tmp->data);
+    if (priv->tracks) {
+        tmp = priv->tracks;
+        while (tmp != NULL) {
+            osm_gps_map_print_track (map, OSM_GPS_MAP_TRACK(tmp->data));
             tmp = g_slist_next(tmp);
         }
     }
@@ -1172,6 +1139,8 @@ osm_gps_map_purge_cache (OsmGpsMap *map)
 static gboolean
 osm_gps_map_map_redraw (OsmGpsMap *map)
 {
+    GtkStyle *style;
+    GtkAllocation allocation;
     OsmGpsMapPrivate *priv = map->priv;
 
     priv->idle_map_redraw = 0;
@@ -1192,7 +1161,7 @@ osm_gps_map_map_redraw (OsmGpsMap *map)
      * change it while we are dragging, we will end up showing it in the wrong
      * place. This could be fixed by carefully recompute the coordinates, but
      * for now it's easier just to disable redrawing the map while dragging */
-    if (priv->dragging)
+    if (priv->is_dragging)
         return FALSE;
 
     /* undo all offsets that may have happened when dragging */
@@ -1202,19 +1171,27 @@ osm_gps_map_map_redraw (OsmGpsMap *map)
     priv->redraw_cycle++;
 
     /* draw white background to initialise pixmap */
+    gtk_widget_get_allocation(GTK_WIDGET(map), &allocation);
+    style = gtk_widget_get_style(GTK_WIDGET(map));
     gdk_draw_rectangle (priv->pixmap,
-                        GTK_WIDGET(map)->style->white_gc,
+                        style->white_gc,
                         TRUE,
                         0, 0,
-                        GTK_WIDGET(map)->allocation.width + EXTRA_BORDER * 2,
-                        GTK_WIDGET(map)->allocation.height + EXTRA_BORDER * 2);
+                        allocation.width + EXTRA_BORDER * 2,
+                        allocation.height + EXTRA_BORDER * 2);
 
     osm_gps_map_fill_tiles_pixel(map);
 
     osm_gps_map_print_tracks(map);
-    osm_gps_map_draw_gps_point(map);
     osm_gps_map_print_images(map);
 
+    /* draw the gps point using the appropriate virtual private method */
+    if (priv->gps_track_used && priv->gps_point_enabled) {
+        OsmGpsMapClass *klass = OSM_GPS_MAP_GET_CLASS(map);
+        if (klass->draw_gps_point)
+            klass->draw_gps_point (map, priv->pixmap);
+    }
+
     if (priv->layers) {
         GSList *list;
         for(list = priv->layers; list != NULL; list = list->next) {
@@ -1238,15 +1215,18 @@ osm_gps_map_map_redraw_idle (OsmGpsMap *map)
         priv->idle_map_redraw = g_idle_add ((GSourceFunc)osm_gps_map_map_redraw, map);
 }
 
+/* call this to update center_rlat and center_rlon after
+ * changin map_x or map_y */
 static void
 center_coord_update(OsmGpsMap *map) {
 
     GtkWidget *widget = GTK_WIDGET(map);
     OsmGpsMapPrivate *priv = OSM_GPS_MAP_PRIVATE(map);
+    GtkAllocation allocation;
 
-    // pixel_x,y, offsets
-    gint pixel_x = priv->map_x + widget->allocation.width/2;
-    gint pixel_y = priv->map_y + widget->allocation.height/2;
+    gtk_widget_get_allocation(widget, &allocation);
+    gint pixel_x = priv->map_x + allocation.width/2;
+    gint pixel_y = priv->map_y + allocation.height/2;
 
     priv->center_rlon = pixel2lon(priv->map_zoom, pixel_x);
     priv->center_rlat = pixel2lat(priv->map_zoom, pixel_y);
@@ -1254,37 +1234,68 @@ center_coord_update(OsmGpsMap *map) {
     g_signal_emit_by_name(widget, "changed");
 }
 
+/* Automatically center the map if the current point, i.e the most recent
+ * gps point, approaches the edge, and map_auto_center is set. Does not
+ * request the map be redrawn */
+static void
+maybe_autocenter_map (OsmGpsMap *map)
+{
+    OsmGpsMapPrivate *priv;
+    GtkAllocation allocation;
+
+    g_return_if_fail (OSM_IS_GPS_MAP (map));
+    priv = map->priv;
+    gtk_widget_get_allocation(GTK_WIDGET(map), &allocation);
+
+    if(priv->map_auto_center_enabled)   {
+        int pixel_x = lon2pixel(priv->map_zoom, priv->gps->rlon);
+        int pixel_y = lat2pixel(priv->map_zoom, priv->gps->rlat);
+        int x = pixel_x - priv->map_x;
+        int y = pixel_y - priv->map_y;
+        int width = allocation.width;
+        int height = allocation.height;
+        if( x < (width/2 - width/8)     || x > (width/2 + width/8)  ||
+            y < (height/2 - height/8)   || y > (height/2 + height/8)) {
+
+            priv->map_x = pixel_x - allocation.width/2;
+            priv->map_y = pixel_y - allocation.height/2;
+            center_coord_update(map);
+        }
+    }
+}
+
 static gboolean 
 on_window_key_press(GtkWidget *widget, GdkEventKey *event, OsmGpsMapPrivate *priv) 
 {
     int i;
     int step;
     gboolean handled;
-    OsmGpsMap *map;
+    GtkAllocation allocation;
+    OsmGpsMap *map = OSM_GPS_MAP(widget);
 
-    //if no keybindings are set, let the app handle them...
+    /* if no keybindings are set, let the app handle them... */
     if (!priv->keybindings_enabled)
         return FALSE;
 
     handled = FALSE;
-    map = OSM_GPS_MAP(widget);
-    step = GTK_WIDGET(widget)->allocation.width/OSM_GPS_MAP_SCROLL_STEP;
+    gtk_widget_get_allocation(GTK_WIDGET(map), &allocation);
+    step = allocation.width/OSM_GPS_MAP_SCROLL_STEP;
 
-    //the map handles some keys on its own
+    /* the map handles some keys on its own */
     for (i = 0; i < OSM_GPS_MAP_KEY_MAX; i++) {
-        //not the key we have a binding for
+        /* not the key we have a binding for */
         if (map->priv->keybindings[i] != event->keyval)
             continue;
 
         switch(i) {
             case OSM_GPS_MAP_KEY_FULLSCREEN: {
                 GtkWidget *toplevel = gtk_widget_get_toplevel(GTK_WIDGET(widget));
-                if(!priv->fullscreen)
+                if(!priv->is_fullscreen)
                     gtk_window_fullscreen(GTK_WINDOW(toplevel));
                 else
                     gtk_window_unfullscreen(GTK_WINDOW(toplevel));
 
-                priv->fullscreen = !priv->fullscreen;
+                priv->is_fullscreen = !priv->is_fullscreen;
                 handled = TRUE;
                 } break;
             case OSM_GPS_MAP_KEY_ZOOMIN:
@@ -1316,7 +1327,7 @@ on_window_key_press(GtkWidget *widget, GdkEventKey *event, OsmGpsMapPrivate *pri
             case OSM_GPS_MAP_KEY_RIGHT:
                 priv->map_x += step;
                 center_coord_update(map);
-                osm_gps_map_map_redraw_idle(OSM_GPS_MAP(widget));
+                osm_gps_map_map_redraw_idle(map);
                 handled = TRUE;
                 break;
             default:
@@ -1328,6 +1339,19 @@ on_window_key_press(GtkWidget *widget, GdkEventKey *event, OsmGpsMapPrivate *pri
 }
 
 static void
+on_gps_point_added (OsmGpsMapTrack *track, OsmGpsMapPoint *point, OsmGpsMap *map)
+{
+    osm_gps_map_map_redraw_idle (map);
+    maybe_autocenter_map (map);
+}
+
+static void
+on_track_changed (OsmGpsMapTrack *track, GParamSpec *pspec, OsmGpsMap *map)
+{
+    osm_gps_map_map_redraw_idle (map);
+}
+
+static void
 osm_gps_map_init (OsmGpsMap *object)
 {
     int i;
@@ -1339,10 +1363,16 @@ osm_gps_map_init (OsmGpsMap *object)
     priv->pixmap = NULL;
 
     priv->trip_history = NULL;
-    priv->gps = g_new0(coord_t, 1);
-    priv->gps_valid = FALSE;
+    priv->gps = osm_gps_map_point_new_radians(0.0, 0.0);
+    priv->gps_track_used = FALSE;
     priv->gps_heading = OSM_GPS_MAP_INVALID;
 
+    priv->gps_track = osm_gps_map_track_new();
+    g_signal_connect(priv->gps_track, "point-added",
+                    G_CALLBACK(on_gps_point_added), object);
+    g_signal_connect(priv->gps_track, "notify",
+                    G_CALLBACK(on_track_changed), object);
+
     priv->tracks = NULL;
     priv->images = NULL;
     priv->layers = NULL;
@@ -1354,7 +1384,7 @@ osm_gps_map_init (OsmGpsMap *object)
     priv->drag_start_mouse_y = 0;
 
     priv->uri_format = 0;
-    priv->the_google = FALSE;
+    priv->is_google = FALSE;
 
     priv->map_source = -1;
 
@@ -1374,8 +1404,10 @@ osm_gps_map_init (OsmGpsMap *object)
                                             USER_AGENT, NULL);
 
 #endif
-    //Hash table which maps tile d/l URIs to SoupMessage requests
-    priv->tile_queue = g_hash_table_new (g_str_hash, g_str_equal);
+    /* Hash table which maps tile d/l URIs to SoupMessage requests, the hashtable
+       must free the key, the soup session unrefs the message */
+    priv->tile_queue = g_hash_table_new_full (g_str_hash, g_str_equal,
+                                              g_free, NULL);
 
     //Some mapping providers (Google) have varying degrees of tiles at multiple
     //zoom levels
@@ -1390,40 +1422,30 @@ osm_gps_map_init (OsmGpsMap *object)
                            GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
                            GDK_POINTER_MOTION_MASK |
                            GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK);
-    GTK_WIDGET_SET_FLAGS (object, GTK_CAN_FOCUS);
+    gtk_widget_set_can_focus (GTK_WIDGET (object), TRUE);
 
     g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_MASK, my_log_handler, NULL);
 
-    //Setup signal handlers
-    g_signal_connect(G_OBJECT(object), "key_press_event",
-                            G_CALLBACK(on_window_key_press), priv);
+    /* setup signal handlers */
+    g_signal_connect(object, "key_press_event",
+                    G_CALLBACK(on_window_key_press), priv);
 }
 
 static char*
-osm_gps_map_get_cache_dir(OsmGpsMapPrivate *priv)
+osm_gps_map_get_cache_base_dir(OsmGpsMapPrivate *priv)
 {
     if (priv->tile_base_dir)
         return g_strdup(priv->tile_base_dir);
     return osm_gps_map_get_default_cache_directory();
 }
 
-/* strcmp0 was introduced with glib 2.16 */
-#if ! GLIB_CHECK_VERSION (2, 16, 0)
-int g_strcmp0(const char *str1, const char *str2)
-{
-    if( str1 == NULL && str2 == NULL ) return 0;
-    if( str1 == NULL ) return -1;
-    if( str2 == NULL ) return 1;
-    return strcmp(str1, str2);
-}
-#endif
-
 static void
-osm_gps_map_setup(OsmGpsMapPrivate *priv)
+osm_gps_map_setup(OsmGpsMap *map)
 {
     const char *uri;
+    OsmGpsMapPrivate *priv = map->priv;
 
-   //user can specify a map source ID, or a repo URI as the map source
+   /* user can specify a map source ID, or a repo URI as the map source */
     uri = osm_gps_map_source_get_repo_uri(OSM_GPS_MAP_SOURCE_NULL);
     if ( (priv->map_source == 0) || (strcmp(priv->repo_uri, uri) == 0) ) {
         g_debug("Using null source");
@@ -1433,7 +1455,7 @@ osm_gps_map_setup(OsmGpsMapPrivate *priv)
         gdk_pixbuf_fill(priv->null_tile, 0xcccccc00);
     }
     else if (priv->map_source >= 0) {
-        //check if the source given is valid
+        /* check if the source given is valid */
         uri = osm_gps_map_source_get_repo_uri(priv->map_source);
         if (uri) {
             g_debug("Setting map source from ID");
@@ -1446,14 +1468,14 @@ osm_gps_map_setup(OsmGpsMapPrivate *priv)
             priv->min_zoom = osm_gps_map_source_get_min_zoom(priv->map_source);
         }
     }
+    /* parse the source uri */
+    inspect_map_uri(priv);
 
-    if (priv->tile_dir == NULL)
-        priv->tile_dir = g_strdup(OSM_GPS_MAP_CACHE_DISABLED);
-
+    /* setup the tile cache */
     if ( g_strcmp0(priv->tile_dir, OSM_GPS_MAP_CACHE_DISABLED) == 0 ) {
         priv->cache_dir = NULL;
     } else if ( g_strcmp0(priv->tile_dir, OSM_GPS_MAP_CACHE_AUTO) == 0 ) {
-        char *base = osm_gps_map_get_cache_dir(priv);
+        char *base = osm_gps_map_get_cache_base_dir(priv);
 #if GLIB_CHECK_VERSION (2, 16, 0)
         char *md5 = g_compute_checksum_for_string (G_CHECKSUM_MD5, priv->repo_uri, -1);
 #else
@@ -1463,26 +1485,46 @@ osm_gps_map_setup(OsmGpsMapPrivate *priv)
         g_free(base);
         g_free(md5);
     } else if ( g_strcmp0(priv->tile_dir, OSM_GPS_MAP_CACHE_FRIENDLY) == 0 ) {
-        char *base = osm_gps_map_get_cache_dir(priv);
+        char *base = osm_gps_map_get_cache_base_dir(priv);
         const char *fname = osm_gps_map_source_get_friendly_name(priv->map_source);
         priv->cache_dir = g_strdup_printf("%s%c%s", base, G_DIR_SEPARATOR, fname);
         g_free(base);
     } else {
-        priv->cache_dir = g_strdup(priv->tile_dir);
+        /* the simple case is handled in g_object_set(PROP_TILE_CACHE_DIR) */
     }
     g_debug("Cache dir: %s", priv->cache_dir);
+
+    /* check if we are being called for a second (or more) time in the lifetime
+       of the object, and if so, do some extra cleanup */
+    if ( priv->is_constructed ) {
+        g_debug("Setup called again in map lifetime");
+        /* flush the ram cache */
+        g_hash_table_remove_all(priv->tile_cache);
+
+        /* adjust zoom if necessary */
+        if(priv->map_zoom > priv->max_zoom)
+            osm_gps_map_set_zoom(map, priv->max_zoom);
+
+        if(priv->map_zoom < priv->min_zoom)
+            osm_gps_map_set_zoom(map, priv->min_zoom);
+
+        osm_gps_map_map_redraw_idle(map);
+    }
 }
 
 static GObject *
 osm_gps_map_constructor (GType gtype, guint n_properties, GObjectConstructParam *properties)
 {
-    //Always chain up to the parent constructor
-    GObject *object = 
-        G_OBJECT_CLASS(osm_gps_map_parent_class)->constructor(gtype, n_properties, properties);
+    GObject *object;
+    OsmGpsMap *map;
+
+    /* always chain up to the parent constructor */
+    object = G_OBJECT_CLASS(osm_gps_map_parent_class)->constructor(gtype, n_properties, properties);
 
-    osm_gps_map_setup(OSM_GPS_MAP_PRIVATE(object));
+    map = OSM_GPS_MAP(object);
 
-    inspect_map_uri(OSM_GPS_MAP(object));
+    osm_gps_map_setup(map);
+    map->priv->is_constructed = TRUE;
 
     return object;
 }
@@ -1501,13 +1543,16 @@ osm_gps_map_dispose (GObject *object)
     soup_session_abort(priv->soup_session);
     g_object_unref(priv->soup_session);
 
+    g_object_unref(priv->gps_track);
+
     g_hash_table_destroy(priv->tile_queue);
     g_hash_table_destroy(priv->missing_tiles);
     g_hash_table_destroy(priv->tile_cache);
 
     /* images and layers contain GObjects which need unreffing, so free here */
-    osm_gps_map_free_images(map);
-    osm_gps_map_free_layers(map);
+    gslist_of_gobjects_free(&priv->images);
+    gslist_of_gobjects_free(&priv->layers);
+    gslist_of_gobjects_free(&priv->tracks);
 
     if(priv->pixmap)
         g_object_unref (priv->pixmap);
@@ -1521,8 +1566,8 @@ osm_gps_map_dispose (GObject *object)
     if (priv->idle_map_redraw != 0)
         g_source_remove (priv->idle_map_redraw);
 
-    if (priv->drag_expose != 0)
-        g_source_remove (priv->drag_expose);
+    if (priv->drag_expose_source != 0)
+        g_source_remove (priv->drag_expose_source);
 
     g_free(priv->gps);
 
@@ -1551,8 +1596,7 @@ osm_gps_map_finalize (GObject *object)
     g_free(priv->image_format);
 
     /* trip and tracks contain simple non GObject types, so free them here */
-    osm_gps_map_free_trip(map);
-    osm_gps_map_free_tracks(map);
+    gslist_of_data_free(&priv->trip_history);
 
     G_OBJECT_CLASS (osm_gps_map_parent_class)->finalize (object);
 }
@@ -1567,16 +1611,16 @@ osm_gps_map_set_property (GObject *object, guint prop_id, const GValue *value, G
     switch (prop_id)
     {
         case PROP_AUTO_CENTER:
-            priv->map_auto_center = g_value_get_boolean (value);
+            priv->map_auto_center_enabled = g_value_get_boolean (value);
             break;
         case PROP_RECORD_TRIP_HISTORY:
-            priv->record_trip_history = g_value_get_boolean (value);
+            priv->trip_history_record_enabled = g_value_get_boolean (value);
             break;
         case PROP_SHOW_TRIP_HISTORY:
-            priv->show_trip_history = g_value_get_boolean (value);
+            priv->trip_history_show_enabled = g_value_get_boolean (value);
             break;
         case PROP_AUTO_DOWNLOAD:
-            priv->map_auto_download = g_value_get_boolean (value);
+            priv->map_auto_download_enabled = g_value_get_boolean (value);
             break;
         case PROP_REPO_URI:
             priv->repo_uri = g_value_dup_string (value);
@@ -1596,18 +1640,29 @@ osm_gps_map_set_property (GObject *object, guint prop_id, const GValue *value, G
                 g_value_take_boxed(&val, uri);
                 g_object_set_property(G_OBJECT(priv->soup_session),SOUP_SESSION_PROXY_URI,&val);
 #endif
-            } else
+            } else {
                 priv->proxy_uri = NULL;
-
+            }
             break;
         case PROP_TILE_CACHE_DIR:
-            priv->tile_dir = g_value_dup_string (value);
+            if ( g_value_get_string(value) ) {
+                priv->tile_dir = g_value_dup_string (value);
+                if ((g_strcmp0(priv->tile_dir, OSM_GPS_MAP_CACHE_DISABLED) == 0)    ||
+                    (g_strcmp0(priv->tile_dir, OSM_GPS_MAP_CACHE_AUTO) == 0)        ||
+                    (g_strcmp0(priv->tile_dir, OSM_GPS_MAP_CACHE_FRIENDLY) == 0)) {
+                    /* this case is handled by osm_gps_map_setup */
+                } else {
+                    priv->cache_dir = g_strdup(priv->tile_dir);
+                    g_debug("Cache dir: %s", priv->cache_dir);
+                }
+            } else {
+                priv->tile_dir = g_strdup(OSM_GPS_MAP_CACHE_DISABLED);
+            }
             break;
         case PROP_TILE_CACHE_BASE_DIR:
             priv->tile_base_dir = g_value_dup_string (value);
             break;
         case PROP_TILE_CACHE_DIR_IS_FULL_PATH:
-             g_warning("GObject property tile-cache-is-full-path depreciated");
              break;
         case PROP_ZOOM:
             priv->map_zoom = g_value_get_int (value);
@@ -1627,7 +1682,9 @@ osm_gps_map_set_property (GObject *object, guint prop_id, const GValue *value, G
             center_coord_update(map);
             break;
         case PROP_GPS_TRACK_WIDTH:
-            priv->ui_gps_track_width = g_value_get_int (value);
+            g_object_set (priv->gps_track,
+                    "line-width", g_value_get_float (value),
+                    NULL);
             break;
         case PROP_GPS_POINT_R1:
             priv->ui_gps_point_inner_radius = g_value_get_int (value);
@@ -1643,21 +1700,11 @@ osm_gps_map_set_property (GObject *object, guint prop_id, const GValue *value, G
                priv->map_source >= OSM_GPS_MAP_SOURCE_NULL &&
                priv->map_source <= OSM_GPS_MAP_SOURCE_LAST) {
 
-                /* we now have to switch the entire map */
-
-                /* flush the ram cache */
-                g_hash_table_remove_all(priv->tile_cache);
-
-                osm_gps_map_setup(priv);
+                if (!priv->is_constructed)
+                    g_critical("Map source setup called twice");
 
-                inspect_map_uri(map);
-
-                /* adjust zoom if necessary */
-                if(priv->map_zoom > priv->max_zoom) 
-                    osm_gps_map_set_zoom(map, priv->max_zoom);
-
-                if(priv->map_zoom < priv->min_zoom)
-                    osm_gps_map_set_zoom(map, priv->min_zoom);
+                /* we now have to switch the entire map */
+                osm_gps_map_setup(map);
 
             } } break;
         case PROP_IMAGE_FORMAT:
@@ -1666,6 +1713,12 @@ osm_gps_map_set_property (GObject *object, guint prop_id, const GValue *value, G
         case PROP_DRAG_LIMIT:
             priv->drag_limit = g_value_get_int (value);
             break;
+        case PROP_AUTO_CENTER_THRESHOLD:
+            priv->map_auto_center_threshold = g_value_get_float (value);
+            break;
+        case PROP_SHOW_GPS_POINT:
+            priv->gps_point_enabled = g_value_get_boolean (value);
+            break;
         default:
             G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
             break;
@@ -1682,16 +1735,16 @@ osm_gps_map_get_property (GObject *object, guint prop_id, GValue *value, GParamS
     switch (prop_id)
     {
         case PROP_AUTO_CENTER:
-            g_value_set_boolean(value, priv->map_auto_center);
+            g_value_set_boolean(value, priv->map_auto_center_enabled);
             break;
         case PROP_RECORD_TRIP_HISTORY:
-            g_value_set_boolean(value, priv->record_trip_history);
+            g_value_set_boolean(value, priv->trip_history_record_enabled);
             break;
         case PROP_SHOW_TRIP_HISTORY:
-            g_value_set_boolean(value, priv->show_trip_history);
+            g_value_set_boolean(value, priv->trip_history_show_enabled);
             break;
         case PROP_AUTO_DOWNLOAD:
-            g_value_set_boolean(value, priv->map_auto_download);
+            g_value_set_boolean(value, priv->map_auto_download_enabled);
             break;
         case PROP_REPO_URI:
             g_value_set_string(value, priv->repo_uri);
@@ -1732,9 +1785,11 @@ osm_gps_map_get_property (GObject *object, guint prop_id, GValue *value, GParamS
         case PROP_TILES_QUEUED:
             g_value_set_int(value, g_hash_table_size(priv->tile_queue));
             break;
-        case PROP_GPS_TRACK_WIDTH:
-            g_value_set_int(value, priv->ui_gps_track_width);
-            break;
+        case PROP_GPS_TRACK_WIDTH: {
+            gfloat f;
+            g_object_get (priv->gps_track, "line-width", &f, NULL);
+            g_value_set_float (value, f);
+            } break;
         case PROP_GPS_POINT_R1:
             g_value_set_int(value, priv->ui_gps_point_inner_radius);
             break;
@@ -1750,6 +1805,12 @@ osm_gps_map_get_property (GObject *object, guint prop_id, GValue *value, GParamS
         case PROP_DRAG_LIMIT:
             g_value_set_int(value, priv->drag_limit);
             break;
+        case PROP_AUTO_CENTER_THRESHOLD:
+            g_value_set_float(value, priv->map_auto_center_threshold);
+            break;
+        case PROP_SHOW_GPS_POINT:
+            g_value_set_boolean(value, priv->gps_point_enabled);
+            break;
         default:
             G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
             break;
@@ -1784,7 +1845,7 @@ osm_gps_map_button_press (GtkWidget *widget, GdkEventButton *event)
         }
     }
 
-    priv->button_down = TRUE;
+    priv->is_button_down = TRUE;
     priv->drag_counter = 0;
     priv->drag_start_mouse_x = (int) event->x;
     priv->drag_start_mouse_y = (int) event->y;
@@ -1800,12 +1861,12 @@ osm_gps_map_button_release (GtkWidget *widget, GdkEventButton *event)
     OsmGpsMap *map = OSM_GPS_MAP(widget);
     OsmGpsMapPrivate *priv = OSM_GPS_MAP_PRIVATE(widget);
 
-    if(!priv->button_down)
+    if(!priv->is_button_down)
         return FALSE;
 
-    if (priv->dragging)
+    if (priv->is_dragging)
     {
-        priv->dragging = FALSE;
+        priv->is_dragging = FALSE;
 
         priv->map_x = priv->drag_start_map_x;
         priv->map_y = priv->drag_start_map_y;
@@ -1819,7 +1880,7 @@ osm_gps_map_button_release (GtkWidget *widget, GdkEventButton *event)
     }
 
     priv->drag_counter = -1;
-    priv->button_down = 0;
+    priv->is_button_down = FALSE;
 
     return FALSE;
 }
@@ -1832,7 +1893,7 @@ osm_gps_map_map_expose (GtkWidget *widget)
 {
     OsmGpsMapPrivate *priv = OSM_GPS_MAP(widget)->priv;
 
-    priv->drag_expose = 0;
+    priv->drag_expose_source = 0;
     osm_gps_map_expose (widget, NULL);
     return FALSE;
 }
@@ -1844,7 +1905,7 @@ osm_gps_map_motion_notify (GtkWidget *widget, GdkEventMotion  *event)
     GdkModifierType state;
     OsmGpsMapPrivate *priv = OSM_GPS_MAP_PRIVATE(widget);
 
-    if(!priv->button_down)
+    if(!priv->is_button_down)
         return FALSE;
 
     if (event->is_hint)
@@ -1872,17 +1933,17 @@ osm_gps_map_motion_notify (GtkWidget *widget, GdkEventMotion  *event)
 
     priv->drag_counter++;
 
-    priv->dragging = TRUE;
+    priv->is_dragging = TRUE;
 
-    if (priv->map_auto_center)
+    if (priv->map_auto_center_enabled)
         g_object_set(G_OBJECT(widget), "auto-center", FALSE, NULL);
 
     priv->drag_mouse_dx = x - priv->drag_start_mouse_x;
     priv->drag_mouse_dy = y - priv->drag_start_mouse_y;
 
     /* instead of redrawing directly just add an idle function */
-    if (!priv->drag_expose)
-        priv->drag_expose = 
+    if (!priv->drag_expose_source)
+        priv->drag_expose_source = 
             g_idle_add ((GSourceFunc)osm_gps_map_map_expose, widget);
 
     return FALSE;
@@ -1891,33 +1952,37 @@ osm_gps_map_motion_notify (GtkWidget *widget, GdkEventMotion  *event)
 static gboolean
 osm_gps_map_configure (GtkWidget *widget, GdkEventConfigure *event)
 {
+    GtkAllocation allocation;
     OsmGpsMapPrivate *priv = OSM_GPS_MAP_PRIVATE(widget);
+    GdkWindow *window;
 
     /* create pixmap */
     if (priv->pixmap)
         g_object_unref (priv->pixmap);
 
+    gtk_widget_get_allocation(widget, &allocation);
+    window = gtk_widget_get_window(widget);
     priv->pixmap = gdk_pixmap_new (
-                        widget->window,
-                        widget->allocation.width + EXTRA_BORDER * 2,
-                        widget->allocation.height + EXTRA_BORDER * 2,
+                        window,
+                        allocation.width + EXTRA_BORDER * 2,
+                        allocation.height + EXTRA_BORDER * 2,
                         -1);
 
     // pixel_x,y, offsets
     gint pixel_x = lon2pixel(priv->map_zoom, priv->center_rlon);
     gint pixel_y = lat2pixel(priv->map_zoom, priv->center_rlat);
 
-    priv->map_x = pixel_x - widget->allocation.width/2;
-    priv->map_y = pixel_y - widget->allocation.height/2;
+    priv->map_x = pixel_x - allocation.width/2;
+    priv->map_y = pixel_y - allocation.height/2;
 
 #ifdef OSD_DOUBLE_BUFFER
     if (priv->dbuf_pixmap)
         g_object_unref (priv->dbuf_pixmap);
 
     priv->dbuf_pixmap = gdk_pixmap_new (
-                        widget->window,
-                        widget->allocation.width,
-                        widget->allocation.height,
+                        window,
+                        allocation.width,
+                        allocation.height,
                         -1);
 #endif
 
@@ -1940,17 +2005,26 @@ osm_gps_map_expose (GtkWidget *widget, GdkEventExpose  *event)
 {
     OsmGpsMap *map = OSM_GPS_MAP(widget);
     OsmGpsMapPrivate *priv = map->priv;
+    GtkAllocation allocation;
+    GtkStateType state;
+    GtkStyle *style;
+    GdkWindow *window;
+    GdkDrawable *drawable;
 
+    window = gtk_widget_get_window (widget);
 #ifdef OSD_DOUBLE_BUFFER
-    GdkDrawable *drawable = priv->dbuf_pixmap;
+    drawable = priv->dbuf_pixmap;
 #else
-    GdkDrawable *drawable = widget->window;
+    drawable = window;
 #endif
+    state = gtk_widget_get_state (widget);
+    gtk_widget_get_allocation (widget, &allocation);
+    style = gtk_widget_get_style (widget);
 
     if (!priv->drag_mouse_dx && !priv->drag_mouse_dy && event)
     {
         gdk_draw_drawable (drawable,
-                           widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
+                           style->fg_gc[state],
                            priv->pixmap,
                            event->area.x + EXTRA_BORDER, event->area.y + EXTRA_BORDER,
                            event->area.x, event->area.y,
@@ -1959,48 +2033,48 @@ osm_gps_map_expose (GtkWidget *widget, GdkEventExpose  *event)
     else
     {
         gdk_draw_drawable (drawable,
-                           widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
+                           style->fg_gc[state],
                            priv->pixmap,
                            0,0,
                            priv->drag_mouse_dx - EXTRA_BORDER, 
                            priv->drag_mouse_dy - EXTRA_BORDER,
                            -1,-1);
         
-        //Paint white outside of the map if dragging. Its less
-        //ugly than painting the corrupted map
+        /* Paint white outside of the map if dragging. Its less 
+           ugly than painting the corrupted map */
         if(priv->drag_mouse_dx>EXTRA_BORDER) {
             gdk_draw_rectangle (drawable,
-                                widget->style->white_gc,
+                                style->white_gc,
                                 TRUE,
                                 0, 0,
                                 priv->drag_mouse_dx - EXTRA_BORDER,
-                                widget->allocation.height);
+                                allocation.height);
         }
         else if (-priv->drag_mouse_dx > EXTRA_BORDER)
         {
             gdk_draw_rectangle (drawable,
-                                widget->style->white_gc,
+                                style->white_gc,
                                 TRUE,
-                                priv->drag_mouse_dx + widget->allocation.width + EXTRA_BORDER, 0,
+                                priv->drag_mouse_dx + allocation.width + EXTRA_BORDER, 0,
                                 -priv->drag_mouse_dx - EXTRA_BORDER,
-                                widget->allocation.height);
+                                allocation.height);
         }
         
         if (priv->drag_mouse_dy>EXTRA_BORDER) {
             gdk_draw_rectangle (drawable,
-                                widget->style->white_gc,
+                                style->white_gc,
                                 TRUE,
                                 0, 0,
-                                widget->allocation.width,
+                                allocation.width,
                                 priv->drag_mouse_dy - EXTRA_BORDER);
         }
         else if (-priv->drag_mouse_dy > EXTRA_BORDER)
         {
             gdk_draw_rectangle (drawable,
-                                widget->style->white_gc,
+                                style->white_gc,
                                 TRUE,
-                                0, priv->drag_mouse_dy + widget->allocation.height + EXTRA_BORDER,
-                                widget->allocation.width,
+                                0, priv->drag_mouse_dy + allocation.height + EXTRA_BORDER,
+                                allocation.width,
                                 -priv->drag_mouse_dy - EXTRA_BORDER);
         }
     }
@@ -2012,7 +2086,7 @@ osm_gps_map_expose (GtkWidget *widget, GdkEventExpose  *event)
             osm_gps_map_layer_draw(layer, map, drawable);
 #ifdef OSD_DOUBLE_BUFFER
             gdk_draw_drawable (widget->window,
-                       widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
+                       style->fg_gc[state],
                        priv->dbuf_pixmap,
                        0,0,0,0,-1,-1);
 #endif
@@ -2043,6 +2117,9 @@ osm_gps_map_class_init (OsmGpsMapClass *klass)
     widget_class->motion_notify_event = osm_gps_map_motion_notify;
     widget_class->scroll_event = osm_gps_map_scroll_event;
 
+    /* default implementation of draw_gps_point */
+    klass->draw_gps_point = osm_gps_map_draw_gps_point;
+
     g_object_class_install_property (object_class,
                                      PROP_AUTO_CENTER,
                                      g_param_spec_boolean ("auto-center",
@@ -2052,6 +2129,16 @@ osm_gps_map_class_init (OsmGpsMapClass *klass)
                                                            G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
 
     g_object_class_install_property (object_class,
+                                     PROP_AUTO_CENTER_THRESHOLD,
+                                     g_param_spec_float ("auto-center-threshold",
+                                                         "auto center threshold",
+                                                         "the amount of the window the gps point must move before auto centering",
+                                                         0.0, /* minimum property value */
+                                                         1.0, /* maximum property value */
+                                                         0.25,
+                                                         G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
+
+    g_object_class_install_property (object_class,
                                      PROP_RECORD_TRIP_HISTORY,
                                      g_param_spec_boolean ("record-trip-history",
                                                            "record trip history",
@@ -2067,6 +2154,21 @@ osm_gps_map_class_init (OsmGpsMapClass *klass)
                                                            TRUE,
                                                            G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
 
+    /**
+     * OsmGpsMap:show-gps-point:
+     *
+     * Controls whether the current gps point is shown on the map. Note that
+     * for derived classes that implement the draw_gps_point vfunc, if this
+     * property is %FALSE
+     **/
+    g_object_class_install_property (object_class,
+                                     PROP_SHOW_GPS_POINT,
+                                     g_param_spec_boolean ("show-gps-point",
+                                                           "show gps point",
+                                                           "should the current gps point be shown on the map",
+                                                           TRUE,
+                                                           G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
+
     g_object_class_install_property (object_class,
                                      PROP_AUTO_DOWNLOAD,
                                      g_param_spec_boolean ("auto-download",
@@ -2075,11 +2177,75 @@ osm_gps_map_class_init (OsmGpsMapClass *klass)
                                                            TRUE,
                                                            G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
 
+    /**
+     * OsmGpsMap:repo-uri:
+     *
+     * A URI string which defines the location and format to fetch tiles
+     * for the map. The string is of the format
+     * "http://tile.openstreetmap.org/#Z/#X/#Y.png". Characters
+     * that begin with # are treated as tokens and replaced according to
+     * the following rules;
+     *
+     * <itemizedlist>
+     * <listitem>
+     * <para>
+     * \#X - X-tile, slippy map format
+     * </para>
+     * </listitem>
+     * <listitem>
+     * <para>
+     * \#Y - Y-tile, slippy map format, mercator projection
+     * </para>
+     * </listitem>
+     * <listitem>
+     * <para>
+     * \#Z - Zoom level, where min_zoom >= zoom <= max_zoom
+     * </para>
+     * </listitem>
+     * <listitem>
+     * <para>
+     * \#S - Zoom level, where -max_zoom >= (zoom-max_zoom) <= min_zoom
+     * </para>
+     * </listitem>
+     * <listitem>
+     * <para>
+     * \#Q - Quad tree format, set of "qrts"
+     * </para>
+     * </listitem>
+     * <listitem>
+     * <para>
+     * \#Q0 - Quad tree format, set of "0123"
+     * </para>
+     * </listitem>
+     * <listitem>
+     * <para>
+     * \#YS - Not Implemented
+     * </para>
+     * </listitem>
+     * <listitem>
+     * <para>
+     * \#R - Random integer in range [0,4]
+     * </para>
+     * </listitem>
+     * </itemizedlist>
+     *
+     * <note>
+     * <para>
+     * If you do not wish to use the default map tiles (provided by OpenStreeMap)
+     * it is recommened that you use one of the predefined map sources, and thus
+     * you should construct the map by setting #OsmGpsMap:map-source and not
+     * #OsmGpsMap:repo-uri. The #OsmGpsMap:repo-uri property is primarily
+     * designed for applications that wish complete control of tile repository
+     * management, or wish to use #OsmGpsMap with a tile repository it does not
+     * explicitly support.
+     * </para>
+     * </note>
+     **/
     g_object_class_install_property (object_class,
                                      PROP_REPO_URI,
                                      g_param_spec_string ("repo-uri",
                                                           "repo uri",
-                                                          "map source tile repository uri",
+                                                          "Map source tile repository uri",
                                                           OSM_REPO_URI,
                                                           G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
 
@@ -2087,39 +2253,76 @@ osm_gps_map_class_init (OsmGpsMapClass *klass)
                                      PROP_PROXY_URI,
                                      g_param_spec_string ("proxy-uri",
                                                           "proxy uri",
-                                                          "http proxy uri on NULL",
+                                                          "HTTP proxy uri or NULL",
                                                           NULL,
                                                           G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
 
+
+    /**
+     * OsmGpsMap:tile-cache:
+     *
+     * Either a full path or one of the special format URIs
+     * #OSM_GPS_MAP_CACHE_DISABLED, #OSM_GPS_MAP_CACHE_AUTO,
+     * #OSM_GPS_MAP_CACHE_FRIENDLY. Also see #OsmGpsMap:tile-cache-base for a
+     * full understanding.
+     *
+     * #OSM_GPS_MAP_CACHE_DISABLED disables the on disk tile cache (so all tiles
+     * are fetched from the network. #OSM_GPS_MAP_CACHE_AUTO causes the tile
+     * cache to be /tile-cache-base/md5(repo-uri), where md5 is the md5sum
+     * of #OsmGpsMap:repo-uri. #OSM_GPS_MAP_CACHE_FRIENDLY
+     * causes the tile cache to be /tile-cache-base/friendlyname(repo-uri).
+     *
+     * Any other string is interpreted as a local path, i.e. /path/to/cache
+     **/
     g_object_class_install_property (object_class,
                                      PROP_TILE_CACHE_DIR,
                                      g_param_spec_string ("tile-cache",
                                                           "tile cache",
-                                                          "osm local tile cache dir",
+                                                          "Tile cache dir",
                                                           OSM_GPS_MAP_CACHE_AUTO,
-                                                          G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
-
+                                                          G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
+
+    /**
+     * OsmGpsMap:tile-cache-base:
+     *
+     * The base directory of the tile cache when you have constructed
+     * the map with #OsmGpsMap:tile-cache set to #OSM_GPS_MAP_CACHE_AUTO or
+     * #OSM_GPS_MAP_CACHE_FRIENDLY
+     *
+     * The string is interpreted as a local path, i.e. /path/to/cache
+     **/
     g_object_class_install_property (object_class,
                                      PROP_TILE_CACHE_BASE_DIR,
                                      g_param_spec_string ("tile-cache-base",
                                                           "tile cache-base",
-                                                          "base directory to which friendly and auto paths are appended",
+                                                          "Base directory to which friendly and auto paths are appended",
                                                           NULL,
                                                           G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
 
+    /**
+     * OsmGpsMap:tile-cache-is-full-path:
+     *
+     * Deprecated: Use #OsmGpsMap:tile-cache and #OsmGpsMap:tile-cache-base instead
+     **/
      g_object_class_install_property (object_class,
                                       PROP_TILE_CACHE_DIR_IS_FULL_PATH,
                                       g_param_spec_boolean ("tile-cache-is-full-path",
                                                             "tile cache is full path",
-                                                            "DEPRECIATED",
+                                                            "",
                                                             FALSE,
                                                             G_PARAM_READABLE | G_PARAM_WRITABLE));
 
+    /**
+     * OsmGpsMap:zoom:
+     *
+     * The map zoom level. Connect to ::notify::zoom if you want to be informed
+     * when this changes.
+    **/
     g_object_class_install_property (object_class,
                                      PROP_ZOOM,
                                      g_param_spec_int ("zoom",
                                                        "zoom",
-                                                       "initial zoom level",
+                                                       "Map zoom level",
                                                        MIN_ZOOM, /* minimum property value */
                                                        MAX_ZOOM, /* maximum property value */
                                                        3,
@@ -2129,7 +2332,7 @@ osm_gps_map_class_init (OsmGpsMapClass *klass)
                                      PROP_MAX_ZOOM,
                                      g_param_spec_int ("max-zoom",
                                                        "max zoom",
-                                                       "maximum zoom level",
+                                                       "Maximum zoom level",
                                                        MIN_ZOOM, /* minimum property value */
                                                        MAX_ZOOM, /* maximum property value */
                                                        OSM_MAX_ZOOM,
@@ -2139,7 +2342,7 @@ osm_gps_map_class_init (OsmGpsMapClass *klass)
                                      PROP_MIN_ZOOM,
                                      g_param_spec_int ("min-zoom",
                                                        "min zoom",
-                                                       "minimum zoom level",
+                                                       "Minimum zoom level",
                                                        MIN_ZOOM, /* minimum property value */
                                                        MAX_ZOOM, /* maximum property value */
                                                        OSM_MIN_ZOOM,
@@ -2149,7 +2352,7 @@ osm_gps_map_class_init (OsmGpsMapClass *klass)
                                      PROP_LATITUDE,
                                      g_param_spec_float ("latitude",
                                                          "latitude",
-                                                         "latitude in degrees",
+                                                         "Latitude in degrees",
                                                          -90.0, /* minimum property value */
                                                          90.0, /* maximum property value */
                                                          0,
@@ -2159,7 +2362,7 @@ osm_gps_map_class_init (OsmGpsMapClass *klass)
                                      PROP_LONGITUDE,
                                      g_param_spec_float ("longitude",
                                                          "longitude",
-                                                         "longitude in degrees",
+                                                         "Longitude in degrees",
                                                          -180.0, /* minimum property value */
                                                          180.0, /* maximum property value */
                                                          0,
@@ -2169,7 +2372,7 @@ osm_gps_map_class_init (OsmGpsMapClass *klass)
                                      PROP_MAP_X,
                                      g_param_spec_int ("map-x",
                                                        "map-x",
-                                                       "initial map x location",
+                                                       "Initial map x location",
                                                        G_MININT, /* minimum property value */
                                                        G_MAXINT, /* maximum property value */
                                                        890,
@@ -2179,17 +2382,23 @@ osm_gps_map_class_init (OsmGpsMapClass *klass)
                                      PROP_MAP_Y,
                                      g_param_spec_int ("map-y",
                                                        "map-y",
-                                                       "initial map y location",
+                                                       "Initial map y location",
                                                        G_MININT, /* minimum property value */
                                                        G_MAXINT, /* maximum property value */
                                                        515,
                                                        G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
 
+    /**
+     * OsmGpsMap:tiles-queued:
+     *
+     * The number of tiles currently waiting to download. Connect to
+     * ::notify::tiles-queued if you want to be informed when this changes
+    **/
     g_object_class_install_property (object_class,
                                      PROP_TILES_QUEUED,
                                      g_param_spec_int ("tiles-queued",
                                                        "tiles-queued",
-                                                       "number of tiles currently waiting to download",
+                                                       "The number of tiles currently waiting to download",
                                                        G_MININT, /* minimum property value */
                                                        G_MAXINT, /* maximum property value */
                                                        0,
@@ -2197,19 +2406,19 @@ osm_gps_map_class_init (OsmGpsMapClass *klass)
 
     g_object_class_install_property (object_class,
                                      PROP_GPS_TRACK_WIDTH,
-                                     g_param_spec_int ("gps-track-width",
-                                                       "gps-track-width",
-                                                       "width of the lines drawn for the gps track",
-                                                       1,           /* minimum property value */
-                                                       G_MAXINT,    /* maximum property value */
-                                                       4,
-                                                       G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
+                                     g_param_spec_float ("gps-track-width",
+                                                         "gps-track-width",
+                                                         "The width of the lines drawn for the gps track",
+                                                         1.0,       /* minimum property value */
+                                                         100.0,     /* maximum property value */
+                                                         4.0,
+                                                         G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
 
     g_object_class_install_property (object_class,
                                      PROP_GPS_POINT_R1,
                                      g_param_spec_int ("gps-track-point-radius",
                                                        "gps-track-point-radius",
-                                                       "radius of the gps point inner circle",
+                                                       "The radius of the gps point inner circle",
                                                        0,           /* minimum property value */
                                                        G_MAXINT,    /* maximum property value */
                                                        5,
@@ -2219,17 +2428,30 @@ osm_gps_map_class_init (OsmGpsMapClass *klass)
                                      PROP_GPS_POINT_R2,
                                      g_param_spec_int ("gps-track-highlight-radius",
                                                        "gps-track-highlight-radius",
-                                                       "radius of the gps point highlight circle",
+                                                       "The radius of the gps point highlight circle",
                                                        0,           /* minimum property value */
                                                        G_MAXINT,    /* maximum property value */
                                                        20,
                                                        G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT));
 
+    /**
+     * OsmGpsMap:map-source:
+     *
+     * A #OsmGpsMapSource_t representing the tile repository to use
+     *
+     * <note>
+     * <para>
+     * If you do not wish to use the default map tiles (provided by OpenStreeMap)
+     * it is recommened that you set this property at construction, instead
+     * of setting #OsmGpsMap:repo-uri.
+     * </para>
+     * </note>
+     **/
     g_object_class_install_property (object_class,
                                      PROP_MAP_SOURCE,
                                      g_param_spec_int ("map-source",
                                                        "map source",
-                                                       "map source ID",
+                                                       "The map source ID",
                                                        -1,          /* minimum property value */
                                                        G_MAXINT,    /* maximum property value */
                                                        -1,
@@ -2239,7 +2461,7 @@ osm_gps_map_class_init (OsmGpsMapClass *klass)
                                      PROP_IMAGE_FORMAT,
                                      g_param_spec_string ("image-format",
                                                           "image format",
-                                                          "map source tile repository image format (jpg, png)",
+                                                          "The map source tile repository image format (jpg, png)",
                                                           OSM_IMAGE_FORMAT,
                                                           G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
 
@@ -2247,213 +2469,49 @@ osm_gps_map_class_init (OsmGpsMapClass *klass)
                                      PROP_DRAG_LIMIT,
                                      g_param_spec_int ("drag-limit",
                                                        "drag limit",
-                                                       "the number of pixels the user has to move the pointer in order to start dragging",
+                                                       "The number of pixels the user has to move the pointer in order to start dragging",
                                                        0,           /* minimum property value */
                                                        G_MAXINT,    /* maximum property value */
                                                        10,
                                                        G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
 
+    /**
+     * OsmGpsMap::changed:
+     *
+     * The #OsmGpsMap::changed signal is emitted any time the map zoom or map center
+     * is chaged (such as by dragging or zooming).
+     *
+     * <note>
+     * <para>
+     * If you are only interested in the map zoom, then you can simply connect
+     * to ::notify::zoom
+     * </para>
+     * </note>
+     **/
     g_signal_new ("changed", OSM_TYPE_GPS_MAP,
                   G_SIGNAL_RUN_FIRST, 0, NULL, NULL,
                   g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
 }
 
-const char* 
-osm_gps_map_source_get_friendly_name(OsmGpsMapSource_t source)
-{
-    switch(source)
-    {
-        case OSM_GPS_MAP_SOURCE_NULL:
-            return "None";
-        case OSM_GPS_MAP_SOURCE_OPENSTREETMAP:
-            return "OpenStreetMap I";
-        case OSM_GPS_MAP_SOURCE_OPENSTREETMAP_RENDERER:
-            return "OpenStreetMap II";
-        case OSM_GPS_MAP_SOURCE_OPENAERIALMAP:
-            return "OpenAerialMap";
-        case OSM_GPS_MAP_SOURCE_OPENCYCLEMAP:
-            return "OpenCycleMap";
-        case OSM_GPS_MAP_SOURCE_OSM_PUBLIC_TRANSPORT:
-            return "Public Transport";
-        case OSM_GPS_MAP_SOURCE_OSMC_TRAILS:
-            return "OSMC Trails";
-        case OSM_GPS_MAP_SOURCE_MAPS_FOR_FREE:
-            return "Maps-For-Free";
-        case OSM_GPS_MAP_SOURCE_GOOGLE_STREET:
-            return "Google Maps";
-        case OSM_GPS_MAP_SOURCE_GOOGLE_SATELLITE:
-            return "Google Satellite";
-        case OSM_GPS_MAP_SOURCE_GOOGLE_HYBRID:
-            return "Google Hybrid";
-        case OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_STREET:
-            return "Virtual Earth";
-        case OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_SATELLITE:
-            return "Virtual Earth Satellite";
-        case OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_HYBRID:
-            return "Virtual Earth Hybrid";
-        case OSM_GPS_MAP_SOURCE_YAHOO_STREET:
-            return "Yahoo Maps";
-        case OSM_GPS_MAP_SOURCE_YAHOO_SATELLITE:
-            return "Yahoo Satellite";
-        case OSM_GPS_MAP_SOURCE_YAHOO_HYBRID:
-            return "Yahoo Hybrid";
-        case OSM_GPS_MAP_SOURCE_LAST:
-        default:
-            return NULL;
-    }
-    return NULL;
-}
-
-//http://www.internettablettalk.com/forums/showthread.php?t=5209
-//https://garage.maemo.org/plugins/scmsvn/viewcvs.php/trunk/src/maps.c?root=maemo-mapper&view=markup
-//http://www.ponies.me.uk/maps/GoogleTileUtils.java
-//http://www.mgmaps.com/cache/MapTileCacher.perl
-const char* 
-osm_gps_map_source_get_repo_uri(OsmGpsMapSource_t source)
-{
-    switch(source)
-    {
-        case OSM_GPS_MAP_SOURCE_NULL:
-            return "none://";
-        case OSM_GPS_MAP_SOURCE_OPENSTREETMAP:
-            return OSM_REPO_URI;
-        case OSM_GPS_MAP_SOURCE_OPENAERIALMAP:
-            /* OpenAerialMap is down, offline till furthur notice
-               http://openaerialmap.org/pipermail/talk_openaerialmap.org/2008-December/000055.html */
-            return NULL;
-        case OSM_GPS_MAP_SOURCE_OPENSTREETMAP_RENDERER:
-            return "http://tah.openstreetmap.org/Tiles/tile/#Z/#X/#Y.png";
-        case OSM_GPS_MAP_SOURCE_OPENCYCLEMAP:
-            return "http://c.andy.sandbox.cloudmade.com/tiles/cycle/#Z/#X/#Y.png";
-        case OSM_GPS_MAP_SOURCE_OSM_PUBLIC_TRANSPORT:
-            return "http://tile.xn--pnvkarte-m4a.de/tilegen/#Z/#X/#Y.png";
-        case OSM_GPS_MAP_SOURCE_OSMC_TRAILS:
-            return "http://topo.geofabrik.de/trails/#Z/#X/#Y.png";
-        case OSM_GPS_MAP_SOURCE_MAPS_FOR_FREE:
-            return "http://maps-for-free.com/layer/relief/z#Z/row#Y/#Z_#X-#Y.jpg";
-        case OSM_GPS_MAP_SOURCE_GOOGLE_STREET:
-            return "http://mt#R.google.com/vt/v=w2.97&x=#X&y=#Y&z=#Z";
-        case OSM_GPS_MAP_SOURCE_GOOGLE_HYBRID:
-            /* No longer working
-               "http://mt#R.google.com/mt?n=404&v=w2t.99&x=#X&y=#Y&zoom=#S" */
-            return NULL;
-        case OSM_GPS_MAP_SOURCE_GOOGLE_SATELLITE:
-            return "http://khm#R.google.com/kh/v=51&x=#X&y=#Y&z=#Z";
-        case OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_STREET:
-            return "http://a#R.ortho.tiles.virtualearth.net/tiles/r#W.jpeg?g=50";
-        case OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_SATELLITE:
-            return "http://a#R.ortho.tiles.virtualearth.net/tiles/a#W.jpeg?g=50";
-        case OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_HYBRID:
-            return "http://a#R.ortho.tiles.virtualearth.net/tiles/h#W.jpeg?g=50";
-        case OSM_GPS_MAP_SOURCE_YAHOO_STREET:
-        case OSM_GPS_MAP_SOURCE_YAHOO_SATELLITE:
-        case OSM_GPS_MAP_SOURCE_YAHOO_HYBRID:
-            /* TODO: Implement signed Y, aka U
-             * http://us.maps3.yimg.com/aerial.maps.yimg.com/ximg?v=1.7&t=a&s=256&x=%d&y=%-d&z=%d 
-             *  x = tilex,
-             *  y = (1 << (MAX_ZOOM - zoom)) - tiley - 1,
-             *  z = zoom - (MAX_ZOOM - 17));
-             */
-            return NULL;
-        case OSM_GPS_MAP_SOURCE_LAST:
-        default:
-            return NULL;
-    }
-    return NULL;
-}
-
-const char *
-osm_gps_map_source_get_image_format(OsmGpsMapSource_t source)
-{
-    switch(source) {
-        case OSM_GPS_MAP_SOURCE_NULL:
-        case OSM_GPS_MAP_SOURCE_OPENSTREETMAP:
-        case OSM_GPS_MAP_SOURCE_OPENSTREETMAP_RENDERER:
-        case OSM_GPS_MAP_SOURCE_OPENCYCLEMAP:
-        case OSM_GPS_MAP_SOURCE_OSM_PUBLIC_TRANSPORT:
-        case OSM_GPS_MAP_SOURCE_OSMC_TRAILS:
-            return "png";
-        case OSM_GPS_MAP_SOURCE_OPENAERIALMAP:
-        case OSM_GPS_MAP_SOURCE_GOOGLE_STREET:
-        case OSM_GPS_MAP_SOURCE_GOOGLE_HYBRID:
-        case OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_STREET:
-        case OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_SATELLITE:
-        case OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_HYBRID:
-        case OSM_GPS_MAP_SOURCE_YAHOO_STREET:
-        case OSM_GPS_MAP_SOURCE_YAHOO_SATELLITE:
-        case OSM_GPS_MAP_SOURCE_YAHOO_HYBRID:
-        case OSM_GPS_MAP_SOURCE_MAPS_FOR_FREE:
-        case OSM_GPS_MAP_SOURCE_GOOGLE_SATELLITE:
-            return "jpg";
-        case OSM_GPS_MAP_SOURCE_LAST:
-        default:
-            return "bin";
-    }
-    return "bin";
-}
-
-
-int 
-osm_gps_map_source_get_min_zoom(OsmGpsMapSource_t source)
-{
-    return 1;
-}
-
-int 
-osm_gps_map_source_get_max_zoom(OsmGpsMapSource_t source)
-{
-    switch(source) {
-        case OSM_GPS_MAP_SOURCE_NULL:
-            return 18;
-        case OSM_GPS_MAP_SOURCE_OPENSTREETMAP:
-        case OSM_GPS_MAP_SOURCE_OPENCYCLEMAP:
-        case OSM_GPS_MAP_SOURCE_OSM_PUBLIC_TRANSPORT:
-            return OSM_MAX_ZOOM;
-        case OSM_GPS_MAP_SOURCE_OPENSTREETMAP_RENDERER:
-        case OSM_GPS_MAP_SOURCE_OPENAERIALMAP:
-        case OSM_GPS_MAP_SOURCE_GOOGLE_STREET:
-        case OSM_GPS_MAP_SOURCE_GOOGLE_HYBRID:
-        case OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_STREET:
-        case OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_SATELLITE:
-        case OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_HYBRID:
-        case OSM_GPS_MAP_SOURCE_YAHOO_STREET:
-        case OSM_GPS_MAP_SOURCE_YAHOO_SATELLITE:
-        case OSM_GPS_MAP_SOURCE_YAHOO_HYBRID:
-            return 17;
-        case OSM_GPS_MAP_SOURCE_OSMC_TRAILS:
-            return 15;
-        case OSM_GPS_MAP_SOURCE_MAPS_FOR_FREE:
-            return 11;
-        case OSM_GPS_MAP_SOURCE_GOOGLE_SATELLITE:
-            return 18;
-        case OSM_GPS_MAP_SOURCE_LAST:
-        default:
-            return 17;
-    }
-    return 17;
-}
-
-gboolean
-osm_gps_map_source_is_valid(OsmGpsMapSource_t source)
-{
-    return osm_gps_map_source_get_repo_uri(source) != NULL;
-}
-
+/**
+ * osm_gps_map_download_maps:
+ *
+ * Downloads all tiles over the supplied zoom range in the rectangular
+ * region specified by pt1 (north west corner) to pt2 (south east corner)
+ *
+ **/
 void
-osm_gps_map_download_maps (OsmGpsMap *map, coord_t *pt1, coord_t *pt2, int zoom_start, int zoom_end)
+osm_gps_map_download_maps (OsmGpsMap *map, OsmGpsMapPoint *pt1, OsmGpsMapPoint *pt2, int zoom_start, int zoom_end)
 {
-    int i,j,zoom,num_tiles;
     OsmGpsMapPrivate *priv = map->priv;
 
-    if (pt1 && pt2)
-    {
+    if (pt1 && pt2) {
         gchar *filename;
-        num_tiles = 0;
+        int i,j,zoom;
+        int num_tiles = 0;
         zoom_end = CLAMP(zoom_end, priv->min_zoom, priv->max_zoom);
-        g_debug("Download maps: z:%d->%d",zoom_start, zoom_end);
 
-        for(zoom=zoom_start; zoom<=zoom_end; zoom++)
-        {
+        for(zoom=zoom_start; zoom<=zoom_end; zoom++) {
             int x1,y1,x2,y2;
 
             x1 = (int)floor((float)lon2pixel(zoom, pt1->rlon) / (float)TILESIZE);
@@ -2462,114 +2520,152 @@ osm_gps_map_download_maps (OsmGpsMap *map, coord_t *pt1, coord_t *pt2, int zoom_
             x2 = (int)floor((float)lon2pixel(zoom, pt2->rlon) / (float)TILESIZE);
             y2 = (int)floor((float)lat2pixel(zoom, pt2->rlat) / (float)TILESIZE);
 
-            // loop x1-x2
-            for(i=x1; i<=x2; i++)
-            {
-                // loop y1 - y2
-                for(j=y1; j<=y2; j++)
-                {
-                    // x = i, y = j
+            /* loop x1-x2 */
+            for(i=x1; i<=x2; i++) {
+                /* loop y1 - y2 */
+                for(j=y1; j<=y2; j++) {
+                    /* x = i, y = j */
                     filename = g_strdup_printf("%s%c%d%c%d%c%d.%s",
                                     priv->cache_dir, G_DIR_SEPARATOR,
                                     zoom, G_DIR_SEPARATOR,
                                     i, G_DIR_SEPARATOR,
                                     j,
                                     priv->image_format);
-                    if (!g_file_test(filename, G_FILE_TEST_EXISTS))
-                    {
+                    if (!g_file_test(filename, G_FILE_TEST_EXISTS)) {
                         osm_gps_map_download_tile(map, zoom, i, j, FALSE);
                         num_tiles++;
                     }
                     g_free(filename);
                 }
             }
-            g_debug("DL @Z:%d = %d tiles",zoom,num_tiles);
+            g_debug("DL @Z:%d = %d tiles", zoom, num_tiles);
         }
     }
 }
 
+static void
+cancel_message (char *key, SoupMessage *value, SoupSession *user_data)
+{
+    soup_session_cancel_message (user_data, value, SOUP_STATUS_CANCELLED);
+}
+
+/**
+ * osm_gps_map_download_cancel_all:
+ *
+ * Cancels all tiles currently being downloaded. Typically used if you wish to
+ * cacel a large number of tiles queued using osm_gps_map_download_maps()
+ *
+ * Since: 0.7.0
+ **/
 void
-osm_gps_map_get_bbox (OsmGpsMap *map, coord_t *pt1, coord_t *pt2)
+osm_gps_map_download_cancel_all (OsmGpsMap *map)
 {
     OsmGpsMapPrivate *priv = map->priv;
+    g_hash_table_foreach (priv->tile_queue, (GHFunc)cancel_message, priv->soup_session);
+}
+
+/**
+ * osm_gps_map_get_bbox:
+ * @pt1: point to be filled with the top left location
+ * @pt2: point to be filled with the bottom right location
+ *
+ * Returns the geographic locations of the bounding box describing the contents
+ * of the current window, i.e the top left and bottom right corners.
+ **/
+void
+osm_gps_map_get_bbox (OsmGpsMap *map, OsmGpsMapPoint *pt1, OsmGpsMapPoint *pt2)
+{
+    GtkAllocation allocation;
+    OsmGpsMapPrivate *priv = map->priv;
 
     if (pt1 && pt2) {
+        gtk_widget_get_allocation(GTK_WIDGET(map), &allocation);
         pt1->rlat = pixel2lat(priv->map_zoom, priv->map_y);
         pt1->rlon = pixel2lon(priv->map_zoom, priv->map_x);
-        pt2->rlat = pixel2lat(priv->map_zoom, priv->map_y + GTK_WIDGET(map)->allocation.height);
-        pt2->rlon = pixel2lon(priv->map_zoom, priv->map_x + GTK_WIDGET(map)->allocation.width);
-
-        g_debug("BBOX: %f %f %f %f", pt1->rlat, pt1->rlon, pt2->rlat, pt2->rlon);
+        pt2->rlat = pixel2lat(priv->map_zoom, priv->map_y + allocation.height);
+        pt2->rlon = pixel2lon(priv->map_zoom, priv->map_x + allocation.width);
     }
 }
 
-void
-osm_gps_map_set_mapcenter (OsmGpsMap *map, float latitude, float longitude, int zoom)
+/**
+ * osm_gps_map_set_center_and_zoom:
+ *
+ * Since: 0.7.0
+ **/
+void osm_gps_map_set_center_and_zoom (OsmGpsMap *map, float latitude, float longitude, int zoom)
 {
     osm_gps_map_set_center (map, latitude, longitude);
     osm_gps_map_set_zoom (map, zoom);
 }
 
+/**
+ * osm_gps_map_set_center:
+ *
+ **/
 void
 osm_gps_map_set_center (OsmGpsMap *map, float latitude, float longitude)
 {
     int pixel_x, pixel_y;
     OsmGpsMapPrivate *priv;
+    GtkAllocation allocation;
 
     g_return_if_fail (OSM_IS_GPS_MAP (map));
-    priv = map->priv;
 
+    priv = map->priv;
+    gtk_widget_get_allocation(GTK_WIDGET(map), &allocation);
     g_object_set(G_OBJECT(map), "auto-center", FALSE, NULL);
 
     priv->center_rlat = deg2rad(latitude);
     priv->center_rlon = deg2rad(longitude);
 
-    // pixel_x,y, offsets
     pixel_x = lon2pixel(priv->map_zoom, priv->center_rlon);
     pixel_y = lat2pixel(priv->map_zoom, priv->center_rlat);
 
-    priv->map_x = pixel_x - GTK_WIDGET(map)->allocation.width/2;
-    priv->map_y = pixel_y - GTK_WIDGET(map)->allocation.height/2;
+    priv->map_x = pixel_x - allocation.width/2;
+    priv->map_y = pixel_y - allocation.height/2;
 
     osm_gps_map_map_redraw_idle(map);
 
     g_signal_emit_by_name(map, "changed");
 }
 
+/**
+ * osm_gps_map_set_zoom:
+ *
+ **/
 int 
 osm_gps_map_set_zoom (OsmGpsMap *map, int zoom)
 {
-    int zoom_old;
-    double factor = 0.0;
     int width_center, height_center;
     OsmGpsMapPrivate *priv;
+    GtkAllocation allocation;
 
     g_return_val_if_fail (OSM_IS_GPS_MAP (map), 0);
     priv = map->priv;
 
     if (zoom != priv->map_zoom)
     {
-        width_center  = GTK_WIDGET(map)->allocation.width / 2;
-        height_center = GTK_WIDGET(map)->allocation.height / 2;
+        gtk_widget_get_allocation(GTK_WIDGET(map), &allocation);
+        width_center  = allocation.width / 2;
+        height_center = allocation.height / 2;
 
-        zoom_old = priv->map_zoom;
-        //constrain zoom min_zoom -> max_zoom
+        /* update zoom but constrain [min_zoom..max_zoom] */
         priv->map_zoom = CLAMP(zoom, priv->min_zoom, priv->max_zoom);
-
         priv->map_x = lon2pixel(priv->map_zoom, priv->center_rlon) - width_center;
         priv->map_y = lat2pixel(priv->map_zoom, priv->center_rlat) - height_center;
 
-        factor = pow(2, priv->map_zoom-zoom_old);
-        g_debug("Zoom changed from %d to %d factor:%f x:%d",
-                zoom_old, priv->map_zoom, factor, priv->map_x);
-
         osm_gps_map_map_redraw_idle(map);
 
         g_signal_emit_by_name(map, "changed");
+        g_object_notify(G_OBJECT(map), "zoom");
     }
     return priv->map_zoom;
 }
 
+/**
+ * osm_gps_map_zoom_in:
+ *
+ **/
 int
 osm_gps_map_zoom_in (OsmGpsMap *map)
 {
@@ -2577,6 +2673,10 @@ osm_gps_map_zoom_in (OsmGpsMap *map)
     return osm_gps_map_set_zoom(map, map->priv->map_zoom+1);
 }
 
+/**
+ * osm_gps_map_zoom_out:
+ *
+ **/
 int
 osm_gps_map_zoom_out (OsmGpsMap *map)
 {
@@ -2584,276 +2684,480 @@ osm_gps_map_zoom_out (OsmGpsMap *map)
     return osm_gps_map_set_zoom(map, map->priv->map_zoom-1);
 }
 
+GtkWidget *
+osm_gps_map_new (void)
+{
+    return g_object_new (OSM_TYPE_GPS_MAP, NULL);
+}
+
+/**
+ * osm_gps_map_scroll:
+ * @map:
+ * @dx:
+ * @dy:
+ *
+ * Scrolls the map by @dx, @dy pixels (positive north, east)
+ *
+ **/
 void
-osm_gps_map_add_track (OsmGpsMap *map, GSList *track)
+osm_gps_map_scroll (OsmGpsMap *map, gint dx, gint dy)
 {
     OsmGpsMapPrivate *priv;
 
     g_return_if_fail (OSM_IS_GPS_MAP (map));
     priv = map->priv;
 
-    if (track) {
-        priv->tracks = g_slist_append(priv->tracks, track);
-        osm_gps_map_map_redraw_idle(map);
-    }
+    priv->map_x += dx;
+    priv->map_y += dy;
+    center_coord_update(map);
+
+    osm_gps_map_map_redraw_idle (map);
 }
 
-void
-osm_gps_map_replace_track (OsmGpsMap *map, GSList *old_track, GSList *new_track)
+/**
+ * osm_gps_map_get_scale:
+ * @map:
+ *
+ * Returns: the scale of the map at the center, in meters/pixel.
+ *
+ **/
+float
+osm_gps_map_get_scale (OsmGpsMap *map)
 {
     OsmGpsMapPrivate *priv;
 
-    if(!old_track) {
-        osm_gps_map_add_track (map, new_track);
-        return;
-    }
-
-    g_return_if_fail (OSM_IS_GPS_MAP (map));
+    g_return_val_if_fail (OSM_IS_GPS_MAP (map), OSM_GPS_MAP_INVALID);
     priv = map->priv;
 
-    GSList *old = g_slist_find(priv->tracks, old_track);
-    if(!old) {
-        g_warning("track to be replaced not found");
-        return;
-    }
+    return osm_gps_map_get_scale_at_point(priv->map_zoom, priv->center_rlat, priv->center_rlon);
+}
 
-    old->data = new_track;
-    osm_gps_map_map_redraw_idle(map);
+/**
+ * osm_gps_map_get_default_cache_directory:
+ *
+ * Returns: the default cache directory for the library, that is the base
+ * directory to which the full cache path is appended. If
+ * #OsmGpsMap:tile-cache-base is omitted from the constructor then this value
+ * is used.
+ *
+ **/
+gchar *
+osm_gps_map_get_default_cache_directory (void)
+{
+    return g_build_filename(
+                        g_get_user_cache_dir(),
+                        "osmgpsmap",
+                        NULL);
 }
 
+/**
+ * osm_gps_map_set_keyboard_shortcut:
+ * @key: a #OsmGpsMapKey_t
+ * @keyval:
+ *
+ * Associates a keyboard shortcut with the supplied @keyval
+ * (as returned by #gdk_keyval_from_name or simiar). The action given in @key
+ * will be triggered when the corresponding @keyval is pressed. By default
+ * no keyboard shortcuts are associated.
+ *
+ **/
 void
-osm_gps_map_clear_tracks (OsmGpsMap *map)
+osm_gps_map_set_keyboard_shortcut (OsmGpsMap *map, OsmGpsMapKey_t key, guint keyval)
 {
     g_return_if_fail (OSM_IS_GPS_MAP (map));
+    g_return_if_fail(key < OSM_GPS_MAP_KEY_MAX);
 
-    osm_gps_map_free_tracks(map);
-    osm_gps_map_map_redraw_idle(map);
+    map->priv->keybindings[key] = keyval;
+    map->priv->keybindings_enabled = TRUE;
 }
 
+/**
+ * osm_gps_map_track_add:
+ *
+ * Since: 0.7.0
+ **/
 void
-osm_gps_map_add_image_with_alignment (OsmGpsMap *map, float latitude, float longitude, GdkPixbuf *image, float xalign, float yalign)
+osm_gps_map_track_add (OsmGpsMap *map, OsmGpsMapTrack *track)
 {
-    g_return_if_fail (OSM_IS_GPS_MAP (map));
-
-    if (image) {
-        OsmGpsMapPrivate *priv = map->priv;
-        image_t *im;
-
-        //cache w/h for speed, and add image to list
-        im = g_new0(image_t,1);
-        im->w = gdk_pixbuf_get_width(image);
-        im->h = gdk_pixbuf_get_height(image);
-        im->pt.rlat = deg2rad(latitude);
-        im->pt.rlon = deg2rad(longitude);
-
-        //handle alignment
-        im->xoffset = xalign * im->w;
-        im->yoffset = yalign * im->h;
+    OsmGpsMapPrivate *priv;
 
-        g_object_ref(image);
-        im->image = image;
+    g_return_if_fail (OSM_IS_GPS_MAP (map));
+    priv = map->priv;
 
-        priv->images = g_slist_append(priv->images, im);
+    g_object_ref(track);
+    g_signal_connect(track, "point-added",
+                    G_CALLBACK(on_gps_point_added), map);
+    g_signal_connect(track, "notify",
+                    G_CALLBACK(on_track_changed), map);
 
-        osm_gps_map_map_redraw_idle(map);
-    }
+    priv->tracks = g_slist_append(priv->tracks, track);
+    osm_gps_map_map_redraw_idle(map);
 }
 
+/**
+ * osm_gps_map_track_remove_all:
+ *
+ * Since: 0.7.0
+ **/
 void
-osm_gps_map_add_image (OsmGpsMap *map, float latitude, float longitude, GdkPixbuf *image)
+osm_gps_map_track_remove_all (OsmGpsMap *map)
 {
-    osm_gps_map_add_image_with_alignment (map, latitude, longitude, image, 0.5, 0.5);
+    g_return_if_fail (OSM_IS_GPS_MAP (map));
+
+    gslist_of_gobjects_free(&map->priv->tracks);
+    osm_gps_map_map_redraw_idle(map);
 }
 
+/**
+ * osm_gps_map_track_remove:
+ *
+ * Since: 0.7.0
+ **/
 gboolean
-osm_gps_map_remove_image (OsmGpsMap *map, GdkPixbuf *image)
+osm_gps_map_track_remove (OsmGpsMap *map, OsmGpsMapTrack *track)
 {
-    OsmGpsMapPrivate *priv = map->priv;
-    if (priv->images) {
-        GSList *list;
-        for(list = priv->images; list != NULL; list = list->next)
-        {
-            image_t *im = list->data;
-	        if (im->image == image)
-	        {
-		        priv->images = g_slist_remove_link(priv->images, list);
-		        g_object_unref(im->image);
-		        g_free(im);
-		        osm_gps_map_map_redraw_idle(map);
-		        return TRUE;
-	        }
-        }
-    }
-    return FALSE;
+    GSList *data;
+
+    g_return_val_if_fail (OSM_IS_GPS_MAP (map), FALSE);
+    g_return_val_if_fail (track != NULL, FALSE);
+
+    data = gslist_remove_one_gobject (&map->priv->tracks, G_OBJECT(track));
+    osm_gps_map_map_redraw_idle(map);
+    return data != NULL;
 }
 
+/**
+ * osm_gps_map_gps_clear:
+ *
+ * Since: 0.7.0
+ **/
 void
-osm_gps_map_clear_images (OsmGpsMap *map)
+osm_gps_map_gps_clear (OsmGpsMap *map)
 {
+    OsmGpsMapPrivate *priv;
+
     g_return_if_fail (OSM_IS_GPS_MAP (map));
+    priv = map->priv;
 
-    osm_gps_map_free_images(map);
+    g_object_unref(priv->gps_track);
+    priv->gps_track = osm_gps_map_track_new();
+    g_signal_connect(priv->gps_track, "point-added",
+                    G_CALLBACK(on_gps_point_added), map);
+    g_signal_connect(priv->gps_track, "notify",
+                    G_CALLBACK(on_track_changed), map);
     osm_gps_map_map_redraw_idle(map);
 }
 
+/**
+ * osm_gps_map_gps_get_track:
+ *
+ * Returns: (transfer none): The #OsmGpsMapTrack of the internal GPS track, 
+ * i.e. that which is modified when calling osm_gps_map_gps_add(). You must 
+ * not free this.
+ * Since: 0.7.0
+ **/
+OsmGpsMapTrack *
+osm_gps_map_gps_get_track (OsmGpsMap *map)
+{
+    g_return_val_if_fail (OSM_IS_GPS_MAP (map), NULL);
+    return map->priv->gps_track;
+}
+
+/**
+ * osm_gps_map_gps_add:
+ * @latitude: degrees
+ * @longitude: degrees
+ * @heading: degrees or #OSM_GPS_MAP_INVALID to disable showing heading
+ *
+ * Since: 0.7.0
+ **/
 void
-osm_gps_map_draw_gps (OsmGpsMap *map, float latitude, float longitude, float heading)
+osm_gps_map_gps_add (OsmGpsMap *map, float latitude, float longitude, float heading)
 {
-    int pixel_x, pixel_y;
+    OsmGpsMapPoint *point;
     OsmGpsMapPrivate *priv;
 
     g_return_if_fail (OSM_IS_GPS_MAP (map));
     priv = map->priv;
 
+    /* update the current point */
     priv->gps->rlat = deg2rad(latitude);
     priv->gps->rlon = deg2rad(longitude);
-    priv->gps_valid = TRUE;
+    priv->gps_track_used = TRUE;
     priv->gps_heading = deg2rad(heading);
 
-    // pixel_x,y, offsets
-    pixel_x = lon2pixel(priv->map_zoom, priv->gps->rlon);
-    pixel_y = lat2pixel(priv->map_zoom, priv->gps->rlat);
-
-    //If trip marker add to list of gps points.
-    if (priv->record_trip_history) {
-        coord_t *tp = g_new0(coord_t,1);
-        tp->rlat = priv->gps->rlat;
-        tp->rlon = priv->gps->rlon;
-        priv->trip_history = g_slist_append(priv->trip_history, tp);
+    /* If trip marker add to list of gps points */
+    if (priv->trip_history_record_enabled) {
+        point = osm_gps_map_point_new_degrees(latitude, longitude);
+        /* this will cause a redraw to be scheduled */
+        osm_gps_map_track_add_point (priv->gps_track, point);
+    } else {
+        osm_gps_map_map_redraw_idle (map);
+        maybe_autocenter_map (map);
     }
+}
 
-    // dont draw anything if we are dragging
-    if (priv->dragging) {
-        g_debug("Dragging");
-        return;
-    }
+/**
+ * osm_gps_map_image_add:
+ *
+ * Returns: (transfer full): A #OsmGpsMapImage representing the added pixbuf
+ * Since: 0.7.0
+ **/
+OsmGpsMapImage *
+osm_gps_map_image_add (OsmGpsMap *map, float latitude, float longitude, GdkPixbuf *image)
+{
+    return osm_gps_map_image_add_with_alignment (map, latitude, longitude, image, 0.5, 0.5);
+}
 
-    //Automatically center the map if the track approaches the edge
-    if(priv->map_auto_center)   {
-        int x = pixel_x - priv->map_x;
-        int y = pixel_y - priv->map_y;
-        int width = GTK_WIDGET(map)->allocation.width;
-        int height = GTK_WIDGET(map)->allocation.height;
-        if( x < (width/2 - width/8)     || x > (width/2 + width/8)  ||
-            y < (height/2 - height/8)   || y > (height/2 + height/8)) {
+static void
+on_image_changed (OsmGpsMapImage *image, GParamSpec *pspec, OsmGpsMap *map)
+{
+    osm_gps_map_map_redraw_idle (map);
+}
 
-            priv->map_x = pixel_x - GTK_WIDGET(map)->allocation.width/2;
-            priv->map_y = pixel_y - GTK_WIDGET(map)->allocation.height/2;
-            center_coord_update(map);
-        }
-    }
+/**
+ * osm_gps_map_image_add_with_alignment:
+ *
+ * Returns: (transfer full): A #OsmGpsMapImage representing the added pixbuf
+ * Since: 0.7.0
+ **/
+OsmGpsMapImage *
+osm_gps_map_image_add_with_alignment (OsmGpsMap *map, float latitude, float longitude, GdkPixbuf *image, float xalign, float yalign)
+{
+    OsmGpsMapImage *im;
+    OsmGpsMapPoint pt;
+
+    g_return_val_if_fail (OSM_IS_GPS_MAP (map), NULL);
+    pt.rlat = deg2rad(latitude);
+    pt.rlon = deg2rad(longitude);
 
-    // this redraws the map (including the gps track, and adjusts the
-    // map center if it was changed
+    im = g_object_new (OSM_TYPE_GPS_MAP_IMAGE, "pixbuf", image, "x-align", xalign, "y-align", yalign, "point", &pt, NULL);
+    g_signal_connect(im, "notify",
+                    G_CALLBACK(on_image_changed), map);
+
+    map->priv->images = g_slist_append(map->priv->images, im);
     osm_gps_map_map_redraw_idle(map);
+    return im;
 }
 
-void
-osm_gps_map_clear_gps (OsmGpsMap *map)
+/**
+ * osm_gps_map_image_remove:
+ *
+ * Since: 0.7.0
+ **/
+gboolean
+osm_gps_map_image_remove (OsmGpsMap *map, OsmGpsMapImage *image)
 {
-    osm_gps_map_free_trip(map);
+    GSList *data;
+
+    g_return_val_if_fail (OSM_IS_GPS_MAP (map), FALSE);
+    g_return_val_if_fail (image != NULL, FALSE);
+
+    data = gslist_remove_one_gobject (&map->priv->images, G_OBJECT(image));
     osm_gps_map_map_redraw_idle(map);
+    return data != NULL;
 }
 
-coord_t
-osm_gps_map_get_co_ordinates (OsmGpsMap *map, int pixel_x, int pixel_y)
+/**
+ * osm_gps_map_image_remove_all:
+ *
+ * Since: 0.7.0
+ **/
+void
+osm_gps_map_image_remove_all (OsmGpsMap *map)
 {
-    coord_t coord;
-    OsmGpsMapPrivate *priv = map->priv;
+    g_return_if_fail (OSM_IS_GPS_MAP (map));
 
-    coord.rlat = pixel2lat(priv->map_zoom, priv->map_y + pixel_y);
-    coord.rlon = pixel2lon(priv->map_zoom, priv->map_x + pixel_x);
-    return coord;
+    gslist_of_gobjects_free(&map->priv->images);
+    osm_gps_map_map_redraw_idle(map);
 }
 
-GtkWidget *
-osm_gps_map_new (void)
+/**
+ * osm_gps_map_layer_add:
+ * @layer: a #OsmGpsMapLayer object
+ *
+ * Since: 0.7.0
+ **/
+void
+osm_gps_map_layer_add (OsmGpsMap *map, OsmGpsMapLayer *layer)
 {
-    return g_object_new (OSM_TYPE_GPS_MAP, NULL);
+    g_return_if_fail (OSM_IS_GPS_MAP (map));
+    g_return_if_fail (OSM_GPS_MAP_IS_LAYER (layer));
+
+    g_object_ref(G_OBJECT(layer));
+    map->priv->layers = g_slist_append(map->priv->layers, layer);
 }
 
-void
-osm_gps_map_screen_to_geographic (OsmGpsMap *map, gint pixel_x, gint pixel_y,
-                                  gfloat *latitude, gfloat *longitude)
+/**
+ * osm_gps_map_layer_remove:
+ * @layer: a #OsmGpsMapLayer object
+ *
+ * Since: 0.7.0
+ **/
+gboolean
+osm_gps_map_layer_remove (OsmGpsMap *map, OsmGpsMapLayer *layer)
 {
-    OsmGpsMapPrivate *priv;
+    GSList *data;
 
-    g_return_if_fail (OSM_IS_GPS_MAP (map));
-    priv = map->priv;
+    g_return_val_if_fail (OSM_IS_GPS_MAP (map), FALSE);
+    g_return_val_if_fail (layer != NULL, FALSE);
 
-    if (latitude)
-        *latitude = rad2deg(pixel2lat(priv->map_zoom, priv->map_y + pixel_y));
-    if (longitude)
-        *longitude = rad2deg(pixel2lon(priv->map_zoom, priv->map_x + pixel_x));
+    data = gslist_remove_one_gobject (&map->priv->layers, G_OBJECT(layer));
+    osm_gps_map_map_redraw_idle(map);
+    return data != NULL;
 }
 
+/**
+ * osm_gps_map_layer_remove:
+ * @layer: a #OsmGpsMapLayer object
+ *
+ * Since: 0.7.0
+ **/
 void
-osm_gps_map_geographic_to_screen (OsmGpsMap *map,
-                                  gfloat latitude, gfloat longitude,
-                                  gint *pixel_x, gint *pixel_y)
+osm_gps_map_layer_remove_all (OsmGpsMap *map)
 {
-    OsmGpsMapPrivate *priv;
-
     g_return_if_fail (OSM_IS_GPS_MAP (map));
-    priv = map->priv;
 
-    if (pixel_x)
-        *pixel_x = lon2pixel(priv->map_zoom, deg2rad(longitude)) -
-            priv->map_x + priv->drag_mouse_dx;
-    if (pixel_y)
-        *pixel_y = lat2pixel(priv->map_zoom, deg2rad(latitude)) -
-            priv->map_y + priv->drag_mouse_dy;
+    gslist_of_gobjects_free(&map->priv->layers);
+    osm_gps_map_map_redraw_idle(map);
 }
 
+/**
+ * osm_gps_map_convert_screen_to_geographic:
+ * @map:
+ * @pixel_x: pixel location on map, x axis
+ * @pixel_y: pixel location on map, y axis
+ * @pt: (out): location 
+ *
+ * Convert the given pixel location on the map into corresponding
+ * location on the globe
+ *
+ * Since: 0.7.0
+ **/
 void
-osm_gps_map_scroll (OsmGpsMap *map, gint dx, gint dy)
+osm_gps_map_convert_screen_to_geographic(OsmGpsMap *map, gint pixel_x, gint pixel_y, OsmGpsMapPoint *pt)
 {
     OsmGpsMapPrivate *priv;
 
     g_return_if_fail (OSM_IS_GPS_MAP (map));
+    g_return_if_fail (pt);
     priv = map->priv;
 
-    priv->map_x += dx;
-    priv->map_y += dy;
-    center_coord_update(map);
-
-    osm_gps_map_map_redraw_idle (map);
+    pt->rlat = pixel2lat(priv->map_zoom, priv->map_y + pixel_y);
+    pt->rlon = pixel2lon(priv->map_zoom, priv->map_x + pixel_x);
 }
 
-float
-osm_gps_map_get_scale(OsmGpsMap *map)
+/**
+ * osm_gps_map_convert_geographic_to_screen:
+ * @map:
+ * @pt: location
+ * @pixel_x: (out): pixel location on map, x axis
+ * @pixel_y: (out): pixel location on map, y axis
+ *
+ * Convert the given location on the globe to the corresponding
+ * pixel locations on the map.
+ *
+ * Since: 0.7.0
+ **/
+void
+osm_gps_map_convert_geographic_to_screen(OsmGpsMap *map, OsmGpsMapPoint *pt, gint *pixel_x, gint *pixel_y)
 {
     OsmGpsMapPrivate *priv;
 
-    g_return_val_if_fail (OSM_IS_GPS_MAP (map), OSM_GPS_MAP_INVALID);
+    g_return_if_fail (OSM_IS_GPS_MAP (map));
+    g_return_if_fail (pt);
     priv = map->priv;
 
-    return osm_gps_map_get_scale_at_point(priv->map_zoom, priv->center_rlat, priv->center_rlon);
+    if (pixel_x)
+        *pixel_x = lon2pixel(priv->map_zoom, pt->rlon) - priv->map_x + priv->drag_mouse_dx;
+    if (pixel_y)
+        *pixel_y = lat2pixel(priv->map_zoom, pt->rlat) - priv->map_y + priv->drag_mouse_dy;
 }
 
-char * osm_gps_map_get_default_cache_directory(void)
+/**
+ * osm_gps_map_get_event_location:
+ * @map:
+ * @event: A #GtkEventButton that occured on the map
+ *
+ * A convenience function for getting the geographic location of events,
+ * such as mouse clicks, on the map
+ *
+ * Returns: (transfer full): The point on the globe corresponding to the click
+ * Since: 0.7.0
+ **/
+OsmGpsMapPoint *
+osm_gps_map_get_event_location (OsmGpsMap *map, GdkEventButton *event)
 {
-    return g_build_filename(
-                        g_get_user_cache_dir(),
-                        "osmgpsmap",
-                        NULL);
+    OsmGpsMapPoint *p = osm_gps_map_point_new_degrees(0.0,0.0);
+    osm_gps_map_convert_screen_to_geographic(map, event->x, event->y, p);
+    return p;
 }
 
-void osm_gps_map_set_keyboard_shortcut(OsmGpsMap *map, OsmGpsMapKey_t key, guint keyval)
+/**
+ * osm_gps_map_remove_image:
+ *
+ * Deprecated: 0.7.0: Use osm_gps_map_image_remove() instead.
+ **/
+gboolean
+osm_gps_map_remove_image (OsmGpsMap *map, GdkPixbuf *image)
 {
-    g_return_if_fail (OSM_IS_GPS_MAP (map));
-    g_return_if_fail(key < OSM_GPS_MAP_KEY_MAX);
+    GSList *tmp;
+    OsmGpsMapImage *im;
 
-    map->priv->keybindings[key] = keyval;
-    map->priv->keybindings_enabled = TRUE;
+    g_critical("%s is deprecated", G_STRFUNC);
+
+    im = NULL;
+    tmp = map->priv->images;
+    while (tmp != NULL) {
+        GdkPixbuf *p;
+        im = tmp->data;
+        /* g_object_get ref's the pixbuf */
+        g_object_get (im, "pixbuf", &p, NULL);
+        if (p == image) {
+            g_object_unref (p);
+            break;
+        }
+        g_object_unref (p);
+        tmp = g_slist_next(tmp);
+    }
+
+    /* we found the image */
+    if (tmp && im)
+        return osm_gps_map_image_remove (map, im);
+
+    return FALSE;
 }
 
-void osm_gps_map_add_layer (OsmGpsMap *map, OsmGpsMapLayer *layer)
+/**
+ * osm_gps_map_replace_track:
+ *
+ * Deprecated: 0.7.0: Use osm_gps_map_track_remove() and osm_gps_map_track_add()
+ * or just edit the #OsmGpsMapTrack object directly
+ **/
+void
+osm_gps_map_replace_track (OsmGpsMap *map, GSList *old_track, GSList *new_track)
 {
-    g_return_if_fail (OSM_IS_GPS_MAP (map));
-    g_return_if_fail (OSM_GPS_MAP_IS_LAYER (layer));
+    GSList *tmp;
+    OsmGpsMapTrack *track;
 
-    g_object_ref(G_OBJECT(layer));
-    map->priv->layers = g_slist_append(map->priv->layers, layer);
+    g_critical("%s is deprecated", G_STRFUNC);
+
+    track = NULL;
+    tmp = map->priv->tracks;
+    while (tmp != NULL) {
+        GSList *l;
+        track = tmp->data;
+        g_object_get (track, "track", &l, NULL);
+        if (l == old_track)
+            break;
+        tmp = g_slist_next(tmp);
+    }
+
+    /* we found the track */
+    if (tmp && track) {
+        osm_gps_map_track_remove (map, track);
+        track = g_object_new (OSM_TYPE_GPS_MAP_TRACK, "track", new_track, NULL);
+        osm_gps_map_track_add (map, track);
+    }
 }
 
diff --git a/src/osm-gps-map-widget.h b/src/osm-gps-map-widget.h
new file mode 100644
index 0000000..da76529
--- /dev/null
+++ b/src/osm-gps-map-widget.h
@@ -0,0 +1,117 @@
+/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 4 -*- */
+/* vim:set et sw=4 ts=4 cino=t0,(0: */
+/*
+ * osm-gps-map-widget.h
+ * Copyright (C) Marcus Bauer 2008 <marcus.bauer at gmail.com>
+ * Copyright (C) John Stowers 2009 <john.stowers at gmail.com>
+ * Copyright (C) Till Harbaum 2009 <till at harbaum.org>
+ *
+ * Contributions by
+ * Everaldo Canuto 2009 <everaldo.canuto at gmail.com>
+ *
+ * This is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2.
+ *
+ * This program 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 General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _OSM_GPS_MAP_WIDGET_H_
+#define _OSM_GPS_MAP_WIDGET_H_
+
+#include <glib.h>
+#include <glib-object.h>
+#include <gtk/gtk.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+G_BEGIN_DECLS
+
+#define OSM_TYPE_GPS_MAP             (osm_gps_map_get_type ())
+#define OSM_GPS_MAP(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSM_TYPE_GPS_MAP, OsmGpsMap))
+#define OSM_GPS_MAP_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), OSM_TYPE_GPS_MAP, OsmGpsMapClass))
+#define OSM_IS_GPS_MAP(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSM_TYPE_GPS_MAP))
+#define OSM_IS_GPS_MAP_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), OSM_TYPE_GPS_MAP))
+#define OSM_GPS_MAP_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), OSM_TYPE_GPS_MAP, OsmGpsMapClass))
+
+typedef struct _OsmGpsMapClass OsmGpsMapClass;
+typedef struct _OsmGpsMap OsmGpsMap;
+typedef struct _OsmGpsMapPrivate OsmGpsMapPrivate;
+
+#include "osm-gps-map-layer.h"
+#include "osm-gps-map-point.h"
+#include "osm-gps-map-track.h"
+#include "osm-gps-map-image.h"
+
+struct _OsmGpsMapClass
+{
+    GtkDrawingAreaClass parent_class;
+
+    void (*draw_gps_point) (OsmGpsMap *map, GdkDrawable *drawable);
+};
+
+struct _OsmGpsMap
+{
+    GtkDrawingArea parent_instance;
+    OsmGpsMapPrivate *priv;
+};
+
+typedef enum {
+    OSM_GPS_MAP_KEY_FULLSCREEN,
+    OSM_GPS_MAP_KEY_ZOOMIN,
+    OSM_GPS_MAP_KEY_ZOOMOUT,
+    OSM_GPS_MAP_KEY_UP,
+    OSM_GPS_MAP_KEY_DOWN,
+    OSM_GPS_MAP_KEY_LEFT,
+    OSM_GPS_MAP_KEY_RIGHT,
+    OSM_GPS_MAP_KEY_MAX
+} OsmGpsMapKey_t;
+
+#define OSM_GPS_MAP_INVALID         (0.0/0.0)
+#define OSM_GPS_MAP_CACHE_DISABLED  "none://"
+#define OSM_GPS_MAP_CACHE_AUTO      "auto://"
+#define OSM_GPS_MAP_CACHE_FRIENDLY  "friendly://"
+
+GType           osm_gps_map_get_type                    (void) G_GNUC_CONST;
+
+GtkWidget*      osm_gps_map_new                         (void);
+
+gchar*          osm_gps_map_get_default_cache_directory (void);
+
+void            osm_gps_map_download_maps               (OsmGpsMap *map, OsmGpsMapPoint *pt1, OsmGpsMapPoint *pt2, int zoom_start, int zoom_end);
+void            osm_gps_map_download_cancel_all         (OsmGpsMap *map);
+void            osm_gps_map_get_bbox                    (OsmGpsMap *map, OsmGpsMapPoint *pt1, OsmGpsMapPoint *pt2);
+void            osm_gps_map_set_center_and_zoom         (OsmGpsMap *map, float latitude, float longitude, int zoom);
+void            osm_gps_map_set_center                  (OsmGpsMap *map, float latitude, float longitude);
+int             osm_gps_map_set_zoom                    (OsmGpsMap *map, int zoom);
+int             osm_gps_map_zoom_in                     (OsmGpsMap *map);
+int             osm_gps_map_zoom_out                    (OsmGpsMap *map);
+void            osm_gps_map_scroll                      (OsmGpsMap *map, gint dx, gint dy);
+float           osm_gps_map_get_scale                   (OsmGpsMap *map);
+void            osm_gps_map_set_keyboard_shortcut       (OsmGpsMap *map, OsmGpsMapKey_t key, guint keyval);
+void            osm_gps_map_track_add                   (OsmGpsMap *map, OsmGpsMapTrack *track);
+void            osm_gps_map_track_remove_all            (OsmGpsMap *map);
+gboolean        osm_gps_map_track_remove                (OsmGpsMap *map, OsmGpsMapTrack *track);
+void            osm_gps_map_gps_add                     (OsmGpsMap *map, float latitude, float longitude, float heading);
+void            osm_gps_map_gps_clear                   (OsmGpsMap *map);
+OsmGpsMapTrack *osm_gps_map_gps_get_track               (OsmGpsMap *map);
+OsmGpsMapImage *osm_gps_map_image_add                   (OsmGpsMap *map, float latitude, float longitude, GdkPixbuf *image);
+OsmGpsMapImage *osm_gps_map_image_add_with_alignment    (OsmGpsMap *map, float latitude, float longitude, GdkPixbuf *image, float xalign, float yalign);
+gboolean        osm_gps_map_image_remove                (OsmGpsMap *map, OsmGpsMapImage *image);
+void            osm_gps_map_image_remove_all            (OsmGpsMap *map);
+void            osm_gps_map_layer_add                   (OsmGpsMap *map, OsmGpsMapLayer *layer);
+gboolean        osm_gps_map_layer_remove                (OsmGpsMap *map, OsmGpsMapLayer *layer);
+void            osm_gps_map_layer_remove_all            (OsmGpsMap *map);
+void            osm_gps_map_convert_screen_to_geographic(OsmGpsMap *map, gint pixel_x, gint pixel_y, OsmGpsMapPoint *pt);
+void            osm_gps_map_convert_geographic_to_screen(OsmGpsMap *map, OsmGpsMapPoint *pt, gint *pixel_x, gint *pixel_y);
+OsmGpsMapPoint *osm_gps_map_get_event_location          (OsmGpsMap *map, GdkEventButton *event);
+
+G_END_DECLS
+
+#endif /* _OSM_GPS_MAP_WIDGET_H_ */
+
diff --git a/src/osm-gps-map.h b/src/osm-gps-map.h
index 704e720..3ea95b6 100644
--- a/src/osm-gps-map.h
+++ b/src/osm-gps-map.h
@@ -1,141 +1,14 @@
-/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4; tab-width: 4 -*- */
-/* vim:set et sw=4 ts=4 cino=t0,(0: */
-/*
- * osm-gps-map.h
- * Copyright (C) Marcus Bauer 2008 <marcus.bauer at gmail.com>
- * Copyright (C) John Stowers 2009 <john.stowers at gmail.com>
- * Copyright (C) Till Harbaum 2009 <till at harbaum.org>
- *
- * Contributions by
- * Everaldo Canuto 2009 <everaldo.canuto at gmail.com>
- *
- * This is free software: you can redistribute it and/or modify it
- * under the terms of the GNU General Public License
- * as published by the Free Software Foundation; version 2.
- *
- * This program 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 General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
 #ifndef _OSM_GPS_MAP_H_
 #define _OSM_GPS_MAP_H_
 
-#include <glib.h>
-#include <glib-object.h>
-#include <gtk/gtk.h>
-#include <gdk-pixbuf/gdk-pixbuf.h>
-
-G_BEGIN_DECLS
-
-#define OSM_TYPE_GPS_MAP             (osm_gps_map_get_type ())
-#define OSM_GPS_MAP(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), OSM_TYPE_GPS_MAP, OsmGpsMap))
-#define OSM_GPS_MAP_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), OSM_TYPE_GPS_MAP, OsmGpsMapClass))
-#define OSM_IS_GPS_MAP(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), OSM_TYPE_GPS_MAP))
-#define OSM_IS_GPS_MAP_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), OSM_TYPE_GPS_MAP))
-#define OSM_GPS_MAP_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), OSM_TYPE_GPS_MAP, OsmGpsMapClass))
-
-typedef struct _OsmGpsMapClass OsmGpsMapClass;
-typedef struct _OsmGpsMap OsmGpsMap;
-typedef struct _OsmGpsMapPrivate OsmGpsMapPrivate;
-
-#include "osm-gps-map-layer.h"
-
-struct _OsmGpsMapClass
-{
-    GtkDrawingAreaClass parent_class;
-};
-
-struct _OsmGpsMap
-{
-    GtkDrawingArea parent_instance;
-    OsmGpsMapPrivate *priv;
-};
-
-typedef struct {
-    float rlat;
-    float rlon;
-} coord_t;
-
-typedef enum {
-    OSM_GPS_MAP_SOURCE_NULL,
-    OSM_GPS_MAP_SOURCE_OPENSTREETMAP,
-    OSM_GPS_MAP_SOURCE_OPENSTREETMAP_RENDERER,
-    OSM_GPS_MAP_SOURCE_OPENAERIALMAP,
-    OSM_GPS_MAP_SOURCE_MAPS_FOR_FREE,
-    OSM_GPS_MAP_SOURCE_OPENCYCLEMAP,
-    OSM_GPS_MAP_SOURCE_OSM_PUBLIC_TRANSPORT,
-    OSM_GPS_MAP_SOURCE_GOOGLE_STREET,
-    OSM_GPS_MAP_SOURCE_GOOGLE_SATELLITE,
-    OSM_GPS_MAP_SOURCE_GOOGLE_HYBRID,
-    OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_STREET,
-    OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_SATELLITE,
-    OSM_GPS_MAP_SOURCE_VIRTUAL_EARTH_HYBRID,
-    OSM_GPS_MAP_SOURCE_YAHOO_STREET,
-    OSM_GPS_MAP_SOURCE_YAHOO_SATELLITE,
-    OSM_GPS_MAP_SOURCE_YAHOO_HYBRID,
-    OSM_GPS_MAP_SOURCE_OSMC_TRAILS,
-
-    OSM_GPS_MAP_SOURCE_LAST
-} OsmGpsMapSource_t;
-
-typedef enum {
-    OSM_GPS_MAP_KEY_FULLSCREEN,
-    OSM_GPS_MAP_KEY_ZOOMIN,
-    OSM_GPS_MAP_KEY_ZOOMOUT,
-    OSM_GPS_MAP_KEY_UP,
-    OSM_GPS_MAP_KEY_DOWN,
-    OSM_GPS_MAP_KEY_LEFT,
-    OSM_GPS_MAP_KEY_RIGHT,
-    OSM_GPS_MAP_KEY_MAX
-} OsmGpsMapKey_t;
-
-#define OSM_GPS_MAP_INVALID         (0.0/0.0)
-#define OSM_GPS_MAP_CACHE_DISABLED  "none://"
-#define OSM_GPS_MAP_CACHE_AUTO      "auto://"
-#define OSM_GPS_MAP_CACHE_FRIENDLY  "friendly://"
-
-GType       osm_gps_map_get_type                    (void) G_GNUC_CONST;
-
-GtkWidget*  osm_gps_map_new                         (void);
-
-char*       osm_gps_map_get_default_cache_directory (void);
-
-const char* osm_gps_map_source_get_friendly_name    (OsmGpsMapSource_t source);
-const char* osm_gps_map_source_get_repo_uri         (OsmGpsMapSource_t source);
-const char* osm_gps_map_source_get_image_format     (OsmGpsMapSource_t source);
-int         osm_gps_map_source_get_min_zoom         (OsmGpsMapSource_t source);
-int         osm_gps_map_source_get_max_zoom         (OsmGpsMapSource_t source);
-gboolean    osm_gps_map_source_is_valid             (OsmGpsMapSource_t source);
-
-void        osm_gps_map_download_maps               (OsmGpsMap *map, coord_t *pt1, coord_t *pt2, int zoom_start, int zoom_end);
-void        osm_gps_map_get_bbox                    (OsmGpsMap *map, coord_t *pt1, coord_t *pt2);
-void        osm_gps_map_set_mapcenter               (OsmGpsMap *map, float latitude, float longitude, int zoom);
-void        osm_gps_map_set_center                  (OsmGpsMap *map, float latitude, float longitude);
-int         osm_gps_map_set_zoom                    (OsmGpsMap *map, int zoom);
-int         osm_gps_map_zoom_in                     (OsmGpsMap *map);
-int         osm_gps_map_zoom_out                    (OsmGpsMap *map);
-void        osm_gps_map_add_track                   (OsmGpsMap *map, GSList *track);
-void        osm_gps_map_replace_track               (OsmGpsMap *map, GSList *old_track, GSList *new_track);
-void        osm_gps_map_clear_tracks                (OsmGpsMap *map);
-void        osm_gps_map_add_image                   (OsmGpsMap *map, float latitude, float longitude, GdkPixbuf *image);
-void        osm_gps_map_add_image_with_alignment    (OsmGpsMap *map, float latitude, float longitude, GdkPixbuf *image, float xalign, float yalign);
-gboolean    osm_gps_map_remove_image                (OsmGpsMap *map, GdkPixbuf *image);
-void        osm_gps_map_clear_images                (OsmGpsMap *map);
-void        osm_gps_map_draw_gps                    (OsmGpsMap *map, float latitude, float longitude, float heading);
-void        osm_gps_map_clear_gps                   (OsmGpsMap *map);
-coord_t     osm_gps_map_get_co_ordinates            (OsmGpsMap *map, int pixel_x, int pixel_y);
-void        osm_gps_map_screen_to_geographic        (OsmGpsMap *map, gint pixel_x, gint pixel_y, gfloat *latitude, gfloat *longitude);
-void        osm_gps_map_geographic_to_screen        (OsmGpsMap *map, gfloat latitude, gfloat longitude, gint *pixel_x, gint *pixel_y);
-void        osm_gps_map_scroll                      (OsmGpsMap *map, gint dx, gint dy);
-float       osm_gps_map_get_scale                   (OsmGpsMap *map);
-void        osm_gps_map_set_keyboard_shortcut       (OsmGpsMap *map, OsmGpsMapKey_t key, guint keyval);
-void        osm_gps_map_add_layer                   (OsmGpsMap *map, OsmGpsMapLayer *layer);
-
-G_END_DECLS
+#include <osm-gps-map-osd.h>
+#include <osm-gps-map-layer.h>
+#include <osm-gps-map-track.h>
+#include <osm-gps-map-point.h>
+#include <osm-gps-map-image.h>
+#include <osm-gps-map-source.h>
+#include <osm-gps-map-widget.h>
+#include <osm-gps-map-compat.h>
 
 #endif /* _OSM_GPS_MAP_H_ */
+

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/osm-gps-map.git



More information about the Pkg-grass-devel mailing list